| 1 | """
|
| 2 | gen_cpp.py - turn yaks.asdl representation into C++
|
| 3 | """
|
| 4 | from __future__ import print_function
|
| 5 |
|
| 6 | from _devbuild.gen.yaks_asdl import (Program, mod_def, mod_def_e, ktype,
|
| 7 | ktype_e, ktype_t, NameType, stmt, stmt_e,
|
| 8 | stmt_t, Int, kexpr_e, kexpr_t, Int)
|
| 9 | from mycpp import mylib
|
| 10 | from mycpp.mylib import tagswitch, log
|
| 11 |
|
| 12 | from typing import cast
|
| 13 |
|
| 14 | _ = log
|
| 15 |
|
| 16 |
|
| 17 | def GenType(typ, f):
|
| 18 | # type: (ktype_t, mylib.Writer) -> None
|
| 19 |
|
| 20 | UP_typ = typ
|
| 21 | with tagswitch(typ) as case:
|
| 22 | if case(ktype_e.Int):
|
| 23 | f.write('int')
|
| 24 |
|
| 25 | elif case(ktype_e.Str):
|
| 26 | f.write('BigStr*')
|
| 27 |
|
| 28 | elif case(ktype_e.List):
|
| 29 | typ = cast(ktype.List, UP_typ)
|
| 30 | f.write('List<')
|
| 31 | GenType(typ.T, f)
|
| 32 | f.write('>*')
|
| 33 |
|
| 34 | else:
|
| 35 | raise AssertionError(typ)
|
| 36 |
|
| 37 |
|
| 38 | def GenParam(p, f):
|
| 39 | # type: (NameType, mylib.Writer) -> None
|
| 40 |
|
| 41 | GenType(p.typ, f)
|
| 42 | f.write(' %s' % p.name)
|
| 43 |
|
| 44 |
|
| 45 | def GenExpr(expr, f):
|
| 46 | # type: (kexpr_t, mylib.Writer) -> None
|
| 47 |
|
| 48 | UP_expr = expr
|
| 49 | with tagswitch(expr) as case:
|
| 50 | if case(kexpr_e.Int):
|
| 51 | expr = cast(Int, UP_expr)
|
| 52 | f.write('%d' % expr.i)
|
| 53 | else:
|
| 54 | raise AssertionError()
|
| 55 |
|
| 56 |
|
| 57 | def GenStatement(st, f):
|
| 58 | # type: (stmt_t, mylib.Writer) -> None
|
| 59 |
|
| 60 | UP_st = st
|
| 61 | with tagswitch(st) as case:
|
| 62 | if case(stmt_e.Return):
|
| 63 | st = cast(stmt.Return, UP_st)
|
| 64 | # TODO: indent
|
| 65 | f.write(' return ')
|
| 66 | GenExpr(st.e, f)
|
| 67 | f.write(';\n')
|
| 68 |
|
| 69 |
|
| 70 | def GenFunction(func, f):
|
| 71 | # type: (mod_def.Func, mylib.Writer) -> None
|
| 72 |
|
| 73 | # log('Function %s', func.name)
|
| 74 |
|
| 75 | GenType(func.sig.return_type, f)
|
| 76 | f.write(' %s(' % func.name)
|
| 77 | for i, p in enumerate(func.sig.params):
|
| 78 | if i != 0:
|
| 79 | f.write(', ')
|
| 80 | GenParam(p, f)
|
| 81 | f.write(') {\n')
|
| 82 |
|
| 83 | for st in func.statements:
|
| 84 | GenStatement(st, f)
|
| 85 | f.write('}\n')
|
| 86 |
|
| 87 |
|
| 88 | def GenCpp(prog, f):
|
| 89 | # type: (Program, mylib.Writer) -> None
|
| 90 |
|
| 91 | # Every program depends on this
|
| 92 | f.write('#include "mycpp/runtime.h"\n')
|
| 93 |
|
| 94 | for module in prog.modules:
|
| 95 |
|
| 96 | f.write('namespace %s {\n' % module.name)
|
| 97 | for d in module.defs:
|
| 98 | UP_d = d
|
| 99 | with tagswitch(d) as case:
|
| 100 | if case(mod_def_e.Func):
|
| 101 | d = cast(mod_def.Func, UP_d)
|
| 102 | GenFunction(d, f)
|
| 103 |
|
| 104 | f.write('} // namespace %s\n' % module.name)
|