OILS / yaks / gen_cpp.py View on Github | oilshell.org

104 lines, 63 significant
1"""
2gen_cpp.py - turn yaks.asdl representation into C++
3"""
4from __future__ import print_function
5
6from _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)
9from mycpp import mylib
10from mycpp.mylib import tagswitch, log
11
12from typing import cast
13
14_ = log
15
16
17def 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
38def GenParam(p, f):
39 # type: (NameType, mylib.Writer) -> None
40
41 GenType(p.typ, f)
42 f.write(' %s' % p.name)
43
44
45def 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
57def 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
70def 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
88def 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)