コード例 #1
0
    def FnExpression(self, node):
        expr_result, expr_jump_stmt = self.accept(node.expr)
        arguments_result, arguments_jump_stmt = self.accept(node.arguments)
        if all(argument.__class__ is ast.Const
               for argument in node.arguments.childs):
            if expr_result.__class__ is Function:
                node.result = expr_result.run(*arguments_result)
            else:
                if not node.initialized:
                    node.body = expr_result.body.clone()
                    func_scope = SymbolTable(expr_result, self.global_scope)
                    self.push_scope(func_scope)
                    for i, parameter in enumerate(
                            expr_result.parameterGroup.childs):
                        func_scope.define(parameter.name, parameter.type,
                                          parameter.linespan[0],
                                          arguments_result[i], None)
                    node.initialized = True

                body_result, body_jump_stmt = self.accept(node.body)
                self.pop_scope()
                node.result = body_result
            if self.get_scope().is_pure_function(
                    expr_result.name) and node.result is not None:
                self.replace(node, ast.Const(node.result, node.linespan))
            else:
                self.set_used(expr_result.name)
            return node.result, None
        else:
            self.set_used(expr_result.name)
            return None, None
コード例 #2
0
 def VaExpression(self, node):
     scope = self.get_scope()
     node.result = scope.get(node.name)
     if self.is_constant(node.name):
         self.replace(node, ast.Const(node.result, node.linespan))
     else:
         self.set_used(node.name)
     return node.result, None
コード例 #3
0
    def UnaryOp(self, node):
        expr_result, expr_jump_stmt = self.accept(node.expr)

        if expr_result is None:
            node.result = None
            return node.result, None

        if node.op == '+':
            node.result = expr_result
        elif node.op == '-':
            node.result = -expr_result
        else:
            raise ValueError

        if node.expr.__class__ is ast.Const:
            self.replace(node, ast.Const(node.result, node.expr.linespan))
        return node.result, None
コード例 #4
0
ファイル: parser.py プロジェクト: jiggum/c-compiler
 def p_const_expression_4(self, p):
   '''const_expression : STRING'''
   p[0] = ast.Const(p[1][1:-1], linespan=p.linespan(1))
コード例 #5
0
    def BinaryOp(self, node):
        prev_freeze_constant_folding = self.freeze_constant_folding
        if node.op == '++' or node.op == '--':
            self.freeze_constant_folding = True
        left_result, left_jump_stmt = self.accept(node.left)
        if node.op == '++' or node.op == '--':
            self.freeze_constant_folding = prev_freeze_constant_folding
        right_result, right_jump_stmt = self.accept(node.right)

        if (left_result is None) or (right_result is None):
            node.result = None
            return node.result, None

        if node.op == '==':
            node.result = left_result == right_result
        elif node.op == '!=':
            node.result = left_result != right_result
        elif node.op == '<':
            node.result = left_result < right_result
        elif node.op == '>':
            node.result = left_result > right_result
        elif node.op == '<=':
            node.result = left_result <= right_result
        elif node.op == '>=':
            node.result = left_result >= right_result
        elif node.op == '+':
            node.result = left_result + right_result
        elif node.op == '-':
            node.result = left_result - right_result
        elif node.op == '&&':
            node.result = left_result and right_result
        elif node.op == '||':
            node.result = left_result or right_result
        elif node.op == '*':
            node.result = left_result * right_result
        elif node.op == '/':
            node.result = left_result / right_result
        elif node.op == '%':
            node.result = left_result % right_result
        elif node.op == '++':
            node.result = left_result + right_result
        elif node.op == '--':
            node.result = left_result - right_result
        else:
            raise ValueError

        if node.result is True:
            node.result = 1
        elif node.result is False:
            node.result = 0

        if node.op == '++' or node.op == '--':
            scope = self.get_scope()
            if node.left.__class__ is ast.VaExpression:
                scope.add(node.left.name, node.linespan[0], node.result, node)
                self.set_constant(node.left.name,
                                  self.is_constant(node.left.name))
            elif (node.left.__class__ is ast.Const):
                self.replace(node, ast.Const(node.result, node.linespan))
        elif node.left.__class__ is ast.Const and node.right.__class__ is ast.Const:
            linespan = (node.left.linespan[0], node.right.linespan[1])
            self.replace(node, ast.Const(node.result, linespan))
        return node.result, None
コード例 #6
0
ファイル: parser.py プロジェクト: jiggum/c-compiler
 def p_const_expression_3(self, p):
   '''const_expression : CHARACTER'''
   p[0] = ast.Const(p[1][1:-1], linespan=p.linespan(1))
コード例 #7
0
ファイル: parser.py プロジェクト: jiggum/c-compiler
 def p_const_expression_2(self, p):
   '''const_expression : NUMBER_INT'''
   p[0] = ast.Const(int(p[1]), linespan=p.linespan(1))
コード例 #8
0
ファイル: parser.py プロジェクト: jiggum/c-compiler
 def p_const_expression_1(self, p):
   '''const_expression : NUMBER_FLOAT'''
   p[0] = ast.Const(float(p[1]), linespan=p.linespan(1))
コード例 #9
0
ファイル: parser.py プロジェクト: jiggum/c-compiler
 def p_unary_expression_4(self, p):
   '''unary_expression : DOUBLE_PLUS function_expression
                       | DOUBLE_MINUS function_expression'''
   linespan = (p.linespan(1)[0], p[2].linespan[1])
   p[0] = ast.BinaryOp(p[1], p[2], ast.Const(1), linespan=linespan)
コード例 #10
0
ファイル: parser.py プロジェクト: jiggum/c-compiler
 def p_unary_expression_3(self, p):
   '''unary_expression : function_expression DOUBLE_PLUS
                       | function_expression DOUBLE_MINUS'''
   linespan = (p[1].linespan[0], p.linespan(2)[1])
   p[0] = ast.BinaryOp(p[2], p[1], ast.Const(1), linespan=linespan)