-
Notifications
You must be signed in to change notification settings - Fork 0
/
superstack.py
128 lines (113 loc) · 3.65 KB
/
superstack.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
##############
# Super Stack!
# v2
# 8/18/09
##############
# changes from v1:
# o output command now adds space after number
# instead of newline
# o added random keyword
##############
# Make a note of bugs you find on the wiki!
import sys,random
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
try:
stack.append(int(inst))
except:
pass
#Math
if 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)
elif inst=='random': stack.append(random.randrange(stack.pop()))
#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':
stack.append(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())+' ')
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]) #Ah, slice steps
#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 not empty stack:\n',stack
def usage():
print 'superstack.py my_program.ss! [-d]'
print ' -d debug'
sys.exit(2)
try:
from string import join
run(
open(sys.argv[1]).read(),
'-d' in sys.argv #debug
)
except IOError:
print'Can not read file',sys.argv[1]
except IndexError:
usage()