Do nothing on undefined variable (now 446 bytes)

The only exception is NIL which has been added to the main Eval().
This change also inlines the ABC Garbage Collector for more speed.
This commit is contained in:
Justine Tunney 2021-11-23 05:09:13 -08:00
parent d66e5d984f
commit bab9ebed18

View file

@ -36,23 +36,17 @@ kCdr: .asciz "CDR" # ordering matters
kCons: .asciz "CONS" # ordering matters kCons: .asciz "CONS" # ordering matters
kEq: .asciz "EQ" # needs to be last kEq: .asciz "EQ" # needs to be last
begin: xor %bx,%bx # we use the tiny memory model begin: push %cs # that means ss = ds = es = cs
push %cs # that means ss = ds = es = cs
pop %ds # noting ljmp set cs to 0x7c00 pop %ds # noting ljmp set cs to 0x7c00
push %cs # that's the bios load address push %cs # that's the bios load address
pop %es # therefore NULL points to NUL pop %es # therefore NULL points to NUL
push %cs # terminated NIL string above! push %cs # terminated NIL string above!
#cli # disables hardware interrupts pop %ss # errata exists but don't care
pop %ss # disable nonmaskable ones too xor %sp,%sp # use highest address as stack
mov %bx,%sp # use highest address as stack mov $2,%bx
#sti # reenable hardware interrupts
#cld # normalize the direction flag
inc %bx
inc %bx
main: mov $0x8000,%cx # dl (g_look) is zero or cr main: mov $0x8000,%cx # dl (g_look) is zero or cr
call GetToken call GetToken
call GetObject call GetObject
xor %dx,%dx
call Eval call Eval
xchg %ax,%si xchg %ax,%si
call PrintObject call PrintObject
@ -66,7 +60,7 @@ GetToken: # GetToken():al, dl is g_look
cmp $' ',%al cmp $' ',%al
jbe 2f jbe 2f
stosb stosb
xchg %ax,%si xchg %ax,%bp
2: call GetChar # exchanges dx and ax 2: call GetChar # exchanges dx and ax
cmp $' ',%al cmp $' ',%al
jbe 1b jbe 1b
@ -75,7 +69,7 @@ GetToken: # GetToken():al, dl is g_look
cmp $')',%dl # dl = g_look cmp $')',%dl # dl = g_look
ja 1b ja 1b
3: movb %bh,(%di) # bh is zero 3: movb %bh,(%di) # bh is zero
xchg %si,%ax xchg %bp,%ax
ret ret
.PutObject: # .PutObject(c:al,x:si) .PutObject: # .PutObject(c:al,x:si)
@ -109,7 +103,8 @@ GetObject: # called just after GetToken
cmpb $'(',%al cmpb $'(',%al
je GetList je GetList
.Intern: .Intern:
xor %di,%di # di = g_str mov %cx,%si
xor %di,%di
xor %al,%al xor %al,%al
0: push %di # save 1 0: push %di # save 1
1: cmpsb 1: cmpsb
@ -118,7 +113,7 @@ GetObject: # called just after GetToken
scasb scasb
jne 1b jne 1b
jmp 5f jmp 5f
2: pop %si # drop 1 2: pop %bp # drop 1
mov %cx,%si mov %cx,%si
3: scasb 3: scasb
jne 3b jne 3b
@ -169,17 +164,14 @@ Evlis: test %di,%di # Evlis(m:di,a:dx):ax
# jmp xCons # jmp xCons
xCons: pop %di # restore 2 xCons: pop %di # restore 2
Cons: xchg %ax,%si # Cons(m:di,a:ax):ax Cons: xchg %di,%cx # Cons(m:di,a:ax):ax
xchg %di,%ax mov %cx,(%di)
mov %cx,%di mov %ax,(%bx,%di)
stosw lea 4(%di),%cx
xchg %si,%ax
stosw
xchg %di,%cx
1: xchg %di,%ax 1: xchg %di,%ax
ret ret
Gc: cmp %dx,%di # Gc(x:di,mark:dx,aj:bp):ax Gc: cmp %dx,%di # Gc(x:di,A:dx,B:si):ax
jb 1b # we assume immutable cells jb 1b # we assume immutable cells
push (%bx,%di) # mark prevents negative gc push (%bx,%di) # mark prevents negative gc
mov (%di),%di mov (%di),%di
@ -189,7 +181,8 @@ Gc: cmp %dx,%di # Gc(x:di,mark:dx,aj:bp):ax
call Gc call Gc
pop %di pop %di
call Cons call Cons
sub %bp,%ax # subtract adjustment sub %si,%ax # ax -= C - B
add %dx,%ax
ret ret
GetList:call GetToken GetList:call GetToken
@ -200,24 +193,21 @@ GetList:call GetToken
call GetList call GetList
jmp xCons jmp xCons
Evaluate: # Evaluate(e:ax,a:dx):ax .dflt1: push %si # save x
test %ax,%ax # Implementation of Eval call Eval
jns Assoc # lookup val if atom pop %si # restore x
xchg %ax,%si # di = e
lodsw # ax = Car(e)
cmp $kQuote,%ax # maybe CONS
mov (%si),%di # di = Cdr(e)
je Car
cmp $kCond,%ax
je Evcon
.Ldflt2:push %ax # save 2
call Evlis # preserves dx
xchg %ax,%si
pop %ax # restore 2
# jmp Apply # jmp Apply
Apply: test %ax,%ax # Apply(fn:ax,x:si:a:dx):ax Apply: test %ax,%ax # Apply(fn:ax,x:si:a:dx):ax
js .lamb # jump if atom jns .switch # jump if atom
xchg %ax,%di # di = fn
.lambda:mov (%bx,%di),%di # di = Cdr(fn)
push %di # save 1
mov (%di),%di # di = Cadr(fn)
call Pairlis
xchg %ax,%dx
pop %di # restore 1
jmp .EvCadr
.switch:cmp $kEq,%ax # eq is last builtin atom .switch:cmp $kEq,%ax # eq is last builtin atom
ja .dflt1 # ah is zero if not above ja .dflt1 # ah is zero if not above
mov (%si),%di # di = Car(x) mov (%si),%di # di = Car(x)
@ -231,14 +221,6 @@ Apply: test %ax,%ax # Apply(fn:ax,x:si:a:dx):ax
jns .retT jns .retT
.retF: xor %ax,%ax # ax = nil .retF: xor %ax,%ax # ax = nil
ret ret
.lamb: xchg %ax,%di # di = fn
.lambda:mov (%bx,%di),%di # di = Cdr(fn)
push %di # save 1
mov (%di),%di # di = Cadr(fn)
call Pairlis
xchg %ax,%dx
pop %di # restore 1
jmp .EvCadr
.ifCons:cmp $kCons,%al .ifCons:cmp $kCons,%al
mov (%bx,%si),%si # si = Cdr(x) mov (%bx,%si),%si # si = Cdr(x)
lodsw # si = Cadr(x) lodsw # si = Cadr(x)
@ -247,24 +229,18 @@ Apply: test %ax,%ax # Apply(fn:ax,x:si:a:dx):ax
jne .retF jne .retF
.retT: mov $kT,%ax .retT: mov $kT,%ax
ret ret
.dflt1: push %si # save x
call Eval
pop %si # restore x
jmp Apply
Cadr: mov (%bx,%di),%di # contents of decrement register Cadr: mov (%bx,%di),%di # contents of decrement register
.byte 0x3C # cmp §scasw,%al (nop next byte) .byte 0x3C # cmp §scasw,%al (nop next byte)
Cdr: scasw # increments our data index by 2 Cdr: scasw # increments our data index by 2
Car: mov (%di),%ax # contents of address register!! Car: mov (%di),%ax # contents of address register!!
ret 2: ret
Assoc: mov %dx,%di # Assoc(x:ax,y:dx):ax Assoc: mov %dx,%si # Assoc(x:ax,y:dx):ax
test %dx,%dx # nil test 1: mov (%si),%di
jz .retF # return nil if end of list mov (%bx,%si),%si
mov (%bx,%di),%dx # we assume Eval() saved dx
mov (%di),%di
scasw scasw
jne Assoc jne 1b
jmp Car jmp Car
1: mov (%bx,%di),%di # di = Cdr(c) 1: mov (%bx,%di),%di # di = Cdr(c)
@ -279,22 +255,33 @@ Evcon: push %di # save c
.EvCadr:call Cadr # ax = Cadar(c) .EvCadr:call Cadr # ax = Cadar(c)
# jmp Eval # jmp Eval
Eval: push %dx # Eval(e:ax,a:dx):ax w/ gc Eval: test %ax,%ax # Eval(e:ax,a:dx):ax
push %cx # w/ ABC garbage collector jz 1f
call Evaluate # discards non-result cons jns Assoc # lookup val if atom
pop %dx xchg %ax,%si # di = e
push %cx lodsw # ax = Car(e)
mov %cx,%bp cmp $kQuote,%ax # maybe CONS
sub %dx,%bp mov (%si),%di # di = Cdr(e)
je Car
cmp $kCond,%ax
je Evcon # ABC Garbage Collector
push %dx # save a
push %cx # save A
push %ax
call Evlis
xchg %ax,%si
pop %ax
call Apply
pop %dx # restore A
mov %cx,%si # si = B
xchg %ax,%di xchg %ax,%di
call Gc call Gc
pop %si mov %dx,%di # di = A
mov %dx,%di sub %si,%cx # cx = C - B
sub %si,%cx
rep movsb rep movsb
mov %di,%cx mov %di,%cx # cx = A + (C - B)
pop %dx pop %dx # restore a
ret 1: ret
.sig: .fill 510 - (. - _start), 1, 0xce .sig: .fill 510 - (. - _start), 1, 0xce
.word 0xAA55 .word 0xAA55