コード例 #1
0
 def p_matrix(self, p):
     """matrix : '[' matrix_body ']'
           | '[' ']'"""
     if len(p) == 3:
         p[0] = AST.Vector([])
     else:
         p[0] = AST.Vector(p[2])
コード例 #2
0
    def visitFunctionDecl(self, ctx: GrammarParser.FunctionDeclContext):
        decl_info_list = [
            self.extract_decl(ctx.pureDecl(i))
            for i in range(len(ctx.pureDecl()))
        ]

        my_ast = AST.FunctionDeclaration(decl_info_list[0][0])
        my_ast.set_source_loc(source_from_ctx(ctx))

        # set type & arg_count of function
        my_st_entry = FuncEntry(decl_info_list[0][1])
        my_st_entry.arg_count = len(decl_info_list) - 1

        self.enter_scope(my_ast)

        # add variable decls for each argument & add arguments info to function's st entries
        for arg_nr in range(1, len(decl_info_list)):
            arg_ctx = ctx.pureDecl(arg_nr)
            arg = AST.Variable(decl_info_list[arg_nr][0])
            arg.set_source_loc(source_from_ctx(arg_ctx))
            decl = AST.Decl()
            decl.set_source_loc(source_from_ctx(arg_ctx))
            decl.add_child(arg)
            my_ast.add_child(decl)
            self._current_sym_table[arg.get_name()] = VarEntry(
                decl_info_list[arg_nr][1])
            my_st_entry.arg_types.append(decl_info_list[arg_nr][1])

        self.exit_scope(my_ast)

        # save function's st entry
        self._current_sym_table[decl_info_list[0][0]] = my_st_entry
        return my_ast
コード例 #3
0
 def p_if_instruction(self, p):
     """if_instruction : IF '(' condition ')' instruction %prec IF
                       | IF '(' condition ')' instruction ELSE instruction"""
     if len(p) == 8:
         p[0] = AST.IfElseInstruction(p[3], p[5], p[7], p.lineno(1))
     else:
         p[0] = AST.IfInstruction(p[3], p[5], p.lineno(2))
コード例 #4
0
 def p_ID(self, p):
     """variable_expression : ID
                             | ID '[' expression ',' expression ']'"""
     if len(p) == 2:
         p[0] = AST.Variable(p[1], p.lineno(1))
     else:
         p[0] = AST.MatrixElement(p[1], p[3], p[5], p.lineno(2))
コード例 #5
0
 def p_vector(self, p):
     """vector : '[' vector_body ']'
           | '[' ']'"""
     if len(p) == 3:
         p[0] = AST.Vector([])
     else:
         p[0] = AST.Vector(p[2])
コード例 #6
0
    def visitCastOp(self, ast: AST.CastOp):
        self.visitChildren(ast)
        conv_type = ast.get_conversion_type()

        if conv_type in {
                AST.conv_type.BOOL_TO_INT, AST.conv_type.BOOL_TO_CHAR,
                AST.conv_type.CHAR_TO_INT, AST.conv_type.INT_TO_CHAR
        }:
            ast.set_adress(self.get_adress_of(ast.get_child(0)))
            return

        adress = self.gen_stack_adress()
        reg = self.get_reg(check_if_floating(ast))
        ast.set_adress(adress)
        var_reg = self.load_in_reg(ast.get_child(0))

        if conv_type == AST.conv_type.INT_TO_BOOL:
            self.gen_comp_instr(reg, var_reg, '$zero', AST.NotEqual(), False)
        elif conv_type in {
                AST.conv_type.INT_TO_FLOAT, AST.conv_type.BOOL_TO_FLOAT,
                AST.conv_type.CHAR_TO_FLOAT
        }:
            self.gen_int_to_float(var_reg, reg)
        elif conv_type in {
                AST.conv_type.FLOAT_TO_INT, AST.conv_type.FLOAT_TO_CHAR
        }:
            self.gen_float_to_int(reg, var_reg)
        elif conv_type == AST.conv_type.FLOAT_TO_BOOL:
            freg = self.get_reg(floating=True)
            self.gen_load(freg, self.get_fp_constant(0), True)
            self.gen_comp_instr(reg, var_reg, freg, AST.NotEqual(), True)

        self.gen_sw(reg, adress, check_if_floating(ast))
        self.reset_reg()
