예제 #1
0
 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')
예제 #2
0
 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')
예제 #3
0
 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')
예제 #4
0
 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')
예제 #5
0
 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,
                                         '=')
예제 #6
0
 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')
예제 #7
0
 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')
예제 #8
0
    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')
예제 #9
0
 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')
예제 #10
0
 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")
예제 #11
0
 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)
예제 #12
0
 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))
예제 #13
0
    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, [])