private void resolveTypes(BlockNode<BaseNode> tree) {
        for(BaseNode node : tree) {
            switch(node.nodeType()) {
                case STRUCT_DECL:
                {
                    StructDeclNode struct = (StructDeclNode)node;
                    StructSymbol symbol = 
                        (StructSymbol)context.global().get(struct.name);
                    assert symbol == null;
                    
                    SymbolTable scope = symbol.scope;

                    StructType type = (StructType)symbol.type;

                    for(VariableDeclNode decl : struct.declarations) {
                        processType(decl.type);
                        scope.add(
                            new VariableSymbol(
                                decl.name, 
                                decl.type.realType()
                            ));
                        decl.setRealType(decl.type.realType());

                        type.addField(decl.name, decl.realType());
                    }

                    break;
                }
                case FUNCTION_DECL:
                {
                    FunctionDeclNode func = (FunctionDeclNode)node;
                    FunctionSymbol symbol = 
                        (FunctionSymbol)context.global().get(func.name);
                    assert symbol != null;
                    
                    SymbolTable scope = symbol.scope;
                    FunctionTypeNode type = (FunctionTypeNode)func.type;

                    for(FunctionTypeNode.ArgumentNode arg : type.arguments) {
                        processType(arg.type);
                        arg.setRealType(arg.type.realType());
                        scope.add(new VariableSymbol(arg.name, arg.realType()));
                    }
                    processType(type.returnValue);

                    List<FunctionType.Argument> arguments = 
                            new LinkedList<FunctionType.Argument>();

                    for(FunctionTypeNode.ArgumentNode arg : type.arguments) {
                        arguments.add(arg.toArgument());
                    }
                    
                    FunctionType realType = 
                        new FunctionType(
                            type.returnValue.realType(),
                            arguments,
                            type.constancy);

                    symbol.setType(realType);
                    type.setRealType(realType);
                    func.setRealType(realType);

                    break;
                }
                default:
                {
                    break;
                }
            }
        }
    }