Skip to content

Commit efa4e63

Browse files
committed
Initial implementation of apply.
THis is the worst evaluator ever.
1 parent 2ea2df6 commit efa4e63

1 file changed

Lines changed: 65 additions & 6 deletions

File tree

lisp.boo

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

2828
class 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+
5158
class 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-
6065
def toNum(obj):
6166
ret = obj cast Num
6267
return ret
@@ -69,6 +74,9 @@ def toError(obj):
6974
def toCons(obj):
7075
ret = obj cast Cons
7176
return ret
77+
def toSubr(obj):
78+
ret = obj cast Subr
79+
return ret
7280

7381
kLPar = char('(')
7482
kRPar = char(')')
@@ -84,6 +92,7 @@ def makeSym(s as string):
8492
8593
sym_t = makeSym('t')
8694
sym_quote = makeSym('quote')
95+
sym_if = makeSym('if')
8796
8897
def safeCar(obj as object):
8998
if obj.GetType() == Cons:
@@ -176,9 +185,19 @@ def findVar(sym, env as object):
176185
g_env = Cons(kNil, kNil)
177186
178187
def 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
193249
addToEnv(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
195254
while true:
196255
System.Console.Write('> ')

0 commit comments

Comments
 (0)