Ejemplo n.º 1
0
        private static Macro IsMacroCall(CallExpression exp, Objects.Environment env)
        {
            var identifier = exp.Function as Identifier;

            if (identifier == null)
            {
                return(null);
            }

            var obj = env.Get(identifier.Value);

            if (obj == null)
            {
                return(null);
            }

            var macro = obj as Macro;

            if (macro == null)
            {
                return(null);
            }

            return(macro);
        }
Ejemplo n.º 2
0
        public static INode ExpandMacros(INode program, Objects.Environment env)
        {
            return(Ast.Ast.Modify(program, node =>
            {
                var callExpression = node as CallExpression;
                if (callExpression == null)
                {
                    return node;
                }

                var macro = IsMacroCall(callExpression, env);
                if (macro == null)
                {
                    return node;
                }

                var args = QuoteArgs(callExpression);
                var evalEnv = ExtendMacroEnv(macro, args);

                var evaluated = Eval(macro.Body, evalEnv);

                var quote = evaluated as Quote;
                if (quote == null)
                {
                    throw new NotSupportedException("we only support returning AST-nodes from macros");
                }

                return quote.Node;
            }));
        }
Ejemplo n.º 3
0
        private static void AddMacro(IStatement stmt, Objects.Environment env)
        {
            var letStatement = (LetStatement)stmt;
            var macroLiteral = (MacroLiteral)letStatement.Value;

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

            env.Set(letStatement.Name.Value, macro);
        }
Ejemplo n.º 4
0
        public static void DefineMacros(Program program, Objects.Environment env)
        {
            var definitions = new List <int> {
            };

            foreach (var(statement, i) in program.Statements.Select((x, i) => (x, i)))
            {
                if (IsMacroDefinition(statement))
                {
                    AddMacro(statement, env);
                    definitions.Add(i);
                }
            }

            for (var i = definitions.Count - 1; i >= 0; i -= 1)
            {
                var definitionIndex = definitions[i];
                program.Statements =
                    program.Statements.Take(definitionIndex).
                    Concat(program.Statements.Skip(definitionIndex + 1)).
                    ToList();
            }
        }