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
114
115
116
117
118
|
from dataclasses import dataclass
from enum import Enum, auto
from typing import Any
from typeclass import TypeEnum
# tokens and types
# NOTE: this can probably be simplified
class TokenType(Enum):
OPEN_PAREN = auto()
CLOSE_PAREN = auto()
EOF = auto()
# literals
INT = auto()
FLOAT = auto()
STRING = auto()
TRUE = auto()
FALSE = auto()
# keywords
IF = auto()
FOR_COUNT = auto()
DEF = auto()
LAMBDA = auto()
FUNC = auto()
# symbols
SYMBOL = auto()
# types
INT_TYPE = auto()
FLOAT_TYPE = auto()
NUMBER_TYPE = auto()
STRING_TYPE = auto()
ANY_TYPE = auto()
LIST_TYPE = auto()
LITERAL_TYPE = auto()
BOOL_TYPE = auto()
MANY = auto()
@dataclass
class Token:
type_: TokenType
text: str
value: Any
line: int
def __str__(self):
return f"{self.type_.name} {self.text} {self.line}"
class Literal:
def __init__(self, value, type_=None):
self.value = value
if type_ is None:
self.type_ = TypeEnum.ANY
else:
self.type_ = type_
def __str__(self):
return f"{self.value}:literal"
class Int(Literal):
def __init__(self, value):
super().__init__(value, TypeEnum.INT)
def __str__(self):
return f"{self.value}"
class Float(Literal):
def __init__(self, value):
super().__init__(value, TypeEnum.FLOAT)
def __str__(self):
return f"{self.value}"
class Bool(Literal):
def __init__(self, value):
super().__init__(value, TypeEnum.BOOL)
def __str__(self):
return f"#{str(self.value).lower()}"
class String(Literal):
def __init__(self, value):
super().__init__(value, TypeEnum.STRING)
def __str__(self):
return f'"{repr(self.value)[1:-1]}"'
class Type:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
class Symbol:
def __init__(self, name, line):
self.name = name
self.line = line
def __str__(self):
return f"'{self.name}"
class List:
def __init__(self, args, data=False):
self.args = args
self.data = data
self.type_ = TypeEnum.LIST
def __str__(self):
return "(" + " ".join(f"{arg}" for arg in self.args) + ")"
class TypedList(List):
def __init__(self, args, data=True, type_=Type("string")):
super().__init__(args, data)
self.type_ = type_
def __str__(self):
return super().__str__() + f"{self.type_}"
class Strings(TypedList):
def __init__(self, args, data=True):
super().__init__(args, data, Type(":string"))
|