Exemplo n.º 1
0
def p_factor(p):
    '''factor  : cst_expression
               | '(' seen_lpar superexpression ')' seen_rpar '''
    global instructions
    if instructions.topOperatorEquals('*') or instructions.topOperatorEquals('/'):
        op2 = instructions.popOperand()
        op1 = instructions.popOperand()
        operator = instructions.popOperator()

        if op1.Type is 'arr' and op2.Type is 'arr':
            op2.Type = arrayType.pop()
            op1.Type = arrayType.pop()
            resultingType = getResultingType(operator, op1.Type, op2.Type)
            if resultingType is None:
                print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
                raise SystemExit

            result = currentDirectory.add_temp(resultingType)
            op1 = '(' + str(op1.Address) + ')'
            op2 = '(' + str(op2.Address) + ')'
        elif op1.Type is 'arr':
            op1.Type = arrayType.pop()
            resultingType = getResultingType(operator, op1.Type, op2.Type)
            if resultingType is None:
                print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
                raise SystemExit

            result = currentDirectory.add_temp(resultingType)
            op1 = '(' + str(op1.Address) + ')'
        elif op2.Type is 'arr':
            op2.Type = arrayType.pop()
            resultingType = getResultingType(operator, op1.Type, op2.Type)
            if resultingType is None:
                print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
                raise SystemExit

            result = currentDirectory.add_temp(resultingType)
            op2 = '(' + str(op2.Address) + ')'
        else:
            resultingType = getResultingType(operator, op1.Type, op2.Type)
            if resultingType is None:
                print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
                raise SystemExit

            result = currentDirectory.add_temp(resultingType)

        if result:
            if operator is '*':
                operator = 'MUL'
            elif operator is '/':
                operator = 'DIV'
            instructions.generateQuadruple(operator, op1, op2, result)
            instructions.pushOperand(result)
        else:
            print ("FACTOR ERROR")
Exemplo n.º 2
0
def p_seen_comp(p):
    '''seen_comp :'''
    global instructions
    op2 = instructions.popOperand()
    op1 = instructions.popOperand()
    operator = instructions.popOperator()

    if op1.Type is 'arr' and op2.Type is 'arr':
        op2.Type = arrayType.pop()
        op1.Type = arrayType.pop()
        resultingType = getResultingType(operator, op1.Type, op2.Type)
        if resultingType is None:
            print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
            raise SystemExit

        result = currentDirectory.add_temp(resultingType)
        op1 = '(' + str(op1.Address) + ')'
        op2 = '(' + str(op2.Address) + ')'
    elif op1.Type is 'arr':
        op1.Type = arrayType.pop()
        resultingType = getResultingType(operator, op1.Type, op2.Type)
        if resultingType is None:
            print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
            raise SystemExit

        result = currentDirectory.add_temp(resultingType)
        op1 = '(' + str(op1.Address) + ')'
    elif op2.Type is 'arr':
        op2.Type = arrayType.pop()
        resultingType = getResultingType(operator, op1.Type, op2.Type)
        if resultingType is None:
            print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
            raise SystemExit

        result = currentDirectory.add_temp(resultingType)
        op2 = '(' + str(op2.Address) + ')'
    else:
        resultingType = getResultingType(operator, op1.Type, op2.Type)
        if resultingType is None:
            print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
            raise SystemExit

        result = currentDirectory.add_temp(resultingType)

    if result:
        operator = {"==" : "CEQ",
                    "!=" : "CNE",
                    "<"  : "CLT",
                    ">"  : "CGT",
                    "<=" : "CLE",
                    ">=" : "CGE"}[operator]
        instructions.generateQuadruple(operator, op1, op2, result)
        instructions.pushOperand(result)
    else:
        print ("SEEN_COMPARISON ERROR")
