Demonstration of a Push-down or LIFO stack

The following LB code pushes 45 random integers onto the stack and pops them off again. It uses a single string of space-separated locations as the stack, so could just as easily store characters ( see second example below). I may use it to write a simple Reverse Polish calculator ( like FORTH). The animations shown here were trivial to produce with ImageMagick- see my other pages on this.

Number Stack

    '   LIFO- Last In, First Out or push-down stack

    nomainwin

    WindowWidth  =1000
    WindowHeight = 420
    UpperLeftX   =  50
    UpperLeftY   =  50

    open "Display Stack- push in 45 items -here, random integers- then pop them out.." for graphics_nsb as #w

    #w "trapclose quit"
    #w "down ; color red ; backcolor lightgray ; size 16 ; fill lightgray"
    #w "place 100 40"
    #w "font arial 36 bold"
    #w "\Pushing down onto stack...."
    #w "font arial 10"

    global Stack$, j

    StackLimit =45
    j          = 0
    Stack$     ="TOS"   '   will hold space-separated contents of stack.
                        '   TOS =TopOfStack sentinel.
    calldll #kernel32, "Sleep", 5000 as long, ret as void

    for i =1 to StackLimit
        RandTerm =int( 100 *rnd( 1))    '   push new value as integer 0 --> 99
        Stack$   =str$( RandTerm) +" " +Stack$
        call display
    next i

    #w "cls"
    #w "font arial 36 bold"
    #w "place 100 40"
    #w "\Popping off top of stack...."
    #w "font arial 10"

    for i =1 to StackLimit    '   pop top term off stack
        p      =instr( Stack$, " ")
        Stack$ =mid$(  Stack$, p +1)
        call display
    next i

    #w "cls ; font arial 36 bold ; place 100 40"
    #w "\Stack empty again."

    wait

    '   In IM & corrct directory, use cmd 'convert -delay 50 scr*.bmp anim.gif'.

sub quit handle$
    close #w
    end
end sub

sub display
    #w "cls"
    k      =1
  [here]
    entry$ =word$( Stack$, k, " ")

    if entry$ <>"TOS" then
        entry =val( entry$)
        #w "place "; k *20;       " 350"
        #w "color "; entry *255 /100; " 255 "; 255 -entry *255 /100
        #w "goto  "; k *20;    " "; 350 -( entry *3)

        #w "color red"
        #w "place "; k *20 -5; " "; 350 -( entry *3) -10
        #w "\"; entry

        #w "place "; k *20 -5;    " 370"
        #w "\"; k
        k =k +1
    end if

    if entry$ <>"TOS" then goto [here]

    j =j +1
    #w "flush"
    #w "getbmp scr 1 1 980 390"
    bmpsave "scr", "C:\IM\scr"+ right$( "000" +str$( j), 3) +".bmp"
    unloadbmp "scr"
    'calldll #kernel32, "Sleep", 500 as long, ret as void
    timer 500, [on]
    wait
  [on]
    timer 0
    end sub

Text Stack


Push down LIFO Stack

As you type new words/ entries they push existing ones down, When you pop them off, it is the most recent which goes.

    '   LIFO- Last In, First Out or push-down stack

    nomainwin

    WindowWidth  = 300
    WindowHeight = 620
    UpperLeftX   =  50
    UpperLeftY   =  50

    open "String Stack" for graphics_nsb as #w

    #w "trapclose quit"
    #w "down ; size 16"
    #w "place 10 40"
    #w "font arial 12 bold"
    #w "\Pushing down onto stack...."
    #w "font arial 10"

    global Stack$, j
    InTxt$ ="2 3 4 + * . FORTH rules KO. It was a wild and windy night and Dick the shepherd said to his mates, 'Tell us a story.'"

    StackLimit =28  '   for the above text...
    j          = 0
    Stack$     ="TOS"   '   will hold space-separated contents of stack.
                        '   TOS =TopOfStack sentinel.
    calldll #kernel32, "Sleep", 5000 as long, ret as void

    for i =1 to StackLimit    '   push new value as string
        Stack$   =word$( InTxt$, i, " ") +" " +Stack$
        call display
    next i

    #w "cls"
    #w "font arial 12 bold"
    #w "place 10 40"
    #w "\Popping off top of stack...."
    #w "font arial 10"

    for i =1 to StackLimit    '   pop top term off stack
        p      =instr( Stack$, " ")
        Stack$ =mid$(  Stack$, p +1)
        call display
    next i

    #w "cls ; font arial 12 bold ; place 10 40"
    #w "\Stack empty again."

    wait

    '   In IM & correct directory, use cmd 'convert -delay 50 scr*.bmp anim.gif'.

sub quit handle$
    close #w
    end
end sub

sub display
    #w "cls"
    k      =1
  [here]
    entry$ =word$( Stack$, k, " ")

    if entry$ <>"TOS" then
        #w "place 50 "; k *20 +15
        #w "\"; entry$

        k =k +1
    end if

    if entry$ <>"TOS" then goto [here]

    j =j +1
    #w "flush"
    #w "getbmp scr 1 1 120 620"
    bmpsave "scr", "C:\IM\scr"+ right$( "000" +str$( j), 3) +".bmp"
    unloadbmp "scr"
    'calldll #kernel32, "Sleep", 500 as long, ret as void
    timer 500, [on]
    wait
  [on]
    timer 0
