OILS / asdl / gen_cpp_test.cc View on Github | oils.pub

302 lines, 194 significant
1#include <stdarg.h> // va_list, etc.
2#include <stdio.h>
3
4#include "_gen/asdl/examples/shared_variant.asdl.h"
5#include "_gen/asdl/examples/typed_arith.asdl.h"
6#include "_gen/asdl/examples/typed_demo.asdl.h" // has simple Sum, etc
7#include "mycpp/runtime.h"
8#include "prebuilt/asdl/runtime.mycpp.h"
9#include "vendor/greatest.h"
10
11using typed_arith_asdl::pipeline;
12
13using typed_arith_asdl::arith_expr; // variant type namespace
14using typed_arith_asdl::arith_expr_e; // variant tag type
15using typed_arith_asdl::arith_expr_t; // sum type
16
17using typed_arith_asdl::arith_expr__Big;
18using typed_arith_asdl::arith_expr__Const;
19using typed_arith_asdl::arith_expr__FuncCall;
20using typed_arith_asdl::arith_expr__Unary;
21using typed_arith_asdl::arith_expr__Var;
22
23using typed_demo_asdl::bool_expr__Binary;
24using typed_demo_asdl::bool_expr__LogicalBinary;
25using typed_demo_asdl::bool_expr_t;
26using typed_demo_asdl::op_array;
27using typed_demo_asdl::op_id_e;
28
29using hnode_asdl::hnode__Leaf;
30using hnode_asdl::hnode_e;
31
32void PrintTag(arith_expr_t* a) {
33 switch (a->tag()) {
34 case arith_expr_e::Const:
35 log("Const");
36 break;
37 case arith_expr_e::Var:
38 log("Var");
39 break;
40 default:
41 log("OTHER");
42 }
43 log("");
44}
45
46TEST misc_test() {
47 auto c = Alloc<arith_expr::Const>(42);
48 log("sizeof *c = %d", sizeof *c); // 16 bytes
49
50 ASSERT_EQ_FMT(42, c->i, "%d");
51 log("c->tag = %d", c->tag());
52 PrintTag(c);
53
54 auto v = Alloc<arith_expr__Var>(StrFromC("foo"));
55 log("sizeof *v = %d", sizeof *v); // 24 bytes
56
57 ASSERT(str_equals(StrFromC("foo"), v->name));
58 log("v->tag = %d", v->tag());
59 PrintTag(v);
60
61 auto u = Alloc<arith_expr__Unary>(StrFromC("-"), v);
62 log("u->op = %s", u->op->data_);
63
64 auto v1 = Alloc<arith_expr__Var>(StrFromC("v1"));
65 auto v2 = Alloc<arith_expr__Var>(StrFromC("v2"));
66 auto args = NewList<arith_expr_t*>({v1, v2});
67
68 auto f = Alloc<arith_expr__FuncCall>(StrFromC("f"), args);
69 log("f->name = %s", f->name->data_);
70
71 auto p = Alloc<pipeline>(true);
72 log("p->negated = %d", p->negated);
73
74#if 0
75 if (t->tag() == hnode_e::Leaf) {
76 hnode__Leaf* t2 = static_cast<hnode__Leaf*>(t);
77 log("%s", hnode_str(t2->tag()));
78 log("%s", color_str(t2->color));
79 log("%s", t2->s->data_);
80 }
81#endif
82
83 // NOTE: This is self-initialization!!!
84 /*
85 if (t->tag == hnode_e::Leaf) {
86 hnode__Leaf* t = static_cast<hnode__Leaf*>(t);
87 log("%s", hnode_str(t->tag));
88 log("%s", color_str(t->color));
89 log("%s", t->s->data_);
90 }
91 */
92
93 PASS();
94}
95
96using shared_variant_asdl::DoubleQuoted;
97using shared_variant_asdl::word_part_e;
98using shared_variant_asdl::word_part_t;
99
100using shared_variant_asdl::tok;
101using shared_variant_asdl::tok_e;
102using shared_variant_asdl::tok_t;
103using shared_variant_asdl::Token;
104
105TEST shared_variant_test() {
106 auto* dq = Alloc<DoubleQuoted>(0, Alloc<List<BigStr*>>());
107
108 word_part_t* wp = nullptr;
109 wp = dq; // assign to base type
110
111 log("wp->tag() %d", wp->tag());
112
113 auto* token = Alloc<Token>(0, StrFromC("hi"));
114 tok_t* tok = nullptr;
115 tok = token;
116
117 log("tok->tag() for Token = %d", tok->tag());
118
119 auto* eof = tok::Eof;
120 tok = eof;
121 log("tok->tag() for Eof = %d", tok->tag());
122
123 PASS();
124}
125
126using typed_demo_asdl::bool_expr_str;
127
128TEST pretty_print_test() {
129 // typed_demo.asdl
130
131 bool_expr_t* b = nullptr;
132 StackRoot _r1(&b);
133
134 auto w1 = Alloc<typed_demo_asdl::word>(StrFromC("left"));
135 auto w2 = Alloc<typed_demo_asdl::word>(StrFromC("right"));
136 b = Alloc<bool_expr__Binary>(w1, w2);
137
138 hnode_t* t1 = b->PrettyTree(false);
139 ASSERT_EQ_FMT(hnode_e::Record, t1->tag(), "%d");
140
141 auto f = mylib::Stdout();
142 format::HNodePrettyPrint(t1, f);
143 printf("\n");
144
145 BigStr* s = bool_expr_str(b->tag());
146 log("bool_expr_str = %s", s->data_);
147 ASSERT(str_equals0("bool_expr.Binary", s));
148
149 s = bool_expr_str(b->tag(), false);
150 ASSERT(str_equals0("Binary", s));
151
152 // typed_arith.asdl
153
154 arith_expr_t* c = nullptr;
155 arith_expr_t* big = nullptr;
156 StackRoot _r2(&c);
157 StackRoot _r3(&big);
158
159 c = Alloc<arith_expr__Const>(42);
160 hnode_t* t2 = c->PrettyTree(false);
161 ASSERT_EQ(hnode_e::Record, t2->tag());
162 format::HNodePrettyPrint(t2, f);
163 printf("\n");
164
165 big = Alloc<arith_expr__Big>(mops::BigInt(INT64_MAX));
166 hnode_t* t3 = big->PrettyTree(false);
167 ASSERT_EQ(hnode_e::Record, t3->tag());
168 format::HNodePrettyPrint(t3, f);
169 printf("\n");
170
171 auto* args =
172 NewList<arith_expr_t*>(std::initializer_list<arith_expr_t*>{c, big});
173 auto* func = Alloc<arith_expr::FuncCall>(StrFromC("myfunc"), args);
174 hnode_t* t4 = func->PrettyTree(false);
175 ASSERT_EQ(hnode_e::Record, t4->tag());
176 format::HNodePrettyPrint(t4, f);
177
178 PASS();
179}
180
181TEST dicts_test() {
182 auto m = typed_demo_asdl::Dicts::CreateNull();
183 log("m.ss = %p", m->ss);
184 log("m.ib = %p", m->ib);
185
186 m->ss = Alloc<Dict<BigStr*, BigStr*>>();
187 m->ib = Alloc<Dict<int, bool>>();
188
189 m->ss->set(StrFromC("foo"), StrFromC("bar"));
190
191 m->ib->set(42, true);
192 // note: Dict<int, bool>::get() doesn't compile because nullptr isn't valid
193 // to return. But Dict<int, bool>::index() does compile.
194 log("mm.ib[42] = %d", m->ib->at(42));
195
196 hnode_t* t = m->PrettyTree(false);
197 auto f = mylib::Stdout();
198 // fails with repr(void *)
199 // OK change the pretty printer!
200 format::HNodePrettyPrint(t, f);
201
202 PASS();
203}
204
205using typed_demo_asdl::flag_type;
206using typed_demo_asdl::flag_type__Bool;
207using typed_demo_asdl::SetToArg_;
208
209ObjHeader make_global(ObjHeader header) {
210 header.heap_tag = HeapTag::Global;
211 return header;
212}
213
214// TODO: We should always use these, rather than 'new flag_type::Bool()'
215GcGlobal<flag_type__Bool> g_ft = {make_global(flag_type__Bool::obj_header())};
216
217// Use __ style
218using typed_demo_asdl::cflow__Return;
219GcGlobal<cflow__Return> g_ret = {make_global(cflow__Return::obj_header()), {5}};
220
221int i0 = 7;
222
223// NOTE: This causes an failed assert() in the GC runtime
224#if 0
225List<int>* g_list = NewList<int>({i0, 8, 9});
226#endif
227
228// Dict<BigStr*, int> g_dict = {4, 5, 6};
229
230TEST literal_test() {
231 // Interesting, initializer list part of the constructor "runs". Otherwise
232 // this doesn't work.
233 log("g_ft.tag() = %d", g_ft.obj.tag());
234 auto ft = flag_type::Bool;
235 ASSERT_EQ(g_ft.obj.tag(), ft->tag());
236
237 log("g_ret.tag() = %d", g_ret.obj.tag());
238 log("g_ret.status = %d", g_ret.obj.status);
239 auto ret = Alloc<cflow__Return>(5);
240 ASSERT_EQ(g_ret.obj.tag(), ret->tag());
241 ASSERT_EQ(g_ret.obj.status, ret->status);
242
243#if 0
244 // Wow this works too? Is it the the constexpr interpreter, or is this code
245 // inserted before main()?
246 ASSERT_EQ(3, len(g_list));
247 ASSERT_EQ_FMT(7, g_list->at(0), "%d");
248 ASSERT_EQ_FMT(8, g_list->at(1), "%d");
249 ASSERT_EQ_FMT(9, g_list->at(2), "%d");
250#endif
251
252 PASS();
253}
254
255TEST string_defaults_test() {
256 auto st = Alloc<typed_demo_asdl::Strings>(kEmptyString, kEmptyString);
257 ASSERT_EQ(kEmptyString, st->required);
258 ASSERT_EQ(kEmptyString, st->optional);
259
260 st = typed_demo_asdl::Strings::CreateNull();
261 ASSERT_EQ(kEmptyString, st->required);
262 ASSERT_EQ(nullptr, st->optional);
263
264 st = Alloc<typed_demo_asdl::Strings>(kEmptyString, nullptr);
265 ASSERT_EQ(kEmptyString, st->required);
266 ASSERT_EQ(nullptr, st->optional);
267
268 PASS();
269}
270
271TEST list_defaults_test() {
272 auto o = op_array::CreateNull();
273 ASSERT_EQ(nullptr, o->ops);
274
275 // Empty list
276 auto o2 = op_array::CreateNull(true);
277 ASSERT_EQ(0, len(o2->ops));
278
279 PASS();
280}
281
282GREATEST_MAIN_DEFS();
283
284int main(int argc, char** argv) {
285 gHeap.Init();
286
287 GREATEST_MAIN_BEGIN();
288
289 RUN_TEST(misc_test);
290 RUN_TEST(shared_variant_test);
291 RUN_TEST(pretty_print_test);
292 RUN_TEST(dicts_test);
293 RUN_TEST(literal_test);
294 RUN_TEST(string_defaults_test);
295 RUN_TEST(list_defaults_test);
296
297 gHeap.CleanProcessExit();
298
299 GREATEST_MAIN_END();
300
301 return 0;
302}