Exemplo n.º 1
0
        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(),
                    };
            }
        }
Exemplo n.º 2
0
        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(),
                });
            }
        }