コード例 #7
0
 def p_print_instruction(self, p):
     """print_instruction :    PRINT expression_list ';'
                             | PRINT '"' expression_list '"' ';'
     """
     if len(p) == 6:
         p[0] = AST.PrintInstructions(p[3], p.lineno(1))
     else:
         p[0] = AST.PrintInstructions(p[2], p.lineno(1))
コード例 #8
0
 def visitControl(self, ctx: GrammarParser.ControlContext):
     my_ast = None
     token_type = ctx.getChild(0).getSymbol().type
     if token_type == GrammarParser.BREAK_KW:
         my_ast = AST.Break()
     if token_type == GrammarParser.CONT_KW:
         my_ast = AST.Continue()
     my_ast.set_source_loc(source_from_ctx(ctx))
     return my_ast
コード例 #9
0
    def p_expression_lists(self, p):
        """expression_lists : expression_lists ';' expression_list
                            | expression_list """

        if len(p) == 4:
            p[0] = AST.ListsOfExpressions(p.lineno(2))
            p[0].flat_expressions(p[1].expression_lists, p[3])
        else:
            p[0] = AST.ListsOfExpressions(p.lineno(1))
            p[0].append_expression(p[1])
コード例 #10
0
 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
コード例 #11
0
 def p_compound_assignment(self, p):
     """compound_assignment_instruction : variable_expression ADDASSIGN expression ';'
                         | variable_expression SUBASSIGN expression ';'
                         | variable_expression MULASSIGN expression ';'
                         | variable_expression DIVASSIGN expression ';'
                         """
     p[0] = AST.CompoundAssignment(p[1], p[2], p[3], p.lineno(2))
コード例 #12
0
 def visitWhileConstr(self, ctx: GrammarParser.WhileConstrContext):
     my_ast = AST.WhileStatement()
     self.enter_scope(my_ast)
     my_ast.set_check(self.visit(ctx.parenCond()))
     my_ast.set_contents(self.visit(ctx.stateOrScope()))
     my_ast.set_source_loc(source_from_ctx(ctx))
     self.exit_scope(my_ast)
     return my_ast
コード例 #13
0
 def visitDoc(self, ctx):
     my_ast = AST.Doc()
     my_ast.IO = ctx.STDIO() is not None
     self.enter_scope(my_ast)
     my_ast.add_childs(self.visitBlock(ctx.block()))
     my_ast.set_source_loc(source_from_ctx(ctx))
     self.exit_scope(my_ast)
     return my_ast
コード例 #14
0
 def p_expression_list(self, p):
     """expression_list : expression_list ',' expression
                        | expression """
     p[0] = AST.ListOfExpressions(p.lineno(1))
     if len(p) == 4:
         p[0].flat_expressions(p[1].expression_list, p[3])
     else:
         p[0].append_expression(p[1])
コード例 #15
0
 def visitScanf(self, ctx):
     my_ast = AST.Scanf(ctx.getChild(2).getText())
     my_ast.set_source_loc(source_from_ctx(ctx))
     for index in range(1, ctx.getChildCount()):
         if isinstance(ctx.getChild(index), GrammarParser.ExprContext):
             my_ast.add_child(self.visit(ctx.getChild(index)))
         pass
     return my_ast
コード例 #16
0
 def visitFunctionCall(self, ctx: GrammarParser.FunctionCallContext):
     my_ast = AST.FunctionCall(ctx.getChild(0).getText())
     for a in range(1, len(ctx.children)):
         if isinstance(ctx.getChild(a),
                       GrammarParser.FunctionArgumentContext):
             my_ast.add_child(self.visit(ctx.getChild(a)))
     my_ast.set_source_loc(source_from_ctx(ctx))
     return my_ast
