|
| 1 | +#!/usr/bin/env python3.4 |
| 2 | +""" |
| 3 | +Write compile_data_test.go |
| 4 | +""" |
| 5 | + |
| 6 | +import sys |
| 7 | +import ast |
| 8 | +import subprocess |
| 9 | +import dis |
| 10 | + |
| 11 | +inp = [ |
| 12 | + ('''pass''', "exec"), |
| 13 | + ('''print("Hello World!")''', "eval"), |
| 14 | +] |
| 15 | + |
| 16 | +def string(s): |
| 17 | + if isinstance(s, str): |
| 18 | + return '"%s"' % s |
| 19 | + elif isinstance(s, bytes): |
| 20 | + out = '"' |
| 21 | + for b in s: |
| 22 | + out += "\\x%02x" % b |
| 23 | + out += '"' |
| 24 | + return out |
| 25 | + else: |
| 26 | + raise AssertionError("Unknown string %r" % s) |
| 27 | + |
| 28 | +def strings(ss): |
| 29 | + """Dump a list of py strings into go format""" |
| 30 | + return "[]string{"+",".join(string(s) for s in ss)+"}" |
| 31 | + |
| 32 | +def const(x): |
| 33 | + if isinstance(x, str): |
| 34 | + return 'py.String("%s")' % x |
| 35 | + elif isinstance(x, int): |
| 36 | + return 'py.Int(%d)' % x |
| 37 | + elif isinstance(x, float): |
| 38 | + return 'py.Float(%g)' % x |
| 39 | + elif x is None: |
| 40 | + return 'py.None' |
| 41 | + else: |
| 42 | + raise AssertionError("Unknown const %r" % x) |
| 43 | + |
| 44 | +def consts(xs): |
| 45 | + return "[]py.Object{"+",".join(const(x) for x in xs)+"}" |
| 46 | + |
| 47 | +def _compile(source, mode): |
| 48 | + """compile source with mode""" |
| 49 | + a = compile(source=source, filename="<string>", mode=mode, dont_inherit=True, optimize=0) |
| 50 | + return a, "\n".join([ |
| 51 | + "py.Code{", |
| 52 | + "Argcount: %s," % a.co_argcount, |
| 53 | + "Kwonlyargcount: %s," % a.co_kwonlyargcount, |
| 54 | + "Nlocals: %s," % a.co_nlocals, |
| 55 | + "Stacksize: %s," % a.co_stacksize, |
| 56 | + "Flags: %s," % a.co_flags, |
| 57 | + "Code: %s," % string(a.co_code), |
| 58 | + "Consts: %s," % consts(a.co_consts), |
| 59 | + "Names: %s," % strings(a.co_names), |
| 60 | + "Varnames: %s," % strings(a.co_varnames), |
| 61 | + "Freevars: %s," % strings(a.co_freevars), |
| 62 | + "Cellvars: %s," % strings(a.co_cellvars), |
| 63 | + # "Cell2arg []byte // Maps cell vars which are arguments". |
| 64 | + "Filename: %s," % string(a.co_filename), |
| 65 | + "Name: %s," % string(a.co_name), |
| 66 | + "Firstlineno: %d," % a.co_firstlineno, |
| 67 | + "Lnotab: %s," % string(a.co_lnotab), |
| 68 | + "}", |
| 69 | + ]) |
| 70 | + |
| 71 | +def escape(x): |
| 72 | + """Encode strings with backslashes for python/go""" |
| 73 | + return x.replace('\\', "\\\\").replace('"', r'\"').replace("\n", r'\n').replace("\t", r'\t') |
| 74 | + |
| 75 | +def main(): |
| 76 | + """Write compile_data_test.go""" |
| 77 | + path = "compile_data_test.go" |
| 78 | + out = ["""// Test data generated by make_compile_test.py - do not edit |
| 79 | +
|
| 80 | +package compile |
| 81 | +
|
| 82 | +import ( |
| 83 | +"github.com/ncw/gpython/py" |
| 84 | +) |
| 85 | +
|
| 86 | +var compileTestData = []struct { |
| 87 | +in string |
| 88 | +mode string // exec, eval or single |
| 89 | +out py.Code |
| 90 | +dis string |
| 91 | +}{"""] |
| 92 | + for source, mode in inp: |
| 93 | + code, gostring = _compile(source, mode) |
| 94 | + discode = dis.Bytecode(code) |
| 95 | + out.append('{"%s", "%s", %s, "%s"},' % (escape(source), mode, gostring, escape(discode.dis()))) |
| 96 | + out.append("}") |
| 97 | + print("Writing %s" % path) |
| 98 | + with open(path, "w") as f: |
| 99 | + f.write("\n".join(out)) |
| 100 | + f.write("\n") |
| 101 | + subprocess.check_call(["gofmt", "-w", path]) |
| 102 | + |
| 103 | +if __name__ == "__main__": |
| 104 | + main() |
0 commit comments