-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpylisp.py
130 lines (94 loc) · 3.09 KB
/
pylisp.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
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
class ControlException(Exception): pass
class BreakException(ControlException): pass
class Parser:
def __init__(self, data):
self.data = data
self._store = {}
def run(self):
for line in self.data:
self.exec_line(line)
def exec_line(self, line):
if type(line) == str or type(line) == int:
return self.str_or_func(line)
name = list(line.keys())[0]
fn = self.__getattribute__("exposed_"+name)
return fn(line[name])
def str_or_func(self, x):
try:
fn = self.__getattribute__("exposed_"+x)
return fn()
except Exception as e:
if isinstance(e, ControlException):
raise e
return x
def exposed_break(self, *args):
raise BreakException
def exposed_get_store(self, *args, **kwargs):
fr = args[0][0]
s = self.exposed_what(fr)
try:
return self._store.get(s)
except:
print("ERR", s)
def exposed_store(self, *args, **kwargs):
kwargs = (args[0][0] | args[0][1])
self._store[kwargs['to']] = self.exposed_what(kwargs['what'])
def exposed_input(self):
return input("> ")
def exposed_what(self, *args, **kwargs):
assert len(args) == 1
arg = args[0]
if type(arg) == dict:
return self.exec_line(arg)
if type(arg) == list:
res = [self.exec_line(code) for code in arg]
return res[0] if len(res) == 1 else res
else:
res = arg
return self.exec_line(res)
exposed_from = exposed_else = exposed_then = exposed_val1 = exposed_val2 = exposed_what
def exposed_helloworld(self, *args):
print("Hello World")
def exposed_say(self, *args, **kwargs):
for arg in args:
for code in arg:
what = self.exec_line(code)
print(what)
def exposed_ifeq(self, arg):
val1 = self.exec_line(arg[0])
val2 = self.exec_line(arg[1])
if str(val1) == str(val2):
then = self.exec_line(arg[2])
return then
else:
try:
otherwise = self.exec_line(arg[3])
except IndexError:
pass
except:
raise
def exposed_repeat(self, arg):
n = arg[0]
for code in arg[1:]:
for _ in range(int(n)):
try:
self.exec_line(code)
except BreakException:
break
def exposed_concat(self, arg):
s = ""
for code in arg:
s += str(self.exposed_what(code))
return s
def exposed_plus(self, arg):
return sum(int(self.exposed_what(code)) for code in arg)
if __name__=="__main__":
from tempfile import TemporaryFile
from yaml import load, dump
try:
from yaml import CLoader as Loader, CDumper as Dumper
except ImportError:
from yaml import Loader, Dumper
data = load(open('first_app.yml', 'r'), Loader=Loader)
parser = Parser(data)
parser.run()