public static LithpPrimitive Scope(LithpList parameters, LithpOpChain state, LithpInterpreter interp) { LithpFunctionDefinition def = (LithpFunctionDefinition)parameters[0]; return(def.CloneWithScope(state)); }
public static LithpOpChain Factorial() { // ( LithpOpChain result = new LithpOpChain(); // (if (== 1 N) ( // (1) // ) (else ( // (* N (fac (- N 1))) // ))) LithpOpChain facBody = new LithpOpChain(result); LithpOpChain return1 = new LithpOpChain(facBody); return1.Add(new LithpLiteral(1)); LithpOpChain elseBody = new LithpOpChain(facBody); elseBody.Add( LithpFunctionCall.New("*/*", LithpFunctionCall.New("get/1", new LithpVariableReference("N")), LithpFunctionCall.New("fac/1", LithpFunctionCall.New("-/*", LithpFunctionCall.New("get/1", new LithpVariableReference("N")), new LithpLiteral(1) ) ) ) ); facBody.Add( LithpFunctionCall.New("if/3", LithpFunctionCall.New("==/2", new LithpLiteral(1), LithpFunctionCall.New("get/1", new LithpVariableReference("N")) ), return1, LithpFunctionCall.New("else/1", elseBody) ) ); // (def fac #N :: ( LithpFunctionCall def = LithpFunctionCall.New("def/2", LithpAtom.Atom("fac"), LithpFunctionDefinition.New(result, "fac", facBody, "N") ); // ) result.Add(def); int n; #if DEBUG n = 10; #else n = 500; #endif result.Add(LithpFunctionCall.New("print/*", "Factorial result: ", LithpFunctionCall.New("fac/1", n))); return(result); }
protected ILithpOpChainMember convert(LithpOpChain chain, JObject curr) { JArray fncode = (JArray)curr["code"]; JArray fnparams = (JArray)curr["_fnparams"]; List <string> defParams = new List <string>(); foreach (JValue p in fnparams) { defParams.Add(p.ToString()); parserDebug("Param: {0}", p.ToString()); } parserDebug("FunctionDef with params {0}, code: {1}", defParams.ToArray(), fncode); LithpOpChain defBody = (LithpOpChain)convert(chain, fncode); string name = "anonymous:" + (AnonymousFnCounter++).ToString(); ILithpOpChainMember def = new LithpFunctionDefinition(chain, name, defBody, defParams.ToArray()); parserDebug("FnDef created: {0}", def); return(def); }
public static LithpPrimitive Def(LithpList parameters, LithpOpChain state, LithpInterpreter interp) { ILithpPrimitive name = parameters[0]; if (name.LithpType() != LithpType.ATOM) { throw new ArgumentException("Function name must be an atom"); } if (parameters[1].LithpType() != LithpType.FN) { throw new ArgumentException("Function body must be a FunctionDefinition"); } LithpFunctionDefinition body = (LithpFunctionDefinition)parameters[1]; body.SetName(parameters[0]); state.Closure.SetImmediate(body.Name, body); return(body); }
static void RunTests() { LithpOpChain chain = new LithpOpChain(); LithpInteger one = 1; LithpAtom test = "test"; LithpDict dict = new LithpDict(); dict["foo"] = "bar"; dict["num"] = 1; dict["list"] = LithpList.New("Hello, world!", one, test); Console.WriteLine(dict.ToLiteral()); LithpFunctionCall fncall = LithpFunctionCall.New("print/*", dict); Console.WriteLine("fncall tostring: {0}", fncall); LithpBuiltins builtins = new LithpBuiltins(); LithpInterpreter interp = new LithpInterpreter(); builtins[fncall.Function].Invoke(fncall.Parameters, chain, interp); // Now put it all together chain.Add(fncall); chain.ImportBuiltins(builtins); Console.WriteLine("Result of print: {0}", interp.Run(chain)); // More complex LithpFunctionCall addStrings = LithpFunctionCall.New("+/*", "foo", "bar"); LithpFunctionCall printAddString = LithpFunctionCall.New("print/*", "Adding two strings: ", addStrings); chain.Add(printAddString); interp.Run(chain); chain.Add(addStrings); Console.WriteLine("Result of add strings: {0}", interp.Run(chain)); LithpFunctionCall setVar = LithpFunctionCall.New("set/2", new LithpVariableReference("Test"), "Foo"); LithpFunctionCall printVar = LithpFunctionCall.New("print/*", "Value of Test:", LithpFunctionCall.New( "get/1", new LithpVariableReference("Test") )); chain.Add(setVar); chain.Add(printVar); // Now run entire chain from the start chain.Rewind(); interp.Run(chain); // Try a user-defined function LithpOpChain addBody = new LithpOpChain(chain); addBody.Add(LithpFunctionCall.New( LithpAtom.Atom("+/*"), LithpFunctionCall.New("get/1", new LithpVariableReference("A")), LithpFunctionCall.New("get/1", new LithpVariableReference("B")) )); chain.Add(LithpFunctionCall.New("def/2", LithpAtom.Atom("add"), LithpFunctionDefinition.New(chain, "add", addBody, "A", "B") )); chain.Add(LithpFunctionCall.New("print/*", "Calling user function add:", LithpFunctionCall.New( "add/2", 2, 5 ) )); interp.Run(chain); }