end sub

Push/pull demo.

This example shows push-and-pop.


    '   LIFO- Last In, First Out or push-down stack

    nomainwin

    cr$ =chr$( 13)

    WindowWidth  = 550
    WindowHeight = 690
    UpperLeftX   =  50
    UpperLeftY   =  50

    graphicbox #w.gb1, 210, 110, 120, 520
    textbox    #w.tb1, 210,  40, 120,  30
    button #w.b1, "Push", [push], LR, 370, 590
    button #w.b1, "Pop ", [pop],  LR, 170, 590
    statictext #w.st1, "Type in the textbox and click" +cr$ +"         'Push'" +cr$ +" to put an entry on the stack, pushing everything else down.", 30, 120, 150, 400
    statictext #w.st2, "Click" +cr$ +"          'Pop'" +cr$ +" to pull an entry off the stack, and move everything else up.", 350, 120, 150, 400

    global Stack$, k

    Stack$     ="EOS"   '   will hold space-separated contents of stack.
                        '   EOS =EndOfStack sentinel.

    open "Stack" for graphics as #w

    #w "trapclose quit"
    #w.gb1 "down"
    #w.gb1 " font arial 16"
    #w.tb1 "!font arial 16"
    #w.tb1 "Empty!"

    wait

  [push]
    #w.tb1 "!contents? inp$"    '   push new value
    if inp$ <>"" then
        Stack$   =inp$ +" " +Stack$
        call display
        #w.tb1 ""
        #w.tb1 "!setfocus"
    end if
    scan
    wait

  [pop]
    trm$ =word$( Stack$, 1, " ")
    if trm$ <>"EOS" then
        #w.tb1  trm$   '   pop top term off stack
        p      =instr( Stack$, " ")
        Stack$ =mid$(  Stack$, p +1)
        call display
    else
        #w.tb1 "Empty!"
    end if
    scan
    wait
'   ____________________________________________________________

sub quit handle$
    close #w
    end
end sub

sub display
    #w.gb1 "cls"
    k      =1
  [here]
    entry$ =word$( Stack$, k, " ")
    if entry$ <>"EOS" then
        #w.gb1 "place 10 "; k *24 +5
        #w.gb1 "\"; entry$
        k =k +1
    end if
    if entry$ <>"EOS" then goto [here]
end sub

Queues

With a queue, the first in is also first out. I entered in this order, "12", "green", "bottles", etc. I have just popped off the first entry ( "12"), which therefore is back in the text box. Again however the queue is allowed to expand as far as your computer memory allows....


    '   FIFO- First In, First Out queue

    nomainwin

    cr$ =chr$( 13)

    WindowWidth  = 550
    WindowHeight = 690
    UpperLeftX   =  50
    UpperLeftY   =  50

    BackgroundColor$ = "lightgray"

    graphicbox #w.gb1, 210, 110, 120, 520
    textbox    #w.tb1, 210,  40, 120,  30
    button     #w.b1, "Push", [push], LR, 370, 590
    button     #w.b1, "Pop ", [pop],  LR, 170, 590
    statictext #w.st1, "",  30, 120, 150, 150
    statictext #w.st2, "", 350, 120, 150, 150

    global Stack$, k

    Stack$     =""   '   will hold space-separated contents of stack.


    open "Queue" for window as #w

    #w "trapclose quit"
    '#w "fill lightgray"
    #w.gb1 "down"
    #w.gb1 " font arial 16"
    #w.tb1 "!font arial 16"
    #w.tb1 Stack$
    #w.st1 "Type in the textbox and click" +cr$ +"         'Push'" +cr$ +" to put an entry on the stack top, pushing everything else down."
    #w.st2 "Click" +cr$ +"          'Pop'" +cr$ +" to pull an entry off stack bottom, making stack shorter."
    wait

  [push]
    #w.tb1 "!contents? inp$"    '   push new value
    if inp$ <>"" then
        Stack$   =inp$ +" " +Stack$
        call display
        #w.tb1 ""
        #w.tb1 "!setfocus"
    end if
    scan
    wait    '____________________________________________________

  [pop]   '   take bottom term off stack
    entries   =0
    lenStack  =len( Stack$)
    for i =1 to lenStack
        if mid$( Stack$, i, 1) =" " then entries =entries +1: lastEntry =i
    next i

    trm$   =word$( Stack$, entries, " ")
    lenTrm =len( trm$)

    if trm$ ="" then #w.tb1 "Empty!" else #w.tb1  trm$ 
    Stack$ =left$(  Stack$, lenStack -lenTrm -1)
    call display
    scan
    wait
'   ____________________________________________________________

sub quit handle$
    close #w
    end
end sub

sub display
    #w.gb1 "cls"
    k      =1
  [here]
    entry$ =word$( Stack$, k, " ")
    #w.gb1 "place 10 "; k *24 +5
    #w.gb1 "\"; entry$
    k =k +1
    if entry$ <>"" then goto [here]
end sub