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); }
static ast.Expression parseCallExpression(ast.Expression function) { ast.CallExpression exp = new ast.CallExpression { Token = curToken, Function = function }; exp.Arguments = parseExpressionList(token.RPAREN); return(exp); }
static bool isUnquoteCall(ast.Node node) { if (!(node is ast.CallExpression)) { return(false); } ast.CallExpression callExpression = (ast.CallExpression)node; return(callExpression.Function.TokenLiteral() == "unquote"); }
static List <Object.Quote> quoteArgs(ast.CallExpression exp) { List <Object.Quote> args = new List <Object.Quote>(); foreach (ast.Expression a in exp.Arguments) { args.Add(new Object.Quote { Node = a }); } return(args); }
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)); }
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); }