def build_unary_expression(self, tree: grammerParser.RContext): if tree.getChildCount() == 1: return self.build_postfix_expression(tree.getChild(0)) elif tree.getChild(0).getChildCount() > 0: op = self.build_unary_operator(tree.getChild(0)) expression = self.build_cast_expression(tree.getChild(1)) if op == '!': if expression.get_type() == 'bool': if isinstance(expression, ConstantExpression): expression.not_value() return expression else: return UnaryExpression(expression, op) else: raise CompilerError('! except bool') elif op == '-': if expression.get_type() != 'bool': if isinstance(expression, ConstantExpression): expression.negetive_value() return expression else: return UnaryExpression(expression, op) else: raise CompilerError('- except int or real') else: expression = self.build_unary_expression(tree.getChild(1)) if isinstance( expression, VariableExpression) and expression.get_type() == 'int': return SelfIncrementUnaryExpression(expression, tree.getChild(0).getText()) else: raise CompilerError('type error')
def build_return_statement(self, tree: grammerParser.RContext): expression = self.build_assignment_expression(tree.getChild(1)) if expression.get_type() == self.symbol_table.get_function_symbol( self.current_function).get_function_type(): return ReturnStatement(expression) else: raise CompilerError('return type error')
def build_primary_expression(self, tree: grammerParser.RContext): if tree.getChildCount() == 3: return self.build_assignment_expression(tree.getChild(1)) elif tree.getChild(0).getChildCount() != 0: identifier, expression_list = self.build_variable_expression( tree.getChild(0)) if self.symbol_table.is_function_existed(identifier) and len( expression_list) == 0: return identifier if self.symbol_table.is_variable_existed(identifier): symbol = self.symbol_table.get_variable(identifier) if len(expression_list) > 0: variable_expression = VariableExpression( symbol, expression_list) else: variable_expression = VariableExpression(symbol) return variable_expression else: raise CompilerError('variable is not defined') elif tree.getChild(0).getPayload().type == grammerLexer.INT_CONSTANT: return ConstantExpression(tree.getText(), 'int') elif tree.getChild(0).getPayload().type == grammerLexer.BOOL_CONSTANT: return ConstantExpression(tree.getText(), 'bool') elif tree.getChild(0).getPayload().type == grammerLexer.REAL_CONSTANT: return ConstantExpression(tree.getText(), 'real')
def build_additive_expression(self, tree: grammerParser.RContext): if tree.getChildCount() == 1: return self.build_multiplicative_expression(tree.getChild(0)) else: left_expression = self.build_additive_expression(tree.getChild(0)) right_expression = self.build_multiplicative_expression( tree.getChild(2)) op = tree.getChild(1).getText() if left_expression.get_type() == right_expression.get_type( ) and left_expression.get_type() != 'bool': if isinstance(left_expression, ConstantExpression) and isinstance( right_expression, ConstantExpression): if op == '+': return ConstantExpression( left_expression.get_value() + right_expression.get_value(), left_expression.get_type()) if op == '-': return ConstantExpression( left_expression.get_value() - right_expression.get_value(), left_expression.get_type()) else: return ArithmeticExpression(left_expression, right_expression, op) else: raise CompilerError('type error')
def build_init_declarator(self, tree: grammerParser.RContext, type): if tree.getChildCount() == 3: identifier, size_list = self.build_declarator(tree.getChild(0)) if len(size_list) > 0: raise CompilerError('you can init a array') else: self.symbol_table.add_variable_name(identifier, type) variable_expression = VariableExpression( self.symbol_table.get_variable(identifier)) expression = self.build_assignment_expression(tree.getChild(2)) if variable_expression.get_type() != expression.get_type(): raise CompilerError('type error') return AssignmentExpression(variable_expression, expression, '=') else: identifier, size_list = self.build_declarator(tree.getChild(0)) if len(size_list) > 0: self.symbol_table.add_variable_name(identifier, type, size_list) symbol = self.symbol_table.get_variable(identifier) code = [] length = reduce(lambda x, y: x * y, size_list) for i in range(length): code += [f'lda 0 {symbol.get_address()}'] code += [f'ldc i {i}'] code += [f'ixa 1'] if symbol.get_type() == 'int': code += [f'ldc i 0'] code += [f'sto i'] elif symbol.get_type() == 'real': code += [f'ldc r 0.0'] code += [f'sto r'] elif symbol.get_type() == 'bool': code += [f'ldc b f'] code += [f'sto b'] return PcodeExpression(code) else: self.symbol_table.add_variable_name(identifier, type) variable_expression = VariableExpression( self.symbol_table.get_variable(identifier)) if type == 'int': expression = ConstantExpression('0', 'int') elif type == 'real': expression = ConstantExpression('0.0', 'real') else: expression = ConstantExpression('false', 'bool') return AssignmentExpression(variable_expression, expression, '=')
def build_relational_expression(self, tree: grammerParser.RContext): if tree.getChildCount() == 1: return self.build_additive_expression(tree.getChild(0)) else: left_expression = self.build_relational_expression( tree.getChild(0)) right_expression = self.build_additive_expression(tree.getChild(2)) op = tree.getChild(1).getText() if left_expression.get_type() == right_expression.get_type( ) and left_expression.get_type() != 'bool': return ComparisonExpression(left_expression, right_expression, op) else: if left_expression.get_type() != right_expression.get_type(): raise CompilerError('you can only compiler same type') else: raise CompilerError('you can only int or real')
def build_multiplicative_expression(self, tree: grammerParser.RContext): if tree.getChildCount() == 1: return self.build_cast_expression(tree.getChild(0)) else: left_expression = self.build_multiplicative_expression( tree.getChild(0)) right_expression = self.build_cast_expression(tree.getChild(2)) op = tree.getChild(1).getText() if left_expression.get_type() == right_expression.get_type( ) and left_expression.get_type() != 'bool': if isinstance(left_expression, ConstantExpression) and isinstance( right_expression, ConstantExpression): if op == '*': return ConstantExpression( left_expression.get_value() * right_expression.get_value(), left_expression.get_type()) if left_expression.get_type() == 'int': if op == '/': return ConstantExpression( left_expression.get_value() // right_expression.get_value(), left_expression.get_type()) elif op == '%': return ConstantExpression( left_expression.get_value() % right_expression.get_value(), left_expression.get_type()) else: if op == '/': return ConstantExpression( left_expression.get_value() / right_expression.get_value(), left_expression.get_type()) else: raise CompilerError('type error') if op != '%' and left_expression.get_type() == 'real': raise CompilerError('you can mod real') else: return ArithmeticExpression(left_expression, right_expression, op) else: raise CompilerError('you can\'t calculate bool')
def build_postfix_expression(self, tree: grammerParser.RContext): if tree.getChildCount() == 1: expression = self.build_primary_expression(tree.getChild(0)) return expression elif tree.getChildCount() == 2: expression = self.build_postfix_expression(tree.getChild(0)) if isinstance( expression, VariableExpression) and expression.get_type() == 'int': return SelfIncrementPostfixExpression( expression, tree.getChild(1).getText()) else: raise CompilerError('++ except variable') elif tree.getChildCount() == 3: function_name = self.build_postfix_expression(tree.getChild(0)) if self.symbol_table.is_function_existed(function_name): function_symbol = self.symbol_table.get_function_symbol( function_name) if function_symbol.is_argument_right([]): return FunctionCallExpression(function_symbol, []) else: raise CompilerError('parameter error') else: raise CompilerError('function is not defined') else: function_name = self.build_postfix_expression(tree.getChild(0)) argument_expression_list = self.build_argument_expression_list( tree.getChild(2)) if self.symbol_table.is_function_existed(function_name): function_symbol = self.symbol_table.get_function_symbol( function_name) if function_symbol.is_argument_right(argument_expression_list): return FunctionCallExpression(function_symbol, argument_expression_list) else: raise CompilerError('parameter error') else: raise CompilerError('function is not defined')
def build_assignment_expression(self, tree: grammerParser.RContext): if tree.getChildCount() == 1: return self.build_logical_or_expression(tree.getChild(0)) else: identifier, expression_list = self.build_variable_expression( tree.getChild(0)) op = self.build_assignment_operator(tree.getChild(1)) expression = self.build_assignment_expression(tree.getChild(2)) if self.symbol_table.is_variable_existed(identifier): symbol = self.symbol_table.get_variable(identifier) if symbol.get_type() == expression.get_type(): if len(expression_list) > 0: variable_expression = VariableExpression( symbol, expression_list) else: variable_expression = VariableExpression(symbol) return AssignmentExpression(variable_expression, expression, op) else: raise CompilerError('type error') else: raise CompilerError('variable is not defined')
def build_logical_and_expression(self, tree: grammerParser.RContext): if tree.getChildCount() == 1: return self.build_equality_expression(tree.getChild(0)) else: left_expression = self.build_logical_and_expression( tree.getChild(0)) right_expression = self.build_equality_expression(tree.getChild(2)) op = tree.getChild(1).getText() if left_expression.get_type() == right_expression.get_type( ) and left_expression.get_type() == 'bool': return ComparisonExpression(left_expression, right_expression, op) else: raise CompilerError("&& only can calculate bool")
def build_cast_expression(self, tree: grammerParser.RContext): if tree.getChildCount() == 1: return self.build_unary_expression(tree.getChild(0)) else: expression = self.build_cast_expression(tree.getChild(3)) type = self.build_declaration_specifiers(tree.getChild(1)) if expression.get_type() != type: if type == 'bool' or expression.get_type() == 'bool': raise CompilerError('you can not cast bool') else: if isinstance(expression, ConstantExpression): expression.change_type() return expression else: return CastExpression(expression, type)
def build_seletion_statement(self, tree: grammerParser.RContext): condition = self.build_assignment_expression(tree.getChild(2)) if condition.get_type() != 'bool': raise CompilerError('condition must be bool') then_statement = self.build_statement(tree.getChild(4)) if not isinstance(then_statement, list): then_statement = [then_statement] if tree.getChildCount() == 7: else_statement = self.build_statement(tree.getChild(6)) if not isinstance(else_statement, list): else_statement = [else_statement] self.label += 2 return SelectionStatement(condition, then_statement, 'label' + str(self.label - 2), else_statement, 'label' + str(self.label - 1)) else: self.label += 1 return SelectionStatement(condition, then_statement, 'label' + str(self.label - 1))
def build_iteration_statement(self, tree: grammerParser.RContext): if tree.getChild(0).getText() == 'while': condition = self.build_assignment_expression(tree.getChild(2)) if condition.get_type() != 'bool': raise CompilerError('condition must be bool') after_start = self.build_statement(tree.getChild(4)) if not isinstance(after_start, list): after_start = [after_start] self.label += 2 return IterationStatement(condition, f'label{self.label - 2}', f'label{self.label - 1}', [], after_start, []) if tree.getChild(0).getText() == 'do': condition = self.build_assignment_expression(tree.getChild(4)) if condition.get_type() != 'bool': raise CompilerError('condition must be bool') after_start = self.build_statement(tree.getChild(1)) if not isinstance(after_start, list): after_start = [after_start] self.label += 2 return IterationStatement(condition, f'label{self.label - 2}', f'label{self.label - 1}', after_start, after_start, []) if tree.getChild(0).getText() == 'repeat': condition = self.build_assignment_expression(tree.getChild(4)) if condition.get_type() != 'bool': raise CompilerError('condition must be bool') condition = UnaryExpression(condition, '!') after_start = self.build_statement(tree.getChild(1)) if not isinstance(after_start, list): after_start = [after_start] self.label += 2 return IterationStatement(condition, f'label{self.label - 2}', f'label{self.label - 1}', after_start, after_start, []) if tree.getChild(0).getText() == 'for' and tree.getChildCount() == 7: condition = self.build_expression_statement(tree.getChild(3)) if condition.get_type() != 'bool': raise CompilerError('condition must be bool') after_start = self.build_statement(tree.getChild(6)) if not isinstance(after_start, list): after_start = [after_start] before_end = self.build_assignment_expression(tree.getChild(4)) if not isinstance(before_end, list): before_end = [before_end] before_start = self.build_expression_statement(tree.getChild(2)) if not isinstance(before_start, list): before_start = [before_start] self.label += 2 return IterationStatement(condition, f'label{self.label - 2}', f'label{self.label - 1}', before_start, after_start, before_end) else: condition = self.build_expression_statement(tree.getChild(3)) if condition.get_type() != 'bool': raise CompilerError('condition must be bool') after_start = self.build_statement(tree.getChild(5)) if not isinstance(after_start, list): after_start = [after_start] before_start = self.build_expression_statement(tree.getChild(2)) if not isinstance(before_start, list): before_start = [before_start] self.label += 2 return IterationStatement(condition, f'label{self.label - 2}', f'label{self.label - 1}', before_start, after_start, [])