~kf5jwc/imp-parser

ref: 9a694fa0d8b73f01beb051b54cdab8a2b000be09 imp-parser/imp_parser/ast/boolean.py -rw-r--r-- 2.0 KiB View raw
9a694fa0 — Kyle Jones I've done more type annotating, which.... helped? 1 year, 6 months ago
                                                                                
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
from dataclasses import dataclass
from .types import Aexp, Bexp
from ..parser import Exp
from typing import Any, Union

@dataclass
class BinopAexp(Aexp):
    op: str
    left: Aexp
    right: Aexp

    def eval(self, env: dict) -> int:
        left_value: int = self.left.eval(env)
        right_value: int = self.right.eval(env)

        if   self.op == '+':
            return left_value + right_value
        elif self.op == '-':
            return left_value - right_value
        elif self.op == '*':
            return left_value * right_value
        elif self.op == '/':
            return int(left_value / right_value)

        raise RuntimeError(f"Unknown operator: {self.op}")


@dataclass
class RelopBexp(Bexp):
    op: str
    left: Bexp
    right: Bexp

    def eval(self, env: dict) -> bool:
        left_value: int = self.left.eval(env)
        right_value: int = self.right.eval(env)

        if   self.op == '<':
            return left_value <  right_value
        elif self.op == '<=':
            return left_value <= right_value
        elif self.op == '>':
            return left_value >  right_value
        elif self.op == '>=':
            return left_value >= right_value
        elif self.op == '=':
            return left_value == right_value
        elif self.op == '!=':
            return left_value != right_value

        raise RuntimeError(f"Unknown operator: {self.op}")


@dataclass
class AndBexp(Bexp):
    left: Bexp
    right: Bexp

    def eval(self, env: dict) -> bool:
        left_value = self.left.eval(env)
        right_value = self.right.eval(env)
        return (left_value and right_value)


@dataclass
class OrBexp(Bexp):
    left: Bexp
    right: Bexp

    def eval(self, env: dict) -> bool:
        left_value = self.left.eval(env)
        right_value = self.right.eval(env)
        return (left_value or right_value)


@dataclass
class NotBexp(Bexp):
    exp: Bexp

    def eval(self, env: dict) -> bool:
        value = self.exp.eval(env)
        return (not value)