Example #1
0
def p_function_call(p):
    '''function_call : IDENTIFIER LEFT_PARENTHESIS expression_list RIGHT_PARENTHESIS
                     | IDENTIFIER LEFT_PARENTHESIS RIGHT_PARENTHESIS'''
    p[0] = IG.Node()
    if len(p) == 4:
        p[0].place = IG.newTempInt()
        p[0].type = p[0].place.type
        p[0].genCode(
            IG.TACInstr(IG.TACInstr.ASSIGN,
                        op=IG.TACInstr.CALLOP,
                        dest=p[0].place,
                        targetLabel=p[1],
                        lineNo=IG.nextQuad))
        IG.nextQuad += 1
    elif len(p) == 5:
        p[0].place = IG.newTempInt()
        p[0].type = p[0].place.type
        p[0].genCode(
            IG.TACInstr(IG.TACInstr.ASSIGN,
                        op=IG.TACInstr.CALLOP,
                        dest=p[0].place,
                        lineNo=IG.nextQuad,
                        paramList=p[3].items,
                        targetLabel=p[1]))
        IG.nextQuad += 1
Example #2
0
def p_expression(p):
    '''expression : simple_expression relational_operator simple_expression
                  | simple_expression'''
    p[0] = IG.Node()
    if len(p) == 2:
        p[0] = p[1]
    elif len(p) == 4:
        p[0].code = p[1].code + p[3].code
        # p[0].place = IG.newTempBool()
        # p[0].type = p[0].place.type
        # p[0].genCode(IG.TACInstr(IG.TACInstr.ASSIGN, op=IG.TACInstr.OpMap[p[2]], src1=p[1].place,
        #                          src2=p[3].place, dest=p[0].place, lineNo=IG.nextQuad))
        p[0].trueList = [IG.nextQuad]
        p[0].falseList = [IG.nextQuad + 1]
        print 'Given src2', p[3].place
        print "Truelist", p[0].trueList
        print "Falselist", p[0].falseList
        p[0].genCode(
            IG.TACInstr(IG.TACInstr.IFGOTO,
                        op=IG.TACInstr.OpMap[p[2]],
                        src1=p[1].place,
                        src2=p[3].place,
                        lineNo=IG.nextQuad))
        IG.nextQuad += 1
        p[0].genCode(IG.TACInstr(IG.TACInstr.GOTO, lineNo=IG.nextQuad))
        IG.nextQuad += 1
Example #3
0
def p_factor(p):
    '''factor : LEFT_PARENTHESIS expression RIGHT_PARENTHESIS
              | sign factor
              | OP_NOT factor
              | OP_BIT_NOT factor
              | function_call
              | variable_reference
              | unsigned_constant'''
    p[0] = IG.Node()
    if len(p) == 3:
        # TODO Generate Code
        if p[1] == 'not':
            p[0].trueList = p[2].falseList
            p[0].falseList = p[2].trueList
            p[0].code = p[2].code
        #    p[0].genCode(IG.TACInstr(IG.TACInstr.ASSIGN, op=IG.TACInstr.LOGICNOT, src1=p[2].place,
        #                             dest=p[0].place, lineNo=IG.nextQuad))
        #    IG.nextQuad += 1
        else:
            p[0].place = IG.newTempInt()
            p[0].type = p[0].place.type
            p[0].code = p[2].code
            p[0].genCode(
                IG.TACInstr(IG.TACInstr.ASSIGN,
                            op=IG.TACInstr.OpMap[p[1]],
                            src1=p[1].place,
                            dest=p[0].place,
                            lineNo=IG.nextQuad))
            IG.nextQuad += 1
            # TODO generate code for other types

    elif len(p) == 2:
        p[0] = p[1]
        if p[1].place == 'true':
            p[0].trueList = [IG.nextQuad]
            p[0].genCode(IG.TACInstr(IG.TACInstr.GOTO, lineNo=IG.nextQuad))
            IG.nextQuad += 1

        elif p[1].place == 'false':
            p[0].falseList = [IG.nextQuad]
            p[0].genCode(IG.TACInstr(IG.TACInstr.GOTO, lineNo=IG.nextQuad))
            IG.nextQuad += 1

        elif type(p[1].place) == ST.SymTabEntry and p[1].place.isBool():
            p[0].trueList = [IG.nextQuad]
            p[0].genCode(IG.TACInstr(IG.TACInstr.GOTO, lineNo=IG.nextQuad))
            IG.nextQuad += 1
            p[0].falseList = [IG.nextQuad]
            p[0].genCode(IG.TACInstr(IG.TACInstr.GOTO, lineNo=IG.nextQuad))
            IG.nextQuad += 1

    elif len(p) == 4:
        p[0].place = p[2].place
        p[0].type = p[2].type
        p[0].trueList = p[2].trueList
        p[0].falseList = p[2].falseList
