コード例 #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
コード例 #2
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)
コード例 #3
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)
コード例 #4
0
def p_value_parameter(p):
    '''value_parameter : identifiers COLON type_identifier
                       | IDENTIFIER COLON type_identifier
                       | identifiers COLON KEYWORD_ARRAY KEYWORD_OF type_identifier
                       | IDENTIFIER COLON KEYWORD_ARRAY KEYWORD_OF type_identifier'''
    p[0] = IG.Node()
    if len(p) == 4:
        if type(p[1]) == IG.Node:
            p[0].items = p[1].items
            for item in p[1].items:
                ST.currSymTab.addVar(item, p[3].type, isParameter=True)
        else:
            p[0].items.append(p[1])
            ST.currSymTab.addVar(p[1], p[3].type, isParameter=True)
    elif len(p) == 5:
        if type(p[1]) == IG.Node:
            p[0].items = p[1].items
            for item in p[1].items:
                ST.currSymTab.addVar(item,
                                     ST.Type('array',
                                             ST.Type.ARRAY,
                                             arrayBaseType=p[5].type),
                                     isParameter=True)
        else:
            p[0].items.append(p[1])
            ST.currSymTab.addVar(p[1],
                                 ST.Type('array',
                                         ST.Type.ARRAY,
                                         arrayBaseType=p[5].type),
                                 isParameter=True)
コード例 #5
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)
コード例 #6
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
コード例 #7
0
def p_parameter_list(p):
    '''parameter_list : LEFT_PARENTHESIS parameter_declarations RIGHT_PARENTHESIS
                      | LEFT_PARENTHESIS RIGHT_PARENTHESIS'''
    if len(p) == 4:
        p[0] = p[2]
    elif len(p) == 3:
        p[0] = IG.Node()
コード例 #8
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
コード例 #9
0
def p_var_statements(p):
    '''var_statements : var_statements var_statement
                      | var_statement'''
    p[0] = IG.Node()
    if len(p) == 3:
        p[0].code = p[1].code + p[2].code
    elif len(p) == 2:
        p[0].code = p[1].code
コード例 #10
0
def p_boolean_range(p):
    '''boolean_range : CONSTANT_BOOLEAN_FALSE DOTDOT CONSTANT_BOOLEAN_FALSE
                     | CONSTANT_BOOLEAN_FALSE DOTDOT CONSTANT_BOOLEAN_TRUE
                     | CONSTANT_BOOLEAN_TRUE DOTDOT CONSTANT_BOOLEAN_TRUE'''

    p[0] = IG.Node()
    p[0].arrayBeginList = [p[1]]
    p[0].arrayEndList = [p[3]]
コード例 #11
0
def p_declarations(p):
    '''declarations : declarations const_declarations
                    | declarations type_declarations
                    | declarations var_declarations
                    | empty'''
    p[0] = IG.Node()
    if len(p) == 3:
        p[0].code = p[1].code + p[2].code
コード例 #12
0
def p_identifiers(p):
    '''identifiers : identifiers COMMA IDENTIFIER
                   | IDENTIFIER COMMA IDENTIFIER'''
    p[0] = IG.Node()
    if type(p[1]) == IG.Node:
        p[0].items = p[1].items + [p[3]]
    else:
        p[0].items = [p[1], p[3]]
コード例 #13
0
def p_array_declaration(p):
    '''array_declaration : KEYWORD_ARRAY LEFT_SQUARE_BRACKETS array_ranges RIGHT_SQUARE_BRACKETS KEYWORD_OF type'''
    p[0] = IG.Node()
    p[0].type = ST.Type('array',
                        ST.Type.ARRAY,
                        arrayBeginList=p[3].arrayBeginList,
                        arrayEndList=p[3].arrayEndList,
                        arrayBaseType=p[6].type)
コード例 #14
0
def p_expression_list(p):
    '''expression_list : expression_list COMMA expression
                       | expression'''
    p[0] = IG.Node()
    if len(p) == 4:
        p[0].items = p[1].items + [p[3].place]
    else:
        p[0].items = [p[1].place]
コード例 #15
0
def p_const_statements(p):
    '''const_statements : const_statements const_statement
                        | const_statement'''
    p[0] = IG.Node()
    if len(p) == 3:
        p[0].code = p[1].code + p[2].code
    elif len(p) == 2:
        p[0].code = p[1].code
コード例 #16
0
def p_parameter_declarations(p):
    '''parameter_declarations : parameter_declarations SEMICOLON value_parameter
                              | value_parameter'''
    p[0] = IG.Node()
    if len(p) == 4:
        p[0].items = p[1].items + p[3].items
        p[0].code = p[1].code + p[3].code
    elif len(p) == 2:
        p[0] = p[1]
