Beispiel #1
0
        public static LithpPrimitive Scope(LithpList parameters, LithpOpChain state,
                                           LithpInterpreter interp)
        {
            LithpFunctionDefinition def = (LithpFunctionDefinition)parameters[0];

            return(def.CloneWithScope(state));
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }