algebrite
Version:
Computer Algebra System in Coffeescript
156 lines (134 loc) • 2.91 kB
text/coffeescript
# _______
# | | <- stack
# | |
# |_______|
# | | <- stack + tos
# | |
# | |
# |_______|
# | | <- frame
# |_______|
# <- stack + TOS
#
# The stack grows from low memory towards high memory. This is so that
# multiple expressions can be pushed on the stack and then accessed as an
# array.
#
# The frame area holds local variables and grows from high memory towards
# low memory. The frame area makes local variables visible to the garbage
# collector.
tos = 0
# p is a U
nil_symbols = 0
push = (p) ->
if !p?
debugger
if p.isZero?
debugger
#console.log "pushing "
#console.log print_list(p)
if p == symbol(NIL)
nil_symbols++
if DEBUG then console.log "pushing symbol(NIL) #" + nil_symbols
#if nil_symbols == 111
# debugger
if (tos >= frame)
stop("stack overflow")
stack[tos++] = p
# returns a U
moveTos = (stackPos) ->
if tos <= stackPos
# we are moving the stack pointer
# "up" the stack (as if we were doing a push)
tos = stackPos
return
# we are moving the stack pointer
# "down" the stack i.e. as if we were
# doing a pop, we can zero-
# out all the elements that we pass
# so we can reclaim the memory
while tos > stackPos
stack[tos] = null
tos--
return
top = ->
stack[tos-1]
pop = ->
#popsNum++
#console.log "pop #" + popsNum
if (tos == 0)
debugger
stop("stack underflow")
if !stack[tos-1]?
debugger
elementToBeReturned = stack[--tos]
# give a chance to the garbage
# collection to reclaim space
# This is JS-specific, it would
# actually make the C garbage
# collector useless.
stack[tos] = null
return elementToBeReturned
# n is an integer
push_frame = (n) ->
i = 0
frame -= n
if (frame < tos)
debugger
stop("frame overflow, circular reference?")
for i in [0...n]
stack[frame + i] = symbol(NIL)
# n is an integer
pop_frame = (n) ->
frame += n
if (frame > TOS)
stop("frame underflow")
save = ->
frame -= 10
if (frame < tos)
debugger
stop("frame overflow, circular reference?")
stack[frame + 0] = p0
stack[frame + 1] = p1
stack[frame + 2] = p2
stack[frame + 3] = p3
stack[frame + 4] = p4
stack[frame + 5] = p5
stack[frame + 6] = p6
stack[frame + 7] = p7
stack[frame + 8] = p8
stack[frame + 9] = p9
restore = ->
if (frame > TOS - 10)
stop("frame underflow")
p0 = stack[frame + 0]
p1 = stack[frame + 1]
p2 = stack[frame + 2]
p3 = stack[frame + 3]
p4 = stack[frame + 4]
p5 = stack[frame + 5]
p6 = stack[frame + 6]
p7 = stack[frame + 7]
p8 = stack[frame + 8]
p9 = stack[frame + 9]
frame += 10
# Local U * is OK here because there is no functional path to the garbage collector.
swap = ->
#U *p, *q
# p and q are both Us
p = pop()
q = pop()
push(p)
push(q)
# Local U * is OK here because there is no functional path to the garbage collector.
dupl = ->
#U *p
p = pop()
push(p)
push(p)
$.dupl = dupl
$.swap = swap
$.restore = restore
$.save = save
$.push = push
$.pop = pop