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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
#!/usr/bin/env python3
from neb import lex, parse, interpret, NebPanic, Environment, MultiFunction, Builtin, UserFunction
from neb.std import *
import sys
import readline
class NebCompleter:
def __init__(self, syntax):
self.syntax = syntax
def complete(self, text, state):
results = [x for x in self.syntax if x.startswith(text)] + [None]
return results[state]
def build_std(repl=False):
GLOBALS = Environment()
envs = [ BOOLEAN.environment,
CORE.environment,
FUNCTOOLS.environment,
FS.environment,
LISTS.environment,
MATH.environment,
STRINGS.environment,
SYS.environment,
TERM.environment,
TYPES.environment ]
global_dict = {}
for env in envs:
for key, val in env.items():
if key not in global_dict:
global_dict[key] = val
continue
global_item = global_dict[key]
if isinstance(global_item, MultiFunction):
for i in val.impls.values():
global_item.register(i)
elif isinstance(global_item, Builtin) or isinstance(global_item, UserFunction):
mf = MultiFunction(key)
mf.register(global_item)
mf.register(val)
global_dict[key] = mf
else:
raise NebPanic("bad environment juju")
'''
global_dict = { **BOOLEAN.environment,
**CORE.environment,
**FUNCTOOLS.environment,
**FS.environment,
**LISTS.environment,
**MATH.environment,
**STRINGS.environment,
**SYS.environment,
**TERM.environment,
**TYPES.environment }
'''
if repl:
for key, val in REPL.environment.items():
if key not in global_dict:
global_dict[key] = val
elif isinstance(global_dict[key], MultiFunction):
for i in val.impls:
global_dict[key].register(i)
else:
raise NebPanic("bad environment juju")
GLOBALS.environment = global_dict
return GLOBALS
def debug(prev_lexed, prev_parsed):
if prev_lexed is not None:
acc = " ".join([f"{l}" for l in prev_lexed])
print(f" - LEX: {acc}")
if prev_parsed is not None:
acc = " ".join([f"{p}" for p in prev_parsed])
print(f" - PARSE: {acc}")
def repl():
env = build_std(True)
readline.parse_and_bind("tab: complete")
cmp = NebCompleter(env.environment.keys())
readline.set_completer(cmp.complete)
readline.set_completer_delims(" ()")
print("### neb :)(:")
print("version: < 0")
idx = 1
prev_idx = 0
prev_lexed = None
prev_parsed = None
while True:
inp = input(f"#{idx}> ")
if len(inp.strip()) == 0:
continue
try:
if inp.strip() == "(debug)":
debug(prev_lexed, prev_parsed)
continue
lexed = lex(inp)
prev_lexed = lexed
parsed = parse(lexed)
prev_parsed = parsed
inter = interpret(parsed, env)
print(f"=> {inter}")
prev_idx = idx
idx += 1
except NebPanic as ne:
print(f"panic! {ne}")
except Exception as e:
print(f"exception! {type(e)} {e}")
def run_file(filename):
env = build_std(True)
readline.parse_and_bind("tab: complete")
cmp = NebCompleter(env.environment.keys())
readline.set_completer(cmp.complete)
readline.set_completer_delims(" ()")
with open(filename, "r") as fil:
data = fil.read()
try:
lexed = lex(data)
parsed = parse(lexed)
ev = interpret(parsed, env)
except NebPanic as ne:
print(f"panic! {ne}")
except Exception as e:
print(f"exception! {type(e)} {e}")
if __name__ == "__main__":
if len(sys.argv) == 1:
repl()
elif len(sys.argv) >= 2:
run_file(sys.argv[1])
else:
print("usage: neb [<file>]")
sys.exit(1)
|