def p_assignment_redefinition(p): 'assignment : IDENTIFIER OP_ASSIGNMENT expression' # To store information p[0] = {} identifierEntry = ST.exists(p[1]) if identifierEntry == True: ST.addAttribute(p[1], 'type', p[3]['type']) # Check if the function is in the current scope or parent one if ST.existsInCurrentScope(p[1]): place = ST.getAttribute(p[1], ST.getCurrentScope()) else: # store the address into the address descriptor displayValue, offset = ST.getAttribute(p[1], 'scopeLevel'), ST.getAttribute(p[1], 'offset') place = ST.newTemp((displayValue, offset), variable=p[1]) ST.addAttribute(p[1], ST.getCurrentScope(), place) TAC.emit(place, p[3]['place'], '', '=') else: debug.printError('Undefined Variable "%s"' %p[1]) raise SyntaxError # print the name of the statement debug.printStatement("ASSIGNMENT of %s" %p[1])
def p_returnStatement(p): 'returnStatement : RETURN expression' # Type rules p[0] = { 'type' : p[2]['type'] } # Get the current returnType from function returnType = ST.getAttributeFromCurrentScope('returnType') # If the function has not been assigned a return type as of yet if returnType == 'UNDEFINED': # Assign a returnType to the function if p[2]['type'] == 'FUNCTION': ST.addAttributeToCurrentScope('returnType', 'CALLBACK') debug.printStatement("Return statement of type 'CALLBACK'") else: ST.addAttributeToCurrentScope('returnType', p[2]['type']) debug.printStatement("Return statement of type '%s'" %p[2]['type']) elif p[2]['type'] != returnType: p[0]['type'] = 'TYPE_ERROR' debug.printError('Return Types dont match') raise SyntaxError else: # In this case, the return types match, so we needn't do anything pass # Emit code for the return type TAC.emit(p[2]['place'], '' ,'', 'RETURN')
def p_returnStatement(p): 'returnStatement : RETURN expression' # Type rules p[0] = {'type': p[2]['type']} # Get the current returnType from function returnType = ST.getAttributeFromCurrentScope('returnType') # If the function has not been assigned a return type as of yet if returnType == 'UNDEFINED': # Assign a returnType to the function if p[2]['type'] == 'FUNCTION': ST.addAttributeToCurrentScope('returnType', 'CALLBACK') debug.printStatement("Return statement of type 'CALLBACK'") else: ST.addAttributeToCurrentScope('returnType', p[2]['type']) debug.printStatement("Return statement of type '%s'" % p[2]['type']) elif p[2]['type'] != returnType: p[0]['type'] = 'TYPE_ERROR' debug.printError('Return Types dont match') raise SyntaxError else: # In this case, the return types match, so we needn't do anything pass # Emit code for the return type TAC.emit(p[2]['place'], '', '', 'RETURN')
def p_assignment_redefinition(p): 'assignment : IDENTIFIER OP_ASSIGNMENT expression' # To store information p[0] = {} identifierEntry = ST.exists(p[1]) if identifierEntry == True: ST.addAttribute(p[1], 'type', p[3]['type']) # Check if the function is in the current scope or parent one if ST.existsInCurrentScope(p[1]): place = ST.getAttribute(p[1], ST.getCurrentScope()) else: # store the address into the address descriptor displayValue, offset = ST.getAttribute( p[1], 'scopeLevel'), ST.getAttribute(p[1], 'offset') place = ST.newTemp((displayValue, offset), variable=p[1]) ST.addAttribute(p[1], ST.getCurrentScope(), place) TAC.emit(place, p[3]['place'], '', '=') else: debug.printError('Undefined Variable "%s"' % p[1]) raise SyntaxError # print the name of the statement debug.printStatement("ASSIGNMENT of %s" % p[1])
def p_assignment(p): 'assignment : VAR assignList' # In case the var is not present p[0] = {'type': 'VOID'} # Now we add all of these statements for identifier in p[2]: if not ST.existsInCurrentScope(identifier['name']): # Store information about the identifier ST.addIdentifier(identifier['name'], identifier['type']) # This is a new variable, so we link the temporary to our variable displayValue, offset = ST.getAttribute( identifier['name'], 'scopeLevel'), ST.getAttribute(identifier['name'], 'offset') ST.changeMemoryLocationOfTemp(identifier['place'], (displayValue, offset), variable=identifier['name']) ST.addAttribute(identifier['name'], ST.getCurrentScope(), identifier['place']) ST.addAttribute(identifier['name'], 'reference', identifier['reference']) # print the name of the statement debug.printStatement("ASSIGNMENT of %s" % identifier['name']) else: debug.printError('Redefined Variable "%s"' % identifier['name']) raise SyntaxError
def p_continueStatement(p): 'continueStatement : CONTINUE' debug.printStatement('Continue') # Type rules p[0] = {} # Emit code p[0]['loopBeginList'] = [TAC.getNextQuad()] TAC.emit('', '', -1, 'GOTO')
def p_breakStatement(p): 'breakStatement : BREAK' debug.printStatement('Break') # Type rules p[0] = {} # Emit code p[0]['loopEndList'] = [TAC.getNextQuad()] TAC.emit('', '', -1, 'GOTO')
def p_printStatement(p): 'printStatement : CONSOLE OP_DOT LOG SEP_OPEN_PARENTHESIS printList SEP_CLOSE_PARENTHESIS' p[0] = {} for printIterator in p[5]: # Check if the given expression is printable or not expType = printIterator.get('type') if expType in ['STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED']: TAC.emit(printIterator['place'], '', printIterator['type'], 'PRINT') debug.printStatement("Print Statement of type %s" %printIterator['type']) else: debug.printError('Given expression is not a printable type') raise SyntaxError
def p_declaration(p): 'declaration : VAR decList' # Add identifiers to local scope for identifierName in p[2]: # Put the identifier into the symbolTable identifierEntry = ST.existsInCurrentScope(identifierName) if identifierEntry == False: ST.addIdentifier(identifierName, 'UNDEFINED') # Create a temporary for the current scope displayValue, offset = ST.getAttribute(identifierName, 'scopeLevel'), ST.getAttribute(identifierName, 'offset') place = ST.newTemp((displayValue, offset), variable=identifierName) ST.addAttribute(identifierName, ST.getCurrentScope(), place) else: debug.printError('Redefined Variable "%s"' %identifierName) raise SyntaxError debug.printStatement("Declaration '%s'" %identifierName) # Type rules p[0] = {}
def p_assignment(p): 'assignment : VAR assignList' # In case the var is not present p[0] = { 'type' : 'VOID' } # Now we add all of these statements for identifier in p[2]: if not ST.existsInCurrentScope(identifier['name']): # Store information about the identifier ST.addIdentifier(identifier['name'], identifier['type']) # This is a new variable, so we link the temporary to our variable displayValue, offset = ST.getAttribute(identifier['name'], 'scopeLevel'), ST.getAttribute(identifier['name'], 'offset') ST.changeMemoryLocationOfTemp(identifier['place'], (displayValue, offset), variable=identifier['name']) ST.addAttribute(identifier['name'], ST.getCurrentScope(), identifier['place']) ST.addAttribute(identifier['name'], 'reference', identifier['reference']) # print the name of the statement debug.printStatement("ASSIGNMENT of %s" %identifier['name']) else: debug.printError('Redefined Variable "%s"' %identifier['name']) raise SyntaxError