OILS / asdl / gen_cpp_test.cc View on Github | oilshell.org

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