public SEMultiCore(SExprAtomic ha, SExprComp c, string f) : base(ha, c) { argumentExprs = (from a in c.Atomics select SExpression.Cast(a)).ToList(); func = f; if (argumentExprs.Count < 1) { throw new VMException("it takes at least 1 argument", ha); } }
public SEDel(SExprAtomic ha, SExprComp c) : base(ha, c) { if (c.Atomics.Count != 2) { throw new VMException("it takes 2 arguments", ha); } host = SExpression.Cast(c.Atomics.Pop()); index = SExpression.Cast(c.Atomics.Pop()); }
public SEGet(SExprAtomic ha, SExprComp c) : base(ha, c) { if (c.Atomics.Count < 2) { throw new VMException("it takes at least 2 arguments", ha); } dict = SExpression.Cast(c.Atomics.Pop()); keys = c.Atomics.Select(a => SExpression.Cast(a)).ToList(); }
public SESplit(SExprAtomic ha, SExprComp c) : base(ha, c) { if (c.Atomics.Count != 2) { throw new VMException("it takes 2 arguments", ha); } text = SExpression.Cast(c.Atomics.Pop()); delim = SExpression.Cast(c.Atomics.Pop()); }
public SENum(SExprAtomic ha, SExprComp c, bool asc) : base(ha, c) { if (c.Atomics.Count != 1) { throw new VMException("it takes 1 argument"); } argument = SExpression.Cast(c.Atomics.Pop()); convertAsc = asc; }
public SEInteropGetSetMember(SExprAtomic ha, SExprComp c) : base(ha, c) { if (c.Atomics.Count < 2) { throw new VMException("it takes at least 2 arguments", ha); } obj = SExpression.Cast(c.Atomics.Pop()); propName = SExpression.Cast(c.Atomics.Pop()); }
public SEStr(SExprAtomic ha, SExprComp c, bool chr) : base(ha, c) { if (c.Atomics.Count != 1) { throw new VMException("it takes 1 argument"); } argument = SExpression.Cast(c.Atomics.Pop()); convertChr = chr; }
public SEInteropNew(SExprAtomic ha, SExprComp c) : base(ha, c) { if (c.Atomics.Count < 1) { throw new VMException("it takes at least 1 argument", ha); } type = SExpression.Cast(c.Atomics.Pop()); arguments = c.Atomics.Select(a => SExpression.Cast(a)).ToList(); }
public SEPrint(SExprAtomic ha, SExprComp c, string d) : base(ha, c) { delim = d; if (c.Atomics.Count == 0) { throw new VMException("it takes at least 1 argument", ha); } arguments = (from a in c.Atomics select SExpression.Cast(a)).ToList(); }
public SEFor(SExprAtomic ha, SExprComp c) : base(ha, c) { if (c.Atomics.Count < 2) { throw new VMException("it takes 2 arguments", ha); } list = SExpression.Cast(c.Atomics.Pop()); body = SExpression.Cast(c.Atomics.Pop()); }
public SEDict(SExprAtomic ha, SExprComp c) : base(ha, c) { values = c.Atomics.Select(a => { if (!(a is SExprComp) || (a as SExprComp).Atomics.Count != 2) { throw new VMException("each element of the dict must be a list with 2 elements", ha); } return(SExpression.Cast(a)); }).ToList(); }
public SEInteropInvokeStaticMethod(SExprAtomic ha, SExprComp c) : base(ha, c) { if (c.Atomics.Count < 2) { throw new VMException("it takes at least 2 arguments", ha); } type = SExpression.Cast(c.Atomics.Pop()); methodName = SExpression.Cast(c.Atomics.Pop()); arguments = c.Atomics.Select(a => SExpression.Cast(a)).ToList(); }
public override SValue Evaluate(ExecEnvironment env) { var arguments = SExpression.EvalSExpressions(this.arguments, env); var subObj = arguments[0]; try { if (subObj is SString) { SString subStr = subObj as SString; if (arguments.Count == 2) { return(new SString(subStr.Get <string>().Substring( (int)arguments[1].Get <Decimal>() ))); } else { return(new SString(subStr.Get <string>().Substring( (int)arguments[1].Get <Decimal>(), (int)arguments[2].Get <Decimal>() ))); } } else if (subObj is SList) { SList subList = subObj as SList; if (arguments.Count == 2) { return(new SList(subList.Get <List <SValue> >().Skip( (int)arguments[1].Get <Decimal>() ).ToList())); } else { return(new SList(subList.Get <List <SValue> >().Skip( (int)arguments[1].Get <Decimal>()).Take( (int)arguments[2].Get <Decimal>() ).ToList())); } } else { throw new VMException("the first argument must be a string or a list", headAtom); } } catch { throw new VMException("invalid arguments", headAtom); } }
public override SValue Evaluate(ExecEnvironment env) { SValue ret = new SBool(false); foreach (var e in SExpression.EvalSExpressions(arguments, env)) { ret = e; Console.Write(printSValue(e, env, 2)); } Console.Write(delim); return(ret); }
public SEEval(SExprAtomic ha, SExprComp c) : base(ha, c) { if (c.Atomics.Count != 1 && c.Atomics.Count != 2) { throw new VMException("it takes 1 or 2 arguments"); } text = SExpression.Cast(c.Atomics.Pop()); if (c.Atomics.Count > 0) { env = SExpression.Cast(c.Atomics.Pop()); } }
public SELambda(SExprAtomic ha, SExprComp c) { if (c.Atomics.Count < 2) { throw new VMException("missing lambda body", ha); } if (!(c.Atomics[0] is SExprComp)) { throw new VMException("the first argument must be the declaration", ha); } arguments = SELambda.CompoundToArguments(c.Atomics.Pop() as SExprComp, ha); body = SExpression.Cast(c.Atomics.Pop()); }
public SEIf(SExprAtomic ha, SExprComp c) { if (c.Atomics.Count == 0) { throw new VMException("missing true branch", ha); } if (c.Atomics.Count == 1) { throw new VMException("missing false branch", ha); } condition = SExpression.Cast(c.Atomics.Pop()); trueBranch = SExpression.Cast(c.Atomics.Pop()); falseBranch = SExpression.Cast(c.Atomics.Pop()); }
public object ExecuteFile(string filePath, ExecEnvironment ee) { string code = File.ReadAllText(filePath); var p = new Parser(); var path = EugineVM.GetDirectoryName(filePath); var source = Path.GetFileName(filePath); ee["~path"] = new SString(path); ee["~source"] = new SString(source); var s = p.Parse(code, path, source); return(SExpression.Cast(s).Evaluate(ee).Get <object>()); }
public SEType(SExprAtomic ha, SExprComp c) : base(ha, c) { if (c.Atomics.Count == 0) { throw new VMException("it takes 1 argument", ha); } var n = c.Atomics.Pop(); if (n is SExprAtomic && (n as SExprAtomic).Token.TType == SToken.TokenType.ATOMIC) { vname = (string)(n as SExprAtomic).Token.TValue; } else { nameExpr = SExpression.Cast(n); } }
public object ExecuteString(string code, ExecEnvironment ee) { var p = new Parser(); var path = ""; var source = ""; if (ee.ContainsKey("~path")) { path = ee["~path"].Evaluate(null).Get <String>(); } if (ee.ContainsKey("~source")) { source = ee["~source"].Evaluate(null).Get <String>(); } var s = p.Parse(code, path, source); return(SExpression.Cast(s).Evaluate(ee).Get <object>()); }
public SERegex(SExprAtomic ha, SExprComp c) : base(ha, c) { if (c.Atomics.Count > 0) { re = SExpression.Cast(c.Atomics.Pop()); if (c.Atomics.Count > 0) { option = SExpression.Cast(c.Atomics.Pop()); } else { option = new SString("None"); } } else { throw new VMException("it takes 1 or 2 arguments", ha); } }
public SERange(SExprAtomic ha, SExprComp c) : base(ha, c) { var args = (from v in c.Atomics select SExpression.Cast(v)).ToList(); if (args.Count == 2) { start = args[0]; end = args[1]; interval = new SNumber(1); } else if (args.Count == 3) { start = args[0]; interval = args[1]; end = args[2]; } else { throw new VMException("it takes 2 or 3 arguments", ha); } }
public SEDefun(SExprAtomic ha, SExprComp c) { if (c.Atomics.Count < 3) { throw new VMException("missing function body", ha); } if (!(c.Atomics[1] is SExprComp)) { throw new VMException("the second argument must be the declaration", ha); } var n = c.Atomics.Pop(); if (!(n is SExprAtomic) || (n as SExprAtomic).Token.TType != SToken.TokenType.ATOMIC) { throw new VMException("function name must be an atom", ha); } func = (string)(n as SExprAtomic).Token.TValue; arguments = SELambda.CompoundToArguments(c.Atomics.Pop() as SExprComp, ha); var tmp = c.Atomics.Pop(); if (tmp is SExprAtomic && (tmp as SExprAtomic).Token.TType == SToken.TokenType.STRING) { description = (string)(tmp as SExprAtomic).Token.TValue; if (c.Atomics.Count == 0) { throw new VMException("missing function body", ha); } body = SExpression.Cast(c.Atomics.Pop()); } else { body = SExpression.Cast(tmp); } }
public SESingleCore(SExprAtomic ha, SExprComp c, string f) : base(ha, c) { argument = c.Atomics.Count > 0 ? SExpression.Cast(c.Atomics.Pop()) : null; func = f; }
public SEChain(SExprComp c) { expressions = (from e in c.Atomics select SExpression.Cast(e)).ToList(); }
public SEReverseChain(SExprComp c) : base((from e in c.Atomics select SExpression.Cast(e)).Reverse()) { }
public override SValue Evaluate(ExecEnvironment env) { arguments = SExpression.EvalSExpressions(argumentExprs, env); try { switch (func) { case "<": return(new SBool(compareNumber(new int[] { -1 }, env))); case "<=": return(new SBool(compareNumber(new int[] { -1, 0 }, env))); case ">": return(new SBool(compareNumber(new int[] { 1 }, env))); case ">=": return(new SBool(compareNumber(new int[] { 1, 0 }, env))); case "==": return(new SBool(objectEquality(true, env))); case "<>": return(new SBool(objectEquality(false, env))); case "&&": return(new SBool(compareBool("and", env))); case "||": return(new SBool(compareBool("or", env))); case "+": return(tryPlus(env)); case "-": case "*": case "/": case "%": var r = arguments[0].Evaluate(env); if (!r.Is <Decimal>()) { throw new VMException("it only apply to numbers", headAtom); } var host = r.Get <Decimal>(); for (var i = 1; i < arguments.Count(); i++) { var v1 = arguments[i].Evaluate(env); if (v1.Is <Decimal>()) { switch (func) { case "-": host -= v1.Get <Decimal>(); break; case "*": host *= v1.Get <Decimal>(); break; case "/": case "%": Decimal tmp = v1.Get <Decimal>(); if (tmp != 0) { if (func == "/") { host /= tmp; } else { host %= tmp; } } else { throw new VMException("divided by 0", headAtom); } break; default: throw new NotImplementedException(); } } else { throw new VMException("it only apply to numbers", headAtom); } } return(new SNumber(host)); default: throw new NotImplementedException(); } } catch (System.OverflowException) { throw new VMException("arithmetic operation failed due to overflow", headAtom); } }
public override SValue Evaluate(ExecEnvironment env) { if (argument == null) { return(new SClosure(env, new List <string>() { "x" }, SExpression.Cast(SExpr.MakeLambda(func, "x")))); } var arg = argument.Evaluate(env); Decimal n = 0; if (arg is SNumber) { n = arg.Get <Decimal>(); } else if (arg is SBool) { n = arg.Get <bool>() ? 1 : 0; } switch (func) { case "sin": return(new SNumber((Decimal)Math.Sin((double)n))); case "cos": return(new SNumber((Decimal)Math.Cos((double)n))); case "tan": return(new SNumber((Decimal)Math.Tan((double)n))); case "asin": return(new SNumber((Decimal)Math.Asin((double)n))); case "acos": return(new SNumber((Decimal)Math.Acos((double)n))); case "atan": return(new SNumber((Decimal)Math.Atan((double)n))); case "round": return(new SNumber((Decimal)Math.Round((double)n))); case "floor": return(new SNumber((Decimal)Math.Floor((double)n))); case "abs": return(new SNumber((Decimal)Math.Abs((double)n))); case "sqrt": return(new SNumber((Decimal)Math.Sqrt((double)n))); case "random": if (n != 0) { var rand = new Random((int)(n % Int32.MaxValue)); return(new SNumber((Decimal)rand.NextDouble())); } else { return(new SNumber((Decimal)SExpression.DefaultRandom.NextDouble())); } case "time": var t = (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))); return(new SNumber((Decimal)t.TotalMilliseconds / n)); case "not": return(new SBool(Math.Abs(n - 1) == 1)); default: throw new NotImplementedException(); } }
public SClosure(ExecEnvironment env, List <string> args, SExpression b) : base(b) { InnerEnv = env; Arguments = args; Body = b; }
public override SValue Evaluate(ExecEnvironment env) { var body = this.body.Evaluate(env) as SClosure; if (body == null) { throw new VMException("the second argument must be a lambda or a named function", headAtom); } SValue _list = this.list.Evaluate(env); List <SValue> values = new List <SValue>(); SList list = new SList(values); bool whileLoop = false; bool condAlwaysTrue = false; if (_list is SList) { list = _list as SList; values = list.Get <List <SValue> >(); if (values.Count == 0) { whileLoop = true; condAlwaysTrue = true; } } else if (_list is SBool) { whileLoop = true; condAlwaysTrue = false; } else { throw new VMException("the first argument must be a list or a bool", headAtom); } if (whileLoop) { while (condAlwaysTrue || this.list.Evaluate(env).Get <bool>()) { var ret = execLoop(body, new SNull(), 0); if (ret.Is <bool>() && !ret.Get <bool>()) { break; } } } else { for (var i = 0; i < values.Count; i++) { var ret = execLoop(body, values[i], i); if (ret.Is <bool>() && !ret.Get <bool>()) { break; } } } return(new SBool(true)); }