コード例 #17
0
 def p_instructions(self, p):
     """instructions : instructions instruction
                     | instruction """
     if len(p) == 3:
         p[1].instructions.append(p[2])
         p[0] = p[1]
     else:
         p[0] = AST.Instructions()
         p[0].instructions.append(p[1])
コード例 #18
0
 def get_adress_of(self, ast: AST.Component):
     if isinstance(ast, AST.Indir):
         reg = self.get_reg()
         self.gen_load(reg, self.get_adress_of(ast.get_child(0)))
         return '0(' + reg + ')'
     elif isinstance(ast, AST.Index):
         self.visitChildren(ast)
         reg = self.get_reg()
         reg2 = self.get_reg()
         self.gen_load_im(reg, 4)
         self.gen_load(reg2, ast.get_child(1).get_adress())
         self.gen_math_instr(reg, reg, reg2, AST.Prod())
         self.gen_load_adress(reg2, self.get_adress_of(ast.get_child(0)))
         self.gen_math_instr(reg, reg, reg2, AST.Sum())
         self.decrease_reg(1, floating=False)
         return '0(' + reg + ')'
     else:
         return ast.get_adress()
コード例 #19
0
    def visitDecl(self, ctx):
        my_ast = AST.Decl()
        decl_info = self.extract_decl(ctx.pureDecl())
        var = AST.Variable(decl_info[0])
        var.set_source_loc(source_from_ctx(ctx))
        my_ast.add_child(var)

        self._current_sym_table[decl_info[0]] = VarEntry(decl_info[1], None)

        my_ast.set_source_loc(source_from_ctx(ctx))
        if ctx.ASSIGN_OP() is not None:
            assign = AST.AssignOp()
            assign.add_child(my_ast)
            assign.add_child(self.visit(ctx.expr()))
            assign.set_source_loc(source_from_ctx(ctx))
            return assign
        else:
            return my_ast
コード例 #20
0
 def visitIfConstr(self, ctx: GrammarParser.IfConstrContext):
     my_ast = AST.IfStatement()
     self.enter_scope(my_ast)
     my_ast.set_condition(self.visit(ctx.parenCond()))
     my_ast.set_then(self.visit(ctx.stateOrScope(0)))
     if len(ctx.stateOrScope()) == 2:
         my_ast.set_else(self.visit(ctx.stateOrScope(1)))
     my_ast.set_source_loc(source_from_ctx(ctx))
     self.exit_scope(my_ast)
     return my_ast
コード例 #21
0
 def aggregateResult(self, aggregate: AST.DummyNode, nextResult):
     if nextResult is None:
         return aggregate
     elif aggregate is None:
         return nextResult
     elif not isinstance(aggregate, AST.DummyNode):
         aggregate = AST.DummyNode([aggregate, nextResult])
     else:
         aggregate.add_child(nextResult)
     return aggregate
コード例 #22
0
 def visitForConstr(self, ctx: GrammarParser.ForConstrContext):
     my_ast = AST.ForStatement()
     self.enter_scope(my_ast)
     params = [self.visit(ctx.general_expr(i)) for i in range(3)]
     my_ast.set_init(params[0])
     my_ast.set_check(params[1])
     my_ast.set_advance(params[2])
     my_ast.set_contents(self.visit(ctx.stateOrScope()))
     my_ast.set_source_loc(source_from_ctx(ctx))
     self.exit_scope(my_ast)
     return my_ast
コード例 #23
0
 def full_fold(self, ast: AST.Composite, op):
     children = self.visitChildren(ast)
     if self.is_foldable(children):
         children = [child.get_value() for child in children]
         new_val = op(*children)
         new_val = self.fix_type(new_val, ast.get_type())
         new_lit = AST.Literal(new_val)
         new_lit.set_type(ast.get_type())
         ast.get_parent().replace_child(ast, new_lit)
         return new_lit
     return ast
