加入自动类型转换
This commit is contained in:
@@ -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;
|
||||||
|
@@ -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>
|
||||||
{
|
{
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user