Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        static Object.Environment extendMacroEnv(Object.Macro macro, List <Object.Quote> args)
        {
            Object.Environment extended = Object.Environment.NewEnclosedEnvironment(macro.Env);

            int paramIdx = 0;

            foreach (ast.Identifier param in macro.Parameters)
            {
                extended.Set(param.Value, args[paramIdx++]);
            }

            return(extended);
        }
Ejemplo n.º 3
0
        static void addMacro(ast.Statement stmt, Object.Environment env)
        {
            ast.LetStatement letStatement = (ast.LetStatement)stmt;
            ast.MacroLiteral macroLiteral = (ast.MacroLiteral)letStatement.Value;

            Object.Macro macro = new Object.Macro
            {
                Parameters = macroLiteral.Parameters,
                Env        = env,
                Body       = macroLiteral.Body
            };

            env.Set(letStatement.Name.Value, macro);
        }
Ejemplo n.º 4
0
        static Object.Macro isMacroCall(ast.CallExpression exp, Object.Environment env)
        {
            if (!(exp.Function is ast.Identifier))
            {
                return(null);
            }
            ast.Identifier identifier = (ast.Identifier)exp.Function;

            Object.Object obj = env.Get(identifier.Value);
            if (obj == null)
            {
                return(null);
            }

            if (!(obj is Object.Macro))
            {
                return(null);
            }
            Object.Macro macro = (Object.Macro)obj;

            return(macro);
        }