Example #4
0
def p_marker_fpdef(p):
    '''marker_fpdef : '''
    p[0] = IG.Node()
    p[0].quad = IG.nextQuad
    p[0].genCode(IG.TACInstr(IG.TACInstr.GOTO, lineNo=IG.nextQuad))
    IG.nextQuad += 1
    ST.currSymTab = ST.SymTab(ST.currSymTab)
Example #5
0
def p_matched_statement(p):
    '''matched_statement : simple_statement
                         | structured_statement
                         | KEYWORD_IF expression KEYWORD_THEN marker_if matched_statement \
                           marker_if_end KEYWORD_ELSE marker_else matched_statement
                         | loop_header matched_statement
                         | KEYWORD_BREAK
                         | KEYWORD_CONTINUE
                         | empty'''
    p[0] = IG.Node()
    if len(p) == 2:
        if type(p[1]) == IG.Node:
            p[0] = p[1]
        else:
            pass
            # TODO: Handle empty production
            # TODO: Generate code for break and continue
    elif len(p) == 10:
        p[0].code = p[2].code + p[4].code + p[5].code + p[6].code + p[9].code
        print 'test', p[8].quad
        backpatch(p[2].falseList, p[8].quad)
        backpatch(p[2].trueList, p[4].quad)
        p[0].nextList = p[5].nextList + p[6].nextList + p[9].nextList

    elif len(p) == 3:
        p[0].code = p[1].code + p[2].code
        p[0].genCode(
            IG.TACInstr(IG.TACInstr.GOTO, target=p[1].quad,
                        lineNo=IG.nextQuad))
        IG.nextQuad += 1
        backpatch(p[1].endList, IG.nextQuad)
Example #6
0
def p_func_head(p):
    '''func_head : KEYWORD_FUNCTION IDENTIFIER parameter_list COLON type_identifier'''
    ST.currSymTab.previousTable.addFunction(p[2], p[5].type, len(p[3].items))
    STEntry = ST.currSymTab.addVar(p[2], p[5].type)
    # TODO Type identifier must be builtin/already defined
    # Generate code
    TypeSTEntry = ST.lookup(p[5].type.name)
    if TypeSTEntry is not None:
        if TypeSTEntry.isType():
            p[0] = IG.Node()
            p[0].place = STEntry
            p[0].genCode(
                IG.TACInstr(IG.TACInstr.LABEL,
                            label=p[2],
                            paramList=p[3].items,
                            lineNo=IG.nextQuad))
            IG.nextQuad += 1
        else:
            # Variable given as type
            print_error("Type error at line", p.linespan(5)[1])
            print_error("\tVariable identifer given as return type")
            sys.exit(1)
    else:
        # Undefined type
        print_error("Type error at line", p.linespan(5)[1])
        print_error("\tReturn type is not a built in or predefined type")
        sys.exit(1)
Example #7
0
def p_proc_def(p):
    '''proc_def : proc_head SEMICOLON declarations block SEMICOLON'''
    ST.currSymTab.previousTable.addTable(ST.currSymTab)
    ST.currSymTab = ST.currSymTab.previousTable
    p[0] = IG.Node()
    p[0].code = p[1].code + p[3].code + p[4].code
    p[0].genCode(IG.TACInstr(IG.TACInstr.RETURN, lineNo=IG.nextQuad))
    IG.nextQuad += 1
