Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1913 | jaeger | 1 | import tokenize |
2 | from tokenize import Token |
||
3 | if '.' in str(1.0): |
||
4 | from boot import * |
||
5 | |||
6 | EOF,ADD,SUB,MUL,DIV,POW,AND,OR,CMP,GET,SET,NUMBER,STRING,GGET,GSET,MOVE,DEF,PASS,JUMP,CALL,RETURN,IF,DEBUG,EQ,LE,LT,DICT,LIST,NONE,LEN,POS,PARAMS,IGET,FILE,NAME,NE,HAS,RAISE,SETJMP,MOD,LSH,RSH,ITER,DEL,REGS = 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44 |
||
7 | |||
8 | class DState: |
||
9 | def __init__(self,code,fname): |
||
10 | self.code, self.fname = code,fname |
||
11 | self.lines = self.code.split('\n') |
||
12 | |||
13 | self.stack,self.out,self._scopei,self.tstack,self._tagi,self.data = [],[('tag','EOF')],0,[],0,{} |
||
14 | self.error = False |
||
15 | def begin(self,gbl=False): |
||
16 | if len(self.stack): self.stack.append((self.vars,self.r2n,self.n2r,self._tmpi,self.mreg,self.snum,self._globals,self.lineno,self.globals,self.cregs,self.tmpc)) |
||
17 | else: self.stack.append(None) |
||
18 | self.vars,self.r2n,self.n2r,self._tmpi,self.mreg,self.snum,self._globals,self.lineno,self.globals,self.cregs,self.tmpc = [],{},{},0,0,str(self._scopei),gbl,-1,[],['regs'],0 |
||
19 | self._scopei += 1 |
||
20 | insert(self.cregs) |
||
21 | def end(self): |
||
22 | self.cregs.append(self.mreg) |
||
23 | code(EOF) |
||
24 | |||
25 | # This next line forces the encoder to |
||
26 | # throw an exception if any tmp regs |
||
27 | # were leaked within the frame |
||
28 | assert(self.tmpc == 0) #REG |
||
29 | |||
30 | if len(self.stack) > 1: |
||
31 | self.vars,self.r2n,self.n2r,self._tmpi,self.mreg,self.snum,self._globals,self.lineno,self.globals,self.cregs,self.tmpc = self.stack.pop() |
||
32 | else: self.stack.pop() |
||
33 | |||
34 | |||
35 | def insert(v): D.out.append(v) |
||
36 | def write(v): |
||
37 | if istype(v,'list'): |
||
38 | insert(v) |
||
39 | return |
||
40 | for n in range(0,len(v),4): |
||
41 | insert(('data',v[n:n+4])) |
||
42 | def setpos(v): |
||
43 | if '-nopos' in ARGV: return |
||
44 | line,x = v |
||
45 | if line == D.lineno: return |
||
46 | text = D.lines[line-1] |
||
47 | D.lineno = line |
||
48 | val = text + "\0"*(4-len(text)%4) |
||
49 | code_16(POS,len(val)/4,line) |
||
50 | write(val) |
||
51 | def code(i,a=0,b=0,c=0): |
||
52 | if not istype(i,'number'): raise |
||
53 | if not istype(a,'number'): raise |
||
54 | if not istype(b,'number'): raise |
||
55 | if not istype(c,'number'): raise |
||
56 | write(('code',i,a,b,c)) |
||
57 | def code_16(i,a,b): |
||
58 | if b < 0: b += 0x8000 |
||
59 | code(i,a,(b&0xff00)>>8,(b&0xff)>>0) |
||
60 | def get_code16(i,a,b): |
||
61 | return ('code',i,a,(b&0xff00)>>8,(b&0xff)>>0) |
||
62 | |||
63 | def _do_string(v,r=None): |
||
64 | r = get_tmp(r) |
||
65 | val = v + "\0"*(4-len(v)%4) |
||
66 | code_16(STRING,r,len(v)) |
||
67 | write(val) |
||
68 | return r |
||
69 | def do_string(t,r=None): |
||
70 | return _do_string(t.val,r) |
||
71 | |||
72 | def _do_number(v,r=None): |
||
73 | r = get_tmp(r) |
||
74 | code(NUMBER,r,0,0) |
||
75 | write(fpack(number(v))) |
||
76 | return r |
||
77 | def do_number(t,r=None): |
||
78 | return _do_number(t.val,r) |
||
79 | |||
80 | def get_tag(): |
||
81 | k = str(D._tagi) |
||
82 | D._tagi += 1 |
||
83 | return k |
||
84 | def stack_tag(): |
||
85 | k = get_tag() |
||
86 | D.tstack.append(k) |
||
87 | return k |
||
88 | def pop_tag(): |
||
89 | D.tstack.pop() |
||
90 | |||
91 | def tag(*t): |
||
92 | t = D.snum+':'+':'.join([str(v) for v in t]) |
||
93 | insert(('tag',t)) |
||
94 | def jump(*t): |
||
95 | t = D.snum+':'+':'.join([str(v) for v in t]) |
||
96 | insert(('jump',t)) |
||
97 | def setjmp(*t): |
||
98 | t = D.snum+':'+':'.join([str(v) for v in t]) |
||
99 | insert(('setjmp',t)) |
||
100 | def fnc(*t): |
||
101 | t = D.snum+':'+':'.join([str(v) for v in t]) |
||
102 | r = get_reg(t) |
||
103 | insert(('fnc',r,t)) |
||
104 | return r |
||
105 | |||
106 | def map_tags(): |
||
107 | tags = {} |
||
108 | out = [] |
||
109 | n = 0 |
||
110 | for item in D.out: |
||
111 | if item[0] == 'tag': |
||
112 | tags[item[1]] = n |
||
113 | continue |
||
114 | if item[0] == 'regs': |
||
115 | out.append(get_code16(REGS,item[1],0)) |
||
116 | n += 1 |
||
117 | continue |
||
118 | out.append(item) |
||
119 | n += 1 |
||
120 | for n in range(0,len(out)): |
||
121 | item = out[n] |
||
122 | if item[0] == 'jump': |
||
123 | out[n] = get_code16(JUMP,0,tags[item[1]]-n) |
||
124 | elif item[0] == 'setjmp': |
||
125 | out[n] = get_code16(SETJMP,0,tags[item[1]]-n) |
||
126 | elif item[0] == 'fnc': |
||
127 | out[n] = get_code16(DEF,item[1],tags[item[2]]-n) |
||
128 | for n in range(0,len(out)): |
||
129 | item = out[n] |
||
130 | if item[0] == 'data': |
||
131 | out[n] = item[1] |
||
132 | elif item[0] == 'code': |
||
133 | i,a,b,c = item[1:] |
||
134 | out[n] = chr(i)+chr(a)+chr(b)+chr(c) |
||
135 | else: |
||
136 | raise str(('huh?',item)) |
||
137 | if len(out[n]) != 4: |
||
138 | raise ('code '+str(n)+' is wrong length '+str(len(out[n]))) |
||
139 | D.out = out |
||
140 | |||
141 | def get_tmp(r=None): |
||
142 | if r != None: return r |
||
143 | return get_tmps(1)[0] |
||
144 | def get_tmps(t): |
||
145 | rs = alloc(t) |
||
146 | regs = range(rs,rs+t) |
||
147 | for r in regs: |
||
148 | set_reg(r,"$"+str(D._tmpi)) |
||
149 | D._tmpi += 1 |
||
150 | D.tmpc += t #REG |
||
151 | return regs |
||
152 | def alloc(t): |
||
153 | s = ''.join(["01"[r in D.r2n] for r in range(0,min(256,D.mreg+t))]) |
||
154 | return s.index('0'*t) |
||
155 | def is_tmp(r): |
||
156 | if r is None: return False |
||
157 | return (D.r2n[r][0] == '$') |
||
158 | def un_tmp(r): |
||
159 | n = D.r2n[r] |
||
160 | free_reg(r) |
||
161 | set_reg(r,'*'+n) |
||
162 | def free_tmp(r): |
||
163 | if is_tmp(r): free_reg(r) |
||
164 | return r |
||
165 | def free_tmps(r): |
||
166 | for k in r: free_tmp(k) |
||
167 | def get_reg(n): |
||
168 | if n not in D.n2r: |
||
169 | set_reg(alloc(1),n) |
||
170 | return D.n2r[n] |
||
171 | #def get_clean_reg(n): |
||
172 | #if n in D.n2r: raise |
||
173 | #set_reg(D.mreg,n) |
||
174 | #return D.n2r[n] |
||
175 | def set_reg(r,n): |
||
176 | D.n2r[n] = r; D.r2n[r] = n |
||
177 | D.mreg = max(D.mreg,r+1) |
||
178 | def free_reg(r): |
||
179 | if is_tmp(r): D.tmpc -= 1 |
||
180 | n = D.r2n[r]; del D.r2n[r]; del D.n2r[n] |
||
181 | |||
182 | def imanage(orig,fnc): |
||
183 | items = orig.items |
||
184 | orig.val = orig.val[:-1] |
||
185 | t = Token(orig.pos,'symbol','=',[items[0],orig]) |
||
186 | return fnc(t) |
||
187 | |||
188 | def infix(i,tb,tc,r=None): |
||
189 | r = get_tmp(r) |
||
190 | b,c = do(tb,r),do(tc) |
||
191 | code(i,r,b,c) |
||
192 | if r != b: free_tmp(b) |
||
193 | free_tmp(c) |
||
194 | return r |
||
195 | def ss_infix(ss,i,tb,tc,r=None): |
||
196 | r = get_tmp(r) |
||
197 | r2 = get_tmp() |
||
198 | ss = _do_number(ss) |
||
199 | t = get_tag() |
||
200 | r = do(tb,r) |
||
201 | code(EQ,r2,r,ss) |
||
202 | code(IF,r2) |
||
203 | jump(t,'else') |
||
204 | jump(t,'end') |
||
205 | tag(t,'else') |
||
206 | r = do(tc,r) |
||
207 | tag(t,'end') |
||
208 | free_tmp(r2) #REG |
||
209 | free_tmp(ss) #REG |
||
210 | return r |
||
211 | |||
212 | def _do_none(r=None): |
||
213 | r = get_tmp(r) |
||
214 | code(NONE,r) |
||
215 | return r |
||
216 | |||
217 | def do_symbol(t,r=None): |
||
218 | sets = ['='] |
||
219 | isets = ['+=','-=','*=','/='] |
||
220 | cmps = ['<','>','<=','>=','==','!='] |
||
221 | metas = { |
||
222 | '+':ADD,'*':MUL,'/':DIV,'**':POW, |
||
223 | '-':SUB,'and':AND,'or':OR, |
||
224 | '%':MOD,'>>':RSH,'<<':LSH, |
||
225 | '&':AND,'|':OR, |
||
226 | } |
||
227 | if t.val == 'None': return _do_none(r) |
||
228 | if t.val == 'True': |
||
229 | return _do_number('1',r) |
||
230 | if t.val == 'False': |
||
231 | return _do_number('0',r) |
||
232 | items = t.items |
||
233 | |||
234 | if t.val in ['and','or']: |
||
235 | ss = int(t.val == 'or') |
||
236 | return ss_infix(ss,metas[t.val],items[0],items[1],r) |
||
237 | if t.val in isets: |
||
238 | return imanage(t,do_symbol) |
||
239 | if t.val == 'is': |
||
240 | return infix(EQ,items[0],items[1],r) |
||
241 | if t.val == 'isnot': |
||
242 | return infix(CMP,items[0],items[1],r) |
||
243 | if t.val == 'not': |
||
244 | return infix(EQ,Token(t.pos,'number',0),items[0],r) |
||
245 | if t.val == 'in': |
||
246 | return infix(HAS,items[1],items[0],r) |
||
247 | if t.val == 'notin': |
||
248 | r = infix(HAS,items[1],items[0],r) |
||
249 | zero = _do_number('0') |
||
250 | code(EQ,r,r,free_tmp(zero)) |
||
251 | return r |
||
252 | if t.val in sets: |
||
253 | return do_set_ctx(items[0],items[1]); |
||
254 | elif t.val in cmps: |
||
255 | b,c = items[0],items[1] |
||
256 | v = t.val |
||
257 | if v[0] in ('>','>='): |
||
258 | b,c,v = c,b,'<'+v[1:] |
||
259 | cd = EQ |
||
260 | if v == '<': cd = LT |
||
261 | if v == '<=': cd = LE |
||
262 | if v == '!=': cd = NE |
||
263 | return infix(cd,b,c,r) |
||
264 | else: |
||
265 | return infix(metas[t.val],items[0],items[1],r) |
||
266 | |||
267 | def do_set_ctx(k,v): |
||
268 | if k.type == 'name': |
||
269 | if (D._globals and k.val not in D.vars) or (k.val in D.globals): |
||
270 | c = do_string(k) |
||
271 | b = do(v) |
||
272 | code(GSET,c,b) |
||
273 | free_tmp(c) |
||
274 | free_tmp(b) |
||
275 | return |
||
276 | a = do_local(k) |
||
277 | b = do(v) |
||
278 | code(MOVE,a,b) |
||
279 | free_tmp(b) |
||
280 | return a |
||
281 | elif k.type in ('tuple','list'): |
||
282 | if v.type in ('tuple','list'): |
||
283 | n,tmps = 0,[] |
||
284 | for kk in k.items: |
||
285 | vv = v.items[n] |
||
286 | tmp = get_tmp(); tmps.append(tmp) |
||
287 | r = do(vv) |
||
288 | code(MOVE,tmp,r) |
||
289 | free_tmp(r) #REG |
||
290 | n+=1 |
||
291 | n = 0 |
||
292 | for kk in k.items: |
||
293 | vv = v.items[n] |
||
294 | tmp = tmps[n] |
||
295 | free_tmp(do_set_ctx(kk,Token(vv.pos,'reg',tmp))) #REG |
||
296 | n += 1 |
||
297 | return |
||
298 | |||
299 | r = do(v); un_tmp(r) |
||
300 | n, tmp = 0, Token(v.pos,'reg',r) |
||
301 | for tt in k.items: |
||
302 | free_tmp(do_set_ctx(tt,Token(tmp.pos,'get',None,[tmp,Token(tmp.pos,'number',str(n))]))) #REG |
||
303 | n += 1 |
||
304 | free_reg(r) |
||
305 | return |
||
306 | r = do(k.items[0]) |
||
307 | rr = do(v) |
||
308 | tmp = do(k.items[1]) |
||
309 | code(SET,r,tmp,rr) |
||
310 | free_tmp(r) #REG |
||
311 | free_tmp(tmp) #REG |
||
312 | return rr |
||
313 | |||
314 | def manage_seq(i,a,items,sav=0): |
||
315 | l = max(sav,len(items)) |
||
316 | n,tmps = 0,get_tmps(l) |
||
317 | for tt in items: |
||
318 | r = tmps[n] |
||
319 | b = do(tt,r) |
||
320 | if r != b: |
||
321 | code(MOVE,r,b) |
||
322 | free_tmp(b) |
||
323 | n +=1 |
||
324 | if not len(tmps): |
||
325 | code(i,a,0,0) |
||
326 | return 0 |
||
327 | code(i,a,tmps[0],len(items)) |
||
328 | free_tmps(tmps[sav:]) |
||
329 | return tmps[0] |
||
330 | |||
331 | def p_filter(items): |
||
332 | a,b,c,d = [],[],None,None |
||
333 | for t in items: |
||
334 | if t.type == 'symbol' and t.val == '=': b.append(t) |
||
335 | elif t.type == 'args': c = t |
||
336 | elif t.type == 'nargs': d = t |
||
337 | else: a.append(t) |
||
338 | return a,b,c,d |
||
339 | |||
340 | def do_import(t): |
||
341 | for mod in t.items: |
||
342 | mod.type = 'string' |
||
343 | v = do_call(Token(t.pos,'call',None,[ |
||
344 | Token(t.pos,'name','import'), |
||
345 | mod])) |
||
346 | mod.type = 'name' |
||
347 | do_set_ctx(mod,Token(t.pos,'reg',v)) |
||
348 | def do_from(t): |
||
349 | mod = t.items[0] |
||
350 | mod.type = 'string' |
||
351 | v = do(Token(t.pos,'call',None,[ |
||
352 | Token(t.pos,'name','import'), |
||
353 | mod])) |
||
354 | item = t.items[1] |
||
355 | if item.val == '*': |
||
356 | free_tmp(do(Token(t.pos,'call',None,[ |
||
357 | Token(t.pos,'name','merge'), |
||
358 | Token(t.pos,'name','__dict__'), |
||
359 | Token(t.pos,'reg',v)]))) #REG |
||
360 | else: |
||
361 | item.type = 'string' |
||
362 | free_tmp(do_set_ctx( |
||
363 | Token(t.pos,'get',None,[ Token(t.pos,'name','__dict__'),item]), |
||
364 | Token(t.pos,'get',None,[ Token(t.pos,'reg',v),item]) |
||
365 | )) #REG |
||
366 | |||
367 | |||
368 | def do_globals(t): |
||
369 | for t in t.items: |
||
370 | if t.val not in D.globals: |
||
371 | D.globals.append(t.val) |
||
372 | def do_del(tt): |
||
373 | for t in tt.items: |
||
374 | r = do(t.items[0]) |
||
375 | r2 = do(t.items[1]) |
||
376 | code(DEL,r,r2) |
||
377 | free_tmp(r); free_tmp(r2) #REG |
||
378 | |||
379 | def do_call(t,r=None): |
||
380 | r = get_tmp(r) |
||
381 | items = t.items |
||
382 | fnc = do(items[0]) |
||
383 | a,b,c,d = p_filter(t.items[1:]) |
||
384 | e = None |
||
385 | if len(b) != 0 or d != None: |
||
386 | e = do(Token(t.pos,'dict',None,[])); un_tmp(e); |
||
387 | for p in b: |
||
388 | p.items[0].type = 'string' |
||
389 | t1,t2 = do(p.items[0]),do(p.items[1]) |
||
390 | code(SET,e,t1,t2) |
||
391 | free_tmp(t1); free_tmp(t2) #REG |
||
392 | if d: free_tmp(do(Token(t.pos,'call',None,[Token(t.pos,'name','merge'),Token(t.pos,'reg',e),d.items[0]]))) #REG |
||
393 | manage_seq(PARAMS,r,a) |
||
394 | if c != None: |
||
395 | t1,t2 = _do_string('*'),do(c.items[0]) |
||
396 | code(SET,r,t1,t2) |
||
397 | free_tmp(t1); free_tmp(t2) #REG |
||
398 | if e != None: |
||
399 | t1 = _do_none() |
||
400 | code(SET,r,t1,e) |
||
401 | free_tmp(t1) #REG |
||
402 | code(CALL,r,fnc,r) |
||
403 | free_tmp(fnc) #REG |
||
404 | return r |
||
405 | |||
406 | def do_name(t,r=None): |
||
407 | if t.val in D.vars: |
||
408 | return do_local(t,r) |
||
409 | r = get_tmp(r) |
||
410 | c = do_string(t) |
||
411 | code(GGET,r,c) |
||
412 | free_tmp(c) |
||
413 | return r |
||
414 | |||
415 | def do_local(t,r=None): |
||
416 | if t.val not in D.vars: |
||
417 | D.vars.append(t.val) |
||
418 | return get_reg(t.val) |
||
419 | |||
420 | def do_def(tok,kls=None): |
||
421 | items = tok.items |
||
422 | |||
423 | t = get_tag() |
||
424 | rf = fnc(t,'end') |
||
425 | |||
426 | D.begin() |
||
427 | setpos(tok.pos) |
||
428 | r = do_local(Token(tok.pos,'name','__params')) |
||
429 | do_info(items[0].val) |
||
430 | a,b,c,d = p_filter(items[1].items) |
||
431 | for p in a: |
||
432 | v = do_local(p) |
||
433 | tmp = _do_none() |
||
434 | code(GET,v,r,tmp) |
||
435 | free_tmp(tmp) #REG |
||
436 | for p in b: |
||
437 | v = do_local(p.items[0]) |
||
438 | do(p.items[1],v) |
||
439 | tmp = _do_none() |
||
440 | code(IGET,v,r,tmp) |
||
441 | free_tmp(tmp) #REG |
||
442 | if c != None: |
||
443 | v = do_local(c.items[0]) |
||
444 | tmp = _do_string('*') |
||
445 | code(GET,v,r,tmp) |
||
446 | free_tmp(tmp) #REG |
||
447 | if d != None: |
||
448 | e = do_local(d.items[0]) |
||
449 | code(DICT,e,0,0) |
||
450 | tmp = _do_none() |
||
451 | code(IGET,e,r,tmp) |
||
452 | free_tmp(tmp) #REG |
||
453 | free_tmp(do(items[2])) #REG |
||
454 | D.end() |
||
455 | |||
456 | tag(t,'end') |
||
457 | |||
458 | if kls == None: |
||
459 | if D._globals: do_globals(Token(tok.pos,0,0,[items[0]])) |
||
460 | r = do_set_ctx(items[0],Token(tok.pos,'reg',rf)) |
||
461 | else: |
||
462 | rn = do_string(items[0]) |
||
463 | code(SET,kls,rn,rf) |
||
464 | free_tmp(rn) |
||
465 | |||
466 | free_tmp(rf) |
||
467 | |||
468 | def do_class(t): |
||
469 | tok = t |
||
470 | items = t.items |
||
471 | parent = None |
||
472 | if items[0].type == 'name': |
||
473 | name = items[0].val |
||
474 | else: |
||
475 | name = items[0].items[0].val |
||
476 | parent = items[0].items[1].val |
||
477 | |||
478 | kls = do(Token(t.pos,'dict',0,[])) |
||
479 | ts = _do_string(name) |
||
480 | code(GSET,ts,kls) |
||
481 | free_tmp(ts) #REG |
||
482 | |||
483 | init,_new = False,[] |
||
484 | if parent: |
||
485 | _new.append(Token(t.pos,'call',None,[ |
||
486 | Token(t.pos,'get',None,[ |
||
487 | Token(t.pos,'name',parent), |
||
488 | Token(t.pos,'string','__new__'), |
||
489 | ]), |
||
490 | Token(t.pos,'name','self'), |
||
491 | ])) |
||
492 | |||
493 | for fc in items[1].items: |
||
494 | if fc.type != 'def': continue |
||
495 | fn = fc.items[0].val |
||
496 | if fn == '__init__': init = True |
||
497 | do_def(fc,kls) |
||
498 | _new.append(Token(fc.pos,'symbol','=',[ |
||
499 | Token(fc.pos,'get',None,[ |
||
500 | Token(fc.pos,'name','self'), |
||
501 | Token(fc.pos,'string',fn)]), |
||
502 | Token(fc.pos,'call',None,[ |
||
503 | Token(fc.pos,'name','bind'), |
||
504 | Token(fc.pos,'get',None,[ |
||
505 | Token(fc.pos,'name',name), |
||
506 | Token(fc.pos,'string',fn)]), |
||
507 | Token(fc.pos,'name','self')]) |
||
508 | ])) |
||
509 | |||
510 | do_def(Token(t.pos,'def',None,[ |
||
511 | Token(t.pos,'name','__new__'), |
||
512 | Token(t.pos,'list',None,[Token(t.pos,'name','self')]), |
||
513 | Token(t.pos,'statements',None,_new)]),kls) |
||
514 | |||
515 | t = get_tag() |
||
516 | rf = fnc(t,'end') |
||
517 | D.begin() |
||
518 | params = do_local(Token(tok.pos,'name','__params')) |
||
519 | |||
520 | slf = do_local(Token(tok.pos,'name','self')) |
||
521 | code(DICT,slf,0,0) |
||
522 | |||
523 | free_tmp(do(Token(tok.pos,'call',None,[ |
||
524 | Token(tok.pos,'get',None,[ |
||
525 | Token(tok.pos,'name',name), |
||
526 | Token(tok.pos,'string','__new__')]), |
||
527 | Token(tok.pos,'name','self')]))) #REG |
||
528 | |||
529 | if init: |
||
530 | tmp = get_tmp() |
||
531 | t3 = _do_string('__init__') |
||
532 | code(GET,tmp,slf,t3) |
||
533 | t4 = get_tmp() |
||
534 | code(CALL,t4,tmp,params) |
||
535 | free_tmp(tmp) #REG |
||
536 | free_tmp(t3) #REG |
||
537 | free_tmp(t4) #REG |
||
538 | code(RETURN,slf) |
||
539 | |||
540 | D.end() |
||
541 | tag(t,'end') |
||
542 | ts = _do_string('__call__') |
||
543 | code(SET,kls,ts,rf) |
||
544 | free_tmp(kls) #REG |
||
545 | free_tmp(ts) #REG |
||
546 | |||
547 | |||
548 | |||
549 | |||
550 | def do_while(t): |
||
551 | items = t.items |
||
552 | t = stack_tag() |
||
553 | tag(t,'begin') |
||
554 | tag(t,'continue') |
||
555 | r = do(items[0]) |
||
556 | code(IF,r) |
||
557 | free_tmp(r) #REG |
||
558 | jump(t,'end') |
||
559 | free_tmp(do(items[1])) #REG |
||
560 | jump(t,'begin') |
||
561 | tag(t,'break') |
||
562 | tag(t,'end') |
||
563 | pop_tag() |
||
564 | |||
565 | def do_for(tok): |
||
566 | items = tok.items |
||
567 | |||
568 | reg = do_local(items[0]) |
||
569 | itr = do(items[1]) |
||
570 | i = _do_number('0') |
||
571 | |||
572 | t = stack_tag(); tag(t,'loop'); tag(t,'continue') |
||
573 | code(ITER,reg,itr,i); jump(t,'end') |
||
574 | free_tmp(do(items[2])) #REG |
||
575 | jump(t,'loop') |
||
576 | tag(t,'break'); tag(t,'end'); pop_tag() |
||
577 | |||
578 | free_tmp(itr) #REG |
||
579 | free_tmp(i) |
||
580 | |||
581 | def do_comp(t,r=None): |
||
582 | name = 'comp:'+get_tag() |
||
583 | r = do_local(Token(t.pos,'name',name)) |
||
584 | code(LIST,r,0,0) |
||
585 | key = Token(t.pos,'get',None,[ |
||
586 | Token(t.pos,'reg',r), |
||
587 | Token(t.pos,'symbol','None')]) |
||
588 | ap = Token(t.pos,'symbol','=',[key,t.items[0]]) |
||
589 | do(Token(t.pos,'for',None,[t.items[1],t.items[2],ap])) |
||
590 | return r |
||
591 | |||
592 | def do_if(t): |
||
593 | items = t.items |
||
594 | t = get_tag() |
||
595 | n = 0 |
||
596 | for tt in items: |
||
597 | tag(t,n) |
||
598 | if tt.type == 'elif': |
||
599 | a = do(tt.items[0]); code(IF,a); free_tmp(a); |
||
600 | jump(t,n+1) |
||
601 | free_tmp(do(tt.items[1])) #REG |
||
602 | elif tt.type == 'else': |
||
603 | free_tmp(do(tt.items[0])) #REG |
||
604 | else: |
||
605 | raise |
||
606 | jump(t,'end') |
||
607 | n += 1 |
||
608 | tag(t,n) |
||
609 | tag(t,'end') |
||
610 | |||
611 | def do_try(t): |
||
612 | items = t.items |
||
613 | t = get_tag() |
||
614 | setjmp(t,'except') |
||
615 | free_tmp(do(items[0])) #REG |
||
616 | jump(t,'end') |
||
617 | tag(t,'except') |
||
618 | free_tmp(do(items[1].items[1])) #REG |
||
619 | tag(t,'end') |
||
620 | |||
621 | def do_return(t): |
||
622 | if t.items: r = do(t.items[0]) |
||
623 | else: r = _do_none() |
||
624 | code(RETURN,r) |
||
625 | free_tmp(r) |
||
626 | return |
||
627 | def do_raise(t): |
||
628 | if t.items: r = do(t.items[0]) |
||
629 | else: r = _do_none() |
||
630 | code(RAISE,r) |
||
631 | free_tmp(r) |
||
632 | return |
||
633 | |||
634 | def do_statements(t): |
||
635 | for tt in t.items: free_tmp(do(tt)) |
||
636 | |||
637 | def do_list(t,r=None): |
||
638 | r = get_tmp(r) |
||
639 | manage_seq(LIST,r,t.items) |
||
640 | return r |
||
641 | |||
642 | def do_dict(t,r=None): |
||
643 | r = get_tmp(r) |
||
644 | manage_seq(DICT,r,t.items) |
||
645 | return r |
||
646 | |||
647 | def do_get(t,r=None): |
||
648 | items = t.items |
||
649 | return infix(GET,items[0],items[1],r) |
||
650 | |||
651 | def do_break(t): jump(D.tstack[-1],'break') |
||
652 | def do_continue(t): jump(D.tstack[-1],'continue') |
||
653 | def do_pass(t): code(PASS) |
||
654 | |||
655 | def do_info(name='?'): |
||
656 | if '-nopos' in ARGV: return |
||
657 | code(FILE,free_tmp(_do_string(D.fname))) |
||
658 | code(NAME,free_tmp(_do_string(name))) |
||
659 | def do_module(t): |
||
660 | do_info() |
||
661 | free_tmp(do(t.items[0])) #REG |
||
662 | def do_reg(t,r=None): return t.val |
||
663 | |||
664 | fmap = { |
||
665 | 'module':do_module,'statements':do_statements,'def':do_def, |
||
666 | 'return':do_return,'while':do_while,'if':do_if, |
||
667 | 'break':do_break,'pass':do_pass,'continue':do_continue,'for':do_for, |
||
668 | 'class':do_class,'raise':do_raise,'try':do_try,'import':do_import, |
||
669 | 'globals':do_globals,'del':do_del,'from':do_from, |
||
670 | } |
||
671 | rmap = { |
||
672 | 'list':do_list, 'tuple':do_list, 'dict':do_dict, 'slice':do_list, |
||
673 | 'comp':do_comp, 'name':do_name,'symbol':do_symbol,'number':do_number, |
||
674 | 'string':do_string,'get':do_get, 'call':do_call, 'reg':do_reg, |
||
675 | } |
||
676 | |||
677 | def do(t,r=None): |
||
678 | if t.pos: setpos(t.pos) |
||
679 | try: |
||
680 | if t.type in rmap: |
||
681 | return rmap[t.type](t,r) |
||
682 | return fmap[t.type](t) |
||
683 | except: |
||
684 | if D.error: raise |
||
685 | D.error = True |
||
686 | tokenize.u_error('encode',D.code,t.pos) |
||
687 | |||
688 | def encode(fname,s,t): |
||
689 | t = Token((1,1),'module','module',[t]) |
||
690 | global D |
||
691 | s = tokenize.clean(s) |
||
692 | D = DState(s,fname) |
||
693 | D.begin(True) |
||
694 | do(t) |
||
695 | D.end() |
||
696 | map_tags() |
||
697 | out = D.out; D = None |
||
698 | return ''.join(out)=':>':>'+v[1:] |
||
699 |