def visit_ID(self, node: ID): name = node.name if not node.env.lookup(name) and not node.global_env.lookup(name): print_error("Error. Variable '%s' not defined." % name) node.env.add_local_var(name, NodeInfo({'type': AnyType})) if node.env.lookup(name): node.node_info = NodeInfo(node.env.lookup(name)) else: node.node_info = NodeInfo(node.global_env.lookup(name))
def visit_InitList(self, node: InitList): for i, d in node.children(): d.env = node.env d.global_env = node.global_env self.visit(d) node.type = {'size': max([x.node_info['depth'] for x in node.list])} # verifica se o vetor possui todos os elementos de mesmo tipo type_aux = None for element in node.list: if type_aux and type_aux != element.type: print_error("Error mismatch type in array's elements") type_aux = element.type node.node_info = NodeInfo({ 'array': True, 'length': len(node.list), 'type': EmptyType if len(node.list) == 0 else node.list[0].node_info['type'], 'depth': max([x.node_info['depth'] for x in node.list]) + 1 })
def visit_BinaryOp(self, node: BinaryOp): for i, d in node.children(): d.env = node.env d.global_env = node.global_env self.visit(d) node.node_info = NodeInfo({'type': self.BinaryOp_check(node)})
def add_global_array(self, array, sym_key): array = self.unbox_InitList(array.list) self.consts.append(array) idx = self.consts.index(array) self.symtable['.str.%d' % idx] = NodeInfo({'global': True}) return idx
def add_global_str(self, str, sym_key): if str not in self.consts: self.consts.append(str) idx = self.consts.index(str) self.symtable['.str.%d' % idx] = NodeInfo({'global': True}) return idx
def visit_Type(self, node: Type): node.node_info = NodeInfo({ 'type': { 'int': IntType, 'char': CharType, 'float': FloatType, 'string': StringType, 'void': VoidType }[node.name[0]] })
def visit_ParamList(self, node: ParamList): for i, d in node.children(): d.env = node.env d.global_env = node.global_env self.visit(d) node.node_info = NodeInfo( {'params': [x.node_info['type'] for x in node.list]}) pass
def visit_ArrayRef(self, node: ArrayRef): for i, d in node.children(): d.env = node.env d.global_env = node.global_env self.visit(d) if node.expr.node_info['type'] != IntType: print_error('Error (array index must be of type int)') node.node_info = NodeInfo(node.post_expr.node_info) node.node_info['depth'] -= 1 if node.node_info['depth'] == 0: node.node_info['array'] = False node.node_info['length'] = None
def visit_Return(self, node: Return): for i, d in node.children(): d.env = node.env d.global_env = node.global_env self.visit(d) node.node_info = node.value.node_info if not node.node_info: node.node_info = NodeInfo({'type': VoidType}) node.func_def = node.env.func_def if node.node_info['type'] != node.func_def.node_info['type']: print_error( 'Type of return statement expression does not match declared return type for function' )
def visit_Cast(self, node: Cast): for i, d in node.children(): d.env = node.env d.global_env = node.global_env self.visit(d) node.node_info = NodeInfo({ 'type': { 'int': IntType, 'char': CharType, 'float': FloatType, 'string': StringType, 'void': VoidType }[node.type.name[0]] })
def visit_ArrayDecl(self, node: ArrayDecl): for i, d in node.children(): d.env = node.env d.global_env = node.global_env self.visit(d) node.node_info = NodeInfo({ 'array': True, 'length': None if not node.const_exp else node.const_exp.value, 'type': node.dir_dec.node_info['type'], 'depth': node.dir_dec.node_info['depth'] + 1 })
def visit_PtrDecl(self, node: PtrDecl): for i, d in node.children(): d.env = node.env d.global_env = node.global_env self.visit(d) node.node_info = NodeInfo({ 'array': True, 'depth': self.get_ptr_depth(node), 'type': { 'int': IntType, 'char': CharType, 'float': FloatType, 'string': StringType, 'void': VoidType }[node.type.name[0]] }) pass
def visit_UnaryOp(self, node: UnaryOp): for i, d in node.children(): d.env = node.env d.global_env = node.global_env self.visit(d) is_array = False depth = 0 if node.expr1: is_array = node.expr1.node_info['array'] depth = node.expr1.node_info['depth'] if node.op == '&': is_array = True depth += 1 node.node_info = NodeInfo({ 'array': is_array, 'depth': depth, 'type': self.UnaryOp_check(node) })
def visit_FuncCall(self, node: FuncCall): for i, d in node.children(): d.env = node.env d.global_env = node.global_env self.visit(d) if node.expr2: params = [ x.node_info['type'] for x in ([node.expr2] if not isinstance(node.expr2, ExprList) else node.expr2.list) ] if len(params) != len(node.expr1.node_info['params']): print_error( "Number of arguments for call to function '%s' do not match function parameter declaration" % node.expr1.name) elif params != node.expr1.node_info['params']: print_error( "Types of arguments for call to function '%s' do not match function parameter declaration" % node.expr1.name) node.node_info = NodeInfo(node.expr1.node_info) node.node_info['func'] = False node.node_info['params'] = None