Example #8
0
def p_const_statement(p):
    'const_statement : IDENTIFIER EQUAL expression SEMICOLON'
    STEntry = ST.currSymTab.addVar(p[1], p[3].type, isConst=True)
    p[0] = IG.Node()
    p[0].genCode(
        IG.TACInstr(IG.TACInstr.ASSIGN,
                    dest=STEntry,
                    src1=p[3].place,
                    lineNo=IG.nextQuad))
    IG.nextQuad += 1
Example #9
0
def p_assignment_statement(p):
    '''assignment_statement : variable_reference COLON_EQUAL expression'''
    p[0] = IG.Node()
    p[0].nextList = p[3].nextList
    p[0].genCode(
        IG.TACInstr(IG.TACInstr.ASSIGN,
                    src1=p[3].place,
                    dest=p[1].place,
                    lineNo=IG.nextQuad))
    IG.nextQuad += 1
Example #10
0
def p_proc_head(p):
    'proc_head : KEYWORD_PROCEDURE IDENTIFIER parameter_list'
    ST.currSymTab.previousTable.addProcedure(p[2], len(p[3].items))
    p[0] = IG.Node()
    p[0].genCode(
        IG.TACInstr(IG.TACInstr.LABEL,
                    label=p[2],
                    paramList=p[3].items,
                    lineNo=IG.nextQuad))
    IG.nextQuad += 1
Example #11
0
def p_marker_while(p):
    '''marker_while : '''
    p[0] = IG.Node()
    p[0].genCode(
        IG.TACInstr(IG.TACInstr.IFGOTO,
                    src1=p[-1].place,
                    src2=False,
                    op=IG.TACInstr.EQ,
                    lineNo=IG.nextQuad))
    p[0].quad = IG.nextQuad
    IG.nextQuad += 1
Example #12
0
def p_var_statement(p):
    '''var_statement : identifiers COLON type SEMICOLON
                     | IDENTIFIER COLON type SEMICOLON
                     | IDENTIFIER COLON type EQUAL expression SEMICOLON'''
    p[0] = IG.Node()
    if len(p) == 5:
        if type(p[1]) == IG.Node:
            for item in p[1].items:
                STEntry = ST.currSymTab.addVar(item, p[3].type)
                if STEntry.isArray():
                    p[0].genCode(
                        IG.TACInstr(IG.TACInstr.DECLARE,
                                    dest='array',
                                    src1=p[3].type.arrayBeginList[0],
                                    src2=p[3].type.arrayEndList[0],
                                    lineNo=IG.nextQuad))
                    IG.nextQuad += 1
        else:
            STEntry = ST.currSymTab.addVar(p[1], p[3].type)
            if STEntry.isArray():
                p[0].genCode(
                    IG.TACInstr(IG.TACInstr.DECLARE,
                                dest='array',
                                src1=p[3].type.arrayBeginList[0],
                                src2=p[3].type.arrayEndList[0],
                                lineNo=IG.nextQuad))
                IG.nextQuad += 1

    else:
        STEntry = ST.currSymTab.addVar(p[1], p[3].type)
        p[0].genCode(
            IG.TACInstr(IG.TACInstr.ASSIGN,
                        dest=STEntry,
                        src1=p[5].place,
                        lineNo=IG.nextQuad))
        IG.nextQuad += 1