Exemplo n.º 3
0
def p_seen_term(p):
    '''seen_term :'''
    global instructions
    if instructions.topOperatorEquals('+') or instructions.topOperatorEquals('-'):
        op2 = instructions.popOperand()
        op1 = instructions.popOperand()
        operator = instructions.popOperator()
        if op1.Type is 'arr' and op2.Type is 'arr':
            op2.Type = arrayType.pop()
            op1.Type = arrayType.pop()
            resultingType = getResultingType(operator, op1.Type, op2.Type)
            if resultingType is None:
                print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
                raise SystemExit

            result = currentDirectory.add_temp(resultingType)
            op1 = '(' + str(op1.Address) + ')'
            op2 = '(' + str(op2.Address) + ')'
        elif op1.Type is 'arr':
            op1.Type = arrayType.pop()
            resultingType = getResultingType(operator, op1.Type, op2.Type)
            if resultingType is None:
                print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
                raise SystemExit

            result = currentDirectory.add_temp(resultingType)
            op1 = '(' + str(op1.Address) + ')'
        elif op2.Type is 'arr':
            op2.Type = arrayType.pop()
            resultingType = getResultingType(operator, op1.Type, op2.Type)
            if resultingType is None:
                print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
                raise SystemExit

            result = currentDirectory.add_temp(resultingType)
            op2 = '(' + str(op2.Address) + ')'
        else:
            resultingType = getResultingType(operator, op1.Type, op2.Type)
            if resultingType is None:
                print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
                raise SystemExit

            result = currentDirectory.add_temp(resultingType)

        if result:
            if operator is '+':
                operator = 'ADD'
            elif operator is '-':
                operator = 'SUB'
            instructions.generateQuadruple(operator, op1, op2, result)
            instructions.pushOperand(result)
        else:
            print ("SEEN_TERM ERROR")
Exemplo n.º 4
0
def p_seen_arg(p):
    '''seen_arg : '''
    global instructions,currentDirectory,functionDirectory,parameterCounter, parameterCounterInt, parameterCounterDou, parameterCounterStr
    op1 = instructions.popOperand()

    if parameterCounter < len(functionDirectory.parameters):
        nextParam = functionDirectory.parameters[parameterCounter]
        variable = functionDirectory.get_variable(nextParam)
        compatibleType = getResultingType('=', variable.Type, op1.Type)
        if variable.Type is compatibleType:
            if variable.Type is int:
                instructions.generateQuadruple('EQU', op1, 0, Variable('Param{}'.format(parameterCounter), variable.Type, parameterCounterInt + 10000))
                parameterCounterInt += 1
            elif variable.Type is float:
                instructions.generateQuadruple('EQU', op1, 0, Variable('Param{}'.format(parameterCounter), variable.Type, parameterCounterDou + 11000))
                parameterCounterDou += 1
            elif variable.Type is str:
                instructions.generateQuadruple('EQU', op1, 0, Variable('Param{}'.format(parameterCounter), variable.Type, parameterCounterStr + 12000))
                parameterCounterStr += 1
        else:
            print ("ERROR: Incompatible arguments. Received '{}', expected '{}'!".format(op1.Type,functionDirectory.get_variable(nextParam).Type))
            raise SystemExit
        parameterCounter += 1
    else:
        print ("ERROR: Function '{}' received more arguments than expected!".format(functionDirectory.identifier))
        raise SystemExit
Exemplo n.º 5
0
def p_return(p):
    '''return : RETURN superexpression SEMICOLON'''
    global currentDirectory, instructions
    if currentDirectory.Type is not 'void':
        var = instructions.popOperand()
        compatibleType = getResultingType('=', currentDirectory.Type, var.Type)

        if compatibleType:
            instructions.generateQuadruple('RET',var,0,0)
        else:
            print ("ERROR: Incompatible return types! Received {}, expected {}!".format(var.Type, currentDirectory.Type))
            raise SystemExit
Exemplo n.º 6
0
def p_expression(p):
    '''expression : numeric_expression compare'''
    global instructions, currentDirectory
    if instructions.topOperatorEquals('&&') or instructions.topOperatorEquals('||') :
        op2 = instructions.popOperand()
        op1 = instructions.popOperand()
        operator = instructions.popOperator()

        resultingType = getResultingType(operator, op1.Type, op2.Type)
        if resultingType is None:
            print ("ERROR: Operation '{}' between '{}' and '{}' cannot be performed. Incompatible types!".format(operator, op1.Type, op2.Type))
            raise SystemExit

        result = currentDirectory.add_temp(resultingType)

        if result:
            operator = {"&&" : "AND", "||" : "ORR"}[operator]
            instructions.generateQuadruple(operator, op1, op2, result)
            instructions.pushOperand(result)
        else:
            print ("EXPRESSION ERROR")
