-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtokens.py
55 lines (40 loc) · 1.23 KB
/
tokens.py
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
import operator
from typing import Optional, Callable
from util import frozendataclass
@frozendataclass
class Operator:
repr: str
func: Optional[Callable[[float, float], float]] = None
def __repr__(self) -> str:
return self.repr
@frozendataclass
class TokenType:
name: str
op: Optional[Operator] = None
def __repr__(self) -> str:
return self.name
@frozendataclass
class Token:
type: TokenType
value: Optional[float] = None
def __repr__(self) -> str:
return (f"{self.type}"
+ (f": {repr(self.value)}"
if self.value is not None else ""))
def tt(
name: str,
op: Optional[str] = None,
func: Optional[Callable[[float, float], float]] = None
) -> TokenType:
return TokenType(name, (Operator(op, func) if op is not None else None))
NUM = tt("NUM")
LPAR = tt("LPAR", "(")
RPAR = tt("RPAR", ")")
ADD = tt("ADD", "+", operator.add)
SUB = tt("SUB", "-", operator.sub)
MUL = tt("MUL", "*", operator.mul)
DIV = tt("DIV", "/", operator.truediv)
POW = tt("POW", "^", operator.pow)
MOD = tt("MOD", "%", operator.mod)
ALL = {v for _, v in globals().items() if isinstance(v, TokenType)}
CONSTANTS = {tt_ for tt_ in ALL if tt_.op is not None}