1
1
# Write this in pseudo-Lark. We have to take a different strategy from
2
- # Arc because we're not on top of a Lisp or Scheme, so roots comes first instead of in arc.arc.
2
+ # Arc because we're not on top of a Lisp or Scheme, so roots comes first
3
+ # instead of in arc.arc.
4
+
5
+ # XXX: ac-dbname and ac-nameit have been elided for now because I'm not sure
6
+ # how to translate them.
7
+
3
8
from roots import *
4
9
from sexpr import str2sexpr
5
10
from symbol import *
6
- from types import *
11
+ from larktypes import *
7
12
8
13
xcar = lambda x : car (x ) if acons (x ) else None
9
14
10
15
# Let's not let them poke at raw Python variables without explicitly
11
- # them.
16
+ # exposing them.
17
+
18
+ def ac_global_name (s ):
19
+ return Symbol ('_' + str (s ))
20
+
12
21
13
- arc_globals = {nil : nil , ac_global_name (t ): t }
22
+ arc_globals = dict ((ac_global_name (sym ), value ) for sym , value in [
23
+ (t , t ),
24
+ (Symbol ('car' ), car )
25
+ ])
26
+
27
+
28
+ class InterpretedFunction (object ):
29
+ # Hacky, non-performant function class for interpreter.
30
+ # When we have a bytecode compiler, life will be better.
31
+ def __init__ (self , TK ):
32
+ pass
14
33
15
34
# Evaluate an Arc expression, represented as an s-expression.
16
35
# Env is a dictionary of lexically-bound variables (symbol->value).
36
+ # Arc just has a list because Scheme actually keeps track of the variables and
37
+ # values, but in Lark we keep track of them ourselves.
17
38
def ac_eval (s , env ):
39
+ print 'DEBUG: eval %s in %s' % (s , env )
18
40
if isinstance (s , String ):
19
41
return s
20
42
elif literal (s ):
21
43
return s
22
44
elif s is nil :
23
45
return s
24
46
elif isSymbol (s ):
47
+ print 'DEBUG: var ref'
25
48
return ac_var_ref (s , env )
26
49
elif xcar (s ) == Symbol ('quote' ):
27
50
return cadr (s )
28
51
elif xcar (s ) == Symbol ('if' ):
29
52
return ac_if (cdr (s ), env )
30
- # elif xcar(s) == Symbol('fn'):
31
- # return ac_fn(cadr(s), cddr(s), env)
53
+ elif xcar (s ) == Symbol ('fn' ):
54
+ return ac_fn (cadr (s ), cddr (s ), env )
32
55
# elif xcar(s) == Symbol('assign'):
33
56
# return ac_set(cdr(s), env)
34
- # elif acons(s):
35
- # return ac_call(car(s), cdr(s), env)
57
+ elif acons (s ):
58
+ print 'DEBUG: funcall'
59
+ return ac_call (car (s ), cdr (s ), env )
36
60
else :
37
61
raise Exception ('Bad object in expression %s (type %s)' % (s , type (s )))
38
62
@@ -41,11 +65,11 @@ def literal(x):
41
65
return isinstance (x , bool ) or isinstance (x , int ) or isinstance (x , float )
42
66
43
67
44
- def ac_global_name (s ):
45
- return Symbol ('_' + str (s ))
46
-
47
-
48
68
def ac_var_ref (s , env ):
69
+ assert isSymbol (s )
70
+ print 'Referencing %s (type %s) in with keys' % (s , type (s )),
71
+ for key in env :
72
+ print key , type (key )
49
73
if s in env :
50
74
return env [s ]
51
75
return arc_globals [ac_global_name (s )]
@@ -66,8 +90,47 @@ def ac_if(s, env):
66
90
67
91
return nil
68
92
93
+ def ac_fn (args , body , env ):
94
+ if ac_complex_args (args ):
95
+ raise NotImplementedError ()
96
+ elif body is nil : # My extension to deal with empty body. No ac-body*.
97
+ return lambda * args : nil
98
+ else :
99
+ env = env .copy () # Not sure if this is necessary. Being paranoid.
100
+ print 'DEBUG: define function with argslist %s' % args
101
+ assert isSymbol (xcar (args ))
102
+ def temp (* fargs ):
103
+ env .update (zip (args , fargs ))
104
+ return ac_body (body , env )
105
+ return temp
106
+
107
+
108
+ def ac_body (body , env ):
109
+ if body is nil :
110
+ return nil
111
+ return car (revmap (lambda x : ac_eval (x , env ), body ))
112
+
113
+
114
+ def ac_complex_args (args ):
115
+ '''Does a fn arg list use optional params or destructuring?'''
116
+ if args is nil or isSymbol (args ):
117
+ return False
118
+ elif acons (args ) and isSymbol (car (args )):
119
+ return ac_complex_args (cdr (args ))
120
+ else :
121
+ return True
122
+
123
+
124
+ def ac_call (fn , args , env ):
125
+ return ac_eval (fn , env )(* topylist (args ))
126
+
127
+
69
128
def tle ():
70
129
while True :
71
130
print 'Lark> ' ,
72
131
expr = str2sexpr (raw_input ())[0 ]
73
132
print ac_eval (expr , {})
133
+
134
+
135
+ if __name__ == '__main__' :
136
+ tle ()
0 commit comments