加入自动类型转换

This commit is contained in:
2025-10-16 10:24:59 +08:00
parent 70051b46a5
commit 3866cdd525
3 changed files with 139 additions and 48 deletions

View File

@@ -1,12 +1,62 @@
using Flee.PublicTypes; using Flee.PublicTypes;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Convention.RScript.Parser namespace Convention.RScript
{ {
public static class ExpressionMath
{
public static int Sign(double value, double accuracy = ExpressionExtension.DefaultDoubleAccuracy)
{
if (value.IsCloseToZero(accuracy))
return 0;
return value > 0 ? 1 : -1;
}
public static int Compare(double value1, double value2, double accuracy = ExpressionExtension.DefaultDoubleAccuracy)
{
if (value1.IsClose(value2, accuracy))
return 0;
return value1 > value2 ? 1 : -1;
}
public static bool IsBetween(double value, double minValue, double maxValue, double accuracy = ExpressionExtension.DefaultDoubleAccuracy)
{
return Compare(value, minValue, accuracy) >= 0 && Compare(value, maxValue, accuracy) <= 0;
}
public static bool IsBetweenExclusive(double value, double minValue, double maxValue, double accuracy = ExpressionExtension.DefaultDoubleAccuracy)
{
return Compare(value, minValue, accuracy) > 0 && Compare(value, maxValue, accuracy) < 0;
}
public static int ToInt(double value)
{
return (int)value;
}
public static int ToInt(float value)
{
return (int)value;
}
public static int ToInt(int value)
{
return (int)value;
}
public static double ToDouble(float value)
{
return (double)value;
}
public static double ToDouble(int value)
{
return (double)value;
}
public static double ToDouble(double value)
{
return (double)value;
}
}
public static class ExpressionExtension public static class ExpressionExtension
{ {
public const double DefaultDoubleAccuracy = 1e-7; public const double DefaultDoubleAccuracy = 1e-7;
@@ -32,7 +82,10 @@ namespace Convention.RScript.Parser
return !(double.IsInfinity(value) || double.IsNaN(value) || value > maximumAbsoluteError || value < -maximumAbsoluteError); return !(double.IsInfinity(value) || double.IsNaN(value) || value > maximumAbsoluteError || value < -maximumAbsoluteError);
} }
} }
}
namespace Convention.RScript.Parser
{
public class ExpressionParser public class ExpressionParser
{ {
public readonly ExpressionContext context; public readonly ExpressionContext context;

View File

@@ -11,7 +11,34 @@ namespace Convention.RScript
public struct RScriptVariableEntry public struct RScriptVariableEntry
{ {
public Type type; public Type type;
public object data; public object data
{
readonly get
{
return internalData;
}
set
{
if (type == null)
{
type = value.GetType();
internalData = value;
return;
}
internalData = Convert.ChangeType(value, type);
}
}
private object internalData;
public RScriptVariableEntry(object data) : this()
{
this.data = data;
}
public RScriptVariableEntry(Type type, object data) : this()
{
this.type = type;
this.data = data;
}
} }
public class RScriptVariables : IDictionary<string, RScriptVariableEntry> public class RScriptVariables : IDictionary<string, RScriptVariableEntry>
{ {

View File

@@ -206,7 +206,7 @@ namespace Convention.RScript
} }
if (CurrentLocalSpaceVariableNames.Peek().Contains(varName) == false) if (CurrentLocalSpaceVariableNames.Peek().Contains(varName) == false)
{ {
Variables.Add(varName, new() { type = varType, data = varDefaultValue }); Variables.Add(varName, new(varType, varDefaultValue));
parser.context.Variables[varName] = varDefaultValue; parser.context.Variables[varName] = varDefaultValue;
CurrentLocalSpaceVariableNames.Peek().Add(varName); CurrentLocalSpaceVariableNames.Peek().Add(varName);
} }
@@ -350,48 +350,59 @@ namespace Convention.RScript
private object RunNextStep(ExpressionParser parser) private object RunNextStep(ExpressionParser parser)
{ {
var sentence = CurrentSentence; var sentence = CurrentSentence;
switch (sentence.mode) try
{ {
case RScriptSentence.Mode.Expression: switch (sentence.mode)
return parser.Evaluate(sentence.content); {
case RScriptSentence.Mode.DefineVariable: case RScriptSentence.Mode.Expression:
{ return parser.Evaluate(sentence.content);
DoDefineVariable(parser, sentence); case RScriptSentence.Mode.DefineVariable:
} {
break; DoDefineVariable(parser, sentence);
case RScriptSentence.Mode.EnterNamespace: }
{ break;
DoEnterNamespace(parser); case RScriptSentence.Mode.EnterNamespace:
} {
break; DoEnterNamespace(parser);
case RScriptSentence.Mode.ExitNamespace: }
{ break;
DoExitNamespace(parser); case RScriptSentence.Mode.ExitNamespace:
} {
break; DoExitNamespace(parser);
case RScriptSentence.Mode.Goto: }
{ break;
DoGoto(parser, sentence); case RScriptSentence.Mode.Goto:
} {
break; DoGoto(parser, sentence);
case RScriptSentence.Mode.Breakpoint: }
{ break;
DoBreakpoint(parser, sentence); case RScriptSentence.Mode.Breakpoint:
} {
break; DoBreakpoint(parser, sentence);
case RScriptSentence.Mode.Backpoint: }
{ break;
DoBackpoint(parser, sentence); case RScriptSentence.Mode.Backpoint:
} {
break; DoBackpoint(parser, sentence);
case RScriptSentence.Mode.NamedSpace: }
{ break;
DoEnterNamedSpace(sentence); case RScriptSentence.Mode.NamedSpace:
} {
break; DoEnterNamedSpace(sentence);
default: }
// Do nothing break;
break; default:
// Do nothing
break;
}
}
catch (RScriptRuntimeException)
{
throw;
}
catch (Exception ex)
{
throw new RScriptRuntimeException($"Runtime error: {ex.Message}", CurrentRuntimePointer, ex);
} }
return null; return null;
} }