def createIdxCol(col=[]): '''create an array from the array returned by the parser in Assignment.valExp''' rcol = [] for i in col: if isinstance(i, str): rcol.append(str(i)) elif isinstance(i, int): rcol.append(int(i)) elif isinstance(i, Assignment): #look for a symbol syym = getSymbol(i.varName, i.varType) if (syym != None): #a symbol was returned syym = solve_pointer(syym) #The symbol returned must be a integer or a string if isinstance(syym.value, int) or isinstance(syym.value, str): rcol.append(syym.value) else: addErr( ErrType.SEMANTIC, "Error: unabled to retrieve value from " + str(i.varType) + "" + str(i.varName), i.row) return None else: #a symbol was not returned, so the var does not exist addErr( ErrType.SEMANTIC, "Error: the variable does not exists " + str(i.varType) + "" + str(i.varName), i.row) #return a None value return None return rcol
def solve_val(i): '''This function returns a ValExpression''' if (i.type != ValType.REFVAR): #if is not a variable reference returns the ValExpression itself return i else: #if is a variable reference, it looks for a coincidence on any symbol table #then create a ValExpression with the raw value (and its type) and returns it assign_instance = i.value #gets an array access arrAccess = None if (assign_instance.valExp == None) else createIdxCol( assign_instance.valExp) #gets a symbol symb_FromAssign = getSymbol(assign_instance.varName, assign_instance.varType) if symb_FromAssign == None: #There was not symbol returned #return a 0 integer value #THIS IS AN ERROR return ValExpression(0, ValType.INTEGER) else: #There was a symbol returned #is a pointer? -> solve the pointer if (symb_FromAssign.type == ValType.POINTER): symb_FromAssign = solve_pointer(symb_FromAssign) if (arrAccess != None): #It is necesary to travel through the given symbol value r = throughDict(symb_FromAssign.value, arrAccess) if r == None: addErr(ErrType.SEMANTIC, "", "") return ValExpression(0, ValType.INTEGER) else: return ValExpression(r.value, r.type) else: return ValExpression(symb_FromAssign.value, symb_FromAssign.type) #is an array? -> access through array elif (symb_FromAssign.type == ValType.ARRAY or symb_FromAssign.type == ValType.STRUCT or symb_FromAssign.type == ValType.STRING): if (arrAccess != None): #It is necesary to travel through the given symbol value r = throughDict(symb_FromAssign.value, arrAccess) if r == None: return ValExpression(0, ValType.INTEGER) else: return ValExpression(r.value, r.type) else: #if the <else> statement is executed perhabps createIdxCol poped an error # or there is a string, or #although is possible to copy an array, this practice is not recomended return ValExpression(symb_FromAssign.value, symb_FromAssign.type) else: #perhaps is a integer, string, float or a char return ValExpression(symb_FromAssign.value, symb_FromAssign.type)
def solve_pointer(sym): '''takes a symbol and finds out if it's a pointer if is, look for a reference in the symbol table else, returns the symbol 'sym' On erro returns an integer symbol with value 0''' if sym.type == ValType.POINTER: #Gets the assignment value valSym = sym.value #gets an array access arrAccess = None if (valSym.valExp == None) else createIdxCol( valSym.valExp) #Gets the Symbol referenced valSym = getSymbol(valSym.varName, valSym.varType) #Checks if valSymm is not None if valSym != None: #Checks if arrAccess is not None if arrAccess == None: #There is no need to travel through the given symbol value #Checks again if valSym is a pointer return solve_pointer(valSym) else: #It is necesary to travel through the given symbol value r = throughDict(valSym.value, arrAccess) if r == None: #an error took place when 'throughDict' were executed return Symbol(None, ValType.INTEGER, 0) else: return r else: #the symbol was not found so, an error pops up and returns a zero addErr( ErrType.SEMANTIC, "Error: unable to reference " + str(valSym.varType) + str(valSym.varName), "") return Symbol(None, ValType.INTEGER, 0) else: return sym
def solve_oper(i): if i.op == Operator.PLUS: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): return Symbol(None, ValType.STRING, str(opl.value) + str(opr.value)) elif any(i is ValType.FLOAT for i in typear): return Symbol(None, ValType.FLOAT, float(opl.value + opr.value)) elif any(i is ValType.INTEGER or ValType.CHAR for i in typear): return Symbol(None, ValType.INTEGER, int(opl.value + opr.value)) else: addErr(ErrType.SEMANTIC, "Error: can't add these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.MINUS: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: can't substract between string operands", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT for i in typear): return Symbol(None, ValType.FLOAT, float(opl.value - opr.value)) elif any(i is ValType.INTEGER or ValType.CHAR for i in typear): return Symbol(None, ValType.INTEGER, int(opl.value - opr.value)) else: addErr(ErrType.SEMANTIC, "Error: can't substract these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.TIMES: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: can't multiply strings", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT for i in typear): return Symbol(None, ValType.FLOAT, float(opl.value * opr.value)) elif any(i is ValType.INTEGER or ValType.CHAR for i in typear): return Symbol(None, ValType.INTEGER, int(opl.value * opr.value)) else: addErr(ErrType.SEMANTIC, "Error: can't multiply these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.QUOTIENT: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: can't divide strings", i.row) return Symbol(None, ValType.FLOAT, 0.0) elif any(i is ValType.INTEGER or ValType.FLOAT or ValType.CHAR for i in typear): if opr.value == 0: addErr(ErrType.SEMANTIC, "Error: division by zero", i.row) return Symbol(None, ValType.FLOAT, 0.0) else: return Symbol(None, ValType.FLOAT, opl.value / opr.value) else: addErr(ErrType.SEMANTIC, "Error: can't divide these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.REMAINDER: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: can't get remainder from strings", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT for i in typear): if opr.value == 0: addErr(ErrType.SEMANTIC, "Error: division by zero", i.row) return Symbol(None, ValType.FLOAT, 0.0) else: return Symbol(None, ValType.FLOAT, float(opl.value % opr.value)) elif any(i is ValType.INTEGER or ValType.CHAR for i in typear): if opr.value == 0: addErr(ErrType.SEMANTIC, "Error: division by zero", i.row) return Symbol(None, ValType.INTEGER, 0) else: return Symbol(None, ValType.INTEGER, int(opl.value % opr.value)) else: addErr( ErrType.SEMANTIC, "Error: can't get remainder of these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.NEGATIVE: opl = solve_val(i.e1) if opl.type == ValType.STRING: addErr(ErrType.SEMANTIC, "Error: can't get a negative value from string", i.row) return Symbol(None, ValType.INTEGER, 0) elif opl.type == ValType.FLOAT: return Symbol(None, ValType.FLOAT, float(opl.value * -1)) elif (opl.type == ValType.INTEGER or opl.type == ValType.CHAR): return Symbol(None, ValType.INTEGER, int(opl.value * -1)) else: addErr( ErrType.SEMANTIC, "Error: can't a negative value of this operand " + str(opl.type), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.ABS: opl = solve_val(i.e1) if opl.type == ValType.STRING: addErr(ErrType.SEMANTIC, "Error: can't get absolute value from string", i.row) return Symbol(None, ValType.INTEGER, 0) elif opl.type == ValType.FLOAT: return Symbol(None, ValType.FLOAT, abs(opl.value)) elif opl.type == ValType.INTEGER: return Symbol(None, ValType.INTEGER, abs(opl.value)) elif opl.type == ValType.CHAR: return Symbol(None, ValType.CHAR, opl.value) else: addErr( ErrType.SEMANTIC, "Error: can't get absolute value from this operand " + str(opl.type), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.NOT: opl = solve_val(i.e1) if opl.type == ValType.STRING: addErr(ErrType.SEMANTIC, "Error: can't negate a string", i.row) return Symbol(None, ValType.INTEGER, 0) elif opl.type == ValType.INTEGER or opl.type == ValType.CHAR or opl.type == ValType.FLOAT: temp = 0 if opl.value != 0 else 1 return Symbol(None, ValType.INTEGER, temp) else: addErr(ErrType.SEMANTIC, "Error: cannot negate this operand " + str(opl.type), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.AND: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: cannot use <and> on strings", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT or ValType.INTEGER or ValType.CHAR for i in typear): tmpl = 0 if opl.value == 0 else 1 tmpr = 0 if opr.value == 0 else 1 return Symbol(None, ValType.INTEGER, tmpl and tmpr) else: addErr(ErrType.SEMANTIC, "Error: cannot use <and> on these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.XOR: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: cannot use <xor> on strings", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT or ValType.INTEGER or ValType.CHAR for i in typear): tmpl = 0 if opl.value == 0 else 1 tmpr = 0 if opr.value == 0 else 1 tmpl_n = 0 if opl.value != 0 else 1 tmpr_n = 0 if opl.value != 0 else 1 return Symbol(None, ValType.INTEGER, (tmpl and tmpr_n) or (tmpl_n and tmpr)) else: addErr(ErrType.SEMANTIC, "Error: cannot use <xor> on these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.OR: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: can't use <or> on strings", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT or ValType.INTEGER or ValType.CHAR for i in typear): tmpl = 0 if opl.value == 0 else 1 tmpr = 0 if opr.value == 0 else 1 return Symbol(None, ValType.INTEGER, tmpl or tmpr) else: addErr(ErrType.SEMANTIC, "Error: cannot use <or> on these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.NOTBW: opl = solve_val(i.e1) if opl.type == ValType.STRING: addErr(ErrType.SEMANTIC, "Error: can't negate a string", i.row) return Symbol(None, ValType.INTEGER, 0) else: temp = ~int(opl.value) return Symbol(None, ValType.INTEGER, temp) elif i.op == Operator.ANDBW: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: cannot use and-bitwise on string", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT or ValType.INTEGER or ValType.CHAR for i in typear): temp = int(opl.value) & int(opr.value) return Symbol(None, ValType.INTEGER, temp) else: addErr( ErrType.SEMANTIC, "Error: cannot use and-bitwise on these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.ORBW: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: cannot use or-bitwise on string", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT or ValType.INTEGER or ValType.CHAR for i in typear): temp = int(opl.value) | int(opr.value) return Symbol(None, ValType.INTEGER, temp) else: addErr( ErrType.SEMANTIC, "Error: cannot use or-bitwise on these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.XORBW: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: cannot use xor-bitwise on string", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT or ValType.INTEGER or ValType.CHAR for i in typear): temp = int(opl.value) ^ int(opr.value) return Symbol(None, ValType.INTEGER, temp) else: addErr( ErrType.SEMANTIC, "Error: cannot use xor-bitwise on these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.SHL: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: cannot use shift-left on string", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT or ValType.INTEGER or ValType.CHAR for i in typear): temp = int(opl.value) << int(opr.value) return Symbol(None, ValType.INTEGER, temp) else: addErr( ErrType.SEMANTIC, "Error: cannot use shift-left on these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.SHR: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: cannot use shift-right on string", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT or ValType.INTEGER or ValType.CHAR for i in typear): temp = int(opl.value) >> int(opr.value) return Symbol(None, ValType.INTEGER, temp) else: addErr( ErrType.SEMANTIC, "Error: cannot use shift-right on these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.EQ: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] try: tmp = 1 if (opl.value == opr.value) else 0 return Symbol(None, ValType.INTEGER, tmp) except: addErr(ErrType.SEMANTIC, "Error: cannot compare these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.NEQ: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] try: tmp = 1 if (opl.value != opr.value) else 0 return Symbol(None, ValType.INTEGER, tmp) except: addErr(ErrType.SEMANTIC, "Error: cannot compare these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.GR: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: cannot use 'greater than' on string", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT or ValType.INTEGER or ValType.CHAR for i in typear): tmp = 1 if (opl.value > opr.value) else 0 return Symbol(None, ValType.INTEGER, tmp) else: addErr( ErrType.SEMANTIC, "Error: cannot use 'greater than' on these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.GRE: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: cannot use 'greater than or equal' on string", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT or ValType.INTEGER or ValType.CHAR for i in typear): tmp = 1 if (opl.value >= opr.value) else 0 return Symbol(None, ValType.INTEGER, tmp) else: addErr( ErrType.SEMANTIC, "Error: cannot use 'greater than or equal' on these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.LS: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: cannot use 'less than' on string", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT or ValType.INTEGER or ValType.CHAR for i in typear): tmp = 1 if (opl.value < opr.value) else 0 return Symbol(None, ValType.INTEGER, tmp) else: addErr( ErrType.SEMANTIC, "Error: cannot use 'less than' on these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.LSE: opl = solve_val(i.e1) opr = solve_val(i.e2) typear = [opl.type, opr.type] if any(i is ValType.STRING for i in typear): addErr(ErrType.SEMANTIC, "Error: cannot use 'less than or equal' on string", i.row) return Symbol(None, ValType.INTEGER, 0) elif any(i is ValType.FLOAT or ValType.INTEGER or ValType.CHAR for i in typear): tmp = 1 if (opl.value <= opr.value) else 0 return Symbol(None, ValType.INTEGER, tmp) else: addErr( ErrType.SEMANTIC, "Error: cannot use 'less than or equal' on these operands " + str(typear), i.row) return Symbol(None, ValType.INTEGER, 0) elif i.op == Operator.AMP: # checks if variable exist r = getSymbol(i.e1.value.varName, i.e1.value.varType) if (r != None): return Symbol(None, ValType.POINTER, i.e1.value) else: addErr( ErrType.SEMANTIC, "Error: cannot use & on " + str(i.e1.value.varType) + str(i.e1.value.varName) + ", doesn't exist", i.row) return Symbol(None, ValType.INTEGER, 0) elif (i.op == Operator.CINT): opr = solve_val(i.e1) r = Symbol(None, ValType.INTEGER, 0) if opr.type == ValType.CHAR: r.value = int(opr.value) elif opr.type == ValType.STRING: if (len(opr.value) > 0): r.value = ord(opr.value[0]) else: r.value = 0 elif opr.type == ValType.FLOAT: r.value = trunc(opr.value) elif opr.type == ValType.INTEGER: r.value = opr.value elif opr.type == ValType.ARRAY: tmp = getFirst(opr.value) #get first value if isinstance(tmp, str): r.value = ord(tmp[0]) elif isinstance(tmp, float): r.value = trunc(tmp) elif isinstance(tmp, int): r.value = tmp else: addErr( ErrType.SEMANTIC, "Error: value in array " + str(opr.type) + " cannot cast to " + str(ValType.INTEGER), i.row) else: addErr( ErrType.SEMANTIC, "Error: " + str(opr.type) + " cannot cast to " + str(ValType.INTEGER), i.row) return r elif (i.op == Operator.CFLOAT): opr = solve_val(i.e1) r = Symbol(None, ValType.FLOAT, float(0.0)) if opr.type == ValType.CHAR: r.value = float(opr.value) elif opr.type == ValType.STRING: if (len(opr.value) > 0): r.value = float(ord(opr.value[0])) else: r.value = 0 elif opr.type == ValType.FLOAT: r.value = opr.value elif opr.type == ValType.INTEGER: r.value = float(opr.value) elif opr.type == ValType.ARRAY: tmp = getFirst(opr.value) #get first value if isinstance(tmp, str): r.value = float(ord(tmp[0])) elif isinstance(tmp, float): r.value = tmp elif isinstance(tmp, int): r.value = float(tmp) else: addErr( ErrType.SEMANTIC, "Error: value in array " + str(opr.type) + " cannot cast to " + str(ValType.FLOAT), i.row) else: addErr( ErrType.SEMANTIC, "Error: " + str(opr.type) + " cannot cast to " + str(ValType.FLOAT), i.row) return r elif (i.op == Operator.CCHAR): opr = solve_val(i.e1) r = Symbol(None, ValType.CHAR, 0) if opr.type == ValType.CHAR: r.value = abs(opr.value) elif opr.type == ValType.STRING: if (len(opr.value) > 0): r.value = abs(ord(opr.value[0]) % 256) else: r.value = 0 elif opr.type == ValType.FLOAT: r.value = abs(trunc(opr.value) % 256) elif opr.type == ValType.INTEGER: r.value = abs(opr.value % 256) elif opr.type == ValType.ARRAY: tmp = getFirst(opr.value) #get first value if isinstance(tmp, str): r.value = abs(ord(opr.value[0]) % 256) elif isinstance(tmp, float): r.value = abs(trunc(opr.value) % 256) elif isinstance(tmp, int): r.value = abs(tmp) % 256 else: addErr( ErrType.SEMANTIC, "Error: value in array " + str(opr.type) + " cannot cast to " + str(ValType.CHAR), i.row) else: addErr( ErrType.SEMANTIC, "Error: " + str(opr.type) + " cannot cast to " + str(ValType.CHAR), i.row) return r elif i.op == Operator.READ: # shows an input box and save a string # creates an string symbol r = Symbol(None, ValType.STRING, "") txt, msg = QtWidgets.QInputDialog.getText(None, 'Read', 'Enter here:') if msg: r.value = txt return r elif i.op == Operator.ARRAY: # creates an array symbol r = Symbol(None, ValType.ARRAY, {}) return r
def run(self): ''' This function start the execution of the code ''' if not self.checkMain(): return # this variable will work as a counter and # will specify what position of the syntax tree is running now = datetime.now() cteTime = now.strftime("%H:%M:%S") self.QtOutput.appendPlainText("starting execution..." + cteTime + "\n") cte_i = self.labelDict['main'] + 1 while (cte_i < len(self.astTree)): lenNode = len(self.astTree[cte_i]) if lenNode == 1: objNode = self.astTree[cte_i][0] if isinstance(objNode, Exit): #print("Execution ended") break elif isinstance(objNode, Print): var_Temp = None #solve oper and print the result if isinstance(objNode.oper, ValExpression): #call solve_var, this function returns an instance of ValExpression var_Temp = solve_val(objNode.oper) elif isinstance(objNode.oper, OperationExpression): #call solve_opr, this function return an instance of Symbol var_Temp = solve_oper(objNode.oper) #returns Symbol if (var_Temp.type != ValType.FLOAT and var_Temp.type != ValType.STRING and var_Temp.type != ValType.INTEGER and var_Temp.type != ValType.CHAR): addErr(ErrType.SEMANTIC, "Error: cannot print an array", objNode.row) else: prevTxt = str(self.QtOutput.toPlainText()) prevTxt += str(var_Temp.value).replace('\\n', '\n') self.QtOutput.setPlainText(prevTxt) elif isinstance(objNode, Unset): #will delete a symbol assig = objNode.varn s = getSymbol(assig.varName, assig.varType) if s: deleteSymbol(assig.varName, assig.varType) else: addErr(ErrType.SEMANTIC, "Error: can't unset variable", objNode.row) elif isinstance(objNode, GoTo): #load the value for the key given by label's name if not objNode.name in self.labelDict: addErr( ErrType.SEMANTIC, "Error: Label '" + objNode.name + "' does not exist", objNode.row) break cte_i = self.labelDict[objNode.name] elif isinstance(objNode, If): #solve oper and if the result is not 0 then it will make a jump var_Temp = None #solve oper and make decision if isinstance(objNode.oper, ValExpression): #call solve_var, this function returns an instance of ValExpression var_Temp = solve_val(objNode.oper) elif isinstance(objNode.oper, OperationExpression): #call solve_opr, this function return an instance of Symbol var_Temp = solve_oper(objNode.oper) #returns Symbol #var_Temp.value has to be an integer type if not isinstance(var_Temp.value, int): addErr( ErrType.SEMANTIC, "Error: If statment can't make decision upon the given operation", objNode.row) elif (var_Temp.value != 0): if not objNode.name in self.labelDict: addErr( ErrType.SEMANTIC, "Error: Label '" + objNode.name + "' does not exist", objNode.row) break cte_i = self.labelDict[objNode.name] elif lenNode == 2: solve_assign(self.astTree[cte_i]) #increment the counter cte_i += 1 now = datetime.now() cteTime = now.strftime("%H:%M:%S") createReport() self.QtOutput.appendPlainText("execution ended " + cteTime + "\n")
def drun(self): ''' This function starts the debuggin ''' if Interpreter.idx_debug >= 0 and Interpreter.idx_debug < len( self.astTree): lenNode = len(self.astTree[Interpreter.idx_debug]) if lenNode == 1: objNode = self.astTree[Interpreter.idx_debug][0] if isinstance(objNode, Exit): #print("Execution ended") Interpreter.idx_debug = -1 return elif isinstance(objNode, Print): var_Temp = None #solve oper and print the result if isinstance(objNode.oper, ValExpression): #call solve_var, this function returns an instance of ValExpression var_Temp = solve_val(objNode.oper) elif isinstance(objNode.oper, OperationExpression): #call solve_opr, this function return an instance of Symbol var_Temp = solve_oper(objNode.oper) #returns Symbol if (var_Temp.type != ValType.FLOAT and var_Temp.type != ValType.STRING and var_Temp.type != ValType.INTEGER and var_Temp.type != ValType.CHAR): addErr(ErrType.SEMANTIC, "Error: cannot print an array", objNode.row) else: prevTxt = str(self.QtOutput.toPlainText()) prevTxt += str(var_Temp.value).replace('\\n', '\n') self.QtOutput.setPlainText(prevTxt) elif isinstance(objNode, Unset): #will delete a symbol assig = objNode.varn s = getSymbol(assig.varName, assig.varType) if s: deleteSymbol(assig.varName, assig.varType) else: addErr(ErrType.SEMANTIC, "Error: can't unset variable", objNode.row) elif isinstance(objNode, GoTo): #load the value for the key given by label's name if not objNode.name in self.labelDict: addErr( ErrType.SEMANTIC, "Error: Label '" + objNode.name + "' does not exist", objNode.row) Interpreter.idx_debug = -1 return else: Interpreter.idx_debug = self.labelDict[objNode.name] #Attemps to put the cursor on the label cursor = self.QtInput.textCursor() match = str(objNode.name) + ":" regex = QtCore.QRegExp(match) idx = regex.indexIn(self.QtInput.toPlainText(), 0) cursor.setPosition(idx) self.QtInput.setTextCursor(cursor) #cursor.movePosition(QtGui.QTextCursor.StartOfLine) elif isinstance(objNode, If): #solve oper and if the result is not 0 then it will make a jump var_Temp = None #solve oper and make decision if isinstance(objNode.oper, ValExpression): #call solve_var, this function returns an instance of ValExpression var_Temp = solve_val(objNode.oper) elif isinstance(objNode.oper, OperationExpression): #call solve_opr, this function return an instance of Symbol var_Temp = solve_oper(objNode.oper) #returns Symbol #var_Temp.value has to be an integer type if not isinstance(var_Temp.value, int): addErr( ErrType.SEMANTIC, "Error: If statment can't make decision upon the given operation", objNode.row) elif (var_Temp.value != 0): if not objNode.name in self.labelDict: addErr( ErrType.SEMANTIC, "Error: Label '" + objNode.name + "' does not exist", objNode.row) Interpreter.idx_debug = -1 return else: Interpreter.idx_debug = self.labelDict[ objNode.name] #Attemps to put the cursor on the label cursor = self.QtInput.textCursor() match = str(objNode.name) + ":" regex = QtCore.QRegExp(match) idx = regex.indexIn(self.QtInput.toPlainText(), 0) cursor.setPosition(idx) self.QtInput.setTextCursor(cursor) elif lenNode == 2: solve_assign(self.astTree[Interpreter.idx_debug]) #increment the counter Interpreter.idx_debug += 1 #moves the cursor self.QtInput.moveCursor(QtGui.QTextCursor.NextBlock, QtGui.QTextCursor.MoveAnchor) else: Interpreter.idx_debug = -1 return