using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
namespace Luneraria.Core.Tests
{
///
/// Float diagnosis for a runtime (docs/port/U1.5-UNITY.md): evaluates the core's own Vec2 and
/// GdMath operations on the inputs of tools/godot-golden/float_probe.gd and compares the raw
/// bits with Godot's results (Golden/float_probe.json). A second part classifies how the
/// runtime evaluates float32 expressions: strictly per operation, with double-precision
/// intermediates (allowed by ECMA-335 I.12.1.3) or with fused multiply-add.
///
public static class FloatProbe
{
public sealed class Result
{
public int Rows;
public readonly OrderedMap Identical = new OrderedMap();
public readonly OrderedMap WorstUlps = new OrderedMap();
public readonly OrderedMap Evaluation = new OrderedMap();
public int EvaluationSamples;
public int Mismatches
{
get
{
int total = 0;
foreach (KeyValuePair pair in Identical)
total += Rows - pair.Value;
return total;
}
}
public string ToJson(string runtime, string label)
{
var text = new StringBuilder();
text.Append("{\n");
text.AppendFormat(" \"runtime\": \"{0}\",\n \"label\": \"{1}\",\n \"rows\": {2},\n", runtime, label, Rows);
text.Append(" \"identical_to_godot\": {");
bool first = true;
foreach (KeyValuePair pair in Identical)
{
text.AppendFormat(CultureInfo.InvariantCulture, "{0}\n \"{1}\": {2}", first ? "" : ",", pair.Key, pair.Value);
first = false;
}
text.Append("\n },\n \"worst_ulps\": {");
first = true;
foreach (KeyValuePair pair in WorstUlps)
{
text.AppendFormat(CultureInfo.InvariantCulture, "{0}\n \"{1}\": {2}", first ? "" : ",", pair.Key, pair.Value);
first = false;
}
text.AppendFormat("\n }},\n \"evaluation_samples\": {0},\n \"evaluation_matches\": {{", EvaluationSamples);
first = true;
foreach (KeyValuePair pair in Evaluation)
{
text.AppendFormat(CultureInfo.InvariantCulture, "{0}\n \"{1}\": {2}", first ? "" : ",", pair.Key, pair.Value);
first = false;
}
text.Append("\n }\n}\n");
return text.ToString();
}
}
public static Result Run(string goldenDirectory)
{
var result = new Result();
var probe = MiniJson.Obj(MiniJson.Parse(File.ReadAllText(Path.Combine(goldenDirectory, "float_probe.json"))));
foreach (object item in MiniJson.Arr(probe["rows"]))
{
List