コード例 #17
0
def p_array_index_cstyle(p):
    '''array_index_cstyle : array_index_cstyle LEFT_SQUARE_BRACKETS expression RIGHT_SQUARE_BRACKETS
                   | LEFT_SQUARE_BRACKETS expression RIGHT_SQUARE_BRACKETS'''
    p[0] = IG.Node()
    if len(p) == 4:
        p[0] = p[2]
    else:
        # TODO Handle Multi Dimensional
        pass
コード例 #18
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
コード例 #19
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
コード例 #20
0
def p_array_ranges(p):
    '''array_ranges : array_ranges COMMA array_range
                    | array_range'''
    p[0] = IG.Node()
    if len(p) == 4:
        p[0].arrayBeginList = p[1].arrayBeginList + p[3].arrayBeginList
        p[0].arrayEndList = p[1].arrayEndList + p[3].arrayEndList
    else:
        p[0].arrayBeginList = p[1].arrayBeginList
        p[0].arrayEndList = p[1].arrayEndList
コード例 #21
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
コード例 #22
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
コード例 #23
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
コード例 #24
0
def p_integer_range(p):
    '''integer_range : CONSTANT_INTEGER DOTDOT CONSTANT_INTEGER'''

    p[0] = IG.Node()
    if (p[1] <= p[3]):
        p[0].arrayBeginList = [p[1]]
        p[0].arrayEndList = [p[3]]
    else:
        print_error("Semantic error at line", p.lineno(3))
        print_error("\tEnd index is less than start index")
        sys.exit(1)
コード例 #25
0
def p_char_range(p):
    '''char_range : char DOTDOT char'''

    p[0] = IG.Node()
    if (p[1] <= p[3]):
        p[0].arrayBeginList = [p[1]]
        p[0].arrayEndList = [p[3]]
    else:
        print_error("Semantic error at line", p.lineno(3))
        print_error("\tEnd index is less than start index")
        sys.exit(1)
コード例 #26
0
def p_statements(p):
    '''statements : statements SEMICOLON marker_statement statement
                  | statement'''
    p[0] = IG.Node()
    if len(p) == 5:
        p[0].code = p[1].code + p[3].code
        p[0].nextList = p[4].nextList
        backpatch(p[1].nextList, p[3].quad)

    elif len(p) == 2:
        p[0] = p[1]
コード例 #27
0
def p_variable_reference(p):
    '''variable_reference : IDENTIFIER
                          | IDENTIFIER LEFT_SQUARE_BRACKETS array_index RIGHT_SQUARE_BRACKETS
                          | IDENTIFIER array_index_cstyle'''

    p[0] = IG.Node()
    STEntry = ST.lookup(p[1])
    if STEntry:
        if len(p) == 2:
            p[0].place = STEntry
            p[0].type = STEntry.type
        elif len(p) == 3:
            p[0].place = IG.ArrayElement(STEntry, p[2].place)
コード例 #28
0
def p_global_decs_defs(p):
    '''global_decs_defs : global_decs_defs const_declarations
                        | global_decs_defs type_declarations
                        | global_decs_defs var_declarations
                        | global_decs_defs marker_fpdef func_def
                        | global_decs_defs marker_fpdef proc_def
                        | empty'''
    p[0] = IG.Node()
    if len(p) == 3:
        p[0].code = p[1].code + p[2].code  # Assuming type_declarations
        # is also a node with code
    elif len(p) == 4:
        backpatch([p[2].quad], IG.nextQuad)
        p[0].code = p[1].code + p[2].code + p[3].code
    else:
        pass
コード例 #29
0
def p_unsigned_constant(p):
    '''unsigned_constant : CONSTANT_INTEGER
                         | CONSTANT_HEX
                         | CONSTANT_BINARY
                         | CONSTANT_OCTAL
                         | CONSTANT_NIL
                         | CONSTANT_BOOLEAN_TRUE
                         | CONSTANT_BOOLEAN_FALSE
                         | string'''
    p[0] = IG.Node()
    p[0].place = p[1]
    if type(p[1]) == int:
        p[0].type = ST.Type('integer', ST.Type.INT)
    elif type(p[1]) == str:
        if p[1] == 'true' or p[1] == 'false':
            p[0].type = ST.Type('boolean', ST.Type.BOOL)
        else:  # TODO Nil is string FIXME
            p[0].type = ST.Type('string', ST.Type.STRING)
コード例 #30
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]