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 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) { var newEnv = new ExecEnvironment(); SValue _closure; SClosure closure = null; if (lambdaObject == null) { if (env.ContainsKey(closureName)) { _closure = env[closureName].Evaluate(env); closure = _closure as SClosure; } else { _closure = new SString(closureName); env[closureName] = _closure; } } else { _closure = lambdaObject.Evaluate(env); closure = _closure as SClosure; } List <SValue> arguments = SExpression.EvalSExpressions(this.arguments, env); if (closure == null) { List <SValue> ret = new List <SValue>(); ret.Add(_closure); foreach (var a in arguments) { ret.Add(a); } return(new SList(ret)); } if (closure.Arguments.Count() > arguments.Count()) { var argNames = closure.Arguments.Skip(arguments.Count); return(new SClosure( env, argNames.ToList(), new SECall( closure, arguments.ConvertAll(a => (SExpression)a) .Concat(argNames.Select(a => new SEVariable(a, headAtom, tailCompound))).ToList(), headAtom, tailCompound ) )); } // prepare the executing environment for (int i = 0; i < closure.Arguments.Count(); i++) { string argName = closure.Arguments[i]; if (argName.Length > 3 && argName.Substring(argName.Length - 3) == "...") { argName = argName.Substring(0, argName.Length - 3); newEnv[argName] = new SList(arguments.Skip(i).ToList()); break; } else { newEnv[argName] = arguments[i]; } } newEnv["~parent"] = new SDict(closure.InnerEnv); newEnv["~atom"] = new SObject(headAtom); newEnv.ParentEnv = closure.InnerEnv; return(closure.Body.Evaluate(newEnv)); }