@@ -23,7 +23,7 @@ class Error:
2323 def constructor (s as string ):
2424 data = s
2525 def ToString ():
26- return data
26+ return '<error: ' + data + '>'
2727
2828class Cons :
2929 public car as object
@@ -48,15 +48,20 @@ class Cons:
4848 else :
4949 return '(' + ret + ' . ' + obj .ToString() + ')'
5050
51+ class Subr :
52+ public data as int
53+ def constructor (n as int ):
54+ data = n
55+ def ToString ():
56+ return "<subr>"
57+
5158class ParseState :
5259 public elm as object
5360 public next as string
5461 def constructor (o , s ):
5562 elm = o
5663 next = s
5764
58- callable Printer(obj as object ) as string
59-
6065def toNum (obj ):
6166 ret = obj cast Num
6267 return ret
@@ -69,6 +74,9 @@ def toError(obj):
6974def toCons (obj ):
7075 ret = obj cast Cons
7176 return ret
77+ def toSubr (obj ):
78+ ret = obj cast Subr
79+ return ret
7280
7381kLPar = char ('(' )
7482kRPar = char (')' )
@@ -84,6 +92,7 @@ def makeSym(s as string):
8492
8593sym_t = makeSym(' t ')
8694sym_quote = makeSym(' quote ')
95+ sym_if = makeSym(' if ')
8796
8897def safeCar(obj as object):
8998 if obj.GetType() == Cons:
@@ -176,9 +185,19 @@ def findVar(sym, env as object):
176185g_env = Cons(kNil, kNil)
177186
178187def addToEnv(sym, val, env as object):
179- toCons(env).car = Cons(Cons(sym, val), toCons(env).cdr )
188+ toCons(env).car = Cons(Cons(sym, val), toCons(env).car )
180189
181- def eval(obj as object, env):
190+ def subrCall(id, args):
191+ if id == 0:
192+ return safeCar(safeCar(args))
193+ elif id == 1:
194+ return safeCdr(safeCar(args))
195+ elif id == 2:
196+ return Cons(safeCar(args), safeCar(safeCdr(args)))
197+ else:
198+ return Error(' unknown subr ')
199+
200+ def eval(obj as object, env as object) as object:
182201 type = obj.GetType()
183202 if type == Nil or type == Num or type == Error:
184203 return obj
@@ -188,9 +207,49 @@ def eval(obj as object, env):
188207 return Error(toSym(obj).data + ' has no value ')
189208 else:
190209 return toCons(bind).cdr
191- return Error(' noimpl ')
210+ op = safeCar(obj)
211+ args = safeCdr(obj)
212+ if op == sym_quote:
213+ return safeCar(args)
214+ elif op == sym_if:
215+ c = eval(safeCar(args), env)
216+ if c.GetType() == Error:
217+ return c
218+ elif c == kNil:
219+ return eval(safeCar(safeCdr(safeCdr(args))), env)
220+ else:
221+ return eval(safeCar(safeCdr(args)), env)
222+
223+ // evlis
224+ aargs as object = kNil
225+ lst as object = args
226+ while lst.GetType() == Cons:
227+ cell = toCons(lst)
228+ elm = eval(cell.car, env)
229+ if elm.GetType() == Error:
230+ aargs = elm
231+ break
232+ aargs = Cons(elm, aargs)
233+ lst = cell.cdr
234+ if aargs.GetType() != Error:
235+ aargs = nreverse(aargs)
236+
237+ // apply
238+ fn = eval(op, env)
239+ type = fn.GetType()
240+ if type == Error:
241+ return fn
242+ elif aargs.GetType() == Error:
243+ return aargs
244+ elif type == Subr:
245+ return subrCall(toSubr(fn).data, aargs)
246+ else:
247+ return Error(fn.ToString() + ' is not function ')
192248
193249addToEnv(sym_t, sym_t, g_env)
250+ addToEnv(makeSym(' car '), Subr(0), g_env)
251+ addToEnv(makeSym(' cdr '), Subr(1), g_env)
252+ addToEnv(makeSym(' cons '), Subr(2), g_env)
194253
195254while true:
196255 System.Console.Write(' > ')
0 commit comments