summaryrefslogtreecommitdiff
path: root/main.py
blob: 0ba9d479c7a9ef14c9306db5f3580cbb66eec695 (plain)
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
import sys

from consts import *
from tokenizer import tokenize
from parser import parse, parse_expr


# RUNTIME

unary_operators = {
    "-": lambda a: -a,
    "+": lambda a: a
}

operators = {
    "+": lambda a, b: a + b,
    "-": lambda a, b: a - b,
    "*": lambda a, b: a * b,
    "^": lambda a, b: a ** b,
}

runtime = {
    "x": 10
}


def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)


runtime_functions = {
    "factorial": factorial
}

# END OF RUNTIME


def _eval(node):
    if node.type == NodeType.NUMBER:
        return node.value

    elif node.type == NodeType.SYMBOL:
        return runtime.get(node.value)

    elif node.type == NodeType.FUNCALL:
        fun_name = node.value[0]
        args = list(map(_eval, node.value[1]))
        return runtime_functions.get(fun_name)(*args)

    elif node.type == NodeType.OPERATOR:
        if node.subtype == NodeType.UNARY:
            return unary_operators.get(node.left.subtype)(_eval(node.right))
        else:
            return operators.get(node.subtype)(_eval(node.left), _eval(node.right))

    elif node.type == NodeType.ASSIGNMENT:
        runtime[node.left.value] = _eval(node.right)


def main(*argv):
    if len(argv) != 0:
        data = argv[0]
    else:
        # data = "2 + 3 * 4"
        data = "let a = 2 + 3; let e = 4;"
        # data = "(3 + 3 * 2) * -4"
        # data = "(2 + factorial(4, )) * 9"

    tokens = tokenize(data)
    # print(tokens)
    statements = parse(tokens)
    for statement in statements:
        _eval(statement)
    # node, _ = parse_expr(tokens, 0)
    # print(expr_eval(node))
    print(1)


if __name__ == "__main__":
    main(*sys.argv[1:])