def run(m: Module) -> Module: filename = Symbol("filename") doSomething = Symbol("doSomething") # todo: import with m.func("Run", LazyFormat("{}: string", filename), return_="error"): config = load_config(m, filename) m.return_(doSomething(config)) # or "return nil" return m
def load_config(m: Module, filename: Symbol) -> Symbol: LoadConfig = Symbol("LoadConfig") # todo: import config = Symbol("config") err = Symbol("err") m.stmt("{}, {} := {}", config, err, LoadConfig(filename)) with m.if_(LazyFormat("{} != nil", err)): m.return_(err) return config
def gen(m: Module, c: str, provider: Provider[T_co]) -> Module: tdict = t.get_type_hints(provider) ret_type = tdict.pop("return") origin = t.get_origin(ret_type) if origin and issubclass(origin, tuple): ret_args = t.get_args(ret_type) else: ret_args = [ret_type] n = len(ret_args) if n == 1: # t.Callable[[Config, ...], Object] m.stmt("x := {}({})", provider.__name__, c) elif n == 2: # t.Callable[[Config, ...], t.Tuple[Object, Error]] pass elif n == 3: # t.Callable[[Config, ...], t.Tuple[Object, Cleanup, Error]] pass else: raise ValueError(f"unexpected return type: {ret_type}") return m
import typing as t from appkit import Config, Error, Cleanup, gen, Symbol from prestring.go import Module class Foo: __gomodule__ = "github.com/podhmo/appkit/foo" def FromConfig(c: Config) -> Foo: pass c = Symbol("c", Config) m = Module() with m.func("run", return_="error"): m.stmt("filename := *config") m.stmt("c, err := conf.LoadConfig(filename)") with m.if_("err != nil"): m.return_("err") m = gen(m, c, FromConfig) m.stmt("fooOb := foo.FromConfig(c)") m.return_("use(fooOb)") print(m)
def crossN(m, n): def rec(m, i, value): if i >= n: m.stmt("r = append(r, []string{{{value}}})".format(value=", ".join(value))) else: v = "v{}".format(i) vs = "vs{}".format(i) with m.for_("_, {} := range {}".format(v, vs)): value.append(v) rec(m, i + 1, value) args = ["vs{} []string".format(i) for i in range(n)] with m.func("cross{}".format(n), *args, return_="[][]string"): m.stmt("var r [][]string") rec(m, 0, []) m.return_("r") return m if __name__ == "__main__": from prestring.go import Module m = Module() print(crossN(m, 5))
from prestring.go import Module m = Module() m.package("main") with m.import_group() as im: im.import_("fmt") with m.func("main"): m.stmt("fmt.Println(`hello world`)") print(m)
from prestring.go import Module m = Module() m.package('main') with m.import_group() as im: pass with m.func('main'): im.import_('log') m.stmt('log.Println("hmm")') print(m)
""" // expected code func (g *Greeter) Hello(name string) string { return fmt.Sprintf("Hello %s\n", name) } """ from prestring.go import Module m = Module() with m.method("g *Greeter", "Hello", "name string", returns="string"): m.stmt('return fmt.Sprintf("Hello %s\\n", name)') print(m)
from prestring.go import Module m = Module() m.stmt("begin foo") sm = m.submodule() m.stmt("end foo") m.stmt("bar") sm.sep() sm.stmt("-- yay!") sm.sep() print(m)
with m.func("Run", LazyFormat("{}: string", filename), return_="error"): config = load_config(m, filename) m.return_(doSomething(config)) # or "return nil" return m def load_config(m: Module, filename: Symbol) -> Symbol: LoadConfig = Symbol("LoadConfig") # todo: import config = Symbol("config") err = Symbol("err") m.stmt("{}, {} := {}", config, err, LoadConfig(filename)) with m.if_(LazyFormat("{} != nil", err)): m.return_(err) return config # ASTの変換でできないかな。。 # そしてこうなるならもう関数として括る必要もないのでは? # やっていることは # - "=", ":=" の使い分け (constがほしい) def load_configX(filename: str) -> Symbol: from xxx import LoadConfig config = LoadConfig(filename) return config print(run(Module()))
from prestring.go import Module m = Module() m.package('main') with m.import_group() as im: im.import_("fmt") with m.func('Fizzbuzz', 'v int', return_='(string, error)'): with m.if_("v == 1"): m.return_('"1", nil') for i in range(2, 101): with m.elif_("v == {}".format(i)): if i % 15 == 0: m.return_('"fizzbuzz", nil') elif i % 3 == 0: m.return_('"fizz", nil') elif i % 5 == 0: m.return_('"buzz", nil') else: m.return_('"{}", nil'.format(i)) with m.else_(): m.return_('"", fmt.Errorf("unsupported value: %q", v)') print(m)
from prestring.go import Module import sys m = Module() N = int(sys.argv[1]) m.package('main') with m.import_group() as im: im('sync') im('fmt') im('math/rand') with m.struct('S'): for i in range(N): m.stmt(f'Value{i} int') with m.func('main'): m.stmt('var wg sync.WaitGroup') m.stmt('s := S{}') for i in range(N): m.stmt('wg.Add(1)') with m.block('go func()', end="()"): m.stmt(f's.Value{i} = rand.Int()') m.stmt('wg.Done()') m.stmt("wg.Wait()") m.stmt('fmt.Printf("%#+v\\n", s)') print(m)
from prestring.go import Module m = Module() m.package('main') with m.import_group() as im: im.import_("fmt") with m.func('main'): with m.for_("i := 1; i <= 100; i++"): m.stmt("v, err := FizzBuzz(i)") with m.if_("err != nil"): m.stmt("panic(err)") m.stmt("fmt.Println(v)") with m.func('FizzBuzz', 'v int', return_='(string, error)'): with m.if_("v == 1"): m.return_('"1", nil') for i in range(2, 101): with m.elif_("v == {}".format(i)): if i % 15 == 0: m.return_('"fizzbuzz", nil') elif i % 3 == 0: m.return_('"fizz", nil') elif i % 5 == 0: m.return_('"buzz", nil') else: m.return_('"{}", nil'.format(i)) with m.else_(): m.return_('"", fmt.Errorf("unsupported value: %q", v)')
from prestring.go import Module import sys m = Module() N = int(sys.argv[1]) m.package('main') with m.import_group() as im: im('sync') im('fmt') im('math/rand') with m.type_('S struct'): for i in range(N): m.stmt(f'Value{i} int') with m.func('main'): m.stmt('var wg sync.WaitGroup') m.stmt("var m sync.Mutex") m.stmt('s := S{}') for i in range(N): m.stmt('wg.Add(1)') m.stmt('go func(){') with m.scope(): m.stmt("m.Lock()") m.stmt("defer m.Unlock()") m.stmt(f's.Value{i} = rand.Int()') m.stmt('wg.Done()') m.unnewline() m.stmt('}()') m.stmt("wg.Wait()") m.stmt('fmt.Printf("%#+v\\n", s)')