mirror of
https://github.com/samsonjs/sectorlisp.git
synced 2026-03-25 09:05:48 +00:00
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:
parent
d66e5d984f
commit
bab9ebed18
1 changed files with 57 additions and 70 deletions
127
sectorlisp.S
127
sectorlisp.S
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue