public override SValue Clone() { SList ret = new SList((List <SValue>)Underlying); SValue.CopyAttributes(ret, this); return(ret); }
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) { 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)); }
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)); }