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

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