コード例 #24
0
 def visitSwitchConstr(self, ctx: GrammarParser.SwitchConstrContext):
     my_ast = AST.SwitchStatement()
     self.enter_scope(my_ast)
     my_ast.set_condition(self.visit(ctx.parenCond()))
     for branch_ctx in ctx.caseBranch():
         my_ast.add_branch(self.visit(branch_ctx))
     if ctx.defaultBranch():
         my_ast.add_branch(self.visit(ctx.defaultBranch()))
     my_ast.set_source_loc(source_from_ctx(ctx))
     self.exit_scope(my_ast)
     return my_ast
コード例 #25
0
 def p_constant(self, p):
     """expression : FLOATNUM
                   | INTNUM
                   | STRING
     """
     if re.match(r"\d*\.\d+", str(p[1])):
         type = 'float'
     elif re.match(r"\d+", str(p[1])):
         type = 'int'
     else:
         type = 'string'
     p[0] = AST.Constant(p[1], type, p.lineno(1))
コード例 #26
0
    def visitNot(self, ast: AST.Not):
        self.visitChildren(ast)
        self.store_rcounter(check_if_floating(ast))
        adress = self.gen_stack_adress()
        ast.set_adress(adress)

        reg = self.get_reg()
        self.gen_load_im(reg, 1)
        self.gen_comp_instr(reg, reg, self.load_in_reg(ast.get_child(0)),
                            AST.NotEqual(), False)
        self.gen_sw(reg, adress, False)

        self.restore_tcounter(floating=check_if_floating(ast))
コード例 #27
0
    def visitArrayLit(self, ctx: GrammarParser.ArrayLitContext
                      ):  # not very type-safe at all (nor safe in general)
        my_ast = AST.Literal(value=[])

        element = None
        for child in ctx.literal():
            element = self.visit(child)
            my_ast.get_value().append(element.get_value())
        my_type: TypeClass = deepcopy(element.get_type())
        my_type.pushType(TypeComponents.ARR)
        my_ast.set_type(my_type)

        my_ast.set_source_loc(source_from_ctx(ctx))
        return my_ast
コード例 #28
0
    def p_binary_expression(self, p):
        """expression : expression '+' expression
                  | expression '-' expression
                  | expression '*' expression
                  | expression '/' expression
                  | expression EQ expression
                  | expression NOTEQ expression
                  | expression LESS expression
                  | expression GREATER expression
                  | expression LESSEQ expression
                  | expression GREATEREQ expression
                  | expression DOTADD expression
                  | expression DOTSUB expression
                  | expression DOTMUL expression
                  | expression DOTDIV expression
        """

        p[0] = AST.BinaryExpression(p[1], p[2], p[3], p.lineno(2))
コード例 #29
0
def get_AST_from_raw(raw: str) -> AST:
    '''
    Get an AST from raw text

    Parameters
    ----------
    raw : str
        raw text

    Returns
    -------
    An unparsed AST object
    
    Raises
    ------
    PyllowException if something like a syntax error is present in `raw`
    '''

    return AST(get_tokens_from_raw(raw))
コード例 #30
0
    def visitFunctionDef(self, ctx: GrammarParser.FunctionDefContext):
        decl = self.visitFunctionDecl(ctx.functionDecl())
        my_ast = AST.FunctionDefinition(decl.get_name())
        my_ast.set_source_loc(source_from_ctx(ctx))

        self.enter_scope(my_ast)

        # add definitions of arguments
        for child_nr in range(decl.get_child_count()):
            var: AST.Variable = decl.get_child(child_nr).get_child(0)
            self._current_sym_table[var.get_name()] = var.get_st_entry()
        my_ast.swap_children(decl)

        # make function body
        my_ast.add_child(self.visit(ctx.stateOrScope()), 0)

        self.exit_scope(my_ast)

        # add function to ST
        # self._current_sym_table[my_ast.get_name()] = decl.get_st_entry()
        # due to weird way st works w/ "current symbol table", the entry is already there

        return my_ast