# figure out if we're in python or tinypy (tinypy displays "1.0" as "1") is_tinypy = (str(1.0) == "1") if not is_tinypy: from boot import * ################################################################################ RM = 'rm -f ' VM = './vm ' TINYPY = './tinypy ' TMP = 'tmp.txt' if '-mingw32' in ARGV or "-win" in ARGV: RM = 'del ' VM = 'vm ' TINYPY = 'tinypy ' TMP = 'tmp.txt' #TMP = 'stdout.txt' def system_rm(fname): system(RM+fname) ################################################################################ #if not is_tinypy: #v = chksize() #assert (v < 65536) ################################################################################ def t_show(t): if t.type == 'string': return '"'+t.val+'"' if t.type == 'number': return t.val if t.type == 'symbol': return t.val if t.type == 'name': return '$'+t.val return t.type def t_tokenize(s,exp=''): import tokenize result = tokenize.tokenize(s) res = ' '.join([t_show(t) for t in result]) #print(s); print(exp); print(res) assert(res == exp) if __name__ == '__main__': t_tokenize("234",'234') t_tokenize("234.234",'234.234') t_tokenize("phil",'$phil') t_tokenize("_phil234",'$_phil234') t_tokenize("'phil'",'"phil"') t_tokenize('"phil"','"phil"') t_tokenize("'phil' x",'"phil" $x') t_tokenize("#comment","") t_tokenize("and","and") t_tokenize("=","=") t_tokenize("()","( )") t_tokenize("(==)","( == )") t_tokenize("phil=234","$phil = 234") t_tokenize("a b","$a $b") t_tokenize("a\nb","$a nl $b") t_tokenize("a\n b","$a nl indent $b dedent") t_tokenize("a\n b\n c", "$a nl indent $b nl indent $c dedent dedent") t_tokenize("a\n b\n c", "$a nl indent $b nl $c dedent") t_tokenize("a\n b\n \n c", "$a nl indent $b nl nl indent $c dedent dedent") t_tokenize("a\n b\nc", "$a nl indent $b nl dedent $c") t_tokenize("a\n b\n c\nd", "$a nl indent $b nl indent $c nl dedent dedent $d") t_tokenize("(\n )","( )") t_tokenize(" x","indent $x dedent") t_tokenize(" #","") t_tokenize("None","None") ################################################################################ def t_lisp(t): if t.type == 'block': return """{%s}"""%' '.join([t_lisp(tt) for tt in t.items]) if t.type == 'statement': return """%s;"""%' '.join([t_lisp(tt) for tt in t.items]) if t.items == None: return t.val args = ''.join([" "+t_lisp(tt) for tt in t.items]) return "("+t.val+args+")" def t_parse(s,ex=''): import tokenize, parse r = '' tokens = tokenize.tokenize(s) tree = parse.parse(s,tokens) r = t_lisp(tree) #print(s); print(ex); print(r) assert(r==ex) if __name__ == '__main__': t_parse('2+4*3', '(+ 2 (* 4 3))') t_parse('4*(2+3)', '(* 4 (+ 2 3))') t_parse('(2+3)*4', '(* (+ 2 3) 4)') t_parse('1<2', '(< 1 2)') t_parse('x=3', '(= x 3)') t_parse('x = 2*3', '(= x (* 2 3))') t_parse('x = y', '(= x y)') t_parse('2,3', '(, 2 3)') t_parse('2,3,4', '(, 2 3 4)') t_parse('[]', '([])') t_parse('[1]', '([] 1)') t_parse('[2,3,4]', '([] 2 3 4)') t_parse('print(3)', '($ print 3)') t_parse('print()', '($ print)') t_parse('print(2,3)', '($ print 2 3)') t_parse('def fnc():pass', '(def fnc (():) pass)') t_parse('def fnc(x):pass', '(def fnc ((): x) pass)') t_parse('def fnc(x,y):pass', '(def fnc ((): x y) pass)') t_parse('x\ny\nz', '(; x y z)') t_parse('return x', '(return x)') t_parse('print(test(2,3))', '($ print ($ test 2 3))') t_parse('x.y', '(. x y)') t_parse('get(2).x', '(. ($ get 2) x)') t_parse('{}', '({})') t_parse('True', 'True') t_parse('False', 'False') t_parse('None', 'None') t_parse('while 1:pass', '(while 1 pass)') t_parse('for x in y:pass', '(for x y pass)') t_parse('print("x")', '($ print x)') t_parse('if 1: pass', '(if (elif 1 pass))') t_parse('x = []', '(= x ([]))') t_parse('x[1]', '(. x 1)') t_parse('import sdl', '(import sdl)') t_parse('2 is 3', '(is 2 3)') t_parse('2 is not 3', '(isnot 2 3)') t_parse('x is None', '(is x None)') t_parse('2 is 3 or 4 is 5', '(or (is 2 3) (is 4 5))') t_parse('e.x == 3 or e.x == 4', '(or (== (. e x) 3) (== (. e x) 4))') t_parse('if 1==2: 3\nelif 4:5\nelse:6', '(if (elif (== 1 2) 3) (elif 4 5) (else 6))') t_parse('x = y(2)*3 + y(4)*5', '(= x (+ (* ($ y 2) 3) (* ($ y 4) 5)))') t_parse('x(1,2)+y(3,4)', '(+ ($ x 1 2) ($ y 3 4))') t_parse('x(a,b,c[d])', '($ x a b (. c d))') t_parse('x(1,2)*j+y(3,4)*k+z(5,6)*l', '(+ (+ (* ($ x 1 2) j) (* ($ y 3 4) k)) (* ($ z 5 6) l))') t_parse('a = b.x/c * 2 - 1', '(= a (- (* (/ (. b x) c) 2) 1))') t_parse('for x in y: z', '(for x y z)') t_parse('min(255,n*2)','($ min 255 (* n 2))') t_parse('c = pal[i*8]','(= c (. pal (* i 8)))') t_parse('{x:y,a:b}','({} x y a b)') t_parse('x[1:2:3]','(. x (: 1 2 3))') if is_tinypy: t_parse('x - -234','(- x -234)') else: t_parse('x - -234','(- x -234.0)') t_parse('x - -y','(- x (- 0 y))') t_parse('x = ((y*4)-2)','(= x (- (* y 4) 2))') if is_tinypy: t_parse('print([1,2,"OK",4][-3:3][1])','($ print (. (. ([] 1 2 OK 4) (: -3 3)) 1))') else: t_parse('print([1,2,"OK",4][-3:3][1])','($ print (. (. ([] 1 2 OK 4) (: -3.0 3)) 1))') t_parse('a,b = 1,2','(= (, a b) (, 1 2))') t_parse('class C: pass','(class C (methods pass))') t_parse('def test(*v): pass','(def test ((): (* v)) pass)') t_parse('def test(**v): pass','(def test ((): (** v)) pass)') t_parse('test(*v)','($ test (* v))') t_parse('test(**v)','($ test (** v))') t_parse('def test(x=y): pass','(def test ((): (= x y)) pass)') t_parse('test(x=y)','($ test (= x y))') t_parse('def test(y="K",x="Z"): pass','(def test ((): (= y K) (= x Z)) pass)') t_parse('return x+y','(return (+ x y))') t_parse('if "a" is not "b": pass','(if (elif (isnot a b) pass))') t_parse('z = 0\nfor x in y: pass','(; (= z 0) (for x y pass))') t_parse('for k in {"OK":0}: pass','(for k ({} OK 0) pass)') t_parse('print(test(10,3,z=50000,*[200],**{"x":4000}))','($ print ($ test 10 3 (= z 50000) (* ([] 200)) (** ({} x 4000))))') t_parse('x="OK";print(x)','(; (= x OK) ($ print x))') t_parse('[(1,3)]','([] (, 1 3))') t_parse('x[:]','(. x (: None None))') t_parse('x[:1]','(. x (: None 1))') t_parse('x[1:]','(. x (: 1 None))') t_parse('return\nx','(; return x)') t_parse('"""test"""','test') t_parse('return a,b','(return (, a b))') ################################################################################ def showerror(cmd, ss, ex, res): print(cmd) print("ss : '" + str(ss) + "'") print("ex : '" + str(ex) + "'") print("res: '" + str(res) + "'") def t_render(ss,ex,exact=True): import tokenize, parse, encode if not istype(ss,'list'): ss =[ss] n = 1 for s in ss: fname = 'tmp'+str(n)+'.tpc' system_rm(fname) tokens = tokenize.tokenize(s) t = parse.parse(s,tokens) r = encode.encode(fname,s,t) f = save(fname,r) n += 1 system_rm('tmp.txt') cmd = VM + fname + " > tmp.txt" system(cmd) res = load(TMP).strip() #print(ss,ex,res) if exact: if res != ex: showerror(cmd, ss, ex, res) assert(res == ex) else: if ex not in res: showerror(cmd, ss, ex, res) assert(ex in res) def test_range(): t_render("""print(str(range(4))[:5])"""," tmp.txt') res = load(TMP).strip() #print(ss,ex,res) if exact: assert(res == ex) else: assert(ex in res) is_boot = False try: assert(is_tinypy == True) x = compile('x=3','') is_boot = True except: pass if is_boot == True and __name__ == '__main__': print("# t_boot") t_boot(["def test(): print('OK')","import tmp1; tmp1.test()"],"OK")