User:Orange/Super Stack!/v1

From Esolang
Jump to navigation Jump to search

V1 of super stack. Includes example programs.

##############
# Super Stack!
# v1
# 8/4/09
##############

import sys

def run(text,debug=0):
    prog = [line.lower()
            for line in text.replace('\t',' ').replace('\n',' ').strip().split(' ')
            if line!=] #Hack and slash the text to put each keyword in an element on a list
    if debug:print 'running:\n',prog
    
    stack = [] #The stack
    jump_stack = [] #The jump stack for if-fi loops
    
    pc = 0 #program counter
    while pc<len(prog):
        inst = prog[pc]
        if debug:print pc,':',inst
        
        #Numbers
        if inst.isdigit():stack.append(int(inst))
        
        #Math
        elif inst=='add':stack.append(stack.pop()+stack.pop())
        elif inst=='sub':
            a,b = stack.pop(),stack.pop()
            stack.append(b-a)
        elif inst=='mul':stack.append(stack.pop()*stack.pop())
        elif inst=='div':
            a,b = stack.pop(),stack.pop()
            stack.append(int(b/a))
        elif inst=='mod':
            a,b = stack.pop(),stack.pop()
            stack.append(b%a)
        
        #Logic
        elif inst=='and':
            stack.append(int(
                bool(stack.pop()) and bool(stack.pop())
                ))
        elif inst=='or':
            stack.append(int(
                bool(stack.pop()) or bool(stack.pop())
                ))
        elif inst=='not':
            int(bool(not stack.pop()))
        elif inst=='xor':
            stack.append(int(
                not (bool(stack.pop()) or bool(stack.pop()))
                ))
        elif inst=='nand':
            stack.append(int(
                not (bool(stack.pop()) and bool(stack.pop()))
                ))
        
        #I/O
        elif inst=='output':sys.stdout.write(str(stack.pop())+'\n')
        elif inst=='input':stack.append(int(raw_input('?')))
        elif inst=='outputascii':sys.stdout.write(chr(stack.pop()))
        elif inst=='inputascii':
            stack.extend(map(ord,raw_input())[::-1])
        
        #Stack manipulation
        elif inst=='pop':stack.pop()
        elif inst=='swap':
            a,b = stack.pop(),stack.pop()
            stack.extend([a,b])
        elif inst=='cycle':stack.insert(0,stack.pop())
        elif inst=='rcycle':
            stack.append(stack[0])
            del stack[0]
        elif inst=='dup':
            a = stack.pop()
            stack.append(a)
            stack.append(a)
        elif inst=='rev':
            stack.reverse()
        
        #Flow
        elif inst=='quit':
            return
        elif inst=='if': #While loop
            if stack[-1]!=0: #If top number true, keep going in the loop
                jump_stack.append(pc-1)
            else: #Else, skip ahead to matching fi keyword
                loop = 1
                while loop:
                    pc += 1
                    inst = prog[pc]
                    if inst=='if':
                        loop += 1
                    elif inst=='fi':
                        loop -= 1
        elif inst=='fi': pc = jump_stack.pop()
        
        #Misc
        elif inst=='debug':print stack
        pc+=1
    
    if stack and debug:
        print'program ended with stack:\n',stack

cat = """
1 if
    0
    inputascii
    if outputascii fi
    pop
    10 outputascii
fi
"""

reverse = """
inputascii
rev
0 cycle
if outputascii fi
"""

fib = """
0 1
if
    dup output
    dup cycle
    add
fi
"""

beep = """
4
if
    7 outputascii
    1 sub
fi
"""

def demo():
    #run("""   #Uncomment this to type in your own super stack! programs(will work in idle)

    #""")
    run(fib) #You can replace fib with one of the example programs, too

try:
    run(
        open(sys.argv[1]).read(),
        '-d' in sys.argv #debug
    )
except IOError:
    print'Can not read file!'
except IndexError:
    #No argument?  Must be running from idle, or testing the program
    demo()