Exemplo n.º 1
0
        private static void runFile(string path) // REPL without the loop
        {
            Object.Environment env      = Object.Environment.NewEnvironment();
            Object.Environment macroEnv = Object.Environment.NewEnvironment();

            string source = readFile(path);

            lexer.Lexer   l = lexer.Lexer.New(source);
            parser.Parser p = parser.Parser.New(l);

            ast.Program program = p.ParseProgram();
            if (parser.Parser.Errors().Count != 0)
            {
                repl.printParserErrors(parser.Parser.Errors());
                System.Environment.Exit(77);
            }

            evaluator.macro_expansion.DefineMacros(program, macroEnv);
            ast.Node expanded = evaluator.macro_expansion.ExpandMacros(program, macroEnv);

            Object.Object evaluated = evaluator.evaluator.Eval(expanded, env);
            if (evaluated != null)
            {
                System.Console.Write(evaluated.Inspect());
                System.Console.WriteLine();
            }
        }
Exemplo n.º 2
0
        static ast.Node _ExpandMacros(ast.Node node)
        {
            if (!(node is ast.CallExpression))
            {
                return(node);
            }
            ast.CallExpression callExpression = (ast.CallExpression)node;

            Object.Macro macro = isMacroCall(callExpression, _env);
            if (macro == null)
            {
                return(node);
            }

            List <Object.Quote> args = quoteArgs(callExpression);

            Object.Environment evalEnv = extendMacroEnv(macro, args);

            Object.Object evaluated = evaluator.Eval(macro.Body, evalEnv);
            if (!(evaluated is Object.Quote))
            {
                System.Console.WriteLine("we only support returning AST-nodes from macros");
                System.Environment.Exit(-1);
            }
            Object.Quote quote = (Object.Quote)evaluated;

            return(quote.Node);
        }
Exemplo n.º 3
0
 public static Object.Object quote(ast.Node node, Object.Environment env)
 {
     node = evalUnquoteCalls(node, env);
     return(new Object.Quote {
         Node = node
     });
 }
Exemplo n.º 4
0
        static bool isUnquoteCall(ast.Node node)
        {
            if (!(node is ast.CallExpression))
            {
                return(false);
            }
            ast.CallExpression callExpression = (ast.CallExpression)node;

            return(callExpression.Function.TokenLiteral() == "unquote");
        }
Exemplo n.º 5
0
        private static Object.Environment _env;  // to pass the environment on the originally crammed-to-argument function definition
        static ast.Node _evalUnquotedCalss(ast.Node node)
        {
            if (!isUnquoteCall(node))
            {
                return(node);
            }

            if (!(node is ast.CallExpression))
            {
                return(node);
            }
            ast.CallExpression call = (ast.CallExpression)node;

            if (call.Arguments.Count != 1)
            {
                return(node);
            }

            Object.Object unquoted = evaluator.Eval(call.Arguments[0], _env); // env needs to reach this
            return(convertObjectToASTNode(unquoted));
        }
Exemplo n.º 6
0
 public static ast.Node ExpandMacros(ast.Node program, Object.Environment env)
 {
     _env = env;
     return(ast.modify.Modify(program, _ExpandMacros));
 }
Exemplo n.º 7
0
        public static Object.Object Eval(ast.Node node, Object.Environment env)
        {
            // Statements
            if (node is ast.Program)
            {
                return(evalProgram((ast.Program)node, env));
            }

            if (node is ast.BlockStatement)
            {
                return(evalBlockStatement((ast.BlockStatement)node, env));
            }

            if (node is ast.ExpressionStatement)
            {
                return(Eval(((ast.ExpressionStatement)node).Expression, env));
            }

            if (node is ast.ReturnStatement)
            {
                Object.Object val = Eval(((ast.ReturnStatement)node).ReturnValue, env);
                if (isError(val))
                {
                    return(val);
                }
                return(new Object.ReturnValue {
                    Value = val
                });
            }

            if (node is ast.LetStatement)
            {
                Object.Object val = Eval(((ast.LetStatement)node).Value, env);
                if (isError(val))
                {
                    return(val);
                }
                env.Set(((ast.LetStatement)node).Name.Value, val);

                return(null);
            }

            // Expressions
            if (node is ast.IntegerLiteral)
            {
                return new Object.Integer {
                           Value = ((ast.IntegerLiteral)node).Value
                }
            }
            ;

            if (node is ast.StringLiteral)
            {
                return new Object.String {
                           Value = ((ast.StringLiteral)node).Value
                }
            }
            ;

            if (node is ast.Boolean)
            {
                return(nativeToBooleanObject(((ast.Boolean)node).Value));
            }

            if (node is ast.PrefixExpression)
            {
                Object.Object right = Eval(((ast.PrefixExpression)node).Right, env);
                if (isError(right))
                {
                    return(right);
                }
                return(evalPrefixExpression(((ast.PrefixExpression)node).Operator, right));
            }

            if (node is ast.InfixExpression)
            {
                Object.Object left = Eval(((ast.InfixExpression)node).Left, env);
                if (isError(left))
                {
                    return(left);
                }

                Object.Object right = Eval(((ast.InfixExpression)node).Right, env);
                if (isError(right))
                {
                    return(right);
                }

                return(evalInfixExpression(((ast.InfixExpression)node).Operator, left, right));
            }


            if (node is ast.IfExpression)
            {
                return(evalIfExpression((ast.IfExpression)node, env));
            }


            if (node is ast.Identifier)
            {
                return(evalIdentifier((ast.Identifier)node, env));
            }

            if (node is ast.FunctionLiteral)
            {
                List <ast.Identifier> params_ = ((ast.FunctionLiteral)node).Parameters;
                ast.BlockStatement    body    = ((ast.FunctionLiteral)node).Body;
                return(new Object.Function {
                    Parameters = params_, Env = env, Body = body
                });
            }

            if (node is ast.CallExpression)
            {
                Object.Object function = Eval(((ast.CallExpression)node).Function, env);
                if (isError(function))
                {
                    return(function);
                }

                List <Object.Object> args = evalExpressions(((ast.CallExpression)node).Arguments, env);
                if (args.Count == 1 && isError(args[0]))
                {
                    return(args[0]);
                }

                return(applyFunction(function, args));
            }

            if (node is ast.ArrayLiteral)
            {
                List <Object.Object> elements = evalExpressions(((ast.ArrayLiteral)node).Elements, env);
                if (elements.Count == 1 && isError(elements[0]))
                {
                    return(elements[0]);
                }
                return(new Object.Array {
                    Elements = elements
                });
            }

            if (node is ast.IndexExpression)
            {
                Object.Object left = Eval(((ast.IndexExpression)node).Left, env);
                if (isError(left))
                {
                    return(left);
                }
                Object.Object index = Eval(((ast.IndexExpression)node).Index, env);
                if (isError(index))
                {
                    return(index);
                }
                return(evalIndexExpression(left, index));
            }

            if (node is ast.HashLiteral)
            {
                return(evalHashLiteral((ast.HashLiteral)node, env));
            }

            return(null);
        }
