def p_insertArgs(p): 'M_insertArgs : empty' # Add identifiers to local scope for argument in p[-2]: # Any callback is stored as a CALLBACK which is a different type if ST.existsInCurrentScope(argument['name']): debug.printError("Redefinition of argument '%s'" % argument['name']) raise SyntaxError else: if argument['type'] == 'FUNCTION': ST.addIdentifier(argument['name'], 'CALLBACK') else: ST.addIdentifier(argument['name'], argument['type']) # store the address into the address descriptor # The parameters have to loaded in form memory displayValue, offset = ST.getAttribute( argument['name'], 'scopeLevel'), ST.getAttribute(argument['name'], 'offset') place = ST.newTemp((displayValue, offset), variable=argument['name'], loadFromMemory=True) ST.addAttribute(argument['name'], ST.getCurrentScope(), place) debug.printStatementBlock("Argument '%s' of type '%s'" % (argument['name'], argument['type'])) # Now we store the number of parameters in the function ST.addAttributeToCurrentScope('numParam', len(p[-2]))
def p_insertArgs(p): 'M_insertArgs : empty' # Add identifiers to local scope for argument in p[-2]: # Any callback is stored as a CALLBACK which is a different type if ST.existsInCurrentScope(argument['name']): debug.printError("Redefinition of argument '%s'" %argument['name']) raise SyntaxError else: if argument['type'] == 'FUNCTION': ST.addIdentifier(argument['name'], 'CALLBACK') else: ST.addIdentifier(argument['name'], argument['type']) # store the address into the address descriptor # The parameters have to loaded in form memory displayValue, offset = ST.getAttribute(argument['name'], 'scopeLevel'), ST.getAttribute(argument['name'], 'offset') place = ST.newTemp((displayValue, offset), variable=argument['name'], loadFromMemory=True) ST.addAttribute(argument['name'], ST.getCurrentScope(), place) debug.printStatementBlock("Argument '%s' of type '%s'" %(argument['name'], argument['type'])) # Now we store the number of parameters in the function ST.addAttributeToCurrentScope('numParam', len(p[-2]))
def p_m_whileBranch(p): 'M_whileBranch : empty' p[0] = {} p[0]['falseList'] = [TAC.getNextQuad()] TAC.emit(p[-2]['place'], '', -1, 'COND_GOTO_Z') # Print to the console debug.printStatementBlock("While Statement")
def p_m_elseBranch(p): 'M_elseBranch : empty' # Print to the console debug.printStatementBlock("Else Branch") p[0] = {} p[0]['nextList'] = [TAC.getNextQuad()] TAC.emit('', '', -1, 'GOTO') p[0]['quad'] = TAC.getNextQuad()
def p_functionCall(p): 'functionCall : IDENTIFIER SEP_OPEN_PARENTHESIS actualParameters SEP_CLOSE_PARENTHESIS' p[0] = {} # If the identifier does not exist then we output error if not ST.exists(p[1]): p[0]['type'] = 'REFERENCE_ERROR' debug.printError("Function '%s' is not defined" % p[1]) raise SyntaxError else: identifierType = ST.getAttribute(p[1], 'type') # If the function exists in the current scope if identifierType in ['FUNCTION', 'CALLBACK']: if not ST.existsInCurrentScope(p[1]): # The definition of the function has to be loaded in from memory displayValue, offset = ST.getAttribute( p[1], 'scopeLevel'), ST.getAttribute(p[1], 'offset') place = ST.newTemp((displayValue, offset), variable=p[1], loadFromMemory=True) ST.addAttribute(p[1], ST.getCurrentScope(), place) else: place = ST.getAttribute(p[1], ST.getCurrentScope()) # Now we print the param statements for param in p[3]: TAC.emit(param, '', '', 'PARAM') # The name of the function debug.printStatementBlock("Function call to '%s'" % p[1]) # We jump to the function TAC.emit('', '', place, 'JUMPLABEL') # In case the function call is used in an expression # The type of the statment is dependent on the input condition if identifierType != 'CALLBACK': reference = ST.getAttribute(p[1], 'reference') p[0]['type'] = ST.getAttributeFromFunctionList( reference, 'returnType') if p[0]['type'] != 'CALLBACK': returnPlace = ST.newTemp() TAC.emit(returnPlace, '', '', 'FUNCTION_RETURN') p[0]['place'] = returnPlace else: p[0]['type'] = 'CALLBACK' else: p[0]['type'] = 'REFERENCE_ERROR' debug.printError('Not a function "%s"' % p[1]) raise SyntaxError
def p_functionCall(p): 'functionCall : IDENTIFIER SEP_OPEN_PARENTHESIS actualParameters SEP_CLOSE_PARENTHESIS' p[0] = {} # If the identifier does not exist then we output error if not ST.exists(p[1]): p[0]['type'] = 'REFERENCE_ERROR' debug.printError("Function '%s' is not defined" %p[1]) raise SyntaxError else: identifierType = ST.getAttribute(p[1], 'type') # If the function exists in the current scope if identifierType in [ 'FUNCTION', 'CALLBACK' ]: if not ST.existsInCurrentScope(p[1]): # The definition of the function has to be loaded in from memory displayValue, offset = ST.getAttribute(p[1], 'scopeLevel'), ST.getAttribute(p[1], 'offset') place = ST.newTemp((displayValue, offset),variable=p[1], loadFromMemory=True) ST.addAttribute(p[1], ST.getCurrentScope(), place) else: place = ST.getAttribute(p[1], ST.getCurrentScope()) # Now we print the param statements for param in p[3]: TAC.emit(param, '', '', 'PARAM') # The name of the function debug.printStatementBlock("Function call to '%s'" %p[1]) # We jump to the function TAC.emit('', '', place, 'JUMPLABEL') # In case the function call is used in an expression # The type of the statment is dependent on the input condition if identifierType != 'CALLBACK': reference = ST.getAttribute(p[1], 'reference') p[0]['type'] = ST.getAttributeFromFunctionList(reference, 'returnType') if p[0]['type'] != 'CALLBACK': returnPlace = ST.newTemp() TAC.emit(returnPlace, '', '', 'FUNCTION_RETURN') p[0]['place'] = returnPlace else: p[0]['type'] = 'CALLBACK' else: p[0]['type'] = 'REFERENCE_ERROR' debug.printError('Not a function "%s"' %p[1]) raise SyntaxError
def p_scope(p): 'M_scope : empty' p[0] = {} # Name the function p[0]['reference'] = ST.nameAnon() # Now add the identifier as a function reference if p[-1] != None: # Check for anon function # Check if the function exists or not if ST.existsInCurrentScope(p[-1]): debug.printError("Redefinition of function '%s'" % p[-1]) raise SyntaxError else: # Print to console debug.printStatementBlock("Definition of function '%s'" % p[-1]) # Create a new variable to hold the function ST.addIdentifier(p[-1], 'FUNCTION') # Create a new temporary for the function and store it in the addressList 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) ST.addAttribute(p[-1], 'reference', p[0]['reference']) # Emit the location of the function reference TAC.emit(place, p[0]['reference'], '', '=REF') else: # Print to console debug.printStatementBlock('Function Definition "%s"' % p[0]['reference']) # Create a function scope ST.addScope(p[0]['reference']) TAC.createFunctionCode(p[0]['reference'])
def p_scope(p): 'M_scope : empty' p[0] = {} # Name the function p[0]['reference'] = ST.nameAnon() # Now add the identifier as a function reference if p[-1] != None: # Check for anon function # Check if the function exists or not if ST.existsInCurrentScope(p[-1]): debug.printError("Redefinition of function '%s'" %p[-1]) raise SyntaxError else: # Print to console debug.printStatementBlock("Definition of function '%s'" %p[-1]) # Create a new variable to hold the function ST.addIdentifier(p[-1], 'FUNCTION') # Create a new temporary for the function and store it in the addressList 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) ST.addAttribute(p[-1], 'reference', p[0]['reference']) # Emit the location of the function reference TAC.emit(place, p[0]['reference'], '', '=REF') else: # Print to console debug.printStatementBlock('Function Definition "%s"' %p[0]['reference']) # Create a function scope ST.addScope(p[0]['reference']) TAC.createFunctionCode(p[0]['reference'])