public override SValue Clone() { SString ret = new SString((string)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 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 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)); }