Exemplo n.º 7
0
def p_variable_declarator3(p):
    '''variable_declarator3 : '=' superexpression
                            | empty'''
    global instructions, currentDirectory
    if p[1]:
        variable = currentDirectory.get_variable(p[-3])
        if variable and variable.Dimension == 0:
            op1 = instructions.popOperand()
            result = variable
            operator = p[1]

            validType = getResultingType(operator, result.Type, op1.Type)
            if validType:
                operator = 'EQU'
                instructions.generateQuadruple(operator, op1, 0, result)
            else:
                print ("ERROR: Invalid types in line {}. Variable '{}' of type '{}' cannot store '{}'!".format(p.lineno(1), currentDirectory.get_variable(result.Name).Name, currentDirectory.get_variable(result.Name).Type, currentDirectory.get_variable(op1.Name).Name))
                raise SystemExit
        else:
            if variable.Dimension > 0:
                print("ERROR: Variable '{}' cannot be initialized since it is an array, in line {}!".format(p[-3], p.lineno(1)))
            else:
                print("ERROR: Variable '{}' not declared in this scope, in line {}!".format(p[-3], p.lineno(1)))
                raise SystemExit
Exemplo n.º 8
0
def p_id_or_array(p):
    '''id_or_array : '=' superexpression
                   | LSQUARE seen_LSQUARE superexpression RSQUARE seen_RSQUARE '=' superexpression'''
    global instructions, currentDirectory

    variable = currentDirectory.get_variable(p[-1])

    if variable:
        if variable.Dimension > 0 and p[1] == '[':
            operator = p[6]
            op2 = variable.Dimension
            tempOp1 = instructions.popOperand()   #value to be assigned.
            op1 = instructions.popOperand()       #index of the array.
            if op1.Type is int:
                instructions.generateQuadruple('VER', op1, op2, variable.Address)
                result = currentDirectory.add_temp(int)
                result.Type = 'arr'
                arrayType.append(variable.Type)
                instructions.generateQuadruple('OFF', variable.Address, op1, result)
                instructions.pushOperand(result)
                op1 = tempOp1
                result = instructions.popOperand()
                if op1.Type is 'arr' and result.Type is 'arr':
                    result.Type = arrayType.pop()
                    op1.Type = arrayType.pop()
                    validType = getResultingType(operator, result.Type, op1.Type)
                    if validType:
                        op1 = '(' + str(op1.Address) + ')'
                        result = '(' + str(result.Address) + ')'
                        operator = 'EQU'
                        instructions.generateQuadruple(operator, op1, 0, result)
                    else:
                        print ("ERROR: Invalid types! Variable '{}' cannot store '{}'!".format(currentDirectory.get_variable(result.Name), currentDirectory.get_variable(op1.Name)))
                        raise SystemExit
                else:
                    result.Type = arrayType.pop()
                    validType = getResultingType(operator, result.Type, op1.Type)
                    if validType:
                        result = '(' + str(result.Address) + ')'
                        operator = 'EQU'
                        instructions.generateQuadruple(operator, op1, 0, result)
                    else:
                        print ("ERROR: Invalid types! Variable '{}' cannot store '{}'!".format(currentDirectory.get_variable(result.Name), currentDirectory.get_variable(op1.Name)))
                        raise SystemExit
            else:
                print("ERROR: Type error. Array index must be of type int, found {} at line {}!".format(op1.Type, p.lineno(1)))
                raise SystemExit
        elif p[1] == '=' and variable.Dimension == 0:
            op1 = instructions.popOperand()
            result = variable
            operator = p[1]

            if op1.Type is 'arr':
                op1.Type = arrayType.pop()
                validType = getResultingType(operator, result.Type, op1.Type)
                if validType:
                    op1 = '(' + str(op1.Address) + ')'
                    operator = 'EQU'
                    instructions.generateQuadruple(operator, op1, 0, result)
                else:
                    print ("ERROR: Invalid types! Variable '{}' cannot store '{}'!".format(currentDirectory.get_variable(result.Name), currentDirectory.get_variable(op1.Name)))
                    raise SystemExit
            else:
                validType = getResultingType(operator, result.Type, op1.Type)
                if validType:
                    operator = 'EQU'
                    instructions.generateQuadruple(operator, op1, 0, result)
                else:
                    print ("ERROR: Invalid types! Variable '{}' cannot store '{}'!".format(currentDirectory.get_variable(result.Name), currentDirectory.get_variable(op1.Name)))
                    raise SystemExit
        else:
            if p[1] == '=':
                print("ERROR: Variable '{}' is of type Array, must be accessed through an index, line {}!".format(p[-1], p.lineno(1)))
                raise SystemExit
            elif p[1] == '[':
                print("ERROR: Variable '{}' is not of type Array, line {}!".format(p[-1], p.lineno(1)))
                raise SystemExit
    else:
        print("ERROR: Variable '{}' not declared in this scope, line {}!".format(p[-1], p.lineno(1)))
        raise SystemExit