BasicNode Compare(Func <int, bool> resCheck, BasicEnvironment env, ConstantNode[] args) { var x = args[0]; var y = args[1]; const int InvalidValue = -99; int realRes = InvalidValue; if (x is NumericConstantNode || y is NumericConstantNode) { var nx = x.ToNumericConstant()?.Value; var ny = y.ToNumericConstant()?.Value; if (nx.HasValue && ny.HasValue) { realRes = nx.Value.CompareTo(ny.Value); } } if (realRes == InvalidValue && (x is StringConstantNode || y is StringConstantNode)) { var sx = x.StringValue; var sy = y.StringValue; realRes = string.Compare(sx, sy, StringComparison.CurrentCulture); } if (realRes == InvalidValue && (x is BoolConstantNode || y is BoolConstantNode)) { var bx = x.BoolValue; var by = y.BoolValue; realRes = bx.CompareTo(by); } if (realRes == InvalidValue) { return(env.RuntimeError("incompatible types for comparison")); } return(new BoolConstantNode(resCheck(realRes))); }
BasicNode NumFunc(BasicEnvironment env, ConstantNode[] args, Func <double, double> func) { var num = args[0].ToNumericConstant()?.Value; if (!num.HasValue) { return(env.RuntimeError($"internal function called with invalid argument {args[0].ToString()}")); } return(new NumericConstantNode(func(num.Value))); }
void SetInternalFunction(BasicEnvironment env, string name, Func <BasicEnvironment, ConstantNode[], BasicNode> func, params string[] argNames) { FunctionProperty prop = new FunctionProperty { Name = name, argumentNames = argNames, FuncImpl = func }; env.SetProperty(prop); }
public BasicNode Redim(BasicEnvironment env, int[] newDims) { if (newDims.Length != dims.Length) { return(env.RuntimeError("dimension count mismatch")); } bool sameDims = true; for (int i = 0; i < newDims.Length; i++) { if (dims[i] == newDims[i]) { continue; } sameDims = false; break; } if (sameDims) { return(ControlNode.Make(EvalResultKind.Ok, null)); } int[] curIndex = new int[dims.Length]; var dst = new ArrayProperty <T>(newDims); while (true) { curIndex[0]++; for (int i = 0; i < curIndex.Length - 1; i++) { if (curIndex[i] < dims[i]) { break; } if (i == curIndex.Length - 1) { break; } curIndex[i] = 0; curIndex[i + 1]++; } if (curIndex[curIndex.Length - 1] >= dims[curIndex.Length - 1]) { break; } T val; if (GetValue(curIndex, out val) && val != null) { dst.SetValue(curIndex, val); } } return(ControlNode.Make(EvalResultKind.Ok, null)); }
public void InitRun(BasicEnvironment env) { rand = new Random(1); SetIntenalNumFunc(env, "abs", Math.Abs); SetIntenalNumFunc(env, "atn", Math.Atan); SetIntenalNumFunc(env, "sin", Math.Sin); SetIntenalNumFunc(env, "cos", Math.Cos); SetIntenalNumFunc(env, "exp", Math.Exp); SetIntenalNumFunc(env, "log", Math.Log); SetIntenalNumFunc(env, "int", Math.Floor); SetIntenalNumFunc(env, "tan", Math.Tan); SetIntenalNumFunc(env, "sqr", Math.Sqrt); SetIntenalNumFunc(env, "sgn", d => Math.Sign(d)); SetInternalFunction(env, "rnd", (e, a) => Rnd(e, a)); SetInternalFunction(env, "randomize", (e, a) => Randomize(e, a)); SetInternalFunction(env, "=", (e, a) => Compare((cr) => cr == 0, e, a), "x", "y"); SetInternalFunction(env, "<>", (e, a) => Compare((cr) => cr != 0, e, a), "x", "y"); SetInternalFunction(env, "<=", (e, a) => Compare((cr) => cr <= 0, e, a), "x", "y"); SetInternalFunction(env, ">=", (e, a) => Compare((cr) => cr >= 0, e, a), "x", "y"); SetInternalFunction(env, "<", (e, a) => Compare((cr) => cr < 0, e, a), "x", "y"); SetInternalFunction(env, ">", (e, a) => Compare((cr) => cr > 0, e, a), "x", "y"); }
BasicNode Randomize(BasicEnvironment env, ConstantNode[] args) { rand = new Random(); return(NumericConstantNode.One); }
BasicNode Rnd(BasicEnvironment env, ConstantNode[] args) { return(new NumericConstantNode(rand.NextDouble())); }
void SetIntenalNumFunc(BasicEnvironment env, string name, Func <double, double> func) { SetInternalFunction(env, name, (e, a) => NumFunc(e, a, func), "x"); }
public AsyncBasicRunner(BasicEnvironment runtime) { this.Runtime = runtime; }
public virtual BasicNode Apply(BasicEnvironment env, ConstantNode[] args) { return(FuncImpl?.Invoke(env, args)); }