| 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)
 |