annotate bin/gs2.py @ 12256:821155c00e34 draft

<fizzie> ` sed -e \'s|wisdom|bin|\' < ../bin/culprits > ../bin/cblprits; chmod a+x ../bin/cblprits
author HackEso <hackeso@esolangs.org>
date Sat, 07 Dec 2019 23:36:22 +0000
parents c989a1669243
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9075
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1 # gs2 interpreter (version 0.2)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
2 # (c) nooodl 2014
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
3
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
4 import copy
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
5 import inspect
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
6 import itertools as it
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
7 import math
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
8 import operator
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
9 import os
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
10 import random
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
11 import re
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
12 import string
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
13 import struct
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
14 import sys
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
15 import traceback
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
16
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
17 from collections import namedtuple
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
18 from fractions import gcd
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
19
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
20 Block = namedtuple('Block', 'code')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
21 STRING_ENDS = '\x05\x06' + ''.join(map(chr, range(0x9b, 0xa0)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
22
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
23 DEBUG = False
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
24
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
25 def log(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
26 if not DEBUG: return
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
27 line, name = inspect.stack()[1][2:4]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
28 sys.stderr.write('\x1b[36m%s:%d\x1b[34m: %r\x1b[0m\n' % (name, line, x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
29
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
30 def lcm(a, b):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
31 if (a, b) == (0, 0): return 0
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
32 return abs(a * b) // gcd(a, b)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
33
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
34 def product(xs):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
35 p = 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
36 for x in xs:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
37 p *= x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
38 return p
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
39
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
40 def split(a, b, clean=False):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
41 res = [[]]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
42 lb = len(b)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
43
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
44 i = 0
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
45 while i < len(a):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
46 if a[i:i + lb] == b:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
47 res.append([])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
48 i += lb
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
49 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
50 res[-1].append(a[i])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
51 i += 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
52
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
53 return filter(None, res) if clean else res
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
54
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
55 def join(a, b):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
56 res = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
57 for i, x in enumerate(a):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
58 if i > 0:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
59 res.extend(b)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
60 res.extend(x if is_list(x) else [x])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
61 return res
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
62
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
63 def set_diff(a, b):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
64 res = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
65 for i in a:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
66 if i not in b:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
67 res.append(i)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
68 return res
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
69
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
70 def set_and(a, b):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
71 res = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
72 for i in a:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
73 if i in b:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
74 res.append(i)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
75 return res
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
76
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
77 def set_or(a, b):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
78 return a + set_diff(b, a)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
79
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
80 def set_xor(a, b):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
81 return set_diff(a, b) + set_diff(b, a)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
82
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
83 # prime number functions
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
84 prime_list = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
85 sieved = 2
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
86 composite = set([1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
87
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
88 def sieve(limit):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
89 global prime_list
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
90 global sieved
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
91 global composite
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
92 if limit <= sieved: return
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
93
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
94 prime_list = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
95 for i in range(2, limit):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
96 if i in composite: continue
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
97 for j in range(i*i, limit, i):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
98 composite.add(j)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
99 prime_list.append(i)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
100 sieved = limit
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
101
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
102 sieve(1000)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
103
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
104 def is_prime(n):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
105 global prime_list
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
106 sieve(n+1)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
107 return n not in composite
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
108
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
109 def nth_prime(n):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
110 global prime_list
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
111 sieve(int(math.log(n) * n) + 100)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
112 return prime_list[n-1]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
113
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
114 def n_primes(n):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
115 global prime_list
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
116 sieve(int(math.log(n) * n) + 100)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
117 return prime_list[:n]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
118
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
119 def primes_below(n):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
120 global prime_list
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
121 sieve(n+1)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
122 return list(it.takewhile(lambda x: x < n, prime_list))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
123
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
124 def next_prime(n):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
125 n += 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
126 while not is_prime(n): n += 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
127 return n
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
128
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
129 def totient(n):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
130 count = 0
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
131 for i in xrange(1, n+1):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
132 if gcd(n, i) == 1: count += 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
133 return count
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
134
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
135 def factor(n, exps=False):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
136 if is_num(n):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
137 p = 2
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
138 res = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
139 while n > 1:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
140 while n % p == 0:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
141 res.append(p)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
142 n //= p
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
143 p = next_prime(p)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
144 if exps:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
145 res = [[k, len(list(g))] for k, g in it.groupby(res)]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
146 return res
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
147 elif is_list(n):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
148 if n and is_num(n[0]):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
149 n = zip(n[0::2], n[1::2])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
150 p = 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
151 for b, e in n: p *= b ** e
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
152 return p
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
153 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
154 raise TypeError('factor')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
155
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
156 def chunks(x, y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
157 # chunks(range(12), 3) ==> [[0, 1, 2], [3, 4, 5], ...]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
158 while x:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
159 yield x[:y]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
160 x = x[y:]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
161
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
162 def tokenize(prog):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
163 # string hack
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
164 cs = STRING_ENDS
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
165 if re.match('^[^\x04]*[%s]' % cs, prog):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
166 prog = '\x04' + prog
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
167
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
168 mode = None
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
169 if prog[0] in '\x30\x31\x32': # set mode
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
170 mode = prog[0]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
171 prog = prog[1:]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
172
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
173 token_re = [
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
174 '\x04[^%s]*[%s]' % (cs, cs), # string (array)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
175 '\x01.', # unsigned byte
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
176 '\x02..', # signed short
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
177 '\x03....', # signed long
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
178 '\x07.', # 1 char string
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
179 '.', # regular token
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
180 ]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
181
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
182 tokens = re.findall('|'.join(token_re), prog, re.DOTALL)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
183
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
184 final = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
185 blocks = [Block([])]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
186 i = 0
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
187 while i < len(tokens):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
188 t = tokens[i]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
189 log(tokens[i:])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
190 if t == '\x08': #= {
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
191 blocks.append(Block([]))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
192 final.append('\x00')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
193 elif t == '\x09': #= }
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
194 blocks[-2].code.append(blocks.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
195 blocks[-1].code.append(final.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
196 elif '\xe0' <= t <= '\xff' and ord(t) & 7 < 6:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
197 # quick block
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
198 # 0b111XXYYY -- Y+1 is number of tokens, X is end token:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
199 # 0 = nop (0x00) 2 = filter (0x35)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
200 # 1 = map (0x34) 3 = both (0x38)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
201 # but 0xfe and 0xff are special (see below.)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
202 num = (ord(t) & 7) + 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
203 ts = blocks[-1].code[-num:]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
204 del blocks[-1].code[-num:]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
205 blocks[-1].code.append(Block(ts))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
206 blocks[-1].code.append('\x00\x34\x35\x38'[(ord(t) >> 3) & 3])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
207 elif t in '\xee\xef': #= z1 zipwith1, z2 zipwith2
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
208 # zipwith (1/2 tokens)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
209 num = (ord(t) & 1) + 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
210 ts = blocks[-1].code[-num:]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
211 del blocks[-1].code[-num:]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
212 blocks[-1].code.append(Block(ts))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
213 blocks[-1].code.append('\xb1')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
214 elif t in '\xf6\xf7': #= dm1 dump-map1, df1 dump-filter1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
215 # like m1/f1 with dump prepended to block
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
216 # useful with transpose, pairwise, cartesian-product, etc.
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
217 f = {'\xf6': '\x34', '\xf7': '\x35'}[t]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
218 x = blocks[-1].code.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
219 blocks[-1].code.extend([Block(['\x0e', x]), f])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
220 elif t == '\xfe': #= m:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
221 blocks.append(Block([]))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
222 final.append('\x34')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
223 elif t == '\xff': #= f:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
224 blocks.append(Block([]))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
225 final.append('\x35')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
226 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
227 blocks[-1].code.append(t)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
228 i += 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
229
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
230 while final:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
231 blocks[-2].code.append(blocks.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
232 blocks[-1].code.append(final.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
233
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
234 assert len(blocks) == 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
235 main = blocks[0]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
236
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
237 if mode == '\x30': #= line-mode
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
238 main = Block(['\x2a', main, '\x34', '\x54'])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
239 elif mode == '\x31': #= word-mode
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
240 main = Block(['\x2c', main, '\x34', '\x55'])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
241 elif mode == '\x32': #= line-mode-skip-first
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
242 main = Block(['\x2a', '\x22', main, '\x34', '\x54'])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
243
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
244 main.code.extend(final)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
245 return main
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
246
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
247 is_num = lambda v: isinstance(v, (int, long))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
248 is_list = lambda v: isinstance(v, list)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
249 is_block = lambda v: isinstance(v, Block)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
250
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
251 def to_gs(ps): return map(ord, ps)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
252
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
253 def to_ps(gs):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
254 if is_list(gs): return ''.join(map(chr, gs))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
255 else: return chr(gs)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
256
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
257 def regex_count(pattern):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
258 c = 0
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
259 if pattern[0] == ']':
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
260 c = 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
261 pattern = pattern[1:]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
262 elif pattern[0] == '}':
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
263 c = ord(pattern[1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
264 pattern = pattern[2:]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
265 return (c, pattern)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
266
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
267 def show(value, nest=False):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
268 if is_list(value):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
269 return ''.join(show(x, nest=True) for x in value)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
270 elif nest and is_num(value):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
271 return chr(value)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
272 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
273 return str(value)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
274
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
275 class Stack(list):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
276 def __init__(self, *args):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
277 list.__init__(self, *args)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
278 self.junk = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
279 def pop(self, i=-1, junk=True):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
280 x = list.pop(self, i)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
281 if junk: self.junk.append(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
282 return x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
283
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
284 class GS2(object):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
285 def __init__(self, code, stdin=''):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
286 self.code = code
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
287 self.stdin = to_gs(stdin)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
288 self.stack = Stack([self.stdin])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
289 self.regs = {
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
290 0: to_gs(stdin), # A
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
291 1: len(stdin), # B
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
292 2: to_gs(code), # C
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
293 3: random.randint(0, 2), # D
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
294 }
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
295 self.counter = 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
296
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
297 def run(self):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
298 try:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
299 self.evaluate(tokenize(self.code))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
300 sys.stdout.write(''.join(map(show, self.stack)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
301 except Exception:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
302 # If the code fails, print something meaningful to stderr,
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
303 # but quine on stdout: this allows GS2 to good at simple
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
304 # "print this string" programs -- just upload a plaintext
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
305 # file, it's unlikely to be valid GS2 code.
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
306 traceback.print_exc()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
307 if not DEBUG: sys.stdout.write(self.code)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
308
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
309 def evaluate(self, block):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
310 log(block)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
311 for t in block.code:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
312 if is_block(t):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
313 self.stack.append(t)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
314 elif t[0] == '\x00': #= nop
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
315 pass
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
316 elif t[0] == '\x01': # push unsigned byte
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
317 self.stack.append(struct.unpack('<B', t[1:])[0])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
318 elif t[0] == '\x02': # push signed short
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
319 self.stack.append(struct.unpack('<h', t[1:])[0])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
320 elif t[0] == '\x03': # push signed long
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
321 self.stack.append(struct.unpack('<l', t[1:])[0])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
322
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
323 elif t[0] == '\x04': # string
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
324 assert len(t) >= 2
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
325 assert t[-1] in STRING_ENDS
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
326 strings = t[1:-1].split('\x07')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
327 strings = map(to_gs, strings)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
328 if t[-1] == '\x05': # regular
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
329 self.stack += strings
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
330 elif t[-1] == '\x06': # array
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
331 self.stack.append(strings)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
332 elif t[-1] == '\x9b': # printf
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
333 f = to_ps(strings.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
334 n = f.count('%') - f.count('%%') * 2
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
335 x = tuple(map(to_ps, self.stack[-n:]))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
336 del self.stack[-n:]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
337 self.stack.append(to_gs(f % x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
338 elif t[-1] == '\x9c': # regex match
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
339 pattern = to_ps(strings.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
340 c, pattern = regex_count(pattern)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
341 s = to_ps(self.stack.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
342 f = re.match if c else re.search
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
343 self.stack.append(1 if f(pattern, s) else 0)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
344 elif t[-1] == '\x9d': # regex sub
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
345 repl = to_ps(strings.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
346 pattern = to_ps(strings.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
347 c, pattern = regex_count(pattern)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
348 s = to_ps(self.stack.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
349 m = re.sub(pattern, repl, s, count=c)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
350 self.stack.append(to_gs(m))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
351 elif t[-1] == '\x9e': # regex find
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
352 pattern = to_ps(strings.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
353 c, pattern = regex_count(pattern)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
354 s = to_ps(self.stack.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
355 ms = re.findall(pattern, s)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
356 if c > 0: ms = ms[0] if ms else []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
357 self.stack.append(map(to_gs, ms))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
358 elif t[-1] == '\x9f': # regex split
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
359 pattern = to_ps(strings.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
360 c, pattern = regex_count(pattern)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
361 s = to_ps(self.stack.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
362 m = re.split(pattern, s, maxsplit=c)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
363 self.stack.append(map(to_gs, m))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
364
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
365 elif t[0] == '\x07': # single char string
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
366 self.stack.append([ord(t[1])])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
367
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
368 # \x08 and \x09 are block syntax
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
369 elif t == '\x0a': #= new-line
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
370 self.stack.append([ord('\n')])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
371 elif t == '\x0b': #= empty-list
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
372 self.stack.append([])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
373 elif t == '\x0c': #= empty-block
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
374 self.stack.append(Block([]))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
375 elif t == '\x0d': #= space
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
376 self.stack.append([ord(' ')])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
377 elif t == '\x0e': #= make-array extract-array dump
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
378 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
379 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
380 self.stack[-x:] = [self.stack[-x:]]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
381 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
382 for i in x:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
383 self.stack.append(i)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
384 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
385 raise TypeError('make-array / extract-array')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
386
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
387 elif t == '\x0f': #= exit
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
388 break
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
389
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
390 elif 0x10 <= ord(t[0]) <= 0x1a: # push small number
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
391 self.stack.append(ord(t[0]) - 0x10)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
392 elif t == '\x1b': self.stack.append(100)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
393 elif t == '\x1c': self.stack.append(1000)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
394 elif t == '\x1d': self.stack.append(16)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
395 elif t == '\x1e': self.stack.append(64)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
396 elif t == '\x1f': self.stack.append(256)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
397
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
398 elif t == '\x20': #= negate reverse eval
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
399 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
400 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
401 self.stack.append(-x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
402 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
403 self.stack.append(x[::-1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
404 elif is_block(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
405 self.evaluate(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
406 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
407 raise TypeError('negate / reverse')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
408
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
409 elif t == '\x21': #= bnot head
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
410 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
411 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
412 self.stack.append(~x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
413 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
414 self.stack.append(x[0])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
415 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
416 raise TypeError('bitwise not / head')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
417
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
418 elif t == '\x22': #= not tail
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
419 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
420 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
421 self.stack.append(0 if x else 1)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
422 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
423 self.stack.append(x[1:])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
424 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
425 raise TypeError('not / tail')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
426
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
427 elif t == '\x23': #= abs init
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
428 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
429 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
430 self.stack.append(abs(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
431 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
432 self.stack.append(x[:-1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
433 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
434 raise TypeError('abs / init')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
435
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
436 elif t == '\x24': #= digits last
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
437 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
438 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
439 self.stack.append(map(int, str(abs(x))))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
440 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
441 self.stack.append(x[-1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
442 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
443 raise ValueError('digits / last')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
444
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
445 elif t == '\x25': #= random
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
446 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
447 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
448 self.stack.append(random.randrange(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
449 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
450 self.stack.append(random.choice(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
451 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
452 raise TypeError('random')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
453
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
454 elif t == '\x26': #= dec left-uncons
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
455 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
456 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
457 self.stack.append(x - 1)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
458 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
459 self.stack.append(x[1:])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
460 self.stack.append(x[0])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
461 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
462 raise TypeError('deincrement / left uncons')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
463
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
464 elif t == '\x27': #= inc right-uncons
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
465 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
466 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
467 self.stack.append(x + 1)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
468 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
469 self.stack.append(x[:-1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
470 self.stack.append(x[-1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
471 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
472 raise TypeError('increment / right uncons')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
473
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
474 elif t == '\x28': #= sign min
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
475 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
476 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
477 self.stack.append(cmp(x, 0))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
478 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
479 self.stack.append(min(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
480 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
481 raise TypeError('sign / min')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
482
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
483 elif t == '\x29': #= thousand max
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
484 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
485 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
486 self.stack.append(x * 1000)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
487 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
488 self.stack.append(max(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
489 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
490 raise TypeError('thousand / max')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
491
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
492 elif t == '\x2a': #= double lines
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
493 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
494 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
495 self.stack.append(x * 2)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
496 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
497 if x and x[-1] == ord('\n'):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
498 x.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
499 self.stack.append(split(x, to_gs('\n')))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
500 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
501 raise TypeError('double / line')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
502
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
503 elif t == '\x2b': #= half unlines
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
504 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
505 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
506 self.stack.append(x // 2)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
507 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
508 x = [to_gs(show(i)) for i in x]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
509 self.stack.append(join(x, to_gs('\n')))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
510 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
511 raise TypeError('half / unlines')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
512
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
513 elif t == '\x2c': #= square words
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
514 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
515 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
516 self.stack.append(x * x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
517 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
518 self.stack.append(map(to_gs, to_ps(x).split()))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
519 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
520 raise TypeError('square / words')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
521
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
522 elif t == '\x2d': #= sqrt unwords
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
523 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
524 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
525 self.stack.append(int(math.sqrt(x)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
526 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
527 x = [to_gs(show(i)) for i in x]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
528 self.stack.append(join(x, to_gs(' ')))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
529 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
530 raise TypeError('sqrt / unwords')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
531
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
532 elif t == '\x2e': #= range length
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
533 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
534 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
535 self.stack.append(range(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
536 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
537 self.stack.append(len(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
538 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
539 raise TypeError('range / length')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
540
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
541 elif t == '\x2f': #= range1 sort
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
542 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
543 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
544 self.stack.append(range(1, x + 1))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
545 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
546 self.stack.append(list(sorted(x)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
547 elif is_block(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
548 l = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
549 def f(z):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
550 self.stack.append(z)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
551 self.evaluate(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
552 return self.stack.pop(junk=False)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
553 self.stack.append(list(sorted(l, key=f)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
554 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
555 raise TypeError('range1 / sort')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
556
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
557 elif t == '\x30': #= + add catenate
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
558 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
559 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
560 if is_num(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
561 self.stack.append(x + y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
562 elif is_list(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
563 self.stack.append(x + y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
564 elif is_block(x) and is_block(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
565 self.stack.append(Block(x.code + y.code))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
566 elif is_list(x) and not is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
567 self.stack.append(x + [y])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
568 elif not is_list(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
569 self.stack.append([x] + y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
570 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
571 raise TypeError('add / catenate')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
572
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
573 elif t == '\x31': #= - sub diff
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
574 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
575 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
576 if is_num(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
577 self.stack.append(x - y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
578 elif is_list(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
579 self.stack.append(set_diff(x, y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
580 elif is_list(x) and not is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
581 self.stack.append(set_diff(x, [y]))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
582 elif not is_list(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
583 self.stack.append(set_diff(y, [x]))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
584 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
585 raise TypeError('subtract / set diff')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
586
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
587 elif t == '\x32': #= * mul join times fold
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
588 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
589 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
590 if is_num(x) and (is_block(y) or is_list(y)):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
591 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
592 if is_block(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
593 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
594
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
595 if is_num(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
596 self.stack.append(x * y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
597 elif is_list(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
598 self.stack.append(join(x, y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
599 elif is_list(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
600 self.stack.append(x * y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
601 elif is_block(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
602 for i in xrange(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
603 self.evaluate(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
604 elif is_list(x) and is_block(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
605 self.stack.append(x[0])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
606 for i in x[1:]:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
607 self.stack.append(i)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
608 self.evaluate(y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
609 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
610 raise TypeError('multiply / join / times / fold')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
611
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
612 elif t == '\x33': #= / div chunks split each
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
613 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
614 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
615
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
616 if not is_list(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
617 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
618
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
619 if is_num(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
620 self.stack.append(x // y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
621 elif is_list(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
622 self.stack.append(list(chunks(x, y)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
623 elif is_list(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
624 self.stack.append(split(x, y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
625 elif is_list(x) and is_block(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
626 for i in x:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
627 self.stack.append(i)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
628 self.evaluate(y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
629 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
630 raise TypeError('divide / chunks / split / each')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
631
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
632 elif t == '\x34': #= % mod step clean-split map
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
633 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
634 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
635
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
636 if not is_list(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
637 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
638
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
639 if is_num(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
640 self.stack.append(x % y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
641 elif is_list(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
642 self.stack.append(x[::y])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
643 elif is_list(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
644 self.stack.append(split(x, y, clean=True))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
645 elif is_list(x) and is_block(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
646 self.eval_map(y, x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
647 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
648 raise TypeError('modulo / step / split\' / map')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
649
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
650 elif t == '\x35': #= & and get when filter
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
651 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
652 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
653
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
654 if is_block(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
655 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
656 if is_num(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
657 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
658 if is_block(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
659 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
660
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
661 if is_num(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
662 self.stack.append(x & y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
663 elif is_list(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
664 self.stack.append(set_and(x, y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
665 elif is_list(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
666 self.stack.append(x[y])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
667 elif is_num(x) and is_block(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
668 if x: self.evaluate(y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
669 elif is_list(x) and is_block(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
670 self.eval_filter(y, x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
671 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
672 raise TypeError('and / get / when / filter')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
673
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
674 elif t == '\x36': #= | or unless
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
675 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
676 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
677
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
678 if is_block(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
679 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
680
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
681 if is_num(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
682 self.stack.append(x | y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
683 elif is_list(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
684 self.stack.append(set_or(x, y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
685 elif is_num(x) and is_block(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
686 if not x: self.evaluate(y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
687 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
688 raise TypeError('bor / unless')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
689
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
690 elif t == '\x37': #= ^ xor concatmap
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
691 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
692 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
693
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
694 if is_block(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
695 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
696
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
697 if is_num(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
698 self.stack.append(x ^ y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
699 elif is_list(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
700 self.stack.append(set_xor(x, y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
701 elif is_list(x) and is_block(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
702 res = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
703 for i in x:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
704 self.stack.append(i)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
705 self.evaluate(y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
706 res.extend(self.stack.pop(junk=False))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
707 self.stack.append(res)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
708 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
709 raise TypeError('xor / concatmap')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
710
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
711 elif t == '\x38': #= smallest both
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
712 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
713 if is_block(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
714 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
715 self.evaluate(y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
716 self.stack.append(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
717 self.evaluate(y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
718 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
719 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
720 self.stack.append(min(x, y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
721
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
722 elif t == '\x39': #= biggest
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
723 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
724 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
725 self.stack.append(max(x, y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
726
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
727 elif t == '\x3a': #= clamp
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
728 z = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
729 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
730 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
731 self.stack.append(min(max(x, y), z))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
732
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
733 elif t == '\x3c': #= gcd take
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
734 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
735 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
736
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
737 if is_num(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
738 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
739
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
740 if is_num(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
741 self.stack.append(gcd(x, y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
742 elif is_list(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
743 self.stack.append(x[:y])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
744 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
745 raise TypeError('gcd / take')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
746
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
747 elif t == '\x3d': #= lcm drop
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
748 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
749 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
750
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
751 if is_num(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
752 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
753
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
754 if is_num(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
755 self.stack.append(lcm(x, y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
756 elif is_list(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
757 self.stack.append(x[y:])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
758 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
759 raise TypeError('lcm / drop')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
760
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
761 elif t == '\x3e': #= pow index
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
762 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
763 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
764
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
765 if is_num(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
766 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
767
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
768 if is_num(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
769 self.stack.append(x ** y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
770 elif is_list(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
771 self.stack.append(x.index(y) if y in x else -1)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
772 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
773 raise TypeError('power / index')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
774
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
775 elif t == '\x3f': #= log member
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
776 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
777 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
778
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
779 if is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
780 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
781
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
782 if is_num(x) and is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
783 self.stack.append(int(math.log(x, y)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
784 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
785 self.stack.append(1 if y in x else 0)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
786 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
787 raise TypeError('log / member')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
788
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
789 elif t == '\x40': #= dup
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
790 self.stack.append(self.stack[-1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
791 elif t == '\x41': #= dup2
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
792 self.stack.append(self.stack[-1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
793 self.stack.append(self.stack[-1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
794 elif t == '\x42': #= swap
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
795 self.stack.append(self.stack.pop(-2))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
796 elif t == '\x43': #= rot
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
797 self.stack.append(self.stack.pop(-3))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
798 elif t == '\x44': #= rrot
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
799 self.stack.append(self.stack.pop(-3))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
800 self.stack.append(self.stack.pop(-3))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
801 elif t == '\x45': #= over
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
802 self.stack.append(self.stack[-2])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
803 elif t == '\x46': #= nip
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
804 self.stack.pop(-2)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
805 elif t == '\x47': #= tuck
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
806 self.stack.insert(-2, self.stack[-1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
807 elif t == '\x48': #= 2dup
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
808 self.stack.append(self.stack[-2])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
809 self.stack.append(self.stack[-2])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
810 elif t == '\x49': #= pick
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
811 n = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
812 self.stack.append(self.stack[-n])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
813 elif t == '\x4a': #= roll
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
814 n = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
815 self.stack.append(self.stack.pop(-n))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
816 elif t == '\x4b': #= wrap-stack
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
817 self.stack = [copy.deepcopy(self.stack)]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
818 elif t == '\x4c': #= leave-top
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
819 del self.stack[:-1]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
820 elif t == '\x4d': #= itemize
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
821 self.stack.append([self.stack.pop()])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
822 elif t == '\x4e': #= rrange
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
823 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
824 self.stack.append(range(x)[::-1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
825 elif t == '\x4f': #= crange
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
826 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
827 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
828 if x > y: x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
829 self.stack.append(range(x, y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
830 elif t == '\x50': #= pop
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
831 self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
832 elif t == '\x51': #= pop2
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
833 self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
834 self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
835 elif t == '\x52': #= show
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
836 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
837 self.stack.append(to_gs(show(x)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
838 elif t == '\x53': #= map-show
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
839 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
840 self.stack.append(map(to_gs, map(show, x)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
841 elif t == '\x54': #= show-lines
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
842 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
843 self.stack.append(to_gs('\n'.join(map(show, x))))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
844 elif t == '\x55': #= show-words
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
845 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
846 self.stack.append(to_gs(' '.join(map(show, x))))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
847 elif t in '\x56\x57': #= read-num, read-nums
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
848 x = to_ps(self.stack.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
849 nums = map(int, re.findall(r'-?\d+', x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
850 self.stack.append(nums[0] if t == '\x56' else nums)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
851 elif t == '\x58': #= show-line
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
852 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
853 self.stack.append(to_gs(show(x) + '\n'))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
854 elif t == '\x59': #= show-space
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
855 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
856 self.stack.append(to_gs(show(x) + ' '))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
857 elif t == '\x5a': #= show-comma
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
858 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
859 self.stack.append(to_gs(', '.join(map(show, x))))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
860 elif t == '\x5b': #= show-python
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
861 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
862 self.stack.append(to_gs(', '.join(map(show, x)).join('[]')))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
863 elif t in '\x5c\x5d\x5e': #= ljust, center, rjust
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
864 fill = ' '
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
865 if is_num(self.stack[-2]):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
866 fill = chr(self.stack.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
867 width = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
868 s = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
869 if t == '\x5c': g = show(s).ljust(width, fill)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
870 if t == '\x5d': g = show(s).center(width, fill)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
871 if t == '\x5e': g = show(s).rjust(width, fill)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
872 self.stack.append(to_gs(g))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
873 elif t == '\x5f': #= inspect
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
874 self.stack.append(to_gs(repr(self.stack.pop())))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
875 elif t == '\x60': #= logical-and
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
876 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
877 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
878 self.stack.append(x and y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
879 elif t == '\x61': #= logical-or
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
880 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
881 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
882 self.stack.append(x or y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
883 elif t == '\x62': #= divides left-cons
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
884 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
885 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
886 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
887 self.stack.append(0 if x % y else 1)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
888 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
889 self.stack.append([y] + x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
890 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
891 raise TypeError('divides / left-cons')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
892 elif t == '\x63': #= divmod group
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
893 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
894 if is_num(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
895 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
896 self.stack.append(x // y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
897 self.stack.append(x % y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
898 elif is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
899 gb = [list(g) for k, g in it.groupby(y)]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
900 self.stack.append(list(gb))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
901 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
902 raise TypeError('divmod / group')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
903 elif t == '\x64': #= sum even
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
904 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
905 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
906 self.stack.append(1 if x % 2 == 0 else 0)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
907 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
908 self.stack.append(sum(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
909 elif t == '\x65': #= product odd
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
910 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
911 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
912 self.stack.append(1 if x % 2 == 1 else 0)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
913 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
914 self.stack.append(product(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
915 elif t == '\x66': #= fizzbuzz
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
916 fizzbuzz = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
917 for i in range(1, 101):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
918 s = ("Fizz" if i % 3 == 0 else "") + \
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
919 ("Buzz" if i % 5 == 0 else "")
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
920 fizzbuzz.append(s or str(i))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
921 self.stack.append(to_gs('\n'.join(fizzbuzz)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
922 elif t == '\x67': #= popcnt right-cons
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
923 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
924 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
925 x = abs(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
926 p = 0
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
927 while x:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
928 p += (x & 1)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
929 x >>= 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
930 self.stack.append(p)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
931 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
932 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
933 self.stack.append(x + [y])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
934 elif t == '\x68': #= hello
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
935 x = 0
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
936 if len(self.stack) >= 1 and is_num(self.stack[-1]):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
937 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
938 x = (range(0, 11) + [100, 1000, 16, 64, 256]).index(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
939 s1 = 'h' if x & 1 else 'H'
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
940 s2 = 'W' if x & 2 else 'w'
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
941 s3 = ['!', '', '.', '...'][((x & 4) >> 2) | ((x & 16) >> 3)]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
942 s4 = '' if x & 8 else ','
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
943 f = '%sello%s %sorld%s' % (s1, s4, s2, s3)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
944 self.stack.append(to_gs(f))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
945 elif t in '\x69\x6a': #= base, binary
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
946 b = 2 if t == '\x6a' else self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
947 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
948 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
949 x = abs(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
950 res = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
951 while x:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
952 res.append(x % b)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
953 x //= b
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
954 self.stack.append(res[::-1])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
955 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
956 res = 0
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
957 for i in x:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
958 res = res * b + i
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
959 self.stack.append(res)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
960 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
961 raise TypeError('base / binary')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
962 elif t == '\x6b': #= is-prime
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
963 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
964 if is_num(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
965 self.stack.append(1 if is_prime(x) else 0)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
966 elif is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
967 self.stack.append(filter(is_prime, x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
968 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
969 raise TypeError('is-prime')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
970 elif t == '\x6c': #= primes
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
971 op = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
972 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
973 if op == 0: self.stack.append(n_primes(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
974 elif op == 1: self.stack.append(primes_below(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
975 elif op == 2: self.stack.append(next_prime(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
976 elif op == 3: self.stack.append(totient(x))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
977 elif op == 4: self.stack.append(factor(x, exps=False))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
978 elif op == 5: self.stack.append(factor(x, exps=True))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
979 elif t == '\x6d': #= scan
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
980 f = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
981 def call_f(x, y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
982 self.stack.append(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
983 self.stack.append(y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
984 self.evaluate(f)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
985 return self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
986 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
987 res = [xs.pop(0)]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
988 while xs:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
989 res.append(call_f(res[-1], xs.pop(0)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
990 self.stack.append(res)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
991 elif t in '\x70\x71\x72\x73\x74\x75': #= lt <, eq =, gt >, ge >=, ne !=, le <=
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
992 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
993 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
994 ops = {
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
995 '\x70': operator.lt,
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
996 '\x71': operator.eq,
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
997 '\x72': operator.gt,
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
998 '\x73': operator.ge,
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
999 '\x74': operator.ne,
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1000 '\x75': operator.le,
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1001 }
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1002 self.stack.append(1 if ops[t](x, y) else 0)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1003 elif t == '\x76': #= cmp
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1004 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1005 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1006 self.stack.append(cmp(x, y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1007 elif t == '\x77': #= is-sorted
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1008 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1009 if is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1010 self.stack.append(1 if x == list(sorted(x)) else 0)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1011 elif is_block(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1012 l = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1013 def f(z):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1014 self.stack.append(z)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1015 self.evaluate(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1016 return self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1017 sorted_l = list(sorted(l, key=f))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1018 self.stack.append(1 if l == sorted_l else 0)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1019 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1020 raise TypeError('sorted')
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1021 elif t == '\x78': #= shift-left inits
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1022 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1023 if is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1024 inits = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1025 for i in xrange(len(y) + 1):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1026 inits.append(y[:i])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1027 self.stack.append(inits)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1028 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1029 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1030 self.stack.append(x << y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1031 elif t == '\x79': #= shift-right tails
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1032 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1033 if is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1034 tails = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1035 for i in xrange(len(y) + 1):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1036 tails.append(y[len(y)-i:])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1037 self.stack.append(tails)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1038 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1039 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1040 self.stack.append(x >> y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1041 elif t == '\x7a': #= digit-left enumerate
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1042 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1043 if is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1044 self.stack.append(list(map(list, enumerate(y))))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1045 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1046 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1047 self.stack.append(x * (10 ** y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1048 elif t == '\x7b': #= digit-right
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1049 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1050 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1051 self.stack.append(x // (10 ** y))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1052 elif t == '\x7c': #= power-of-2
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1053 self.stack.append(2 ** self.stack.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1054 elif t == '\x7d': #= power-of-10
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1055 self.stack.append(10 ** self.stack.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1056 elif t == '\x7e': #= sub-power-of-2
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1057 self.stack.append(2 ** self.stack.pop() - 1)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1058 elif t == '\x7f': #= sub-power-of-10
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1059 self.stack.append(10 ** self.stack.pop() - 1)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1060
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1061 elif t == '\x80': #= pair
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1062 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1063 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1064 self.stack.append([x, y])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1065 elif t == '\x81': #= copies
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1066 n = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1067 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1068 self.stack.append([x for _ in xrange(n)])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1069 elif t == '\x82': #= take-end
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1070 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1071 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1072 if is_num(x) and is_list(y):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1073 x, y = y, x
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1074 self.stack.append(x[-y:])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1075 elif t == '\x83': #= cartesian-product
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1076 y = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1077 x = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1078 p = it.product(x, y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1079 self.stack.append(list(map(list, p)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1080 elif t == '\x84': #= uppercase-alphabet
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1081 self.stack.append(range(ord('A'), ord('Z') + 1))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1082 elif t == '\x85': #= lowercase-alphabet
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1083 self.stack.append(range(ord('a'), ord('z') + 1))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1084 elif t == '\x86': #= ascii-digits
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1085 self.stack.append(range(ord('0'), ord('9') + 1))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1086 elif t == '\x87': #= printable-ascii
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1087 self.stack.append(range(32, 127))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1088 elif t in '\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f': #= is-alnum, is-alpha, is-digit, is-lower, is-space, is-upper, is-printable, is-hexdigit
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1089 m = [str.isalnum, str.isalpha, str.isdigit,
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1090 str.islower, str.isspace, str.isupper,
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1091 lambda x: all(32 <= ord(c) <= 126 for c in x),
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1092 lambda x: x in '0123456789abcdefABCDEF']
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1093 p = m[ord(t) - 0x88]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1094 x = to_ps(self.stack.pop())
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1095 self.stack.append(1 if p(x) else 0)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1096 elif t == '\x90': #= uniq nub
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1097 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1098 uniq = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1099 for x in xs:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1100 if x not in uniq:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1101 uniq.append(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1102 self.stack.append(uniq)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1103 elif t == '\x91': #= compress
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1104 ns = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1105 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1106 new = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1107 for n, x in zip(ns, xs):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1108 new += [x for _ in xrange(n)]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1109 self.stack.append(new)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1110 elif t == '\x92': #= select
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1111 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1112 iis = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1113 new = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1114 for i in iis:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1115 new.append(xs[i])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1116 self.stack.append(new)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1117 elif t == '\x93': #= permutations
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1118 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1119 if is_num(xs):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1120 n = xs
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1121 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1122 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1123 n = None
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1124 ps = list(map(list, it.permutations(xs, n)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1125 self.stack.append(ps)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1126 elif t == '\x94': #= fold-product
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1127 xss = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1128 ys = list(map(list, it.product(*xss)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1129 self.stack.append(ys)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1130 elif t == '\x95': #= repeat-product
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1131 n = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1132 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1133 ys = list(map(list, it.product(xs, repeat=n)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1134 self.stack.append(ys)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1135 elif t == '\x96': #= combinations
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1136 n = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1137 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1138 ys = list(map(list, it.combinations(xs, n)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1139 self.stack.append(ys)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1140 elif t == '\x97': #= combinations-with-replacement
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1141 n = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1142 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1143 ys = list(map(list, it.combinations_with_replacement(xs, n)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1144 self.stack.append(ys)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1145 elif t == '\x98': #= pairwise
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1146 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1147 ys = map(list, zip(xs, xs[1:]))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1148 self.stack.append(ys)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1149 elif t == '\x99': #= flatten
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1150 def flatten(xs):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1151 acc = []
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1152 for x in xs:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1153 if is_list(x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1154 acc += flatten(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1155 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1156 acc.append(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1157 return acc
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1158 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1159 self.stack.append(flatten(xs))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1160 elif t == '\x9a': #= transpose
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1161 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1162 self.stack.append(map(list, zip(*xs)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1163 elif '\xa0' <= t <= '\xaf': # junk (recently popped items)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1164 self.stack.append(self.stack.junk[-1 - (ord(t) & 15)])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1165 elif t == '\xb0': #= zip
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1166 ys = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1167 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1168 self.stack.append(map(list, zip(xs, ys)))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1169 elif t == '\xb1': #= zipwith
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1170 f = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1171 ys = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1172 xs = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1173 l0 = len(self.stack)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1174 for x, y in zip(xs, ys):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1175 self.stack.append(x)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1176 self.stack.append(y)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1177 self.evaluate(f)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1178 self.stack[l0:] = [self.stack[l0:]]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1179 elif t == '\xb2': #= counter
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1180 self.stack.append(self.counter)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1181 self.counter += 1
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1182 elif '\xc8' <= t <= '\xcb': # save
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1183 self.regs[ord(t) & 3] = self.stack[-1]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1184 elif '\xcc' <= t <= '\xcf': # put
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1185 self.regs[ord(t) & 3] = self.stack.pop()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1186 elif '\xd0' <= t <= '\xd3': # get
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1187 self.stack.append(self.regs[ord(t) & 3])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1188 elif '\xd4' <= t <= '\xd7': # nip
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1189 self.regs[ord(t) & 3] = self.stack.pop(-2)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1190 elif '\xd8' <= t <= '\xdb': # tuck
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1191 self.stack.insert(-1, self.regs[ord(t) & 3])
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1192 elif '\xdc' <= t <= '\xdf': # show
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1193 self.stack.append(to_gs(show(self.regs[ord(t) & 3])))
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1194 else:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1195 raise ValueError('invalid token %r' % t)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1196
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1197 def eval_map(self, f, x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1198 l0 = len(self.stack)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1199 for i in x:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1200 self.stack.append(i)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1201 self.evaluate(f)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1202 self.stack[l0:] = [self.stack[l0:]]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1203
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1204 def eval_filter(self, f, x):
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1205 l0 = len(self.stack)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1206 for i in x:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1207 self.stack.append(i)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1208 self.evaluate(f)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1209 if self.stack.pop():
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1210 self.stack.append(i)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1211 self.stack[l0:] = [self.stack[l0:]]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1212
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1213 if __name__ == '__main__':
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1214 if len(sys.argv) <= 1:
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1215 print >> sys.stderr, 'usage: python %s [-d] <code file>' % sys.argv[0]
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1216 sys.exit(1)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1217
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1218 if sys.argv[1] == '-d':
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1219 DEBUG = True
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1220 sys.argv.pop(1)
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1221
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1222 code = open(sys.argv[1], 'rb').read()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1223 stdin = '' if sys.stdin.isatty() else sys.stdin.read()
c989a1669243 <fizzie> revert 58b9ee8f97a7
HackBot
parents:
diff changeset
1224 GS2(code, stdin).run()