-
Notifications
You must be signed in to change notification settings - Fork 1
/
repl.py
91 lines (63 loc) · 2.11 KB
/
repl.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
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
"""A read-eval-print-loop implementation."""
from __future__ import print_function
import core, reader
import readline
class REPL:
def __init__(self):
self.scope = core.GlobalScope()
self.init_history()
self.init_completer()
def init_history(self):
import os, atexit
histfile = os.path.join(os.path.expanduser("~"), ".schemepyhist")
try:
readline.read_history_file(histfile)
except IOError:
pass
atexit.register(readline.write_history_file, histfile)
def init_completer(self):
readline.parse_and_bind("tab: complete")
readline.set_completer_delims(' ')
readline.set_completer(self.completer)
def start(self):
stored_tokens = []
while True:
try:
line = raw_input("scheme> ").strip()
except EOFError:
print
break
if not line:
continue
try:
tokens = reader.tokenize(line)
except Exception as e:
print(e)
continue
stored_tokens += tokens
ast, balance = reader.get_ast(stored_tokens)
if balance > 0:
continue
elif balance < 0:
print('Unexpected ")"')
stored_tokens = []
continue
stored_tokens = []
ast = reader.expand_quotes(ast)
ast = reader.expand_define(ast)
for expr in ast:
print(self.scope.eval(expr))
def completer(self, input, state):
tokens = reader.tokenize(input)
symbol = tokens[-1]
if not reader.is_symbol(symbol):
return None
options = self.get_options(self.scope, symbol.name)
if state >= len(options):
return None
tokens[-1] = options[state]
return ''.join(tokens)
@staticmethod
def get_options(scope, name):
known_names = core.fexpr.keys() + scope.vars.keys()
return [var for var in known_names if var.startswith(name)]