public static IASTNode Compile(SymbolTable symTable, object exp) { if (exp is string) { return new ASTNode_GetVar { address = SymbolTable.Lookup(symTable, (string)exp) }; } else if (exp is INumber) { return new ASTNode_Literal { value = exp }; } List<object> form = exp as List<object>; switch (form[0] as string) { case "quote": return new ASTNode_Literal { value = ListProcess.ListExpToPairExp(form[1]) }; case "if": return new ASTNode_If { predNode = Compile(symTable, form[1]), thenNode = Compile(symTable, form[2]), elseNode = Compile(symTable, form[3]) }; case "begin": return new ASTNode_Begin { nodes = form.Skip(1).Select(e => Compile(symTable, e)).ToList() }; case "lambda": { SymbolTable newSymTable = new SymbolTable(symTable); var formals = ((List<object>)form[1]).Cast<string>(); foreach (var name in formals) { newSymTable.DefineLocalSymbol(name); } List<string> defines = new List<string>(); ListProcess.FindDefinition(defines, (List<object>)form[2], 1); foreach (var name in defines) { newSymTable.DefineLocalSymbol(name); } IASTNode body = Compile(newSymTable, form[2]); var finder = new ASTNodeVisitor_FindFreeAddresses(body); return new ASTNode_Lambda { formalCount = ((List<object>)form[1]).Count, locals = formals.Concat(defines).ToList(), bodyNode = body, bodyFreeAddresses = finder.BodyFreeAddresses.ToList(), childrenFreeAddresses = finder.ChildrenFreeAddresses.ToList(), }; } case "define": case "set!": return new ASTNode_SetVar { address = SymbolTable.Lookup(symTable, (string)form[1]), rightNode = Compile(symTable, form[2]) }; default: return new ASTNode_Application { procedureNode = Compile(symTable, form[0]), actualNodes = form.Skip(1).Select(e => Compile(symTable, e)).ToList(), }; } }
static public IASTNode Compile(SymbolTable symTable, object exp) { if (exp is string) { return(new ASTNode_GetVar { address = SymbolTable.Lookup(symTable, (string)exp) }); } else if (exp is INumber) { return(new ASTNode_Literal { value = exp }); } List <object> form = exp as List <object>; switch (form[0] as string) { case "quote": return(new ASTNode_Literal { value = ListProcess.ListExpToPairExp(form[1]) }); case "if": return(new ASTNode_If { predNode = Compile(symTable, form[1]), thenNode = Compile(symTable, form[2]), elseNode = Compile(symTable, form[3]) }); case "begin": return(new ASTNode_Begin { nodes = form.Skip(1).Select(e => Compile(symTable, e)).ToList() }); case "lambda": { SymbolTable newSymTable = new SymbolTable(symTable); var formals = ((List <object>)form[1]).Cast <string>(); foreach (var name in formals) { newSymTable.DefineLocalSymbol(name); } List <string> defines = new List <string>(); ListProcess.FindDefinition(defines, (List <object>)form[2], 1); foreach (var name in defines) { newSymTable.DefineLocalSymbol(name); } IASTNode body = Compile(newSymTable, form[2]); var finder = new ASTNodeVisitor_FindFreeAddresses(body); return(new ASTNode_Lambda { formalCount = ((List <object>)form[1]).Count, locals = formals.Concat(defines).ToList(), bodyNode = body, bodyFreeAddresses = finder.BodyFreeAddresses.ToList(), childrenFreeAddresses = finder.ChildrenFreeAddresses.ToList(), }); } case "define": case "set!": return(new ASTNode_SetVar { address = SymbolTable.Lookup(symTable, (string)form[1]), rightNode = Compile(symTable, form[2]) }); default: return(new ASTNode_Application { procedureNode = Compile(symTable, form[0]), actualNodes = form.Skip(1).Select(e => Compile(symTable, e)).ToList(), }); } }