Exemplo n.º 8
0
 public static ast.Node evalUnquoteCalls(ast.Node quoted, Object.Environment env)
 {
     _env = env;
     return(ast.modify.Modify(quoted, _evalUnquotedCalss));
 }
Exemplo n.º 9
0
        public static ast.Node Modify(ast.Node node, MofifierFunc modifier)
        {
            if (node is ast.Program)
            {
                ast.Program _node = (ast.Program)node;
                for (int i = 0; i < _node.Statements.Count; i++)
                {
                    _node.Statements[i] = (ast.Statement)Modify(_node.Statements[i], modifier);
                }
                node = _node;
            }

            if (node is ast.ExpressionStatement)
            {
                ast.ExpressionStatement _node = (ast.ExpressionStatement)node;
                _node.Expression = (ast.Expression)Modify(_node.Expression, modifier);
                node             = _node;
            }

            if (node is ast.InfixExpression)
            {
                ast.InfixExpression _node = (ast.InfixExpression)node;
                _node.Left  = (ast.Expression)Modify(_node.Left, modifier);
                _node.Right = (ast.Expression)Modify(_node.Right, modifier);
                node        = _node;
            }

            if (node is ast.PrefixExpression)
            {
                ast.PrefixExpression _node = (ast.PrefixExpression)node;
                _node.Right = (ast.Expression)Modify(_node.Right, modifier);
                node        = _node;
            }

            if (node is ast.IndexExpression)
            {
                ast.IndexExpression _node = (ast.IndexExpression)node;
                _node.Left  = (ast.Expression)Modify(_node.Left, modifier);
                _node.Index = (ast.Expression)Modify(_node.Index, modifier);
                node        = _node;
            }

            if (node is ast.IfExpression)
            {
                ast.IfExpression _node = (ast.IfExpression)node;
                _node.Condition   = (ast.Expression)Modify(_node.Condition, modifier);
                _node.Consequence = (ast.BlockStatement)Modify(_node.Consequence, modifier);
                node = _node;
                if (_node.Alternative != null)
                {
                    _node.Alternative = (ast.BlockStatement)Modify(_node.Alternative, modifier);
                }
            }

            if (node is ast.BlockStatement)
            {
                ast.BlockStatement _node = (ast.BlockStatement)node;
                for (int i = 0; i < _node.Statements.Count; i++)
                {
                    _node.Statements[i] = (ast.Statement)Modify(_node.Statements[i], modifier);
                }
                node = _node;
            }


            if (node is ast.ReturnStatement)
            {
                ast.ReturnStatement _node = (ast.ReturnStatement)node;
                _node.ReturnValue = (ast.Expression)Modify(_node.ReturnValue, modifier);
                node = _node;
            }

            if (node is ast.LetStatement)
            {
                ast.LetStatement _node = (ast.LetStatement)node;
                _node.Value = (ast.Expression)Modify(_node.Value, modifier);
                node        = _node;
            }

            if (node is ast.FunctionLiteral)
            {
                ast.FunctionLiteral _node = (ast.FunctionLiteral)node;
                for (int i = 0; i < _node.Parameters.Count; i++)
                {
                    _node.Parameters[i] = (ast.Identifier)Modify(_node.Parameters[i], modifier);
                }
                _node.Body = (ast.BlockStatement)Modify(_node.Body, modifier);
                node       = _node;
            }

            if (node is ast.ArrayLiteral)
            {
                ast.ArrayLiteral _node = (ast.ArrayLiteral)node;
                for (int i = 0; i < _node.Elements.Count; i++)
                {
                    _node.Elements[i] = (ast.Expression)Modify(_node.Elements[i], modifier);
                }
                node = _node;
            }

            if (node is ast.HashLiteral)
            {
                ast.HashLiteral _node = (ast.HashLiteral)node;
                Dictionary <ast.Expression, ast.Expression> newPairs = new Dictionary <ast.Expression, ast.Expression>();
                foreach (KeyValuePair <ast.Expression, ast.Expression> kv in _node.Pairs)
                {
                    ast.Expression newKey = (ast.Expression)Modify(kv.Key, modifier);
                    ast.Expression newVal = (ast.Expression)Modify(kv.Value, modifier);
                    newPairs.Add(newKey, newVal);
                }
                _node.Pairs = newPairs;
                node        = _node;
            }

            return(modifier(node));
        }