import sys import calc def debug(tag, msg): #print("[{}] {}".format(tag, msg)) pass def eval_binary(frame, statement): debug("BINARY", statement) op = calc.condition_operator(statement) if op == "+": return eval_expression(frame, calc.condition_left(statement)) \ + eval_expression(frame, calc.condition_right(statement)) elif op == "-": return eval_expression(frame, calc.condition_left(statement)) \ - eval_expression(frame, calc.condition_right(statement)) elif op == "*": return eval_expression(frame, calc.condition_left(statement)) \ * eval_expression(frame, calc.condition_right(statement)) elif op == "/": return eval_expression(frame, calc.condition_left(statement)) \ / eval_expression(frame, calc.condition_right(statement)) def eval_expression(frame, statement): debug("EXPRESSION", statement) if calc.isconstant(statement): if not (type(statement) is int or type(statement) is float): print("{} is not a valid constant, need to be either int or float" .format(statement)) sys.exit(-1) return statement elif calc.isvariable(statement): if statement not in frame: print("variable {} not declared".format(statement)) sys.exit(-1) return frame[statement] elif calc.isbinary(statement): return eval_binary(frame, statement) else: print("{} is not valid syntax".format(statement)) sys.exit(-1) def eval_assignment(frame, statement): debug("ASSIGNMENT", statement) new_frame = frame.copy() new_frame[calc.assignment_variable(statement)] = \ eval_expression(frame, calc.assignment_expression(statement)) return new_frame def eval_condition(frame, statement): debug("CONDITION", statement) op = calc.condition_operator(statement) if op == ">": return eval_expression(frame, calc.condition_left(statement)) \ > eval_expression(frame, calc.condition_right(statement)) elif op == "<": return eval_expression(frame, calc.condition_left(statement)) \ < eval_expression(frame, calc.condition_right(statement)) elif op == "=": return eval_expression(frame, calc.condition_left(statement)) \ == eval_expression(frame, calc.condition_right(statement)) else: print("{} is not valid syntax".format(statement)) sys.exit(-1) def eval_repetition(frame, statement): debug("REPETITION", statement) new_frame = frame.copy() while eval_condition(new_frame, calc.repetition_condition(statement)): new_frame = eval_statements(new_frame, calc.repetition_statements(statement)) return new_frame def eval_selection(frame, statement): debug("SELECTION", statement) new_frame = frame.copy() if eval_condition(frame, calc.selection_condition): new_frame = eval_statement(frame, calc.selection_true(statement)) elif calc.hasfalse(statement): new_frame = eval_statement(frame, calc.selection_false(statement)) return new_frame def eval_input(frame, statement): debug("INPUT", statement) new_frame = frame.copy() var = calc.input_variable(statement) val = input("Enter value for {}: ".format(var)) try: new_frame[var] = int(val) except ValueError: try: new_frame[var] = float(val) except ValueError: pass #TODO return new_frame def eval_output(frame, statement): debug("OUTPUT", statement) var = calc.output_variable(statement) val = frame[var] print("{} = {}".format(var, val)) def eval_statement(frame, statement): debug("STATEMENT", statement) new_frame = frame.copy() if calc.isassignment(statement): new_frame = eval_assignment(frame, statement) elif calc.isrepetition(statement): new_frame = eval_repetition(frame, statement) elif calc.isselection(statement): new_frame = eval_selection(frame, statement) elif calc.isinput(statement): new_frame = eval_input(frame, statement) elif calc.isoutput(statement): eval_output(frame, statement) else: print("{} is not valid syntax".format(statement)) sys.exit(-1) return new_frame def eval_statements(frame, statements): debug("STATEMENTS", statements) new_frame = eval_statement(frame, calc.first_statement(statements)) if calc.empty_statements(calc.rest_statements(statements)): return new_frame else: return eval_statements(new_frame, calc.rest_statements(statements)) def eval_program(program): if not calc.isprogram(program): return statements = calc.program_statements(program) return eval_statements({}, statements)