Example #13
0
def p_term(p):
    '''term : term OP_MULT factor
            | term OP_DIV factor
            | term OP_MOD factor
            | term OP_AND bool_exp_marker factor
            | term OP_BIT_AND factor
            | term OP_SHIFTLEFT factor
            | term OP_SHIFTRIGHT factor
            | factor'''

    p[0] = IG.Node()
    if len(p) == 5:
        backpatch(p[1].trueList, p[3].quad)
        p[0].trueList = p[4].trueList
        p[0].falseList = p[1].falseList + p[4].falseList
        p[0].place = IG.newTempBool()
        p[0].type = p[0].place.type
        p[0].code = p[1].code + p[4].code
        # p[0].genCode(IG.TACInstr(IG.TACInstr.ASSIGN, op=IG.TACInstr.LOGICAND, src1=p[1].place, src2=p[4].place,
        #                          dest=p[0].place, lineNo=IG.nextQuad))
        # IG.nextQuad += 1

    elif len(p) == 4:
        if p[1].type == p[3].type:
            p[0].place = IG.newTempInt()
            p[0].type = p[0].place.type
            p[0].code = p[1].code + p[3].code
            p[0].genCode(
                IG.TACInstr(IG.TACInstr.ASSIGN,
                            op=IG.TACInstr.OpMap[p[2]],
                            src1=p[1].place,
                            src2=p[3].place,
                            dest=p[0].place,
                            lineNo=IG.nextQuad))
            IG.nextQuad += 1
            # TODO Generate code for other types
        else:
            # TODO Type checking error
            pass
    elif len(p) == 2:
        p[0] = p[1]
Example #14
0
def p_simple_expression(p):
    '''simple_expression : simple_expression OP_PLUS term
                         | simple_expression OP_MINUS term
                         | simple_expression OP_OR bool_exp_marker term
                         | simple_expression OP_XOR term
                         | simple_expression OP_BIT_OR term
                         | simple_expression OP_BIT_XOR term
                         | term'''
    p[0] = IG.Node()
    if len(p) == 5:
        backpatch(p[1].falseList, p[3].quad)
        p[0].trueList = p[1].trueList + p[4].trueList
        p[0].falseList = p[4].falseList
        p[0].code = p[1].code + p[4].code
        # p[0].genCode(IG.TACInstr(IG.TACInstr.ASSIGN, op=IG.TACInstr.LOGICOR, src1=p[1].place, src2=p[4].place,
        #                          dest=p[0].place, lineNo=IG.nextQuad))
        # IG.nextQuad += 1

    elif len(p) == 4:
        if p[1].type == p[3].type:
            p[0].place = IG.newTempInt()
            p[0].type = p[0].place.type
            p[0].code = p[1].code + p[3].code
            p[0].genCode(
                IG.TACInstr(IG.TACInstr.ASSIGN,
                            op=IG.TACInstr.OpMap[p[2]],
                            src1=p[1].place,
                            src2=p[3].place,
                            dest=p[0].place,
                            lineNo=IG.nextQuad))
            IG.nextQuad += 1
            # TODO Generate Code for other types
        else:
            # TODO Type checking error
            pass

    elif len(p) == 2:
        p[0] = p[1]
Example #15
0
def p_unmatched_statement(p):
    '''unmatched_statement : KEYWORD_IF expression KEYWORD_THEN marker_if statement
                           | KEYWORD_IF expression KEYWORD_THEN marker_if matched_statement \
                             marker_if_end KEYWORD_ELSE marker_else unmatched_statement
                           | loop_header unmatched_statement'''
    p[0] = IG.Node()
    if len(p) == 6:
        p[0].code = p[2].code + p[4].code + p[5].code
        backpatch(p[2].trueList, p[4].quad)
        p[0].nextList = p[2].falseList + p[5].nextList

    elif len(p) == 10:
        p[0].code = p[2].code + p[4].code + p[5].code + p[6].code + p[9].code
        backpatch(p[2].falseList, p[8].quad)
        backpatch(p[2].trueList, p[4].quad)
        p[0].nextList = p[5].nextList + p[6].nextList + p[9].nextList

    elif len(p) == 3:
        p[0].code = p[1].code + p[2].code
        p[0].genCode(
            IG.TACInstr(IG.TACInstr.GOTO, target=p[1].quad,
                        lineNo=IG.nextQuad))
        IG.nextQuad += 1
        backpatch(p[1].endList, IG.nextQuad)
Example #16
0
def p_start(p):
    'start : program_statement global_decs_defs block DOT'
    p[0] = IG.Node()
    p[0].code = p[2].code + p[3].code
    p[0].genCode(IG.TACInstr(IG.TACInstr.RETURN, lineNo=IG.nextQuad))
    IG.nextQuad += 1
