Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

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