Mercurial > repo
comparison bin/gs2c.py @ 9075:c989a1669243
<fizzie> revert 58b9ee8f97a7
author | HackBot |
---|---|
date | Sun, 25 Sep 2016 20:31:46 +0000 |
parents | |
children | c9f5afad5250 |
comparison
equal
deleted
inserted
replaced
9074:560a73f4f0a4 | 9075:c989a1669243 |
---|---|
1 # gs2 compiler (version 0.2) | |
2 # (c) nooodl 2014 | |
3 | |
4 import re | |
5 import struct | |
6 import sys | |
7 | |
8 if sys.platform == "win32": | |
9 import os, msvcrt | |
10 msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) | |
11 | |
12 mnemonics = {} | |
13 with open('bin/gs2.py') as f: | |
14 for line in f: | |
15 if '#=' in line: | |
16 a, b = line.split('#=') | |
17 a = re.findall(r'\\x(..)', a.strip()) | |
18 b = b.strip().split(', ') | |
19 assert len(a) == len(b) | |
20 for i, j in zip(a, b): | |
21 for k in j.split(): | |
22 mnemonics[k] = chr(int(i, 16)) | |
23 | |
24 mnemonics["'"] = '\xe0' # block1 | |
25 | |
26 for i in xrange(16): | |
27 mnemonics['@%d' % i] = chr(0xA0 | i) | |
28 mnemonics['junk%d' % i] = chr(0xA0 | i) | |
29 for i, c in enumerate('abcd'): | |
30 mnemonics['save-%s' % c] = chr(0xC8 | i) | |
31 mnemonics['pop-%s' % c] = chr(0xCC | i) | |
32 mnemonics['push-%s' % c] = chr(0xD0 | i) | |
33 mnemonics['nip-%s' % c] = chr(0xD4 | i) | |
34 mnemonics['tuck-%s' % c] = chr(0xD8 | i) | |
35 mnemonics['show-%s' % c] = chr(0xDC | i) | |
36 for i in xrange(8): | |
37 mnemonics['b%d' % (i+1)] = chr(0xE0 | i) | |
38 mnemonics['block%d' % (i+1)] = chr(0xE0 | i) | |
39 mnemonics['m%d' % (i+1)] = chr(0xE8 | i) | |
40 mnemonics['map%d' % (i+1)] = chr(0xE8 | i) | |
41 mnemonics['f%d' % (i+1)] = chr(0xF0 | i) | |
42 mnemonics['filter%d' % (i+1)] = chr(0xF0 | i) | |
43 if 0xF8 | i < 0xFD: | |
44 mnemonics['t%d' % (i+1)] = chr(0xF8 | i) | |
45 mnemonics['both%d' % (i+1)] = chr(0xF8 | i) | |
46 | |
47 def compile_num(i): | |
48 if 0 <= i <= 10: | |
49 return chr(i + 0x10) | |
50 elif i == 100: | |
51 return '\x1b' | |
52 elif i == 1000: | |
53 return '\x1c' | |
54 elif i == 16: | |
55 return '\x1d' | |
56 elif i == 64: | |
57 return '\x1e' | |
58 elif i == 256: | |
59 return '\x1f' | |
60 | |
61 elif 0x00 <= i <= 0xFF: | |
62 return '\x01' + struct.pack('B', i) | |
63 elif -0x8000 <= i <= 0x7FFF: | |
64 return '\x02' + struct.pack('<h', i) | |
65 elif -0x80000000 <= i <= 0x7FFFFFFF: | |
66 return '\x03' + struct.pack('<l', i) | |
67 else: | |
68 raise Exception("couldn't compile number: %s" % i) | |
69 | |
70 def compile_gs2(s): | |
71 s = '\n'.join(l for l in s.split('\n') if l and l[0] != '#') | |
72 tokens = re.findall(r'"[^"]*"|\S+', s) | |
73 string_mode = False | |
74 string_array = False | |
75 strings = [] | |
76 output_code = [] | |
77 | |
78 for i in tokens: | |
79 # sys.stderr.write('[%s]\n' % i) | |
80 try: | |
81 v = compile_num(int(i)) | |
82 output_code.append(v) | |
83 continue | |
84 except ValueError: pass | |
85 | |
86 if i[0] == "'" and len(i) > 1: | |
87 v = compile_num(ord(i[1])) | |
88 output_code.append(v) | |
89 elif i == ')': | |
90 string_mode = False | |
91 s_open = '\x04' | |
92 s_close = { | |
93 'regular': '\x05', | |
94 'array': '\x06', | |
95 'printf': '\x9b', | |
96 'regex-match': '\x9c', | |
97 'regex-sub': '\x9d', | |
98 'regex-find': '\x9e', | |
99 'regex-split': '\x9f', | |
100 }[string_type] | |
101 if len(strings) == 1 and len(strings[0]) == 1: | |
102 output_code.append('\x07' + strings[0]) | |
103 else: | |
104 output_code.append(s_open + '\x07'.join(strings) + s_close) | |
105 elif string_mode or i[0] == '"': | |
106 if i[0] == '"': | |
107 if string_mode: | |
108 strings.append(eval(i)) | |
109 elif len(eval(i)) == 1: | |
110 output_code.append('\x07' + eval(i)) | |
111 else: | |
112 output_code.append('\x04' + eval(i) + '\x05') | |
113 else: | |
114 strings.append(i) | |
115 elif i in ['(', 'w(', 'p(', 'm(', 's(', 'f(', 'v(']: | |
116 string_mode = True | |
117 string_type = { | |
118 '(': 'regular', | |
119 'w(': 'array', | |
120 'p(': 'printf', | |
121 'm(': 'regex-match', | |
122 's(': 'regex-sub', | |
123 'f(': 'regex-find', | |
124 'v(': 'regex-split', | |
125 }[i] | |
126 strings = [] | |
127 elif i.lower() in mnemonics: | |
128 output_code.append(mnemonics[i.lower()]) | |
129 else: | |
130 raise Exception('unknown symbol: ' + i) | |
131 # shortcut: strip leading \x04 | |
132 return ''.join(output_code).lstrip('\x04') | |
133 | |
134 if __name__ == '__main__': | |
135 sys.stdout.write(compile_gs2(sys.stdin.read())) |