Exemplo n.º 1
0
        public static LispLiteral COND(Context context, params LispLiteral[] args)
        {
            if (args.Length < 1)
            {
                throw new LispPrimitiveBadArgNumber("COND", 1, args.Length);
            }

            LispLiteral result = null;
            int         i      = 0;

            while (i < args.Length && result == null)
            {
                if (args[i] is SExpr cond)
                {
                    var condition = EvalArg(context, cond.Head);
                    if (condition.BooleanValue)
                    {
                        result = EvalArg(context, cond.Tail.First());
                    }
                }

                i++;
            }

            if (result == null)
            {
                result = NilLiteral.Instance;
            }
            return(result);
        }
Exemplo n.º 2
0
        public static LispLiteral SETQ(Context context, params LispLiteral[] args)
        {
            if (args.Length != 2)
            {
                throw new LispPrimitiveBadArgNumber("SETQ", 2, args.Length);
            }

            LispLiteral v1 = args[0];

            if (args[1].Type == LispValueType.Sexpr)
            {
                //Console.WriteLine($"will call function {args[1]}");
            }
            LispLiteral v2 = EvalArg(context, args[1]);

            if (v2 is LispRuntimeFunction r)
            {
                r.Name = v1.StringValue;
            }


            if (v1.Type != LispValueType.Symbol)
            {
                throw new LispPrimitiveBadArgType("SETQ", 1, LispValueType.Symbol, args[0].Type);
            }

            if (v1 is SymbolLiteral symbol)
            {
                context.Set(symbol.Value, v2);
            }

            return(NilLiteral.Instance);
        }
Exemplo n.º 3
0
        public static LispLiteral SET(Context context, params LispLiteral[] args)
        {
            if (args.Length != 2)
            {
                throw new LispPrimitiveBadArgNumber("SET", 2, args.Length);
            }
            var evaluatedArgs = EvalArgs(context, args.ToList());

            LispLiteral v1 = evaluatedArgs[0];
            LispLiteral v2 = evaluatedArgs[1];


            if (v1.Type != LispValueType.Symbol)
            {
                throw new LispPrimitiveBadArgType("SET", 1, LispValueType.Symbol, args[0].Type);
            }


            if (v1 is SymbolLiteral symbol)
            {
                context.Set(symbol.Value, v2);
            }

            return(NilLiteral.Instance);
        }
Exemplo n.º 4
0
        public static LispLiteral CONS(Context context, params LispLiteral[] args)
        {
            var evaluatedArgs = EvalArgs(context, args.ToList());

            AssertArgNumber("cons", args, 2);

            List <LispLiteral> cons = new List <LispLiteral>();

            cons.Add(evaluatedArgs[0]);
            LispLiteral tail = evaluatedArgs[1];

            if (evaluatedArgs[1].Type == LispValueType.Sexpr)
            {
                cons.AddRange((evaluatedArgs[1] as SExpr).Elements);
            }
            else
            {
                if (evaluatedArgs[1] != NilLiteral.Instance)
                {
                    cons.Add(evaluatedArgs[1]);
                }
            }

            return(new SExpr(cons));
        }
Exemplo n.º 5
0
        public static void AssertArgType(string primitiveName, LispLiteral[] args, int position, LispValueType expectedType)
        {
            LispLiteral arg = args[position];

            if (arg.Type != expectedType)
            {
                throw new LispPrimitiveBadArgType(primitiveName, position, expectedType, arg.Type);
            }
        }
Exemplo n.º 6
0
        public void FactorialTest()
        {
            string factorialLisp = File.ReadAllText("factorial.lisp");
            var    r             = Test(factorialLisp);

            Assert.IsInstanceOf <LispLiteral>(r);
            LispLiteral result = r as LispLiteral;

            Assert.AreEqual(10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1, r.IntValue);
        }
Exemplo n.º 7
0
        public static LispLiteral DebugArg(LispLiteral lit, Context context)
        {
            var val = context.Get(lit.StringValue);

            if (lit is SymbolLiteral symb && symb != null && context.Scope.ContainsKey(symb.Value))
            {
                return(context.Get(symb.Value));
            }

            return(lit);
        }
Exemplo n.º 8
0
        public static LispLiteral Interprete(Context context, LispProgram program)
        {
            if (program.Statements.Any())
            {
                LispLiteral t = null;
                foreach (var statement in program.Statements)
                {
                    t = Interprete(context, statement);
                }

                return(t ?? NilLiteral.Instance);
            }

            return(NilLiteral.Instance);
        }
Exemplo n.º 9
0
        public static LispLiteral Add(Context context, params LispLiteral[] args)
        {
            var evaluatedArgs = EvalArgs(context, args.ToList());

            if (evaluatedArgs.Count != 2)
            {
                throw new LispPrimitiveBadArgNumber("ADD", 1, evaluatedArgs.Count);
            }

            var v1 = evaluatedArgs[0] as LispLiteral;
            var v2 = evaluatedArgs[1] as LispLiteral;
            var t1 = v1.Type;
            var t2 = v2.Type;

            if (!v1.IsNumericType)
            {
                throw new LispPrimitiveBadArgType("ADD", 1, LispValueType.Numeric, t1);
            }

            if (!v2.IsNumericType)
            {
                throw new LispPrimitiveBadArgType("ADD", 1, LispValueType.Numeric, t2);
            }

            var resultType = t1 == LispValueType.Double || t2 == LispValueType.Double
                ? LispValueType.Double
                : LispValueType.Int;

            LispLiteral result = null;

            if (resultType == LispValueType.Double)
            {
                result = new DoubleLiteral(v1.DoubleValue + v2.DoubleValue);
            }
            else if (resultType == LispValueType.Int)
            {
                result = new IntLiteral(v1.IntValue + v2.IntValue);
            }
            else
            {
                result = NilLiteral.Instance;
            }

            return(result);
        }
Exemplo n.º 10
0
        public static LispLiteral Interprete(Context context, LispLiteral literal)
        {
            if (literal is SExpr sexpr)
            {
                return(InterpreteSExpr(context, sexpr));
            }

            if (literal is SymbolLiteral id)
            {
                var eval = context.Get(id.Value);
                return(eval);
            }

            if (literal is LispRuntimeFunction f)
            {
                return(f);
            }

            return(literal);
        }
Exemplo n.º 11
0
 public static LispLiteral EvalArg(Context context, LispLiteral arg)
 {
     return(LispInterpreter.Interprete(context, arg));
 }
Exemplo n.º 12
0
 public void Set(string name, LispLiteral value)
 {
     Scope.Add(name, value);
 }