def not_instr(): """ NOT <var> <symb> """ check_scope_and_find_var('NOT', ActInstr.args[0]) op = check_logical_op('NOT', 1) value = not op.value var = Variable(ActInstr.args[0], 'bool', value) insert_var_to_right_frame(var)
def check_string_op(instr, position): """ Check operand in string operation in instructions like int2char, stri2int, concat, strlen, getchar, setchar """ if ActInstr.argsType[position] == 'var': op = check_scope_and_find_var(instr, ActInstr.args[position]) else: value = ippcode_type_to_python_type(ActInstr.argsType[position], ActInstr.args[position]) op = Variable('op' + str(position), ActInstr.argsType[position], value) return op
def mul(): """ MUL <var> <symb1> <symb2> """ check_scope_and_find_var('MUL', ActInstr.args[0]) op1 = check_arithmetic_op('MUL', 1) op2 = check_arithmetic_op('MUL', 2) value = op1 * op2 var = Variable(ActInstr.args[0], 'int', value) insert_var_to_right_frame(var)
def check_jump_op(instr, position): """ Check operand in jump operation in instructions like jump, jumpifeq, jumpifneq """ if ActInstr.argsType[position] == 'var': op = check_scope_and_find_var(instr, ActInstr.args[position]) else: value = ippcode_type_to_python_type(ActInstr.argsType[position], ActInstr.args[position]) op = Variable('op' + str(position), ActInstr.argsType[position], value) return op
def or_instr(): """ OR <var> <symb1> <symb2> """ check_scope_and_find_var('OR', ActInstr.args[0]) op1 = check_logical_op('OR', 1) op2 = check_logical_op('OR', 2) value = op1.value or op2.value var = Variable(ActInstr.args[0], 'bool', value) insert_var_to_right_frame(var)
def strlen(): """ STRLEN <var> <symb> """ check_scope_and_find_var('STRLEN', ActInstr.args[0]) op = check_string_op('STRLEN', 1) # check data type if op.dataType != 'string': sys.stderr.write('STRLEN: symb1 data type isnt str\n') sys.exit(operand_type_err) value = len(op.value) var = Variable(ActInstr.args[0], 'int', value) insert_var_to_right_frame(var)
def gt(): """ GT <var> <symb1> <symb2> """ check_scope_and_find_var('GT', ActInstr.args[0]) op1 = check_relational_op('GT', 1) op2 = check_relational_op('GT', 2) # check allowed data types if op1.dataType != op2.dataType: sys.stderr.write('GT: symb1 a symb2 doesn\'t have the same data type') sys.exit(operand_type_err) value = op1.value > op2.value var = Variable(ActInstr.args[0], 'bool', value) insert_var_to_right_frame(var)
def idiv(): """ IDIV <var> <symb1> <symb2> """ check_scope_and_find_var('IDIV', ActInstr.args[0]) op1 = check_arithmetic_op('IDIV', 1) op2 = check_arithmetic_op('IDIV', 2) # check division by 0 if op2 == 0: sys.stderr.write('IDIV: division by 0\n') sys.exit(zero_div_err) value = op1 // op2 var = Variable(ActInstr.args[0], 'int', value) insert_var_to_right_frame(var)
def concat(): """" CONCAT <var> <symb1> <symb2> """ check_scope_and_find_var('CONCAT', ActInstr.args[0]) op1 = check_string_op('CONCAT', 1) op2 = check_string_op('CONCAT', 2) # check data type if op1.dataType != 'string' or op2.dataType != 'string': sys.stderr.write('CONCAT: symb1 or symb2 data type isnt string') sys.exit(operand_type_err) value = op1.value + op2.value var = Variable(ActInstr.args[0], 'string', value) insert_var_to_right_frame(var)
def type_instr(): """ TYPE <var> <symb> """ check_scope_and_find_var('TYPE', ActInstr.args[0]) op1 = check_string_op('SETCHAR', 1) # save value to right frame acorfing <var> if re.search(r'^[-+]?\d+$', str(op1.value)): data_type = "int" elif re.search(r'^True|False$', str(op1.value)): data_type = "bool" else: data_type = "string" var = Variable(ActInstr.args[0], 'setBool', data_type) insert_var_to_right_frame(var)
def pops(): """ POPS <var> """ global dataStack # check data stack size if len(dataStack) == 0: sys.stderr.write('POPS: data stack is empty\n') sys.exit(no_value_err) # check scope of <var> check_scope_and_find_var('POPS', ActInstr.args[0]) # remove value from data stack var = dataStack.pop() new_var = Variable(ActInstr.args[0], var.dataType, var.value) # add new_var to <var> frame insert_var_to_right_frame(new_var)
def write(): """ WRITE <symb> """ if ActInstr.argsType[0] == 'var': var = check_scope_and_find_var('WRITE', ActInstr.args[0]) else: value = ippcode_type_to_python_type(ActInstr.argsType[0], ActInstr.args[0]) var = Variable('literal', ActInstr.argsType[0], value) if var.dataType == 'bool': if var.value is True: print('true') else: print('false') else: print(str(var.value))
def check_logical_op(instr, position): """ Check operand in logical operation in instructions like and, or, not """ if ActInstr.argsType[position] == 'var': op = check_scope_and_find_var(instr, ActInstr.args[position]) if op.dataType != 'bool': sys.stderr.write(instr + ' symb' + str(position) + ' is var but value ins\'t bool\n') sys.exit(operand_type_err) else: value = ippcode_type_to_python_type(ActInstr.argsType[position], ActInstr.args[position]) op = Variable('op' + str(position), ActInstr.argsType[position], value) if op.data_type != 'bool': sys.stderr.write(instr + 'op' + str(position) + ' is literal but value ins\'t bool') sys.exit(operand_type_err) return op
def int2char(): """ INT2CHAR <var> <symb> """ check_scope_and_find_var('INT2CHAR', ActInstr.args[0]) op = check_string_op('INT2CHAR', 1) # check data type if op.dataType != 'int': sys.stderr.write('INT2CHAR: symb data type isn\'t int') sys.exit(operand_type_err) try: value = chr(op.value) except TypeError: sys.stderr.write('INT2CHAR: not unciode value') sys.exit(str_operation_err) var = Variable(ActInstr.args[0], 'str', value) insert_var_to_right_frame(var)
def pushs(): """ PUSHS <symb> """ global dataStack if ActInstr.argsType[0] == 'var': # <symb> is variable var = check_scope_and_find_var('PUSHS', ActInstr.args[0]) if var.dataType == 'nondef': sys.stderr.write('PUSHS: variable has undefined value\n') sys.exit(no_value_err) else: # <symb> is literal value = ippcode_type_to_python_type(ActInstr.argsType[0], ActInstr.args[0]) var = Variable('literal', ActInstr.argsType[0], value) # add value and data type to data stack dataStack.append(var)
def stri2int(): """ STRI2INT <var> <symb1> <symb2> """ check_scope_and_find_var('STRI2INT', ActInstr.args[0]) op1 = check_string_op('STRI2INT', 1) op2 = check_string_op('STRI2INT', 2) # check data types and indexing in string if op1.dataType != 'string' or op2.dataType != 'int': sys.stderr.write('STRI2INT: symb1 or symb2 data type isn\'t ok') sys.exit(operand_type_err) if len(op1.value) - 1 < op2.value or op2.value < 0: sys.stderr.write('STRI2INT: indexing out of the string\n') sys.exit(str_operation_err) value = ord(op1.value[op2.value]) var = Variable(ActInstr.args[0], 'int', value) insert_var_to_right_frame(var)
def getchar(): """ GETCHAR <var> <symb1> <symb2> """ check_scope_and_find_var('GETCHAR', ActInstr.args[0]) op1 = check_string_op('GETCHAR', 1) op2 = check_string_op('GETCHAR', 2) # check data types and indexing if op1.dataType != 'string' or op2.dataType != 'int': sys.stderr.write('GETCHAR: symb1 or symb2 data type isn\'t ok') sys.exit(operand_type_err) if len(op1.value) - 1 < op2.value or op2.value < 0: sys.stderr.write( 'GETCHAR: len of op1 string is bigger than required index op2') sys.exit(str_operation_err) value = op1.value[op2.value] var = Variable(ActInstr.args[0], 'string', value) insert_var_to_right_frame(var)