def visitNot(self, node: Not): self.visitChildren(node) bool_type = TypeClass([TypeComponents.BOOL]) for child_nr in range(node.get_child_count()): self.assume_mono_conversion(node, child_nr, bool_type) node.set_type(bool_type) return bool_type
def visitMathOp(self, node: MathOp): child_types = self.visitChildren(node) own_type = None if isinstance(node, Sum) or isinstance(node, Sub): int_type = TypeClass([TypeComponents.INT]) if child_types[0].is_array(): self.add_error(InvalidTypeError(node, child_types[0])) elif child_types[1].is_array(): self.add_error(InvalidTypeError(node, child_types[1])) elif child_types[0].is_ptr(): self.assume_mono_conversion(node, 1, int_type) own_type = child_types[0] elif child_types[1].is_ptr(): self.assume_mono_conversion(node, 0, int_type) own_type = child_types[1] else: own_type = self.assume_bi_conversion(node, 0, 1) else: if child_types[0].is_array() or child_types[0].is_ptr(): self.add_error(InvalidTypeError(node, child_types[0])) elif child_types[1].is_array() or child_types[1].is_ptr(): self.add_error(InvalidTypeError(node, child_types[1])) else: own_type = self.assume_bi_conversion(node, 0, 1) node.set_type(own_type) return own_type
def visitReturnStatement(self, ctx: GrammarParser.ReturnStatementContext): my_ast = AST.ReturnStatement() my_ast.set_source_loc(source_from_ctx(ctx)) if ctx.getChildCount() > 1: my_ast.add_child(self.visit(ctx.getChild(1))) else: void = AST.Literal(value=None) void.set_source_loc(source_from_ctx(ctx)) void.set_type(TypeClass([TypeComponents.VOID])) my_ast.add_child(void) return my_ast
def visitLiteral(self, ctx): my_ast = AST.Literal() if ctx.CHAR(): # TODO (maybe) multivalue chars my_ast.val = ord(ctx.getText()[1]) my_ast.set_type(TypeClass([TypeComponents.CHAR])) if ctx.INT(): my_ast.val = int(ctx.getText()) my_ast.set_type(TypeClass([TypeComponents.INT])) if ctx.FLOAT(): my_ast.val = float(ctx.getText()) my_ast.set_type(TypeClass([TypeComponents.FLOAT])) if ctx.arrayLit(): my_ast = self.visit(ctx.arrayLit()) if ctx.STRING(): my_ast.val = list(ctx.getText()[1:len(ctx.getText()) - 1]) # type should really be [char const] my_ast.set_type( TypeClass([TypeComponents.CHAR, TypeComponents.ARR], [None, len(my_ast.val)])) my_ast.set_source_loc(source_from_ctx(ctx)) return my_ast
def visitIndex(self, node: Index): child_types = self.visitChildren(node) indexed_type: TypeClass = child_types[0] own_type = None self.assume_mono_conversion(node, 1, TypeClass([TypeComponents.INT])) if indexed_type.is_ptr(): indexed_type = deepcopy(child_types[0]) indexed_type.popType(True) indexed_type.pushType(TypeComponents.ARR) self.insert_conversion(node, 0, indexed_type, False) if indexed_type.is_array(): own_type = deepcopy(indexed_type) own_type.popType() else: self.add_error(InvalidTypeError(node, child_types[0], "can only index arrays or pointers")) node.set_type(own_type) return own_type
def visitTypeObject(self, ctx): type_stack = [] const_reminder = False # TODO syntax errors, semantic shit and warnings # TODO (maybe) no more strings =( for tokenNr in range(ctx.getChildCount()): token = ctx.getChild(tokenNr) token_type = token.getSymbol().type if token_type in { GrammarParser.CHAR_TYPE, GrammarParser.INT_TYPE, GrammarParser.FLOAT_TYPE, GrammarParser.VOID_TYPE }: assert len(type_stack) == 0 if token_type == GrammarParser.VOID_TYPE: type_stack.append(TypeComponents.VOID) if token_type == GrammarParser.CHAR_TYPE: type_stack.append(TypeComponents.CHAR) if token_type == GrammarParser.INT_TYPE: type_stack.append(TypeComponents.INT) if token_type == GrammarParser.FLOAT_TYPE: type_stack.append(TypeComponents.FLOAT) if const_reminder: type_stack.append(TypeComponents.CONST) if token_type == GrammarParser.STAR: assert len(type_stack) > 0 type_stack.append(TypeComponents.PTR) if token_type == GrammarParser.CONST: if len(type_stack) == 0: const_reminder = True else: assert type_stack[len(type_stack) - 1] != TypeComponents.CONST type_stack.append(TypeComponents.CONST) return TypeClass(type_stack)
def visitCaseBranch(self, node: CaseBranch): self.visit_children_outside_statement(node) int_type = TypeClass([TypeComponents.INT]) self.assume_mono_conversion(node, 0, int_type)
def visitSwitchStatement(self, node: SwitchStatement): self.visit_children_outside_statement(node) int_type = TypeClass([TypeComponents.INT]) self.assume_mono_conversion(node, 0, int_type)
def visitWhileStatement(self, node: WhileStatement): self.visit_children_outside_statement(node) bool_type = TypeClass([TypeComponents.BOOL]) self.assume_mono_conversion(node, 0, bool_type)
def implicit_conversion_warning(self, node, from_type: TypeClass, to_type: TypeClass): if from_type == TypeClass([TypeComponents.INT]) and to_type == TypeClass([TypeComponents.BOOL]): return self.add_warning(ImplicitConversionWarning(node, from_type, to_type))
def visitCompOp(self, node: CompOp): self.visitChildren(node) bool_type = TypeClass([TypeComponents.BOOL]) self.assume_bi_conversion(node, 0, 1) node.set_type(bool_type) return bool_type