UNPKG

algebrite

Version:

Computer Algebra System in Coffeescript

156 lines (134 loc) 2.91 kB
# _______ # | | <- 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