def verifyHasIdByScope(id, symbolTable, scope): if symbolTable.hasSymbolByScope(id, scope): return True else: logError("Semantic error: id \"" + id + "\" not found in scope " + scope) return False
def forLoopWithRange(node, varID, indexes, symbolTable, scope): Step = 1 if node.getSon(4).getName() == "STEP": Step = node.getSon(5).getName() lowerLimit = int(indexes[0][0]) upperLimit = int(indexes[0][2]) if lowerLimit < upperLimit: if node.getSon(4).getName() == "STEP": Step = node.getSon(5).getName() totalCycles = upperLimit-lowerLimit if Step == 1: for cycle in range(lowerLimit, upperLimit): tempSymbol = symbolTable.getSymbolByScope(varID, scope) tempSymbol.setValue(cycle) symbolTable.modifySymbol(tempSymbol) tempStatementList = node.getSon(5) statementList(tempStatementList, symbolTable, scope) symbolTable.eliminateSymbolByScope(varID, scope) else: cycle = lowerLimit while cycle < upperLimit: tempSymbol = symbolTable.getSymbolByScope(varID, scope) tempSymbol.setValue(cycle) symbolTable.modifySymbol(tempSymbol) tempStatementList = node.getSon(7) statementList(tempStatementList, symbolTable, scope) cycle += Step symbolTable.eliminateSymbolByScope(varID, scope) else: logError("Semantic: UpperLimit " + str(upperLimit) + " doesn't match LowerLimit " + str(lowerLimit))
def ifStatementInteger(node, comparable, value, operator, symbolTable, scope): if operator == "==": if comparable.getValue() == value: statementList(node.getSon(5), symbolTable, scope) else: pass elif operator == '<': if comparable.getValue() < value: statementList(node.getSon(5), symbolTable, scope) else: pass elif operator == ">": if comparable.getValue() > value: statementList(node.getSon(5), symbolTable, scope) else: pass elif operator == "<=": if comparable.getValue() <= value: statementList(node.getSon(5), symbolTable, scope) else: pass elif operator == ">=": if comparable.getValue() >= value: statementList(node.getSon(5), symbolTable, scope) else: pass elif operator == "!=": if comparable.getValue() != value: statementList(node.getSon(5), symbolTable, scope) else: pass else: logError("Value type not supported")
def verifyIsAMatrix(id, list): if verifyIsAList(id, list): isAMatrix = all(isinstance(subList, type([])) for subList in list) if isAMatrix: return True else: logError("Semantic error: id \"" + id + "\" is not a matrix") return False
def verifyIndexInBounds(id, list, index): indexBound = len(list) - 1 indexOutOfRange = index > indexBound or index < 0 if not indexOutOfRange: return True else: logError("Semantic error: index out of range in list \"" + id + "\"") return False
def getTypeByValue(value): from Compiler.DataStructures.symbolTable import Types if isinstance(value, bool): return Types.Boolean if isinstance(value, list): return Types.List if isinstance(value, int) or isinstance(value, float): return Types.Integer logError("getTypeByValue encounter an unrecognized value" + str(value))
def ifStatementBoolean(node, comparable, value, operator, symbolTable, scope): if operator == "==": if comparable == value: statementList(node.getSon(5), symbolTable, scope) else: pass elif operator == "!=": if comparable != value: statementList(node.getSon(5), symbolTable, scope) else: pass else: logError(operator + ": Operator not supported in variable " + str(type(value)))
def verifyColumnIsInBounds(id, matrix, index): if index < 0: return False inBounds = True for row in matrix: if len(row) < index + 1: inBounds = False if inBounds: return True else: logError("Semantic error: column at \"" + id + "\" out of range") return False
def changeValueInList(lista, indexes, value): if len(indexes) == 1: lista[indexes[0]] = value elif not isinstance(lista[0], list): lista[indexes[0]] = value else: if indexes[0] < len(lista): changeValueInList(lista[indexes[0]], indexes[1:], value) else: logError( "Semantic Error: Error in function changeValueInList: " + str(indexes[0]) + " is bigger than the size of the dimensions of the list or matrix" )
def multipleDeclaration(node, symbolTable, scope): if not isReadyForRun(): idNodeList = node.getSon(2) valueNodeList = node.getSon(6) idList = [node.getSon(0).name] + getNestedIdNodesAsList(idNodeList) valueList = [node.getSon(4)] + getNestedValueNodesAsList(valueNodeList) if len(idList) == len(valueList): for i in range(len(idList)): varValue(valueList[i], symbolTable, scope, idList[i]) else: logError( "Semantic Error: one line multiple assignment impossible with id's " + str(idList) + ", amount of id's and values don't match")
def resolveIndexes(indexes, symbolTable, scope): for index in range(len(indexes)): if not isinstance(indexes[index], int): tempSymbol = symbolTable.getSymbolByScope(indexes[index], scope) if tempSymbol != None: indexes[index] = tempSymbol.getValue() else: tempSymbol = symbolTable.getSymbolByScope( indexes[index], "global") if tempSymbol != None: indexes[index] = tempSymbol.getValue() else: if not "," in indexes[index] and not ":" in indexes[index]: logError("Index id \"" + str(indexes[index]) + "\" not found") return indexes
def list_process(valueNode, symbolTable, scope, varID): elements = valueNode.getSon(1) newValue = listElements(elements, []) if varID in symbolTable.getReservedId(): cubeSymbol = symbolTable.getSymbolByScope(varID, "global") previousCube = copy.deepcopy(cubeSymbol.getValue()) if not verifyListsDimensions(newValue, previousCube): logError( "Semantic Error: New cube doesn't have the correct dimensions") return False tempSymbol = Symbol(varID, newValue, Types.List, scope) symbolTable.modifySymbol(tempSymbol) newCube = symbolTable.getSymbolByScope(varID, "global") reportCubeChanges(previousCube, newCube) else: tempSymbol = Symbol(varID, newValue, Types.List, scope) symbolTable.modifySymbol(tempSymbol)
def verifyIndexesInBounds(id, originalList, indexes): indexesInRange = True list = copy.deepcopy(originalList) for index in indexes: if isAList(list): if not verifyIndexInBounds(id, list, index): indexesInRange = False break else: id += "[" + str(index) + "]" list = getElementAtIndexes(list, [index]) else: indexesInRange = False logError("Semantic error: index out of range, element \"" + id + "\" is not a list") break return indexesInRange
def modifySymbol(self, newSymbol): tempID = newSymbol.getID() tempScope = newSymbol.getScope() if self.hasSymbol(tempID): tempSymbolValue = self.getSymbolByScope(tempID, tempScope).getValue() if getTypeByValue(tempSymbolValue) == getTypeByValue( newSymbol.getValue()): self.eliminateSymbolByScope(tempID, tempScope) tempNode = Node(newSymbol) self.symbols[tempID].add(tempNode) else: logError("Semantic Error: Value: " + str(newSymbol.getValue()) + " doesn't match type for variable " + str(tempID)) else: self.add(newSymbol)
def modifySymbolList(tempID, tempIndex, tempValue, scope, symbolTable): tempSymbol = symbolTable.getSymbolByScope(tempID, scope) if tempSymbol != None: tempList = tempSymbol.getValue() if verifyIndexBoundries(tempList, tempIndex): changeValueInList(tempList, tempIndex, tempValue) return True else: logError( "Semantic Error: Error in modifySymbolList: indexes out of range" ) return False tempSymbol = symbolTable.getSymbolByScope(tempID, "global") if tempSymbol != None: tempList = tempSymbol.getValue() if verifyIndexBoundries(tempList, tempIndex): changeValueInList(tempList, tempIndex, tempValue) return True
def ifStatementIterativeAux(node, comparable, value, operator, symbolTable, scope, indexList): if indexList == []: if isinstance(comparable, list): ifStatementIterative(node, comparable, value, operator, symbolTable, scope) elif isinstance(comparable, bool): ifStatementBoolean(node, comparable, value, operator, symbolTable, scope) elif isinstance(indexList[0], str): try: if indexList[0][0] == ":": index = int(indexList[0][2:]) indexList[0] = index else: index = [int(indexList[0][0]), int(indexList[0][2])] indexList = index ifStatementIterativeAux(node, comparable, value, operator, symbolTable, scope, indexList) return except ValueError: return logError(str(indexList[0][2:]) + " must be integer type") try: for item in range(0, len(comparable)): if len(comparable) > indexList[0]: if isinstance(comparable[item], list): if len(indexList) == 1: ifStatementBoolean(node, comparable[item][indexList[0]], value, operator, symbolTable, scope) else: ifStatementIterativeAux(node, comparable[item][indexList[0]], value, operator, symbolTable, scope, indexList[1:]) elif isinstance(comparable[item], bool): if len(indexList) == 1: if item == indexList[0]: ifStatementBoolean(node, comparable[indexList[0]], value, operator, symbolTable, scope) else: return logError("List out of range") else: return logError(str(comparable[item]) + " Must be list or boolean") else: return logError("List out of range") return except: return logError(str(comparable)+" is not iterable") else: if isinstance(comparable, list): if indexList[0] < len(comparable): if isinstance(value, bool): ifStatementIterativeAux(node, comparable[indexList[0]], value, operator, symbolTable, scope, indexList[1:]) else: return logError(str(value) + " Must be boolean") else: return logError("List out of range") else: return logError("List out of range")
def indexVarValue(valueNode, symbolTable, scope): value = valueNode.getSon(0) if type(True) == type(value.getName()): return value.getName() elif value.getName() == "list": return listElements(value.getSon(1), []) elif value.getName() == "indexedId": tempIndexes = getIndexes(value.getSon(1), [], symbolTable, scope) tempVarSymbol = symbolTable.getSymbolByScope( value.getSon(0).getName(), scope) if verifyIndexBoundries(tempVarSymbol.getValue(), tempIndexes): return getElementAtIndexes(tempVarSymbol.getValue(), tempIndexes) else: logError("Semantic: Variable " + str(value.getSon(0).getName()) + " doesn't match size of index " + str(tempIndexes)) else: tempSymbol = symbolTable.getSymbolByScope(value.getName(), scope) tempValue = tempSymbol.getValue() return tempValue
def verifyIndexInBounds(id, list, index): index = ''.join(str(index).split()) # form [a,b] if "," in index: indexes = splitIndexBySymbol(index, ",") # form [:,int] asking for column if indexes[0] == ":": id += "[" + str(index) + "]" return verifyColumnIsInBounds(id, list, indexes[1]) # form [int, int] else: if verifyIndexInBounds(id, list, indexes[0]): id += "[" + str(indexes[0]) + "]" if verifyIsAList(id, list[int(index[0])]): return verifyIndexInBounds(id, list[int(indexes[0])], int(indexes[1])) else: return False else: return False # form [a:b] elif ":" in index: if processIndexRange(list, index) != []: return True else: id += "[" + index + "]" logError("Semantic error: index out of range at \"" + id + "\"") # form [a] else: index = int(index) indexBound = len(list) - 1 indexOutOfRange = index > indexBound or index < 0 if not indexOutOfRange: return True else: id += "[" + str(index) + "]" logError("Semantic error: index out of range at \"" + id + "\"") return False
def ifStatement(node, symbolTable, scope): if isReadyForRun(): comparable = node.getSon(1).getSon(0).getName() operator = node.getSon(2).getName() value = node.getSon(3).getSon(0).getName() if comparable == "indexedId": elements = getIndexes(node.getSon(1).getSon(0).getSon(1), [], symbolTable, scope) if elements[0] == "x,y": elements = [0, 0] elements[0] = symbolTable.getSymbolByScope("x", scope).getValue() elements[1] = symbolTable.getSymbolByScope("y", scope).getValue() comparable = node.getSon(1).getSon(0).getSon(0).getName() if symbolTable.hasSymbolByScope(comparable, scope): comparable = symbolTable.getSymbolByScope(comparable, scope) ifStatementIterativeAux(node, comparable.getValue(), value, operator, symbolTable, scope, elements) elif symbolTable.hasSymbolByScope(comparable, scope): comparable = symbolTable.getSymbolByScope(comparable, scope) if isinstance(comparable.getValue(), list): if isinstance(value, bool): ifStatementIterative(node, comparable.getValue(), value, operator, symbolTable, scope) else: logError(str(value) + " Must be boolean") elif isinstance(comparable.getValue(), bool): if isinstance(value, bool): ifStatementBoolean(node, comparable.getValue(), value, operator, symbolTable, scope) else: logError(str(value) + " Must be boolean") elif isinstance(comparable.getValue(), int): if isinstance(value, int): ifStatementInteger(node, comparable, value, operator, symbolTable, scope) else: logError(str(value) + " Must be integer") else: logError("Comparator type not supported") else: logError("Symbol not found" + str(comparable))
def forLoop(node, symbolTable, scope): if isReadyForRun(): varID = node.getSon(1).getName() iterable = node.getSon(3).getSon(0).getName() symbolTable.simpleAdd(varID, 0, Types.Integer, scope) isRange = False if not isinstance(iterable, int): iterableValueLength = 0 if iterable == "indexedId": tempNode = node.getSon(3).getSon(0) tempListSymbol = symbolTable.getSymbolByScope(tempNode.getSon(0).getName(), scope) if tempListSymbol == None: tempListSymbol = symbolTable.getSymbolByScope(tempNode.getSon(0).getName(), "global") tempList = tempListSymbol.getValue() indexes = getIndexes(tempNode.getSon(1), [], symbolTable, scope) for value in indexes: if not isinstance(value, int): if value[1] == ':': isRange = True forLoopWithRange(node, varID, indexes, symbolTable, scope) break else: break if not isRange: iterableValueLength = len(getListElementByIndex(tempList, indexes)) elif iterable == "len": tempID = node.getSon(3).getSon(0).getSon(0).getName() iterableValue = symbolTable.getSymbolByScope(tempID, scope) if iterableValue == None: logError("Semantic: Variable " + str(tempID) + " was not found") iterableValueLength = len(iterableValue.getValue()) else: iterableValue = symbolTable.getSymbolByScope(iterable, scope) if iterableValue == None: iterableValue = symbolTable.getSymbolByScope(node.getSon(3).getSon(0).getName(), "global") if isinstance(iterableValue.getValue(), int): iterableValueLength = iterableValue.getValue() else: iterableValueLength = len(iterableValue.getValue()) if not isRange: Step = 1 if node.getSon(4).getName() == "STEP": Step = node.getSon(5).getName() totalCycles = iterableValueLength if Step == 1: for cycle in range(totalCycles): tempSymbol = symbolTable.getSymbolByScope(varID, scope) tempSymbol.setValue(cycle) symbolTable.modifySymbol(tempSymbol) tempStatementList = node.getSon(5) statementList(tempStatementList, symbolTable, scope) symbolTable.eliminateSymbolByScope(varID, scope) else: cycle = 0 while cycle < totalCycles: tempSymbol = symbolTable.getSymbolByScope(varID, scope) tempSymbol.setValue(cycle) symbolTable.modifySymbol(tempSymbol) tempStatementList = node.getSon(7) statementList(tempStatementList, symbolTable, scope) cycle += Step symbolTable.eliminateSymbolByScope(varID, scope) else: for cycle in range(iterable): tempSymbol = symbolTable.getSymbolByScope(varID, scope) tempSymbol.setValue(cycle) symbolTable.modifySymbol(tempSymbol) tempStatementList = node.getSon(5) statementList(tempStatementList, symbolTable, scope) symbolTable.eliminateSymbolByScope(varID, scope)
def verifyIsAList(id, list): if isAList(list): return True else: logError("Semantic error: id \"" + id + "\" is not a list") return False
def verifyHasId(id, symbolTable): if symbolTable.hasSymbol(id): return True else: logError("Semantic error: id \"" + id + "\" not found") return False