public static object Defmacro(FunctionInvocation call) { var func = call.Args[1] as SymbolNode; var definedArgs = call.Args[2] as ConsNode; var definedBody = call.Args[3] as ConsNode; LispFunc lispFunc = kall => { //---kall.StackFrame.ScopeId = Guid.NewGuid();--- //nope. stay in the same scope Scope oldScope = kall.StackFrame.Scope; var newScope = new Scope(kall.StackFrame.Scope); Utils.SetupMacroArgs(definedArgs, kall, newScope); kall.StackFrame.Scope = newScope; //call the body object tmpBody = definedBody.Eval(kall.StackFrame); object res = Utils.Eval(kall.StackFrame, tmpBody); Utils.TearDownArgs(definedArgs, kall); kall.StackFrame.Scope = oldScope; return(res); }; call.StackFrame.Scope.SetSymbolValue(func.Name, lispFunc); return(null); }
public static object Defun(FunctionInvocation call) { var func = call.Args[1] as SymbolNode; var definedArgs = call.Args[2] as ConsNode; //ConsNode definedBody = call.Args[3] as ConsNode; ConsNode definedBody = WrapInProgn(call.Args, 3, call.StackFrame.Root); Scope creatorScope = call.StackFrame.Scope; LispFunc lispFunc = kall => { //if (kall.Args.Count - 1 < definedArgs.Args.Count) //{ // LispFunc curryFunc = MakeCurryCall(call, definedArgs, definedBody, kall); // return curryFunc; //} //else //{ Scope oldScope = kall.StackFrame.Scope; var newScope = new Scope(creatorScope); Utils.SetupArgs(definedArgs, kall, newScope); kall.StackFrame.Scope = newScope; //call the body object res = definedBody.Eval(kall.StackFrame); //tail recursion int recursions = 0; while (res is TailRecursionValue) { recursions++; var tail = res as TailRecursionValue; var tailCons = tail.Expression as ConsNode; newScope = new Scope(creatorScope); kall.Args = tailCons.Args; Utils.SetupArgs(definedArgs, kall, newScope); kall.StackFrame.Scope = newScope; res = definedBody.Eval(kall.StackFrame); } Utils.TearDownArgs(definedArgs, kall); kall.StackFrame.Scope = oldScope; return(res); //} }; call.StackFrame.Scope.SetSymbolValue(func.Name, lispFunc); // FunctionMeta meta = call.StackFrame.Root.GetFunctionMeta(lispFunc); // meta.ParameterCount = definedArgs.Args.Count; return(null); }
public void SetSymbolValue(string name, LispFunc value) { Symbol var = GetSymbol(name); var.Value = value; }
public FunctionInvocation(LispFunc func, List <object> args, StackFrame stackFrame) { Func = func; Args = args; StackFrame = stackFrame; }
protected internal virtual void OnEndNotifyCall(StackFrame stackFrame, ConsNode cons, LispFunc func, string funcName, object res) { if (EndNotifyCall != null) { EndNotifyCall(stackFrame, cons, func, funcName, res); } }
public static object Lambda(FunctionInvocation call) { ConsNode definedArgs = null; ConsNode definedBody = null; var info = new CloneInfo(); info.StackFrame = call.StackFrame; Scope creatorScope = call.StackFrame.Scope; ValueNode bodyNode = null; if (call.Args.Count == 2) { definedArgs = new ConsNode(); definedArgs.Args = new List <object>(); var varNode = new SymbolNode(); varNode.Name = "item"; definedArgs.Args.Add(varNode); bodyNode = call.Args[1] as ConsNode; } else if (call.Args.Count == 3) { if (call.Args[1] is ConsNode) { definedArgs = call.Args[1] as ConsNode; } else { definedArgs = Utils.Eval(call.StackFrame, call.Args[1]) as ConsNode; } bodyNode = call.Args[2] as ConsNode; } info.LocalIdentifiers = definedArgs.Args.Cast <SymbolNode>().Select(arg => Utils.CleanName(arg.Name)).ToList(); //make snapshot of bound non local identifiers definedBody = bodyNode.Clone(info) as ConsNode; LispFunc lispFunc = kall => { //todo: verify arg list, only identifiers allowed Scope oldScope = kall.StackFrame.Scope; var newScope = new Scope(creatorScope); Utils.SetupArgs(definedArgs, kall, newScope); kall.StackFrame.Scope = newScope; //call the body object res = definedBody.Eval(kall.StackFrame); Utils.TearDownArgs(definedArgs, kall); kall.StackFrame.Scope = oldScope; return(res); }; return(lispFunc); }
protected internal virtual void OnBeginNotifyCall(StackFrame stackFrame, ConsNode cons, LispFunc func, string funcName) { if (BeginNotifyCall != null) { BeginNotifyCall(stackFrame, cons, func, funcName); } }
protected internal virtual void OnEndNotifyCall(StackFrame stackFrame, ConsNode cons, LispFunc func, string funcName, object res) { if (EndNotifyCall != null) EndNotifyCall(stackFrame, cons, func, funcName, res); }
protected internal virtual void OnBeginNotifyCall(StackFrame stackFrame, ConsNode cons, LispFunc func, string funcName) { if (BeginNotifyCall != null) BeginNotifyCall(stackFrame, cons, func, funcName); }
public FunctionInvocation(LispFunc func, List<object> args, StackFrame stackFrame) { Func = func; Args = args; StackFrame = stackFrame; }