summaryrefslogtreecommitdiffstats
path: root/l6/kod.py
blob: 6f1c33a8f39abf4eaea66778a8e2f149be99b2b4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import sys

import calc

def eval_binary(frame, statement):
    op = calc.condition_operator(statement)
    left = eval_expression(frame, calc.condition_left(statement))
    right = eval_expression(frame, calc.condition_right(statement))
    if op == "+":
        return left + right
    elif op == "-":
        return left - right
    elif op == "*":
        return left * right
    elif op == "/":
        return left / right

def eval_expression(frame, 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):
    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):
    op = calc.condition_operator(statement)
    left = eval_expression(frame, calc.condition_left(statement))
    right = eval_expression(frame, calc.condition_right(statement))
    if op == ">":
        return left > right
    elif op == "<":
        return left < right
    elif op == "=":
        return left == right
    else:
        print("{} is not valid syntax".format(statement))
        sys.exit(-1)

def eval_repetition(frame, statement):
    while eval_condition(frame, calc.repetition_condition(statement)):
        frame = eval_statements(frame, calc.repetition_statements(statement))
    return frame

def eval_selection(frame, statement):
    if eval_condition(frame, calc.selection_condition):
        frame = eval_statement(frame, calc.selection_true(statement))
    elif calc.hasfalse(statement):
        frame = eval_statement(frame, calc.selection_false(statement))
    return frame

def eval_input(frame, 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):
    var = calc.output_variable(statement)
    val = frame[var]
    print("{} = {}".format(var, val))

def eval_statement(frame, statement):
    if calc.isassignment(statement):
        frame = eval_assignment(frame, statement)
    elif calc.isrepetition(statement):
        frame = eval_repetition(frame, statement)
    elif calc.isselection(statement):
        frame = eval_selection(frame, statement)
    elif calc.isinput(statement):
        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 frame

def eval_statements(frame, statements):
    frame = eval_statement(frame, calc.first_statement(statements))
    if calc.empty_statements(calc.rest_statements(statements)):
        return frame
    else:
        return eval_statements(frame, calc.rest_statements(statements))

def eval_program(program, frame={}):
    if not calc.isprogram(program):
        return
    statements = calc.program_statements(program)
    return eval_statements(frame, statements)