Example #17
0
def p_marker_if_end(p):
    '''marker_if_end : '''
    p[0] = IG.Node()
    p[0].nextList = [IG.nextQuad]
    p[0].genCode(IG.TACInstr(IG.TACInstr.GOTO, lineNo=IG.nextQuad))
    IG.nextQuad += 1
Example #18
0
def p_func_proc_statement(p):
    '''func_proc_statement : IDENTIFIER LEFT_PARENTHESIS expression_list RIGHT_PARENTHESIS
                           | IDENTIFIER LEFT_PARENTHESIS RIGHT_PARENTHESIS'''
    p[0] = IG.Node()
    if len(p) == 5:
        if p[1] == 'read' or p[1] == 'readln':
            if len(p[3].items) == 1:
                # TODO Type Readln FIXME
                if p[3].items[0].getDeepestType() == ST.Type.INT:
                    ioFmtString = '"%d"'
                elif p[3].items[0].getDeepestType() == ST.Type.STRING:
                    ioFmtString = '"%s"'
                elif p[3].items[0].getDeepestType() == ST.Type.CHAR:
                    ioFmtString = '"%c"'
                else:
                    # TODO ERROR
                    pass
                    # print_error('Type Not Supported for Read Operation')
                ioArgList = [IG.Operand(item) for item in p[3].items]
                p[0].genCode(
                    IG.TACInstr(IG.TACInstr.SCANF,
                                ioArgList=ioArgList,
                                ioFmtString=ioFmtString,
                                lineNo=IG.nextQuad))
                IG.nextQuad += 1
        elif p[1] == 'write' or p[1] == 'writeln':
            if len(p[3].items) == 1:
                # TODO Type Writeln FIXME
                if type(p[3].items[0]) == ST.SymTabEntry or type(
                        p[3].items[0]) == IG.ArrayElement:
                    #print p[3].items[0].type.name, p[3].items[0].type.getDeepestType()
                    if p[3].items[0].type.getDeepestType() == 'integer':
                        ioFmtString = '%d'
                    elif p[3].items[0].type.getDeepestType() == 'string':
                        ioFmtString = '%s'
                    elif p[3].items[0].type.getDeepestType() == 'char':
                        ioFmtString = '%c'
                    else:
                        # TODO ERROR
                        pass
                        # print_error('Type Not Supported for Read Operation')
                else:
                    if type(p[3].items[0]) == int:
                        ioFmtString = '%d'
                    elif type(p[3].items[0]) == str and len(
                            p[3].items[0]) == 1:
                        ioFmtString = '%c'
                    elif type(p[3].items[0]) == str:
                        ioFmtString = '%s'
                        # TODO Error
                        pass
                if p[1] == 'writeln':
                    ioFmtString += '\\n'
                ioFmtString = '"' + ioFmtString + '"'
                ioArgList = [IG.Operand(item) for item in p[3].items]
                p[0].genCode(
                    IG.TACInstr(IG.TACInstr.PRINTF,
                                ioArgList=ioArgList,
                                ioFmtString=ioFmtString,
                                lineNo=IG.nextQuad))
                IG.nextQuad += 1
        else:
            STEntry = ST.lookup(p[1])
            if STEntry and (STEntry.isFunction() or STEntry.isProcedure()):
                p[0].genCode(
                    IG.TACInstr(IG.TACInstr.CALL,
                                paramList=p[3].items,
                                lineNo=IG.nextQuad,
                                targetLabel=p[1]))
                IG.nextQuad += 1

    else:
        STEntry = ST.lookup(p[1])
        if STEntry and (STEntry.isFunction() or STEntry.isProcedure()):
            p[0].genCode(
                IG.TACInstr(IG.TACInstr.CALL,
                            paramList=[],
                            lineNo=IG.nextQuad,
                            targetLabel=p[1]))
            IG.nextQuad += 1
        else:
            # TODO Type Checking Error
            pass