• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "operand_types_print.h"
17 #include "mangling.h"
18 
19 #include <gtest/gtest.h>
20 #include <string>
21 
22 using namespace panda::pandasm;
23 
TEST(parsertests,test1)24 TEST(parsertests, test1)
25 {
26     std::vector<std::vector<panda::pandasm::Token>> v;
27     Lexer l;
28     Parser p;
29     v.push_back(l.TokenizeString(".function u8 main(){").first);
30     v.push_back(l.TokenizeString("mov v1, v2}").first);
31     auto item = p.Parse(v);
32 
33     const auto sig_main = GetFunctionSignatureFromName("main", {});
34 
35     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].opcode, Opcode::MOV);
36     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].regs[0], 1) << "1 expected";
37     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].regs[1], 2) << "2 expected";
38     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
39 }
40 
TEST(parsertests,test2)41 TEST(parsertests, test2)
42 {
43     std::vector<std::vector<panda::pandasm::Token>> v;
44     Lexer l;
45     Parser p;
46     v.push_back(l.TokenizeString(".function u8 main(){").first);
47     v.push_back(l.TokenizeString("label:}").first);
48     auto item = p.Parse(v);
49 
50     const auto sig_main = GetFunctionSignatureFromName("main", {});
51 
52     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].label, "label") << "label expected";
53     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].set_label, true) << "true expected";
54     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].opcode, Opcode::INVALID) << "NONE expected";
55     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
56 }
57 
TEST(parsertests,test3)58 TEST(parsertests, test3)
59 {
60     std::vector<std::vector<panda::pandasm::Token>> v;
61     Lexer l;
62     Parser p;
63     v.push_back(l.TokenizeString(".function u8 main(){").first);
64     v.push_back(l.TokenizeString("jlt v10, lab123}").first);
65     auto item = p.Parse(v);
66     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_LABEL_EXT) << "ERR_BAD_LABEL_EXT expected";
67 }
68 
TEST(parsertests,test4)69 TEST(parsertests, test4)
70 {
71     std::vector<std::vector<panda::pandasm::Token>> v;
72     Lexer l;
73     Parser p;
74     v.push_back(l.TokenizeString(".function u8 main(){").first);
75     v.push_back(l.TokenizeString("11111111}").first);
76     auto item = p.Parse(v);
77     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_OPERATION_NAME) << "ERR_BAD_OPERATION_NAME expected";
78 }
79 
TEST(parsertests,test5)80 TEST(parsertests, test5)
81 {
82     std::vector<std::vector<panda::pandasm::Token>> v;
83     Lexer l;
84     Parser p;
85     v.push_back(l.TokenizeString(".function u8 main(){").first);
86     v.push_back(l.TokenizeString("addi 1}").first);
87     auto item = p.Parse(v);
88 
89     const auto sig_main = GetFunctionSignatureFromName("main", {});
90 
91     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].opcode, Opcode::ADDI) << "IMM expected";
92     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(int64_t(1))) << "1 expected";
93     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
94 }
95 
TEST(parsertests,test6)96 TEST(parsertests, test6)
97 {
98     std::vector<std::vector<panda::pandasm::Token>> v;
99     Lexer l;
100     Parser p;
101     v.push_back(l.TokenizeString(".function u8 main(){").first);
102     v.push_back(l.TokenizeString("addi 12345}").first);
103     auto item = p.Parse(v);
104 
105     const auto sig_main = GetFunctionSignatureFromName("main", {});
106 
107     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].opcode, Opcode::ADDI) << "IMM expected";
108     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(int64_t(12345))) << "12345 expected";
109     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
110 }
111 
TEST(parsertests,test7)112 TEST(parsertests, test7)
113 {
114     std::vector<std::vector<panda::pandasm::Token>> v;
115     Lexer l;
116     Parser p;
117     v.push_back(l.TokenizeString(".function u8 main(){").first);
118     v.push_back(l.TokenizeString("addi 11.3}").first);
119     auto item = p.Parse(v);
120     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_INTEGER_NAME) << "ERR_NONE expected";
121 }
122 
TEST(parsertests,test8)123 TEST(parsertests, test8)
124 {
125     std::vector<std::vector<panda::pandasm::Token>> v;
126     Lexer l;
127     Parser p;
128     v.push_back(l.TokenizeString(".function u8 main(){").first);
129     v.push_back(l.TokenizeString("ashdjbf iashudbfiun as}").first);
130     auto item = p.Parse(v);
131     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_OPERATION_NAME) << "ERR_BAD_OPERATION expected";
132 }
133 
TEST(parsertests,test9)134 TEST(parsertests, test9)
135 {
136     std::vector<std::vector<panda::pandasm::Token>> v;
137     Lexer l;
138     Parser p;
139     v.push_back(l.TokenizeString(".function u8 main(){").first);
140     v.push_back(l.TokenizeString("lda v1").first);
141     v.push_back(l.TokenizeString("movi v10, 1001}").first);
142     auto item = p.Parse(v);
143 
144     const auto sig_main = GetFunctionSignatureFromName("main", {});
145 
146     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].opcode, Opcode::LDA) << "V expected";
147     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].regs[0], 1) << "1 expected";
148     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[1].opcode, Opcode::MOVI) << "V_IMM expected";
149     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[1].regs[0], 10) << "10 expected";
150     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[1].imms[0], Ins::IType(int64_t(1001))) << "1001 expected";
151     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
152 }
153 
TEST(parsertests,test10)154 TEST(parsertests, test10)
155 {
156     std::vector<std::vector<panda::pandasm::Token>> v;
157     Lexer l;
158     Parser p;
159     v.push_back(l.TokenizeString(".function u1 main(){").first);
160     v.push_back(l.TokenizeString("call.short nain, v1, v2}").first);
161     v.push_back(l.TokenizeString(".function u1 nain(){}").first);
162     auto item = p.Parse(v);
163 
164     const auto sig_main = GetFunctionSignatureFromName("main", {});
165     const auto sig_nain = GetFunctionSignatureFromName("nain", {});
166 
167     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].opcode, Opcode::CALL_SHORT) << "V_V_ID expected";
168     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].ids[0], sig_nain) << "nain expected";
169     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].regs[0], 1) << "1 expected";
170     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].regs[1], 2) << "2 expected";
171     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
172 }
173 
TEST(parsertests,test11)174 TEST(parsertests, test11)
175 {
176     std::vector<std::vector<panda::pandasm::Token>> v;
177     Lexer l;
178     Parser p;
179     v.push_back(l.TokenizeString(".function u8 main(){").first);
180     v.push_back(l.TokenizeString("i64tof64}").first);
181     auto item = p.Parse(v);
182 
183     const auto sig_main = GetFunctionSignatureFromName("main", {});
184 
185     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].opcode, Opcode::I64TOF64) << "NONE expected";
186     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
187 }
188 
TEST(parsertests,test12)189 TEST(parsertests, test12)
190 {
191     std::vector<std::vector<panda::pandasm::Token>> v;
192     Lexer l;
193     Parser p;
194     v.push_back(l.TokenizeString(".function u8 main(){").first);
195     v.push_back(l.TokenizeString("jmp l123}").first);
196     auto item = p.Parse(v);
197     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_LABEL_EXT) << "ERR_BAD_LABEL_EXT expected";
198 }
199 
TEST(parsertests,test13)200 TEST(parsertests, test13)
201 {
202     std::vector<std::vector<panda::pandasm::Token>> v;
203     Lexer l;
204     Parser p;
205     v.push_back(l.TokenizeString(".function u8 main(){").first);
206     v.push_back(l.TokenizeString("l123: jmp l123}").first);
207     auto item = p.Parse(v);
208 
209     const auto sig_main = GetFunctionSignatureFromName("main", {});
210 
211     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].opcode, Opcode::JMP) << "ID expected";
212     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].ids[0], "l123") << "l123 expected";
213     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE";
214 }
215 
TEST(parsertests,test14)216 TEST(parsertests, test14)
217 {
218     std::vector<std::vector<panda::pandasm::Token>> v;
219     Lexer l;
220     Parser p;
221     v.push_back(l.TokenizeString(".function u8 main(){").first);
222     v.push_back(l.TokenizeString("jmp 123}").first);
223     auto item = p.Parse(v);
224     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NAME_ID) << "ERR_BAD_NAME_ID expected";
225 }
226 
TEST(parsertests,test15)227 TEST(parsertests, test15)
228 {
229     std::vector<std::vector<panda::pandasm::Token>> v;
230     Lexer l;
231     Parser p;
232     v.push_back(l.TokenizeString(".function u8 main(){").first);
233     v.push_back(l.TokenizeString("shli 12 asd}").first);
234     auto item = p.Parse(v);
235     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NUMBER_OPERANDS) << "ERR_BAD_NUMBER_OPERANDS expected";
236 }
237 
TEST(parsertests,test17)238 TEST(parsertests, test17)
239 {
240     std::vector<std::vector<panda::pandasm::Token>> v;
241     Lexer l;
242     Parser p;
243     v.push_back(l.TokenizeString(".function u8 main(){").first);
244     v.push_back(l.TokenizeString("ldarr.8 v120}").first);
245     auto item = p.Parse(v);
246 
247     const auto sig_main = GetFunctionSignatureFromName("main", {});
248 
249     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].opcode, Opcode::LDARR_8) << "V expected";
250     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].regs[0], 120) << "120 expected";
251     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
252 }
253 
TEST(parsertests,test18)254 TEST(parsertests, test18)
255 {
256     std::vector<std::vector<panda::pandasm::Token>> v;
257     Lexer l;
258     Parser p;
259     v.push_back(l.TokenizeString(".function u8 main(){").first);
260     v.push_back(l.TokenizeString("return}").first);
261     auto item = p.Parse(v);
262 
263     const auto sig_main = GetFunctionSignatureFromName("main", {});
264 
265     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].opcode, Opcode::RETURN) << "NONE expected";
266     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
267 }
268 
TEST(parsertests,test19)269 TEST(parsertests, test19)
270 {
271     std::vector<std::vector<panda::pandasm::Token>> v;
272     Lexer l;
273     Parser p;
274     v.push_back(l.TokenizeString(".function u8 main(){").first);
275     v.push_back(l.TokenizeString("return1}").first);
276     auto item = p.Parse(v);
277     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_OPERATION_NAME) << "ERR_BAD_OPERATION expected";
278 }
279 
TEST(parsertests,test20)280 TEST(parsertests, test20)
281 {
282     std::vector<std::vector<panda::pandasm::Token>> v;
283     Lexer l;
284     Parser p;
285     v.push_back(l.TokenizeString(".function u8 main(){").first);
286     v.push_back(l.TokenizeString("return 1}").first);
287     auto item = p.Parse(v);
288     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NUMBER_OPERANDS) << "ERR_BAD_NUMBER_OPERANDS expected";
289 }
290 
TEST(parsertests,test21)291 TEST(parsertests, test21)
292 {
293     std::vector<std::vector<panda::pandasm::Token>> v;
294     Lexer l;
295     Parser p;
296     v.push_back(l.TokenizeString(".function u8 main(){").first);
297     v.push_back(l.TokenizeString("ashr2.64 1234}").first);
298     auto item = p.Parse(v);
299     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NAME_REG) << "ERR_BAD_NAME_REG expected";
300 }
301 
TEST(parsertests,test22)302 TEST(parsertests, test22)
303 {
304     std::vector<std::vector<panda::pandasm::Token>> v;
305     Lexer l;
306     Parser p;
307     v.push_back(l.TokenizeString(".function u8 main(){").first);
308     v.push_back(l.TokenizeString("ashr2.64 v12}").first);
309     auto item = p.Parse(v);
310 
311     const auto sig_main = GetFunctionSignatureFromName("main", {});
312 
313     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].opcode, Opcode::ASHR2_64) << "V expected";
314     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
315     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].regs[0], 12) << "12 expected";
316 }
317 
TEST(parsertests,test23)318 TEST(parsertests, test23)
319 {
320     std::vector<std::vector<panda::pandasm::Token>> v;
321     Lexer l;
322     Parser p;
323     v.push_back(l.TokenizeString(".function u8 main(){").first);
324     v.push_back(l.TokenizeString("label1:").first);
325     v.push_back(l.TokenizeString("jle v0, label2").first);
326     v.push_back(l.TokenizeString("movi v15, 26").first);
327     v.push_back(l.TokenizeString("label2: mov v0, v1").first);
328     v.push_back(l.TokenizeString("call m123, v2, v6, v3, v4").first);
329     v.push_back(l.TokenizeString("}").first);
330     v.push_back(l.TokenizeString(".function f64 m123(u1 a0, f32 a1){").first);
331     v.push_back(l.TokenizeString("lda v10").first);
332     v.push_back(l.TokenizeString("sta a0").first);
333     v.push_back(l.TokenizeString("la1:").first);
334     v.push_back(l.TokenizeString("jle a1, la1").first);
335     v.push_back(l.TokenizeString("}").first);
336 
337     auto item = p.Parse(v);
338 
339     const auto sig_main = GetFunctionSignatureFromName("main", {});
340     std::vector<Function::Parameter> params;
341     panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
342     params.emplace_back(Type {"u1", 0}, language);
343     params.emplace_back(Type {"f32", 0}, language);
344     const auto sig_m123 = GetFunctionSignatureFromName("m123", params);
345 
346     ASSERT_EQ(item.Value().function_table.at(sig_main).name, sig_main);
347     ASSERT_EQ(item.Value().function_table.at(sig_m123).name, sig_m123);
348     ASSERT_EQ(item.Value().function_table.at(sig_main).GetParamsNum(), 0U);
349     ASSERT_EQ(item.Value().function_table.at(sig_m123).GetParamsNum(), 2U);
350     ASSERT_EQ(item.Value().function_table.at(sig_m123).params[0].type.GetId(), panda::panda_file::Type::TypeId::U1);
351     ASSERT_EQ(item.Value().function_table.at(sig_m123).params[1].type.GetId(), panda::panda_file::Type::TypeId::F32);
352     ASSERT_EQ(item.Value().function_table.at(sig_main).return_type.GetId(), panda::panda_file::Type::TypeId::U8);
353     ASSERT_EQ(item.Value().function_table.at(sig_m123).return_type.GetId(), panda::panda_file::Type::TypeId::F64);
354     ASSERT_EQ(item.Value().function_table.at(sig_main).label_table.at("label1").file_location->line_number, 2U);
355     ASSERT_EQ(item.Value().function_table.at(sig_main).label_table.at("label1").file_location->is_defined, true);
356     ASSERT_EQ(item.Value().function_table.at(sig_main).label_table.at("label2").file_location->line_number, 3U);
357     ASSERT_EQ(item.Value().function_table.at(sig_main).label_table.at("label2").file_location->is_defined, true);
358     ASSERT_EQ(item.Value().function_table.at(sig_m123).label_table.at("la1").file_location->line_number, 11U);
359     ASSERT_EQ(item.Value().function_table.at(sig_m123).label_table.at("la1").file_location->is_defined, true);
360     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].opcode, Opcode::INVALID);
361     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].label, "label1");
362     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[1].opcode, Opcode::JLE);
363     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[1].regs[0], 0);
364     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[1].ids[0], "label2");
365     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[2].opcode, Opcode::MOVI);
366     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[2].regs[0], 15);
367     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[2].imms[0], Ins::IType(int64_t(26)));
368     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[2].set_label, false);
369     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[3].opcode, Opcode::MOV);
370     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[3].regs[0], 0);
371     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[3].regs[1], 1);
372     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[3].label, "label2");
373     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[3].set_label, true);
374     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[4].opcode, Opcode::CALL);
375     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[4].regs[0], 2);
376     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[4].regs[1], 6);
377     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[4].regs[2], 3);
378     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[4].regs[3], 4);
379     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[4].ids[0], sig_m123);
380     ASSERT_EQ(item.Value().function_table.at(sig_m123).ins[0].opcode, Opcode::LDA);
381     ASSERT_EQ(item.Value().function_table.at(sig_m123).ins[0].regs[0], 10);
382     ASSERT_EQ(item.Value().function_table.at(sig_m123).ins[1].opcode, Opcode::STA);
383     ASSERT_EQ(item.Value().function_table.at(sig_m123).ins[1].regs[0], 11);
384     ASSERT_EQ(item.Value().function_table.at(sig_m123).ins[2].opcode, Opcode::INVALID);
385     ASSERT_EQ(item.Value().function_table.at(sig_m123).ins[2].label, "la1");
386     ASSERT_EQ(item.Value().function_table.at(sig_m123).ins[2].set_label, true);
387     ASSERT_EQ(item.Value().function_table.at(sig_m123).ins[3].opcode, Opcode::JLE);
388     ASSERT_EQ(item.Value().function_table.at(sig_m123).ins[3].regs[0], 12);
389     ASSERT_EQ(item.Value().function_table.at(sig_m123).ins[3].ids[0], "la1");
390     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
391 }
392 
TEST(parsertests,test24_functions)393 TEST(parsertests, test24_functions)
394 {
395     std::vector<std::vector<panda::pandasm::Token>> v;
396     Lexer l;
397     Parser p;
398     v.push_back(l.TokenizeString(".function void main()").first);
399     v.push_back(l.TokenizeString("{").first);
400     v.push_back(l.TokenizeString("movi v0, 0x100").first);
401     v.push_back(l.TokenizeString("movi v15, 0xffffffff").first);
402     v.push_back(l.TokenizeString("movi v15, 0xf").first);
403     v.push_back(l.TokenizeString("fmovi.64 v15, 1e3").first);
404     v.push_back(l.TokenizeString("movi v15, 0xE994").first);
405     v.push_back(l.TokenizeString("fmovi.64 v15, 1.1").first);
406     v.push_back(l.TokenizeString("fmovi.64 v15, 1.").first);
407     v.push_back(l.TokenizeString("fmovi.64 v15, .1").first);
408     v.push_back(l.TokenizeString("movi v15, 0").first);
409     v.push_back(l.TokenizeString("fmovi.64 v15, 0.1").first);
410     v.push_back(l.TokenizeString("fmovi.64 v15, 00.1").first);
411     v.push_back(l.TokenizeString("fmovi.64 v15, 00.").first);
412     v.push_back(l.TokenizeString("}").first);
413     v.push_back(l.TokenizeString(".function u8 niam(){").first);
414     v.push_back(l.TokenizeString("ldai -1").first);
415     v.push_back(l.TokenizeString("}").first);
416 
417     auto item = p.Parse(v);
418 
419     const auto sig_main = GetFunctionSignatureFromName("main", {});
420     const auto sig_niam = GetFunctionSignatureFromName("niam", {});
421 
422     ASSERT_EQ(item.Value().function_table.at(sig_main).return_type.GetId(), panda::panda_file::Type::TypeId::VOID);
423     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(int64_t(256))) << "256 expected";
424     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[1].imms[0], Ins::IType(int64_t(4294967295)))
425         << "4294967295 expected";
426     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[2].imms[0], Ins::IType(int64_t(15))) << "15 expected";
427     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[3].imms[0], Ins::IType(1000.0)) << "1000.0 expected";
428     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[4].imms[0], Ins::IType(int64_t(59796))) << "59796 expected";
429     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[5].imms[0], Ins::IType(1.1)) << "1.1 expected";
430     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[7].imms[0], Ins::IType(.1)) << ".1 expected";
431     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[8].imms[0], Ins::IType(int64_t(0))) << "0 expected";
432     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[9].imms[0], Ins::IType(0.1)) << "0.1 expected";
433     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[10].imms[0], Ins::IType(00.1)) << "00.1 expected";
434     ASSERT_EQ(item.Value().function_table.at(sig_main).ins[11].imms[0], Ins::IType(00.)) << "00. expected";
435     ASSERT_EQ(item.Value().function_table.at(sig_niam).ins[0].imms[0], Ins::IType(int64_t(-1))) << "-1 expected";
436 }
437 
TEST(parsertests,test25_record_alone)438 TEST(parsertests, test25_record_alone)
439 {
440     std::vector<std::vector<panda::pandasm::Token>> v;
441     Lexer l;
442     Parser p;
443     v.push_back(l.TokenizeString(".record Asm {").first);
444     v.push_back(l.TokenizeString("i64 asm1").first);
445     v.push_back(l.TokenizeString("void asm2").first);
446     v.push_back(l.TokenizeString("i32 asm3").first);
447     v.push_back(l.TokenizeString("}").first);
448     auto item = p.Parse(v);
449     ASSERT_EQ(item.Value().record_table.at("Asm").name, "Asm");
450     ASSERT_EQ(item.Value().record_table.at("Asm").field_list[0].name, "asm1");
451     ASSERT_EQ(item.Value().record_table.at("Asm").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
452     ASSERT_EQ(item.Value().record_table.at("Asm").field_list[1].name, "asm2");
453     ASSERT_EQ(item.Value().record_table.at("Asm").field_list[1].type.GetId(), panda::panda_file::Type::TypeId::VOID);
454     ASSERT_EQ(item.Value().record_table.at("Asm").field_list[2].name, "asm3");
455     ASSERT_EQ(item.Value().record_table.at("Asm").field_list[2].type.GetId(), panda::panda_file::Type::TypeId::I32);
456 }
457 
TEST(parsertests,test26_records)458 TEST(parsertests, test26_records)
459 {
460     std::vector<std::vector<panda::pandasm::Token>> v;
461     Lexer l;
462     Parser p;
463 
464     v.push_back(l.TokenizeString(".record Asm1 {").first);
465     v.push_back(l.TokenizeString("i64 asm1").first);
466     v.push_back(l.TokenizeString("void asm2").first);
467     v.push_back(l.TokenizeString("i32 asm3").first);
468     v.push_back(l.TokenizeString("}").first);
469     v.push_back(l.TokenizeString(".record Asm2 {").first);
470     v.push_back(l.TokenizeString("i64 asm1").first);
471     v.push_back(l.TokenizeString("void asm2").first);
472     v.push_back(l.TokenizeString("i32 asm3 }").first);
473     v.push_back(l.TokenizeString(".record Asm3").first);
474     v.push_back(l.TokenizeString("{").first);
475     v.push_back(l.TokenizeString("i64 asm1").first);
476     v.push_back(l.TokenizeString("void asm2").first);
477     v.push_back(l.TokenizeString("i32 asm3").first);
478     v.push_back(l.TokenizeString("}").first);
479     v.push_back(l.TokenizeString(".record Asm4 { i32 asm1 }").first);
480     v.push_back(l.TokenizeString(".record Asm5 { i32 asm1").first);
481     v.push_back(l.TokenizeString("}").first);
482 
483     auto item = p.Parse(v);
484 
485     ASSERT_EQ(item.Value().record_table.at("Asm1").name, "Asm1");
486     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[0].name, "asm1");
487     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
488     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[1].name, "asm2");
489     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[1].type.GetId(), panda::panda_file::Type::TypeId::VOID);
490     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[2].name, "asm3");
491     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[2].type.GetId(), panda::panda_file::Type::TypeId::I32);
492     ASSERT_EQ(item.Value().record_table.at("Asm2").name, "Asm2");
493     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[0].name, "asm1");
494     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
495     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[1].name, "asm2");
496     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[1].type.GetId(), panda::panda_file::Type::TypeId::VOID);
497     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[2].name, "asm3");
498     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[2].type.GetId(), panda::panda_file::Type::TypeId::I32);
499     ASSERT_EQ(item.Value().record_table.at("Asm3").name, "Asm3");
500     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[0].name, "asm1");
501     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
502     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[1].name, "asm2");
503     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[1].type.GetId(), panda::panda_file::Type::TypeId::VOID);
504     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[2].name, "asm3");
505     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[2].type.GetId(), panda::panda_file::Type::TypeId::I32);
506     ASSERT_EQ(item.Value().record_table.at("Asm4").field_list[0].name, "asm1");
507     ASSERT_EQ(item.Value().record_table.at("Asm4").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I32);
508     ASSERT_EQ(item.Value().record_table.at("Asm5").field_list[0].name, "asm1");
509     ASSERT_EQ(item.Value().record_table.at("Asm5").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I32);
510 }
511 
TEST(parsertests,test27_record_and_function)512 TEST(parsertests, test27_record_and_function)
513 {
514     std::vector<std::vector<panda::pandasm::Token>> v;
515     Lexer l;
516     Parser p;
517 
518     v.push_back(l.TokenizeString(".record Asm1 {").first);
519     v.push_back(l.TokenizeString("i64 asm1").first);
520     v.push_back(l.TokenizeString("void asm2").first);
521     v.push_back(l.TokenizeString("i32 asm3").first);
522     v.push_back(l.TokenizeString("}").first);
523     v.push_back(l.TokenizeString(".function u8 niam(){").first);
524     v.push_back(l.TokenizeString("ldai -1").first);
525     v.push_back(l.TokenizeString("}").first);
526 
527     auto item = p.Parse(v);
528 
529     const auto sig_niam = GetFunctionSignatureFromName("niam", {});
530 
531     ASSERT_EQ(item.Value().record_table.at("Asm1").name, "Asm1");
532     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[0].name, "asm1");
533     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
534     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[1].name, "asm2");
535     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[1].type.GetId(), panda::panda_file::Type::TypeId::VOID);
536     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[2].name, "asm3");
537     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[2].type.GetId(), panda::panda_file::Type::TypeId::I32);
538     ASSERT_EQ(item.Value().function_table.at(sig_niam).ins[0].imms[0], Ins::IType(int64_t(-1))) << "-1 expected";
539 }
540 
TEST(parsertests,test28_records_and_functions)541 TEST(parsertests, test28_records_and_functions)
542 {
543     std::vector<std::vector<panda::pandasm::Token>> v;
544     Lexer l;
545     Parser p;
546 
547     v.push_back(l.TokenizeString(".record Asm1 {").first);
548     v.push_back(l.TokenizeString("i64 asm1").first);
549     v.push_back(l.TokenizeString("void asm2").first);
550     v.push_back(l.TokenizeString("i32 asm3").first);
551     v.push_back(l.TokenizeString("}").first);
552 
553     v.push_back(l.TokenizeString(".function u8 niam1(){").first);
554     v.push_back(l.TokenizeString("ldai -1").first);
555     v.push_back(l.TokenizeString("}").first);
556 
557     v.push_back(l.TokenizeString(".record Asm2 {").first);
558     v.push_back(l.TokenizeString("i64 asm1").first);
559     v.push_back(l.TokenizeString("void asm2").first);
560     v.push_back(l.TokenizeString("i32 asm3").first);
561     v.push_back(l.TokenizeString("}").first);
562 
563     v.push_back(l.TokenizeString(".function u8 niam2(){").first);
564     v.push_back(l.TokenizeString("ldai -1").first);
565     v.push_back(l.TokenizeString("}").first);
566 
567     v.push_back(l.TokenizeString(".record Asm3 {").first);
568     v.push_back(l.TokenizeString("i64 asm1").first);
569     v.push_back(l.TokenizeString("void asm2").first);
570     v.push_back(l.TokenizeString("i32 asm3").first);
571     v.push_back(l.TokenizeString("}").first);
572 
573     v.push_back(l.TokenizeString(".function u8 niam3(){").first);
574     v.push_back(l.TokenizeString("ldai -1").first);
575     v.push_back(l.TokenizeString("}").first);
576 
577     auto item = p.Parse(v);
578 
579     const auto sig_niam1 = GetFunctionSignatureFromName("niam1", {});
580     const auto sig_niam2 = GetFunctionSignatureFromName("niam2", {});
581     const auto sig_niam3 = GetFunctionSignatureFromName("niam3", {});
582 
583     ASSERT_EQ(item.Value().record_table.at("Asm1").name, "Asm1");
584     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[0].name, "asm1");
585     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
586     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[1].name, "asm2");
587     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[1].type.GetId(), panda::panda_file::Type::TypeId::VOID);
588     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[2].name, "asm3");
589     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[2].type.GetId(), panda::panda_file::Type::TypeId::I32);
590 
591     ASSERT_EQ(item.Value().function_table.at(sig_niam1).ins[0].imms[0], Ins::IType(int64_t(-1))) << "-1 expected";
592 
593     ASSERT_EQ(item.Value().record_table.at("Asm2").name, "Asm2");
594     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[0].name, "asm1");
595     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
596     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[1].name, "asm2");
597     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[1].type.GetId(), panda::panda_file::Type::TypeId::VOID);
598     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[2].name, "asm3");
599     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[2].type.GetId(), panda::panda_file::Type::TypeId::I32);
600 
601     ASSERT_EQ(item.Value().function_table.at(sig_niam2).ins[0].imms[0], Ins::IType(int64_t(-1))) << "-1 expected";
602 
603     ASSERT_EQ(item.Value().record_table.at("Asm3").name, "Asm3");
604     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[0].name, "asm1");
605     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
606     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[1].name, "asm2");
607     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[1].type.GetId(), panda::panda_file::Type::TypeId::VOID);
608     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[2].name, "asm3");
609     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[2].type.GetId(), panda::panda_file::Type::TypeId::I32);
610 
611     ASSERT_EQ(item.Value().function_table.at(sig_niam3).ins[0].imms[0], Ins::IType(int64_t(-1))) << "-1 expected";
612 }
613 
TEST(parsertests,test29_instructions_def_lines)614 TEST(parsertests, test29_instructions_def_lines)
615 {
616     std::vector<std::vector<panda::pandasm::Token>> v;
617     Lexer l;
618     Parser p;
619 
620     v.push_back(l.TokenizeString(".function u8 niam1(){").first);
621     v.push_back(l.TokenizeString("ldai -1").first);
622     v.push_back(l.TokenizeString("}").first);
623 
624     v.push_back(l.TokenizeString(".function u8 niam2(){").first);
625     v.push_back(l.TokenizeString("ldai -1").first);
626     v.push_back(l.TokenizeString("}").first);
627 
628     v.push_back(l.TokenizeString(".function u8 niam3()").first);
629     v.push_back(l.TokenizeString("{").first);
630     v.push_back(l.TokenizeString("ldai -1").first);
631     v.push_back(l.TokenizeString("}").first);
632 
633     v.push_back(l.TokenizeString(".function u8 niam4(){ldai -1}").first);
634 
635     v.push_back(l.TokenizeString(".function u8 niam5(){ldai -1").first);
636     v.push_back(l.TokenizeString("}").first);
637 
638     auto item = p.Parse(v);
639 
640     const auto sig_niam1 = GetFunctionSignatureFromName("niam1", {});
641     const auto sig_niam2 = GetFunctionSignatureFromName("niam2", {});
642     const auto sig_niam3 = GetFunctionSignatureFromName("niam3", {});
643     const auto sig_niam4 = GetFunctionSignatureFromName("niam4", {});
644     const auto sig_niam5 = GetFunctionSignatureFromName("niam5", {});
645 
646     ASSERT_EQ(item.Value().function_table.at(sig_niam1).ins[0].ins_debug.line_number, 2U) << "2 expected";
647     ASSERT_EQ(item.Value().function_table.at(sig_niam2).ins[0].ins_debug.line_number, 5U) << "5 expected";
648     ASSERT_EQ(item.Value().function_table.at(sig_niam3).ins[0].ins_debug.line_number, 9U) << "9 expected";
649     ASSERT_EQ(item.Value().function_table.at(sig_niam4).ins[0].ins_debug.line_number, 11U) << "11 expected";
650     ASSERT_EQ(item.Value().function_table.at(sig_niam5).ins[0].ins_debug.line_number, 12U) << "12 expected";
651 }
652 
TEST(parsertests,test30_fields_def_lines)653 TEST(parsertests, test30_fields_def_lines)
654 {
655     std::vector<std::vector<panda::pandasm::Token>> v;
656     Lexer l;
657     Parser p;
658 
659     v.push_back(l.TokenizeString(".record Asm1 {").first);
660     v.push_back(l.TokenizeString("i64 asm1").first);
661     v.push_back(l.TokenizeString("void asm2").first);
662     v.push_back(l.TokenizeString("i32 asm3").first);
663     v.push_back(l.TokenizeString("}").first);
664 
665     v.push_back(l.TokenizeString(".record Asm2 {").first);
666     v.push_back(l.TokenizeString("i64 asm1").first);
667     v.push_back(l.TokenizeString("void asm2").first);
668     v.push_back(l.TokenizeString("i32 asm3 }").first);
669 
670     v.push_back(l.TokenizeString(".record Asm3").first);
671     v.push_back(l.TokenizeString("{").first);
672     v.push_back(l.TokenizeString("i64 asm1").first);
673     v.push_back(l.TokenizeString("void asm2").first);
674     v.push_back(l.TokenizeString("i32 asm3").first);
675     v.push_back(l.TokenizeString("}").first);
676 
677     v.push_back(l.TokenizeString(".record Asm4 { i32 asm1 }").first);
678 
679     v.push_back(l.TokenizeString(".record Asm5 { i32 asm1").first);
680     v.push_back(l.TokenizeString("}").first);
681 
682     auto item = p.Parse(v);
683 
684     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[0].line_of_def, 2U);
685     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[1].line_of_def, 3U);
686     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[2].line_of_def, 4U);
687 
688     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[0].line_of_def, 7U);
689     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[1].line_of_def, 8U);
690     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[2].line_of_def, 9U);
691 
692     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[0].line_of_def, 12U);
693     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[1].line_of_def, 13U);
694     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[2].line_of_def, 14U);
695 
696     ASSERT_EQ(item.Value().record_table.at("Asm4").field_list[0].line_of_def, 16U);
697 
698     ASSERT_EQ(item.Value().record_table.at("Asm5").field_list[0].line_of_def, 17U);
699 }
700 
TEST(parsertests,test31_own_types)701 TEST(parsertests, test31_own_types)
702 {
703     std::vector<std::vector<panda::pandasm::Token>> v;
704     Lexer l;
705     Parser p;
706 
707     v.push_back(l.TokenizeString(".record Asm {").first);
708     v.push_back(l.TokenizeString("i64 asm1").first);
709     v.push_back(l.TokenizeString("void asm2").first);
710     v.push_back(l.TokenizeString("i32 asm3").first);
711     v.push_back(l.TokenizeString("}").first);
712 
713     v.push_back(l.TokenizeString(".record Asm1 {").first);
714     v.push_back(l.TokenizeString("Asm asm1").first);
715     v.push_back(l.TokenizeString("void asm2").first);
716     v.push_back(l.TokenizeString("i32 asm3 }").first);
717 
718     v.push_back(l.TokenizeString(".record Asm2 { Asm1 asm1 }").first);
719 
720     v.push_back(l.TokenizeString(".record Asm3 { Asm2 asm1").first);
721     v.push_back(l.TokenizeString("}").first);
722 
723     auto item = p.Parse(v);
724 
725     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[0].type.GetName(), "Asm");
726     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[1].type.GetId(), panda::panda_file::Type::TypeId::VOID);
727     ASSERT_EQ(item.Value().record_table.at("Asm1").field_list[2].type.GetId(), panda::panda_file::Type::TypeId::I32);
728 
729     ASSERT_EQ(item.Value().record_table.at("Asm2").field_list[0].type.GetName(), "Asm1");
730 
731     ASSERT_EQ(item.Value().record_table.at("Asm3").field_list[0].type.GetName(), "Asm2");
732 }
733 
TEST(parsertests,test32_names)734 TEST(parsertests, test32_names)
735 {
736     ASSERT_EQ(GetOwnerName("Asm.main"), "Asm");
737 
738     ASSERT_EQ(GetOwnerName("main"), "");
739 
740     ASSERT_EQ(GetItemName("Asm.main"), "main");
741 
742     ASSERT_EQ(GetItemName("main"), "main");
743 }
744 
TEST(parsertests,test33_params_number)745 TEST(parsertests, test33_params_number)
746 {
747     std::vector<std::vector<panda::pandasm::Token>> v;
748     Lexer l;
749     Parser p;
750 
751     v.push_back(l.TokenizeString(".function u8 niam1(){").first);
752     v.push_back(l.TokenizeString("ldai -1").first);
753     v.push_back(l.TokenizeString("}").first);
754 
755     v.push_back(l.TokenizeString(".function u8 niam2(u1 a0, i64 a1, i32 a2){").first);
756     v.push_back(l.TokenizeString("mov v0, v3").first);
757     v.push_back(l.TokenizeString("}").first);
758 
759     auto item = p.Parse(v);
760 
761     const auto sig_niam1 = GetFunctionSignatureFromName("niam1", {});
762     std::vector<Function::Parameter> params;
763     panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
764     params.emplace_back(Type {"u1", 0}, language);
765     params.emplace_back(Type {"i64", 0}, language);
766     params.emplace_back(Type {"i32", 0}, language);
767     const auto sig_niam2 = GetFunctionSignatureFromName("niam2", params);
768 
769     ASSERT_EQ(item.Value().function_table.at(sig_niam1).GetParamsNum(), 0U);
770     ASSERT_EQ(item.Value().function_table.at(sig_niam1).value_of_first_param + 1, 0);
771 
772     ASSERT_EQ(item.Value().function_table.at(sig_niam2).GetParamsNum(), 3U);
773     ASSERT_EQ(item.Value().function_table.at(sig_niam2).value_of_first_param + 1, 4);
774 }
775 
TEST(parsertests,test34_vregs_number)776 TEST(parsertests, test34_vregs_number)
777 {
778     std::vector<std::vector<panda::pandasm::Token>> v;
779     Lexer l;
780     Parser p;
781 
782     v.push_back(l.TokenizeString(".function u8 niam1(){").first);
783     v.push_back(l.TokenizeString("ldai -1").first);
784     v.push_back(l.TokenizeString("}").first);
785 
786     v.push_back(l.TokenizeString(".function u8 niam2(u1 a0, i64 a1, i32 a2){").first);
787     v.push_back(l.TokenizeString("mov v0, v5").first);
788     v.push_back(l.TokenizeString("}").first);
789 
790     auto item = p.Parse(v);
791 
792     const auto sig_niam1 = GetFunctionSignatureFromName("niam1", {});
793     std::vector<Function::Parameter> params;
794     panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
795     params.emplace_back(Type {"u1", 0}, language);
796     params.emplace_back(Type {"i64", 0}, language);
797     params.emplace_back(Type {"i32", 0}, language);
798     const auto sig_niam2 = GetFunctionSignatureFromName("niam2", params);
799 
800     ASSERT_EQ(item.Value().function_table.at(sig_niam1).regs_num, 0U);
801 
802     ASSERT_EQ(item.Value().function_table.at(sig_niam2).regs_num, 6U);
803 }
804 
TEST(parsertests,test35_functions_bracket)805 TEST(parsertests, test35_functions_bracket)
806 {
807     std::vector<std::vector<panda::pandasm::Token>> v;
808     Lexer l;
809     Parser p;
810     v.push_back(l.TokenizeString(".function u1 nain1(i64 a0) <> {").first);
811     v.push_back(l.TokenizeString("mov v0, a0").first);
812     v.push_back(l.TokenizeString("}").first);
813 
814     v.push_back(l.TokenizeString(".function u1 nain2(i64 a0) <> {   mov v0, a0}").first);
815     v.push_back(l.TokenizeString(".function u1 nain3(i64 a0) <> {    mov v0, a0").first);
816     v.push_back(l.TokenizeString("}").first);
817 
818     v.push_back(l.TokenizeString(".function u1 nain4(i64 a0) ").first);
819     v.push_back(l.TokenizeString("{").first);
820     v.push_back(l.TokenizeString("mov v0, a0").first);
821     v.push_back(l.TokenizeString("}").first);
822 
823     v.push_back(l.TokenizeString(".function u1 nain5(i64 a0) <>{").first);
824     v.push_back(l.TokenizeString("mov v0, a0}").first);
825 
826     v.push_back(l.TokenizeString(".function u1 nain6(i64 a0) <>").first);
827     v.push_back(l.TokenizeString("{").first);
828     v.push_back(l.TokenizeString("mov v0, a0}").first);
829 
830     v.push_back(l.TokenizeString(".function u1 nain7(i64 a0) <> {").first);
831     v.push_back(l.TokenizeString("mov v0, a0").first);
832     v.push_back(l.TokenizeString("}").first);
833 
834     v.push_back(l.TokenizeString(".function u1 nain8(i64 a0) {   mov v0, a0}").first);
835     v.push_back(l.TokenizeString(".function u1 nain9(i64 a0) {    mov v0, a0").first);
836     v.push_back(l.TokenizeString("}").first);
837 
838     v.push_back(l.TokenizeString(".function u1 nain10(i64 a0) <>").first);
839     v.push_back(l.TokenizeString("{").first);
840     v.push_back(l.TokenizeString("mov v0, a0").first);
841     v.push_back(l.TokenizeString("}").first);
842 
843     v.push_back(l.TokenizeString(".function u1 nain11(i64 a0) {").first);
844     v.push_back(l.TokenizeString("mov v0, a0}").first);
845 
846     v.push_back(l.TokenizeString(".function u1 nain12(i64 a0)").first);
847     v.push_back(l.TokenizeString("{").first);
848     v.push_back(l.TokenizeString("mov v0, a0}").first);
849 
850     auto item = p.Parse(v);
851 
852     std::vector<Function::Parameter> params;
853     panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
854     params.emplace_back(Type {"i64", 0}, language);
855     const auto sig_nain1 = GetFunctionSignatureFromName("nain1", params);
856     const auto sig_nain2 = GetFunctionSignatureFromName("nain2", params);
857     const auto sig_nain3 = GetFunctionSignatureFromName("nain3", params);
858     const auto sig_nain4 = GetFunctionSignatureFromName("nain4", params);
859     const auto sig_nain5 = GetFunctionSignatureFromName("nain5", params);
860     const auto sig_nain6 = GetFunctionSignatureFromName("nain6", params);
861     const auto sig_nain7 = GetFunctionSignatureFromName("nain7", params);
862     const auto sig_nain8 = GetFunctionSignatureFromName("nain8", params);
863     const auto sig_nain9 = GetFunctionSignatureFromName("nain9", params);
864     const auto sig_nain10 = GetFunctionSignatureFromName("nain10", params);
865     const auto sig_nain11 = GetFunctionSignatureFromName("nain11", params);
866     const auto sig_nain12 = GetFunctionSignatureFromName("nain12", params);
867 
868     ASSERT_EQ(item.Value().function_table.at(sig_nain1).name, sig_nain1);
869     ASSERT_EQ(item.Value().function_table.at(sig_nain12).name, sig_nain12);
870     ASSERT_EQ(item.Value().function_table.at(sig_nain3).name, sig_nain3);
871     ASSERT_EQ(item.Value().function_table.at(sig_nain2).name, sig_nain2);
872     ASSERT_EQ(item.Value().function_table.at(sig_nain4).name, sig_nain4);
873     ASSERT_EQ(item.Value().function_table.at(sig_nain5).name, sig_nain5);
874     ASSERT_EQ(item.Value().function_table.at(sig_nain6).name, sig_nain6);
875     ASSERT_EQ(item.Value().function_table.at(sig_nain7).name, sig_nain7);
876     ASSERT_EQ(item.Value().function_table.at(sig_nain8).name, sig_nain8);
877     ASSERT_EQ(item.Value().function_table.at(sig_nain9).name, sig_nain9);
878     ASSERT_EQ(item.Value().function_table.at(sig_nain10).name, sig_nain10);
879     ASSERT_EQ(item.Value().function_table.at(sig_nain11).name, sig_nain11);
880 
881     ASSERT_EQ(item.Value().function_table.at(sig_nain1).ins[0].opcode, Opcode::MOV);
882     ASSERT_EQ(item.Value().function_table.at(sig_nain2).ins[0].opcode, Opcode::MOV);
883     ASSERT_EQ(item.Value().function_table.at(sig_nain3).ins[0].opcode, Opcode::MOV);
884     ASSERT_EQ(item.Value().function_table.at(sig_nain4).ins[0].opcode, Opcode::MOV);
885     ASSERT_EQ(item.Value().function_table.at(sig_nain5).ins[0].opcode, Opcode::MOV);
886     ASSERT_EQ(item.Value().function_table.at(sig_nain6).ins[0].opcode, Opcode::MOV);
887     ASSERT_EQ(item.Value().function_table.at(sig_nain7).ins[0].opcode, Opcode::MOV);
888     ASSERT_EQ(item.Value().function_table.at(sig_nain8).ins[0].opcode, Opcode::MOV);
889     ASSERT_EQ(item.Value().function_table.at(sig_nain9).ins[0].opcode, Opcode::MOV);
890     ASSERT_EQ(item.Value().function_table.at(sig_nain10).ins[0].opcode, Opcode::MOV);
891     ASSERT_EQ(item.Value().function_table.at(sig_nain11).ins[0].opcode, Opcode::MOV);
892     ASSERT_EQ(item.Value().function_table.at(sig_nain12).ins[0].opcode, Opcode::MOV);
893 }
894 
TEST(parsertests,test36_records_bracket)895 TEST(parsertests, test36_records_bracket)
896 {
897     std::vector<std::vector<panda::pandasm::Token>> v;
898     Lexer l;
899     Parser p;
900     v.push_back(l.TokenizeString(".record rec1 <> {").first);
901     v.push_back(l.TokenizeString("i64 asm1 <>").first);
902     v.push_back(l.TokenizeString("}").first);
903 
904     v.push_back(l.TokenizeString(".record rec2 <> {   i64 asm1}").first);
905     v.push_back(l.TokenizeString(".record rec3 <> {    i64 asm1").first);
906     v.push_back(l.TokenizeString("}").first);
907 
908     v.push_back(l.TokenizeString(".record rec4").first);
909     v.push_back(l.TokenizeString("{").first);
910     v.push_back(l.TokenizeString("i64 asm1").first);
911     v.push_back(l.TokenizeString("}").first);
912 
913     v.push_back(l.TokenizeString(".record rec5{").first);
914     v.push_back(l.TokenizeString("i64 asm1}").first);
915 
916     v.push_back(l.TokenizeString(".record rec6").first);
917     v.push_back(l.TokenizeString("{").first);
918     v.push_back(l.TokenizeString("i64 asm1}").first);
919 
920     v.push_back(l.TokenizeString(".record rec7{").first);
921     v.push_back(l.TokenizeString("i64 asm1").first);
922     v.push_back(l.TokenizeString("}").first);
923 
924     auto item = p.Parse(v);
925 
926     ASSERT_EQ(item.Value().record_table.at("rec1").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
927     ASSERT_EQ(item.Value().record_table.at("rec2").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
928     ASSERT_EQ(item.Value().record_table.at("rec3").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
929     ASSERT_EQ(item.Value().record_table.at("rec4").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
930     ASSERT_EQ(item.Value().record_table.at("rec5").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
931     ASSERT_EQ(item.Value().record_table.at("rec6").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
932     ASSERT_EQ(item.Value().record_table.at("rec7").field_list[0].type.GetId(), panda::panda_file::Type::TypeId::I64);
933 }
934 
TEST(parsertests,test37_operand_type_print)935 TEST(parsertests, test37_operand_type_print)
936 {
937     std::vector<std::vector<panda::pandasm::Token>> v;
938     Lexer l;
939     Parser p;
940     v.push_back(l.TokenizeString(".function u1 nain1(i64 a0) <> {").first);
941     v.push_back(l.TokenizeString("L: mov v0, a0").first);
942     v.push_back(l.TokenizeString("movi v0, 0").first);
943     v.push_back(l.TokenizeString("jmp L").first);
944     v.push_back(l.TokenizeString("sta a0").first);
945     v.push_back(l.TokenizeString("neg").first);
946     v.push_back(l.TokenizeString("call.short nain1, v0, v1").first);
947     v.push_back(l.TokenizeString("}").first);
948 
949     auto item = p.Parse(v);
950 
951     std::vector<Function::Parameter> params;
952     panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
953     params.emplace_back(Type {"i64", 0}, language);
954     const auto sig_nain1 = GetFunctionSignatureFromName("nain1", params);
955 
956     ASSERT_EQ(OperandTypePrint(item.Value().function_table.at(sig_nain1).ins[0].opcode), "reg_reg");
957     ASSERT_EQ(OperandTypePrint(item.Value().function_table.at(sig_nain1).ins[1].opcode), "reg_imm");
958     ASSERT_EQ(OperandTypePrint(item.Value().function_table.at(sig_nain1).ins[2].opcode), "label");
959     ASSERT_EQ(OperandTypePrint(item.Value().function_table.at(sig_nain1).ins[3].opcode), "reg");
960     ASSERT_EQ(OperandTypePrint(item.Value().function_table.at(sig_nain1).ins[4].opcode), "none");
961     ASSERT_EQ(OperandTypePrint(item.Value().function_table.at(sig_nain1).ins[5].opcode), "call_reg_reg");
962 }
963 
TEST(parsertests,test38_record_invalid_field)964 TEST(parsertests, test38_record_invalid_field)
965 {
966     {
967         std::vector<std::vector<panda::pandasm::Token>> v;
968         Lexer l;
969         Parser p;
970 
971         std::string f = "T";
972 
973         v.push_back(l.TokenizeString(".record Rec {").first);
974         v.push_back(l.TokenizeString(f).first);
975         v.push_back(l.TokenizeString("}").first);
976 
977         p.Parse(v);
978 
979         Error e = p.ShowError();
980 
981         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_FIELD_MISSING_NAME);
982         ASSERT_EQ(e.line_number, 2U);
983         ASSERT_EQ(e.pos, f.length());
984         ASSERT_EQ(e.message, "Expected field name.");
985     }
986 
987     {
988         std::vector<std::vector<panda::pandasm::Token>> v;
989         Lexer l;
990         Parser p;
991 
992         std::string f = "T f <";
993 
994         v.push_back(l.TokenizeString(".record Rec {").first);
995         v.push_back(l.TokenizeString(f).first);
996         v.push_back(l.TokenizeString("}").first);
997 
998         p.Parse(v);
999 
1000         Error e = p.ShowError();
1001 
1002         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_METADATA_BOUND);
1003         ASSERT_EQ(e.line_number, 2U);
1004         ASSERT_EQ(e.pos, f.length());
1005         ASSERT_EQ(e.message, "Expected '>'.");
1006     }
1007 }
1008 
TEST(parsertests,test39_parse_operand_string)1009 TEST(parsertests, test39_parse_operand_string)
1010 {
1011     {
1012         std::vector<std::vector<panda::pandasm::Token>> v;
1013         Lexer l;
1014         Parser p;
1015 
1016         std::string op = "lda.str 123";
1017 
1018         v.push_back(l.TokenizeString(".function void f() {").first);
1019         v.push_back(l.TokenizeString(op).first);
1020         v.push_back(l.TokenizeString("}").first);
1021 
1022         p.Parse(v);
1023 
1024         Error e = p.ShowError();
1025 
1026         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_OPERAND);
1027         ASSERT_EQ(e.line_number, 2U);
1028         ASSERT_EQ(e.pos, op.find(' ') + 1);
1029         ASSERT_EQ(e.message, "Expected string literal");
1030     }
1031 
1032     {
1033         std::vector<std::vector<panda::pandasm::Token>> v;
1034         Lexer l;
1035         Parser p;
1036 
1037         std::string op = "lda.str a\"bcd";
1038 
1039         v.push_back(l.TokenizeString(".function void f() {").first);
1040         v.push_back(l.TokenizeString(op).first);
1041         v.push_back(l.TokenizeString("}").first);
1042 
1043         p.Parse(v);
1044 
1045         Error e = p.ShowError();
1046 
1047         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_OPERAND);
1048         ASSERT_EQ(e.line_number, 2U);
1049         ASSERT_EQ(e.pos, op.find(' ') + 1);
1050         ASSERT_EQ(e.message, "Expected string literal");
1051     }
1052 
1053     {
1054         std::vector<std::vector<panda::pandasm::Token>> v;
1055         Lexer l;
1056         Parser p;
1057 
1058         v.push_back(l.TokenizeString(".function void f() {").first);
1059         v.push_back(l.TokenizeString("lda.str \" abc123 \"").first);
1060         v.push_back(l.TokenizeString("lda.str \"zxcvb\"").first);
1061         v.push_back(l.TokenizeString("}").first);
1062 
1063         auto item = p.Parse(v);
1064 
1065         std::unordered_set<std::string> strings = {" abc123 ", "zxcvb"};
1066 
1067         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1068         ASSERT_TRUE(item.HasValue());
1069         ASSERT_EQ(item.Value().strings, strings);
1070     }
1071 }
1072 
TEST(parsertests,test40_parse_operand_string_escape_seq)1073 TEST(parsertests, test40_parse_operand_string_escape_seq)
1074 {
1075     {
1076         std::vector<std::vector<panda::pandasm::Token>> v;
1077         Lexer l;
1078         Parser p;
1079 
1080         std::string op = "lda.str \"123\\z\"";
1081 
1082         v.push_back(l.TokenizeString(".function void f() {").first);
1083         v.push_back(l.TokenizeString(op).first);
1084         v.push_back(l.TokenizeString("}").first);
1085 
1086         p.Parse(v);
1087 
1088         Error e = p.ShowError();
1089 
1090         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_STRING_UNKNOWN_ESCAPE_SEQUENCE);
1091         ASSERT_EQ(e.line_number, 2U);
1092         ASSERT_EQ(e.pos, op.find('\\'));
1093         ASSERT_EQ(e.message, "Unknown escape sequence");
1094     }
1095 
1096     {
1097         std::vector<std::vector<panda::pandasm::Token>> v;
1098         Lexer l;
1099         Parser p;
1100 
1101         std::string op = "lda.str \" \\\" \\' \\\\ \\a \\b \\f \\n \\r \\t \\v \"";
1102 
1103         v.push_back(l.TokenizeString(".function void f() {").first);
1104         v.push_back(l.TokenizeString(op).first);
1105         v.push_back(l.TokenizeString("}").first);
1106 
1107         Error e = p.ShowError();
1108 
1109         auto item = p.Parse(v);
1110 
1111         std::unordered_set<std::string> strings = {" \" ' \\ \a \b \f \n \r \t \v "};
1112 
1113         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1114         ASSERT_TRUE(item.HasValue());
1115         ASSERT_EQ(item.Value().strings, strings);
1116     }
1117 }
1118 
TEST(parsertests,test41_parse_operand_string_hex_escape_seq)1119 TEST(parsertests, test41_parse_operand_string_hex_escape_seq)
1120 {
1121     {
1122         std::vector<std::vector<panda::pandasm::Token>> v;
1123         Lexer l;
1124         Parser p;
1125 
1126         std::string op = "lda.str \"123\\x\"";
1127 
1128         v.push_back(l.TokenizeString(".function void f() {").first);
1129         v.push_back(l.TokenizeString(op).first);
1130         v.push_back(l.TokenizeString("}").first);
1131 
1132         p.Parse(v);
1133 
1134         Error e = p.ShowError();
1135 
1136         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_STRING_INVALID_HEX_ESCAPE_SEQUENCE);
1137         ASSERT_EQ(e.line_number, 2U);
1138         ASSERT_EQ(e.pos, op.find('\\'));
1139         ASSERT_EQ(e.message, "Invalid \\x escape sequence");
1140     }
1141 
1142     {
1143         std::vector<std::vector<panda::pandasm::Token>> v;
1144         Lexer l;
1145         Parser p;
1146 
1147         std::string op = "lda.str \"123\\xZZ\"";
1148 
1149         v.push_back(l.TokenizeString(".function void f() {").first);
1150         v.push_back(l.TokenizeString(op).first);
1151         v.push_back(l.TokenizeString("}").first);
1152 
1153         p.Parse(v);
1154 
1155         Error e = p.ShowError();
1156 
1157         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_STRING_INVALID_HEX_ESCAPE_SEQUENCE);
1158         ASSERT_EQ(e.line_number, 2U);
1159         ASSERT_EQ(e.pos, op.find('\\'));
1160         ASSERT_EQ(e.message, "Invalid \\x escape sequence");
1161     }
1162 
1163     {
1164         std::vector<std::vector<panda::pandasm::Token>> v;
1165         Lexer l;
1166         Parser p;
1167 
1168         std::string op = "lda.str \"123\\xAZ\"";
1169 
1170         v.push_back(l.TokenizeString(".function void f() {").first);
1171         v.push_back(l.TokenizeString(op).first);
1172         v.push_back(l.TokenizeString("}").first);
1173 
1174         p.Parse(v);
1175 
1176         Error e = p.ShowError();
1177 
1178         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_STRING_INVALID_HEX_ESCAPE_SEQUENCE);
1179         ASSERT_EQ(e.line_number, 2U);
1180         ASSERT_EQ(e.pos, op.find('\\'));
1181         ASSERT_EQ(e.message, "Invalid \\x escape sequence");
1182     }
1183 
1184     {
1185         std::vector<std::vector<panda::pandasm::Token>> v;
1186         Lexer l;
1187         Parser p;
1188 
1189         std::string op = "lda.str \"123\\xZA\"";
1190 
1191         v.push_back(l.TokenizeString(".function void f() {").first);
1192         v.push_back(l.TokenizeString(op).first);
1193         v.push_back(l.TokenizeString("}").first);
1194 
1195         p.Parse(v);
1196 
1197         Error e = p.ShowError();
1198 
1199         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_STRING_INVALID_HEX_ESCAPE_SEQUENCE);
1200         ASSERT_EQ(e.line_number, 2U);
1201         ASSERT_EQ(e.pos, op.find('\\'));
1202         ASSERT_EQ(e.message, "Invalid \\x escape sequence");
1203     }
1204 
1205     {
1206         std::vector<std::vector<panda::pandasm::Token>> v;
1207         Lexer l;
1208         Parser p;
1209 
1210         std::string op = "lda.str \"123\\xaa\\x65\"";
1211 
1212         v.push_back(l.TokenizeString(".function void f() {").first);
1213         v.push_back(l.TokenizeString(op).first);
1214         v.push_back(l.TokenizeString("}").first);
1215 
1216         auto item = p.Parse(v);
1217 
1218         std::unordered_set<std::string> strings = {"123\xaa\x65"};
1219 
1220         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1221         ASSERT_TRUE(item.HasValue());
1222         ASSERT_EQ(item.Value().strings, strings);
1223     }
1224 }
1225 
TEST(parsertests,test42_parse_operand_string_octal_escape_seq)1226 TEST(parsertests, test42_parse_operand_string_octal_escape_seq)
1227 {
1228     std::vector<std::vector<panda::pandasm::Token>> v;
1229     Lexer l;
1230     Parser p;
1231 
1232     std::string op = "lda.str \"123\\1\\02\\00123\"";
1233 
1234     v.push_back(l.TokenizeString(".function void f() {").first);
1235     v.push_back(l.TokenizeString(op).first);
1236     v.push_back(l.TokenizeString("}").first);
1237 
1238     auto item = p.Parse(v);
1239 
1240     std::unordered_set<std::string> strings = {"123\1\02\00123"};
1241 
1242     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1243     ASSERT_TRUE(item.HasValue());
1244     ASSERT_EQ(item.Value().strings, strings);
1245 }
1246 
TEST(parsertests,test43_call_short)1247 TEST(parsertests, test43_call_short)
1248 {
1249     {
1250         std::vector<std::vector<panda::pandasm::Token>> v;
1251         Lexer l;
1252         Parser p;
1253         v.push_back(l.TokenizeString(".function void f() {").first);
1254         v.push_back(l.TokenizeString("call.short f").first);
1255         v.push_back(l.TokenizeString("call.virt.short f").first);
1256         v.push_back(l.TokenizeString("}").first);
1257 
1258         auto item = p.Parse(v);
1259 
1260         const auto sig_f = GetFunctionSignatureFromName("f", {});
1261 
1262         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1263         ASSERT_TRUE(item.HasValue());
1264         std::vector<uint16_t> regs {};
1265         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[0].regs, regs);
1266         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[1].regs, regs);
1267     }
1268 
1269     {
1270         std::vector<std::vector<panda::pandasm::Token>> v;
1271         Lexer l;
1272         Parser p;
1273         v.push_back(l.TokenizeString(".function void f() {").first);
1274         v.push_back(l.TokenizeString("call.short f, v0").first);
1275         v.push_back(l.TokenizeString("call.virt.short f, v0").first);
1276         v.push_back(l.TokenizeString("}").first);
1277 
1278         auto item = p.Parse(v);
1279 
1280         const auto sig_f = GetFunctionSignatureFromName("f", {});
1281 
1282         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1283         ASSERT_TRUE(item.HasValue());
1284         std::vector<uint16_t> regs {0};
1285         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[0].regs, regs);
1286         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[1].regs, regs);
1287     }
1288 
1289     {
1290         std::vector<std::vector<panda::pandasm::Token>> v;
1291         Lexer l;
1292         Parser p;
1293         v.push_back(l.TokenizeString(".function void f() {").first);
1294         v.push_back(l.TokenizeString("call.short f, v0, v1").first);
1295         v.push_back(l.TokenizeString("call.virt.short f, v0, v1").first);
1296         v.push_back(l.TokenizeString("}").first);
1297 
1298         auto item = p.Parse(v);
1299 
1300         const auto sig_f = GetFunctionSignatureFromName("f", {});
1301 
1302         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1303         ASSERT_TRUE(item.HasValue());
1304         std::vector<uint16_t> regs {0, 1};
1305         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[0].regs, regs);
1306         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[1].regs, regs);
1307     }
1308 
1309     {
1310         std::vector<std::vector<panda::pandasm::Token>> v;
1311         Lexer l;
1312         Parser p;
1313         v.push_back(l.TokenizeString(".function void f() {").first);
1314         v.push_back(l.TokenizeString("call.short f, v0, v1, v2").first);
1315         v.push_back(l.TokenizeString("}").first);
1316 
1317         p.Parse(v);
1318 
1319         Error e = p.ShowError();
1320 
1321         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_NUMBER_OPERANDS);
1322     }
1323 
1324     {
1325         std::vector<std::vector<panda::pandasm::Token>> v;
1326         Lexer l;
1327         Parser p;
1328         v.push_back(l.TokenizeString(".function void f() {").first);
1329         v.push_back(l.TokenizeString("call.virt.short f, v0, v1, v2").first);
1330         v.push_back(l.TokenizeString("}").first);
1331 
1332         p.Parse(v);
1333 
1334         Error e = p.ShowError();
1335 
1336         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_NUMBER_OPERANDS);
1337     }
1338 }
1339 
TEST(parsertests,test44_call)1340 TEST(parsertests, test44_call)
1341 {
1342     {
1343         std::vector<std::vector<panda::pandasm::Token>> v;
1344         Lexer l;
1345         Parser p;
1346         v.push_back(l.TokenizeString(".function void f() {").first);
1347         v.push_back(l.TokenizeString("call f").first);
1348         v.push_back(l.TokenizeString("call.virt f").first);
1349         v.push_back(l.TokenizeString("}").first);
1350 
1351         auto item = p.Parse(v);
1352 
1353         const auto sig_f = GetFunctionSignatureFromName("f", {});
1354 
1355         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1356         ASSERT_TRUE(item.HasValue());
1357         std::vector<uint16_t> regs {};
1358         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[0].regs, regs);
1359         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[1].regs, regs);
1360     }
1361 
1362     {
1363         std::vector<std::vector<panda::pandasm::Token>> v;
1364         Lexer l;
1365         Parser p;
1366         v.push_back(l.TokenizeString(".function void f() {").first);
1367         v.push_back(l.TokenizeString("call f, v0").first);
1368         v.push_back(l.TokenizeString("call.virt f, v0").first);
1369         v.push_back(l.TokenizeString("}").first);
1370 
1371         auto item = p.Parse(v);
1372 
1373         const auto sig_f = GetFunctionSignatureFromName("f", {});
1374 
1375         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1376         ASSERT_TRUE(item.HasValue());
1377         std::vector<uint16_t> regs {0};
1378         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[0].regs, regs);
1379         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[1].regs, regs);
1380     }
1381 
1382     {
1383         std::vector<std::vector<panda::pandasm::Token>> v;
1384         Lexer l;
1385         Parser p;
1386         v.push_back(l.TokenizeString(".function void f() {").first);
1387         v.push_back(l.TokenizeString("call f, v0, v1").first);
1388         v.push_back(l.TokenizeString("call.virt f, v0, v1").first);
1389         v.push_back(l.TokenizeString("}").first);
1390 
1391         auto item = p.Parse(v);
1392 
1393         const auto sig_f = GetFunctionSignatureFromName("f", {});
1394 
1395         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1396         ASSERT_TRUE(item.HasValue());
1397         std::vector<uint16_t> regs {0, 1};
1398         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[0].regs, regs);
1399         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[1].regs, regs);
1400     }
1401 
1402     {
1403         std::vector<std::vector<panda::pandasm::Token>> v;
1404         Lexer l;
1405         Parser p;
1406         v.push_back(l.TokenizeString(".function void f() {").first);
1407         v.push_back(l.TokenizeString("call f, v0, v1, v2").first);
1408         v.push_back(l.TokenizeString("call.virt f, v0, v1, v2").first);
1409         v.push_back(l.TokenizeString("}").first);
1410 
1411         auto item = p.Parse(v);
1412 
1413         const auto sig_f = GetFunctionSignatureFromName("f", {});
1414 
1415         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1416         ASSERT_TRUE(item.HasValue());
1417         std::vector<uint16_t> regs {0, 1, 2};
1418         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[0].regs, regs);
1419         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[1].regs, regs);
1420     }
1421 
1422     {
1423         std::vector<std::vector<panda::pandasm::Token>> v;
1424         Lexer l;
1425         Parser p;
1426         v.push_back(l.TokenizeString(".function void f() {").first);
1427         v.push_back(l.TokenizeString("call f, v0, v1, v2, v3").first);
1428         v.push_back(l.TokenizeString("call.virt f, v0, v1, v2, v3").first);
1429         v.push_back(l.TokenizeString("}").first);
1430 
1431         auto item = p.Parse(v);
1432 
1433         const auto sig_f = GetFunctionSignatureFromName("f", {});
1434 
1435         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1436         ASSERT_TRUE(item.HasValue());
1437         std::vector<uint16_t> regs {0, 1, 2, 3};
1438         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[0].regs, regs);
1439         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[1].regs, regs);
1440     }
1441 
1442     {
1443         std::vector<std::vector<panda::pandasm::Token>> v;
1444         Lexer l;
1445         Parser p;
1446         v.push_back(l.TokenizeString(".function void f() {").first);
1447         v.push_back(l.TokenizeString("call.short f, v0, v1, v2, v3, v4").first);
1448         v.push_back(l.TokenizeString("}").first);
1449 
1450         p.Parse(v);
1451 
1452         Error e = p.ShowError();
1453 
1454         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_NUMBER_OPERANDS);
1455     }
1456 
1457     {
1458         std::vector<std::vector<panda::pandasm::Token>> v;
1459         Lexer l;
1460         Parser p;
1461         v.push_back(l.TokenizeString(".function void f() {").first);
1462         v.push_back(l.TokenizeString("call.virt.short f, v0, v1, v2, v3, v4").first);
1463         v.push_back(l.TokenizeString("}").first);
1464 
1465         p.Parse(v);
1466 
1467         Error e = p.ShowError();
1468 
1469         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_NUMBER_OPERANDS);
1470     }
1471 }
1472 
TEST(parsertests,function_argument_mismatch)1473 TEST(parsertests, function_argument_mismatch)
1474 {
1475     {
1476         std::vector<std::vector<panda::pandasm::Token>> v;
1477         Lexer l;
1478         Parser p;
1479         v.push_back(l.TokenizeString(".function u8 main(){").first);
1480         v.push_back(l.TokenizeString("call.short nain, v0, v1").first);
1481         v.push_back(l.TokenizeString("}").first);
1482         v.push_back(l.TokenizeString(".function u8 nain(i32 a0, i32 a1){").first);
1483         v.push_back(l.TokenizeString("}").first);
1484         auto item = p.Parse(v);
1485         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1486     }
1487     {
1488         std::vector<std::vector<panda::pandasm::Token>> v;
1489         Lexer l;
1490         Parser p;
1491         v.push_back(l.TokenizeString(".function u8 main(){").first);
1492         v.push_back(l.TokenizeString("call.range nain, v0").first);
1493         v.push_back(l.TokenizeString("}").first);
1494         v.push_back(l.TokenizeString(".function u8 nain(i32 a0, i32 a1){").first);
1495         v.push_back(l.TokenizeString("}").first);
1496         auto item = p.Parse(v);
1497         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1498     }
1499     {
1500         std::vector<std::vector<panda::pandasm::Token>> v;
1501         Lexer l;
1502         Parser p;
1503         v.push_back(l.TokenizeString(".function u8 main(){").first);
1504         v.push_back(l.TokenizeString("call nain, v0").first);
1505         v.push_back(l.TokenizeString("}").first);
1506         v.push_back(l.TokenizeString(".function u8 nain(i32 a0, i32 a1){").first);
1507         v.push_back(l.TokenizeString("}").first);
1508         auto item = p.Parse(v);
1509         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_FUNCTION_ARGUMENT_MISMATCH);
1510     }
1511     {
1512         std::vector<std::vector<panda::pandasm::Token>> v;
1513         Lexer l;
1514         Parser p;
1515         v.push_back(l.TokenizeString(".function u8 main(){").first);
1516         v.push_back(l.TokenizeString("call nain, v0, v1, v2, v3").first);
1517         v.push_back(l.TokenizeString("}").first);
1518         v.push_back(l.TokenizeString(".function u8 nain(i32 a0, i32 a1){").first);
1519         v.push_back(l.TokenizeString("}").first);
1520         auto item = p.Parse(v);
1521         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1522     }
1523 }
1524 
TEST(parsertests,test45_argument_width_mov)1525 TEST(parsertests, test45_argument_width_mov)
1526 {
1527     std::vector<std::vector<panda::pandasm::Token>> v;
1528     Lexer l;
1529     Parser p;
1530     v.push_back(l.TokenizeString(".function void f() {").first);
1531     v.push_back(l.TokenizeString("mov v67000, v0").first);
1532     v.push_back(l.TokenizeString("}").first);
1533 
1534     p.Parse(v);
1535 
1536     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_OPERAND);
1537 }
1538 
TEST(parsertests,test45_argument_width_call)1539 TEST(parsertests, test45_argument_width_call)
1540 {
1541     std::vector<std::vector<panda::pandasm::Token>> v;
1542     Lexer l;
1543     Parser p;
1544     v.push_back(l.TokenizeString(".function void f() {").first);
1545     v.push_back(l.TokenizeString("call.range f, v256").first);
1546     v.push_back(l.TokenizeString("}").first);
1547 
1548     p.Parse(v);
1549 
1550     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_OPERAND);
1551 }
1552 
TEST(parsertests,test_argument_width_call_param)1553 TEST(parsertests, test_argument_width_call_param)
1554 {
1555     std::vector<std::vector<panda::pandasm::Token>> v;
1556     Lexer l;
1557     Parser p;
1558     v.push_back(l.TokenizeString(".function void g(u1 a0, u1 a1) {").first);
1559     v.push_back(l.TokenizeString("call.range f, v256").first);
1560     v.push_back(l.TokenizeString("}").first);
1561     v.push_back(l.TokenizeString(".function void f() {").first);
1562     v.push_back(l.TokenizeString("movi v5, 0").first);
1563     v.push_back(l.TokenizeString("call g, a1, v15").first);
1564     v.push_back(l.TokenizeString("return").first);
1565     v.push_back(l.TokenizeString("}").first);
1566 
1567     p.Parse(v);
1568 
1569     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_OPERAND);
1570 }
1571 
TEST(parsertests,Naming_function_function)1572 TEST(parsertests, Naming_function_function)
1573 {
1574     std::vector<std::vector<panda::pandasm::Token>> v;
1575     Lexer l;
1576     Parser p;
1577     v.push_back(l.TokenizeString(".function u1 nain(i64 a0) <> {").first);
1578     v.push_back(l.TokenizeString("L: mov v0, a0").first);
1579     v.push_back(l.TokenizeString("}").first);
1580     v.push_back(l.TokenizeString(".function u1 nain(i64 a0) <> {").first);
1581     v.push_back(l.TokenizeString("L: mov v0, a0").first);
1582     v.push_back(l.TokenizeString("}").first);
1583 
1584     auto item = p.Parse(v);
1585     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_ID_FUNCTION);
1586 }
1587 
TEST(parsertests,Naming_label_label)1588 TEST(parsertests, Naming_label_label)
1589 {
1590     std::vector<std::vector<panda::pandasm::Token>> v;
1591     Lexer l;
1592     Parser p;
1593     v.push_back(l.TokenizeString(".function u1 nain(i64 a0) <> {").first);
1594     v.push_back(l.TokenizeString("SAME: mov v0, a0").first);
1595     v.push_back(l.TokenizeString("SAME: sta v0").first);
1596     v.push_back(l.TokenizeString("}").first);
1597 
1598     auto item = p.Parse(v);
1599     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_LABEL_EXT);
1600 }
1601 
TEST(parsertests,Naming_function_label)1602 TEST(parsertests, Naming_function_label)
1603 {
1604     std::vector<std::vector<panda::pandasm::Token>> v;
1605     Lexer l;
1606     Parser p;
1607     v.push_back(l.TokenizeString(".function u1 nain(i64 a0) <> {").first);
1608     v.push_back(l.TokenizeString("nain: mov v0, a0").first);
1609     v.push_back(l.TokenizeString("}").first);
1610 
1611     auto item = p.Parse(v);
1612     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1613 }
1614 
TEST(parsertests,Naming_function_operation)1615 TEST(parsertests, Naming_function_operation)
1616 {
1617     std::vector<std::vector<panda::pandasm::Token>> v;
1618     Lexer l;
1619     Parser p;
1620     v.push_back(l.TokenizeString(".function u1 mov(i64 a0) <> {").first);
1621     v.push_back(l.TokenizeString("L: mov v0, a0").first);
1622     v.push_back(l.TokenizeString("}").first);
1623 
1624     auto item = p.Parse(v);
1625     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1626 }
1627 
TEST(parsertests,Naming_label_operation)1628 TEST(parsertests, Naming_label_operation)
1629 {
1630     std::vector<std::vector<panda::pandasm::Token>> v;
1631     Lexer l;
1632     Parser p;
1633     v.push_back(l.TokenizeString(".function u1 nain(i64 a0) <> {").first);
1634     v.push_back(l.TokenizeString("mov: mov v0, a0").first);
1635     v.push_back(l.TokenizeString("}").first);
1636 
1637     auto item = p.Parse(v);
1638     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1639 }
1640 
TEST(parsertests,Naming_function_label_operation)1641 TEST(parsertests, Naming_function_label_operation)
1642 {
1643     std::vector<std::vector<panda::pandasm::Token>> v;
1644     Lexer l;
1645     Parser p;
1646     v.push_back(l.TokenizeString(".function u1 mov(i64 a0) <> {").first);
1647     v.push_back(l.TokenizeString("mov: mov v0, a0").first);
1648     v.push_back(l.TokenizeString("}").first);
1649 
1650     auto item = p.Parse(v);
1651     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1652 }
1653 
TEST(parsertests,Naming_jump_label)1654 TEST(parsertests, Naming_jump_label)
1655 {
1656     std::vector<std::vector<panda::pandasm::Token>> v;
1657     Lexer l;
1658     Parser p;
1659     v.push_back(l.TokenizeString(".function u1 mov(i64 a0) <> {").first);
1660     v.push_back(l.TokenizeString("jmp mov").first);
1661     v.push_back(l.TokenizeString("mov:").first);
1662     v.push_back(l.TokenizeString("return").first);
1663     v.push_back(l.TokenizeString("}").first);
1664 
1665     auto item = p.Parse(v);
1666     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1667 }
1668 
TEST(parsertests,Naming_call_function)1669 TEST(parsertests, Naming_call_function)
1670 {
1671     std::vector<std::vector<panda::pandasm::Token>> v;
1672     Lexer l;
1673     Parser p;
1674     v.push_back(l.TokenizeString(".function u1 mov(i64 a0) <> {").first);
1675     v.push_back(l.TokenizeString("call.short mov, v0, v1").first);
1676     v.push_back(l.TokenizeString("}").first);
1677 
1678     auto item = p.Parse(v);
1679     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1680 }
1681 
TEST(parsertests,register_naming_incorr)1682 TEST(parsertests, register_naming_incorr)
1683 {
1684     {
1685         std::vector<std::vector<panda::pandasm::Token>> v;
1686         Lexer l;
1687         Parser p;
1688         v.push_back(l.TokenizeString(".function void f() {").first);
1689         v.push_back(l.TokenizeString("sta 123").first);
1690         v.push_back(l.TokenizeString("}").first);
1691         auto item = p.Parse(v);
1692         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NAME_REG);
1693     }
1694     {
1695         std::vector<std::vector<panda::pandasm::Token>> v;
1696         Lexer l;
1697         Parser p;
1698         v.push_back(l.TokenizeString(".function void f() {").first);
1699         v.push_back(l.TokenizeString("sta a0").first);
1700         v.push_back(l.TokenizeString("}").first);
1701         auto item = p.Parse(v);
1702         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NAME_REG);
1703     }
1704     {
1705         std::vector<std::vector<panda::pandasm::Token>> v;
1706         Lexer l;
1707         Parser p;
1708         v.push_back(l.TokenizeString(".function void f(i32 a0) {").first);
1709         v.push_back(l.TokenizeString("sta a01").first);
1710         v.push_back(l.TokenizeString("}").first);
1711         auto item = p.Parse(v);
1712         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NAME_REG);
1713     }
1714     {
1715         std::vector<std::vector<panda::pandasm::Token>> v;
1716         Lexer l;
1717         Parser p;
1718         v.push_back(l.TokenizeString(".function void f() {").first);
1719         v.push_back(l.TokenizeString("sta 123").first);
1720         v.push_back(l.TokenizeString("}").first);
1721         auto item = p.Parse(v);
1722         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NAME_REG);
1723     }
1724     {
1725         std::vector<std::vector<panda::pandasm::Token>> v;
1726         Lexer l;
1727         Parser p;
1728         v.push_back(l.TokenizeString(".function void f() {").first);
1729         v.push_back(l.TokenizeString("sta q0").first);
1730         v.push_back(l.TokenizeString("}").first);
1731         auto item = p.Parse(v);
1732         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NAME_REG);
1733     }
1734     {
1735         std::vector<std::vector<panda::pandasm::Token>> v;
1736         Lexer l;
1737         Parser p;
1738         v.push_back(l.TokenizeString(".function void f() {").first);
1739         v.push_back(l.TokenizeString("sta vy1").first);
1740         v.push_back(l.TokenizeString("}").first);
1741         auto item = p.Parse(v);
1742         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NAME_REG);
1743     }
1744     {
1745         std::vector<std::vector<panda::pandasm::Token>> v;
1746         Lexer l;
1747         Parser p;
1748         v.push_back(l.TokenizeString(".function void f() {").first);
1749         v.push_back(l.TokenizeString("sta v01").first);
1750         v.push_back(l.TokenizeString("}").first);
1751         auto item = p.Parse(v);
1752         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NAME_REG);
1753     }
1754 }
TEST(parsertests,register_naming_corr)1755 TEST(parsertests, register_naming_corr)
1756 {
1757     {
1758         std::vector<std::vector<panda::pandasm::Token>> v;
1759         Lexer l;
1760         Parser p;
1761         v.push_back(l.TokenizeString(".function void f() {").first);
1762         v.push_back(l.TokenizeString("sta v123").first);
1763         v.push_back(l.TokenizeString("}").first);
1764         auto item = p.Parse(v);
1765         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1766     }
1767     {
1768         std::vector<std::vector<panda::pandasm::Token>> v;
1769         Lexer l;
1770         Parser p;
1771         v.push_back(l.TokenizeString(".function void f() {").first);
1772         v.push_back(l.TokenizeString("sta v0").first);
1773         v.push_back(l.TokenizeString("}").first);
1774         auto item = p.Parse(v);
1775         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1776     }
1777     {
1778         std::vector<std::vector<panda::pandasm::Token>> v;
1779         Lexer l;
1780         Parser p;
1781         v.push_back(l.TokenizeString(".function void f(i32 a0) {").first);
1782         v.push_back(l.TokenizeString("sta a0").first);
1783         v.push_back(l.TokenizeString("}").first);
1784         auto item = p.Parse(v);
1785         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1786     }
1787     {
1788         std::vector<std::vector<panda::pandasm::Token>> v;
1789         Lexer l;
1790         Parser p;
1791         v.push_back(l.TokenizeString(".function void f(i32 a0) {").first);
1792         v.push_back(l.TokenizeString("mov v0, a0").first);
1793         v.push_back(l.TokenizeString("}").first);
1794         auto item = p.Parse(v);
1795         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1796     }
1797 }
1798 
TEST(parsertests,array_type)1799 TEST(parsertests, array_type)
1800 {
1801     {
1802         std::vector<std::vector<panda::pandasm::Token>> v;
1803         Lexer l;
1804         Parser p;
1805 
1806         v.push_back(l.TokenizeString(".record R {").first);
1807         v.push_back(l.TokenizeString("R[][] f").first);
1808         v.push_back(l.TokenizeString("}").first);
1809 
1810         v.push_back(l.TokenizeString(".function R[] f(i8[ ] a0) {").first);
1811         v.push_back(l.TokenizeString("newarr v0, v0, i32[  ][]").first);
1812         v.push_back(l.TokenizeString("}").first);
1813 
1814         auto item = p.Parse(v);
1815 
1816         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1817 
1818         std::vector<Function::Parameter> params;
1819         panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
1820         params.emplace_back(Type {"i8", 1}, language);
1821         const auto sig_f = GetFunctionSignatureFromName("f", params);
1822 
1823         ASSERT_TRUE(item.HasValue());
1824 
1825         ASSERT_EQ(item.Value().record_table.at("R").field_list.size(), 1U);
1826         ASSERT_TRUE(item.Value().record_table.at("R").field_list[0].type.IsArray());
1827         ASSERT_TRUE(item.Value().record_table.at("R").field_list[0].type.IsObject());
1828         ASSERT_EQ(item.Value().record_table.at("R").field_list[0].type.GetName(), "R[][]");
1829         ASSERT_EQ(item.Value().record_table.at("R").field_list[0].type.GetComponentName(), "R");
1830         ASSERT_EQ(item.Value().record_table.at("R").field_list[0].type.GetDescriptor(), "[[LR;");
1831 
1832         ASSERT_TRUE(item.Value().function_table.at(sig_f).return_type.IsArray());
1833         ASSERT_TRUE(item.Value().function_table.at(sig_f).return_type.IsObject());
1834         ASSERT_EQ(item.Value().function_table.at(sig_f).return_type.GetName(), "R[]");
1835         ASSERT_EQ(item.Value().function_table.at(sig_f).return_type.GetComponentName(), "R");
1836         ASSERT_EQ(item.Value().function_table.at(sig_f).return_type.GetDescriptor(), "[LR;");
1837 
1838         ASSERT_EQ(item.Value().function_table.at(sig_f).params.size(), 1U);
1839         ASSERT_TRUE(item.Value().function_table.at(sig_f).params[0].type.IsArray());
1840         ASSERT_TRUE(item.Value().function_table.at(sig_f).params[0].type.IsObject());
1841         ASSERT_EQ(item.Value().function_table.at(sig_f).params[0].type.GetName(), "i8[]");
1842         ASSERT_EQ(item.Value().function_table.at(sig_f).params[0].type.GetComponentName(), "i8");
1843         ASSERT_EQ(item.Value().function_table.at(sig_f).params[0].type.GetDescriptor(), "[B");
1844 
1845         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[0].ids.size(), 1U);
1846         ASSERT_EQ(item.Value().function_table.at(sig_f).ins[0].ids[0], "i32[][]");
1847     }
1848 
1849     {
1850         std::vector<std::vector<panda::pandasm::Token>> v;
1851         Lexer l;
1852         Parser p;
1853         v.push_back(l.TokenizeString(".function void f(i32 a0) {").first);
1854         v.push_back(l.TokenizeString("newarr v0, v0, i32[][").first);
1855         v.push_back(l.TokenizeString("}").first);
1856 
1857         auto item = p.Parse(v);
1858 
1859         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_ARRAY_TYPE_BOUND);
1860     }
1861 
1862     {
1863         std::vector<std::vector<panda::pandasm::Token>> v;
1864         Lexer l;
1865         Parser p;
1866         v.push_back(l.TokenizeString(".function f64[ f(i32 a0) {").first);
1867         v.push_back(l.TokenizeString("newarr v0, v0, i32[]").first);
1868         v.push_back(l.TokenizeString("}").first);
1869 
1870         auto item = p.Parse(v);
1871 
1872         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_ARRAY_TYPE_BOUND);
1873     }
1874 
1875     {
1876         std::vector<std::vector<panda::pandasm::Token>> v;
1877         Lexer l;
1878         Parser p;
1879         v.push_back(l.TokenizeString(".function void f(i32[][][ a0) {").first);
1880         v.push_back(l.TokenizeString("newarr v0, v0, i32[]").first);
1881         v.push_back(l.TokenizeString("}").first);
1882 
1883         auto item = p.Parse(v);
1884 
1885         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_ARRAY_TYPE_BOUND);
1886     }
1887 
1888     {
1889         std::vector<std::vector<panda::pandasm::Token>> v;
1890         Lexer l;
1891         Parser p;
1892         v.push_back(l.TokenizeString(".record R {").first);
1893         v.push_back(l.TokenizeString("R[][ f").first);
1894         v.push_back(l.TokenizeString("}").first);
1895 
1896         auto item = p.Parse(v);
1897 
1898         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_ARRAY_TYPE_BOUND);
1899     }
1900 }
1901 
TEST(parsertests,undefined_type)1902 TEST(parsertests, undefined_type)
1903 {
1904     {
1905         std::vector<std::vector<panda::pandasm::Token>> v;
1906         Lexer l;
1907         Parser p;
1908         v.push_back(l.TokenizeString(".function void main() <> {").first);
1909         v.push_back(l.TokenizeString("movi v0, 5").first);
1910         v.push_back(l.TokenizeString("newarr v0, v0, panda.String[]").first);
1911         v.push_back(l.TokenizeString("return.void").first);
1912         v.push_back(l.TokenizeString("}").first);
1913 
1914         auto item = p.Parse(v);
1915         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_ID_RECORD);
1916     }
1917     {
1918         std::vector<std::vector<panda::pandasm::Token>> v;
1919         Lexer l;
1920         Parser p;
1921         v.push_back(l.TokenizeString(".record panda.String <external>").first);
1922         v.push_back(l.TokenizeString(".function void main() <> {").first);
1923         v.push_back(l.TokenizeString("movi v0, 5").first);
1924         v.push_back(l.TokenizeString("newarr v0, v0, panda.String[]").first);
1925         v.push_back(l.TokenizeString("return.void").first);
1926         v.push_back(l.TokenizeString("}").first);
1927 
1928         auto item = p.Parse(v);
1929         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1930     }
1931     {
1932         std::vector<std::vector<panda::pandasm::Token>> v;
1933         Lexer l;
1934         Parser p;
1935         v.push_back(l.TokenizeString(".function void main() <> {").first);
1936         v.push_back(l.TokenizeString("movi v0, 5").first);
1937         v.push_back(l.TokenizeString("newarr v0, v0, i32[]").first);
1938         v.push_back(l.TokenizeString("return.void").first);
1939         v.push_back(l.TokenizeString("}").first);
1940 
1941         auto item = p.Parse(v);
1942         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
1943     }
1944 }
1945 
TEST(parsertests,parse_undefined_record_field)1946 TEST(parsertests, parse_undefined_record_field)
1947 {
1948     {
1949         Parser p;
1950         std::string source = R"(
1951             .function u1 main() {
1952                 newobj v0, ObjWrongType
1953                 lda.obj v0
1954                 return
1955             }
1956 
1957             .record ObjType {}
1958         )";
1959 
1960         auto res = p.Parse(source);
1961 
1962         Error e = p.ShowError();
1963 
1964         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
1965         ASSERT_EQ(e.line_number, 3);
1966         ASSERT_EQ(e.pos, 27);
1967         ASSERT_EQ(e.message, "This record does not exist.");
1968     }
1969 
1970     {
1971         Parser p;
1972         std::string source = R"(
1973             .function u1 main() {
1974                 newobj v0, ObjType
1975                 lda.obj v0
1976                 return
1977             }
1978 
1979             .record ObjType {}
1980         )";
1981 
1982         auto res = p.Parse(source);
1983 
1984         Error e = p.ShowError();
1985 
1986         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
1987     }
1988 
1989     {
1990         Parser p;
1991         std::string source = R"(
1992             .function u1 main() {
1993                 ldobj v0, ObjWrongType.fld
1994                 return
1995             }
1996 
1997             .record ObjType {
1998                 i32 fld
1999             }
2000         )";
2001 
2002         auto res = p.Parse(source);
2003 
2004         Error e = p.ShowError();
2005 
2006         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
2007         ASSERT_EQ(e.line_number, 3);
2008         ASSERT_EQ(e.pos, 26);
2009         ASSERT_EQ(e.message, "This record does not exist.");
2010     }
2011 
2012     {
2013         Parser p;
2014         std::string source = R"(
2015             .function u1 main() {
2016                 ldobj v0, ObjType.fldwrong
2017                 return
2018             }
2019 
2020             .record ObjType {
2021                 i32 fld
2022             }
2023         )";
2024 
2025         auto res = p.Parse(source);
2026 
2027         Error e = p.ShowError();
2028 
2029         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_FIELD);
2030         ASSERT_EQ(e.line_number, 3);
2031         ASSERT_EQ(e.pos, 34);
2032         ASSERT_EQ(e.message, "This field does not exist.");
2033     }
2034 
2035     {
2036         Parser p;
2037         std::string source = R"(
2038             .function u1 main() {
2039                 ldobj v0, ObjType.fld
2040                 return
2041             }
2042 
2043             .record ObjType {
2044                 i32 fld
2045             }
2046         )";
2047 
2048         auto res = p.Parse(source);
2049 
2050         Error e = p.ShowError();
2051 
2052         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
2053     }
2054 
2055     {
2056         Parser p;
2057         std::string source = R"(
2058             .function u1 main() {
2059                 lda.type i64[]
2060                 return
2061             }
2062 
2063             .record ObjType {
2064                 i32 fld
2065             }
2066         )";
2067 
2068         auto res = p.Parse(source);
2069 
2070         Error e = p.ShowError();
2071 
2072         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
2073     }
2074 
2075     {
2076         Parser p;
2077         std::string source = R"(
2078             .record panda.String <external>
2079 
2080             .function panda.String panda.NullPointerException.getMessage(panda.NullPointerException a0) {
2081                 ldobj.obj a0, panda.NullPointerException.messagewrong
2082                 return.obj
2083             }
2084 
2085             .record panda.NullPointerException {
2086                 panda.String message
2087             }
2088         )";
2089 
2090         auto res = p.Parse(source);
2091 
2092         Error e = p.ShowError();
2093 
2094         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_FIELD);
2095         ASSERT_EQ(e.line_number, 5);
2096         ASSERT_EQ(e.pos, 57);
2097         ASSERT_EQ(e.message, "This field does not exist.");
2098     }
2099 
2100     {
2101         Parser p;
2102         std::string source = R"(
2103             .record panda.String <external>
2104 
2105             .function panda.String panda.NullPointerException.getMessage(panda.NullPointerException a0) {
2106                 ldobj.obj a0, panda.NullPointerException.message
2107                 return.obj
2108             }
2109 
2110             .record panda.NullPointerException {
2111                 panda.String message
2112             }
2113         )";
2114 
2115         auto res = p.Parse(source);
2116 
2117         Error e = p.ShowError();
2118 
2119         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
2120     }
2121 
2122     {
2123         Parser p;
2124         std::string source = R"(
2125             .function u1 main(u1 a0) {
2126                 newarr a0, a0, ObjWrongType[]
2127                 return
2128             }
2129 
2130             .record ObjType {}
2131         )";
2132 
2133         auto res = p.Parse(source);
2134 
2135         Error e = p.ShowError();
2136 
2137         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
2138         ASSERT_EQ(e.line_number, 3);
2139         ASSERT_EQ(e.pos, 44);
2140         ASSERT_EQ(e.message, "This record does not exist.");
2141     }
2142 
2143     {
2144         Parser p;
2145         std::string source = R"(
2146             .function u1 main(u1 a0) {
2147                 newarr a0, a0, ObjType[]
2148                 return
2149             }
2150 
2151             .record ObjType {}
2152         )";
2153 
2154         auto res = p.Parse(source);
2155 
2156         Error e = p.ShowError();
2157 
2158         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
2159     }
2160 }
2161 
TEST(parsertests,Vreg_width)2162 TEST(parsertests, Vreg_width)
2163 {
2164     {
2165         std::vector<std::vector<panda::pandasm::Token>> v;
2166         Lexer l;
2167         Parser p;
2168         v.push_back(l.TokenizeString(".function u1 nain(i64 a0) <> {").first);
2169         v.push_back(l.TokenizeString("mov v999, a0").first);
2170         v.push_back(l.TokenizeString("movi a0, 0").first);
2171         v.push_back(l.TokenizeString("lda a0").first);
2172         v.push_back(l.TokenizeString("return").first);
2173         v.push_back(l.TokenizeString("mov a0, v999").first);
2174         v.push_back(l.TokenizeString("}").first);
2175 
2176         auto item = p.Parse(v);
2177         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NAME_REG);
2178     }
2179 
2180     {
2181         std::vector<std::vector<panda::pandasm::Token>> v;
2182         Lexer l;
2183         Parser p;
2184         v.push_back(l.TokenizeString(".function u1 nain(i64 a0) <> {").first);
2185         v.push_back(l.TokenizeString("movi.64 v15, 222").first);
2186         v.push_back(l.TokenizeString("call bar, a0, v0").first);
2187         v.push_back(l.TokenizeString("return").first);
2188         v.push_back(l.TokenizeString("}").first);
2189 
2190         auto item = p.Parse(v);
2191         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_NAME_REG);
2192     }
2193 }
2194 
TEST(parsertests,Num_vregs)2195 TEST(parsertests, Num_vregs)
2196 {
2197     {
2198         Parser p;
2199         std::string source = R"(
2200             .record KKK{}
2201 
2202             .function u1 main(u1 a0) {
2203                 movi v1, 1
2204                 mov v0, a0
2205 
2206                 return
2207             }
2208         )";
2209 
2210         auto res = p.Parse(source);
2211 
2212         Error e = p.ShowError();
2213 
2214         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
2215 
2216         auto &program = res.Value();
2217 
2218         std::vector<Function::Parameter> params;
2219         panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
2220         params.emplace_back(Type {"u1", 0}, language);
2221         const auto sig_main = GetFunctionSignatureFromName("main", params);
2222 
2223         auto it_func = program.function_table.find(sig_main);
2224 
2225         ASSERT_TRUE(it_func != program.function_table.end());
2226         ASSERT_EQ(it_func->second.regs_num, 2);
2227     }
2228 
2229     {
2230         Parser p;
2231         std::string source = R"(
2232             .function u1 main(u1 a0) {
2233                 movi v1, 1
2234                 mov v0, a0
2235 
2236                 return
2237             }
2238 
2239             .record KKK{}
2240         )";
2241 
2242         auto res = p.Parse(source);
2243 
2244         Error e = p.ShowError();
2245 
2246         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
2247 
2248         std::vector<Function::Parameter> params;
2249         panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
2250         params.emplace_back(Type {"u1", 0}, language);
2251         const auto sig_main = GetFunctionSignatureFromName("main", params);
2252 
2253         auto &program = res.Value();
2254         auto it_func = program.function_table.find(sig_main);
2255 
2256         ASSERT_TRUE(it_func != program.function_table.end());
2257         ASSERT_EQ(it_func->second.regs_num, 2);
2258     }
2259 
2260     {
2261         Parser p;
2262         std::string source = R"(
2263             .function u1 main() {
2264                 movi v0, 1
2265 
2266                 return
2267             }
2268 
2269             .record KKK{}
2270         )";
2271 
2272         auto res = p.Parse(source);
2273 
2274         Error e = p.ShowError();
2275 
2276         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
2277 
2278         const auto sig_main = GetFunctionSignatureFromName("main", {});
2279 
2280         auto &program = res.Value();
2281         auto it_func = program.function_table.find(sig_main);
2282 
2283         ASSERT_TRUE(it_func != program.function_table.end());
2284         ASSERT_EQ(it_func->second.regs_num, 1);
2285     }
2286 
2287     {
2288         Parser p;
2289         std::string source = R"(
2290             .function u1 main() {
2291                 movi v1, 1
2292                 movi v0, 0
2293                 movi v2, 2
2294                 movi v3, 3
2295                 movi v4, 4
2296 
2297                 return
2298             }
2299 
2300             .record KKK{}
2301         )";
2302 
2303         auto res = p.Parse(source);
2304 
2305         Error e = p.ShowError();
2306 
2307         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
2308 
2309         const auto sig_main = GetFunctionSignatureFromName("main", {});
2310 
2311         auto &program = res.Value();
2312         auto it_func = program.function_table.find(sig_main);
2313 
2314         ASSERT_TRUE(it_func != program.function_table.end());
2315         ASSERT_EQ(it_func->second.regs_num, 5);
2316     }
2317 }
2318 
TEST(parsertests,Bad_imm_value)2319 TEST(parsertests, Bad_imm_value)
2320 {
2321     {
2322         std::vector<std::vector<panda::pandasm::Token>> v;
2323         Lexer l;
2324         Parser p;
2325         v.push_back(l.TokenizeString(".function u n(){movi v0,.").first);
2326         auto item = p.Parse(v);
2327         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_INTEGER_NAME);
2328     }
2329     {
2330         std::vector<std::vector<panda::pandasm::Token>> v;
2331         Lexer l;
2332         Parser p;
2333         v.push_back(l.TokenizeString(".function u n(){movi v0,%").first);
2334         auto item = p.Parse(v);
2335         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_INTEGER_NAME);
2336     }
2337     {
2338         std::vector<std::vector<panda::pandasm::Token>> v;
2339         Lexer l;
2340         Parser p;
2341         v.push_back(l.TokenizeString(".function u n(){movi v0,;").first);
2342         auto item = p.Parse(v);
2343         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_INTEGER_NAME);
2344     }
2345 }
2346 
TEST(parsertests,parse_catch_directive)2347 TEST(parsertests, parse_catch_directive)
2348 {
2349     {
2350         std::vector<std::vector<panda::pandasm::Token>> v;
2351         Lexer l;
2352         Parser p;
2353 
2354         v.push_back(l.TokenizeString(".record Exception {}").first);
2355         v.push_back(l.TokenizeString(".catch Exception, try_begin, try_end, catch_begin").first);
2356 
2357         p.Parse(v);
2358 
2359         Error e = p.ShowError();
2360 
2361         ASSERT_EQ(e.err, Error::ErrorType::ERR_INCORRECT_DIRECTIVE_LOCATION);
2362         ASSERT_EQ(e.line_number, 2);
2363         ASSERT_EQ(e.message, ".catch directive is located outside of a function body.");
2364     }
2365 
2366     {
2367         std::vector<std::string> directives {
2368             ".catch",        ".catch R",         ".catch R,",         ".catch R, t1",
2369             ".catch R, t1,", ".catch R, t1, t2", ".catch R, t1, t2,", ".catch R, t1, t2, c,"};
2370 
2371         for (auto s : directives) {
2372             std::vector<std::vector<panda::pandasm::Token>> v;
2373             Lexer l;
2374             Parser p;
2375 
2376             v.push_back(l.TokenizeString(".record Exception {}").first);
2377             v.push_back(l.TokenizeString(".function void main() {").first);
2378             v.push_back(l.TokenizeString(s).first);
2379             v.push_back(l.TokenizeString("}").first);
2380 
2381             p.Parse(v);
2382 
2383             Error e = p.ShowError();
2384 
2385             ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_DIRECTIVE_DECLARATION);
2386             ASSERT_EQ(e.line_number, 3);
2387             ASSERT_EQ(e.pos, 0);
2388             ASSERT_EQ(e.message,
2389                       "Incorrect catch block declaration. Must be in the format: .catch <exception_record>, "
2390                       "<try_begin_label>, <try_end_label>, <catch_begin_label>[, <catch_end_label>]");
2391         }
2392     }
2393 
2394     {
2395         std::vector<std::vector<panda::pandasm::Token>> v;
2396         Lexer l;
2397         Parser p;
2398 
2399         std::string s = ".catch $Exception, try_begin, try_end, catch_begin";
2400 
2401         v.push_back(l.TokenizeString(".record Exception {}").first);
2402         v.push_back(l.TokenizeString(".function void main() {").first);
2403         v.push_back(l.TokenizeString(s).first);
2404         v.push_back(l.TokenizeString("}").first);
2405 
2406         p.Parse(v);
2407 
2408         Error e = p.ShowError();
2409 
2410         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_RECORD_NAME);
2411         ASSERT_EQ(e.line_number, 3);
2412         ASSERT_EQ(e.pos, s.find("$"));
2413         ASSERT_EQ(e.message, "Invalid name of the exception record.");
2414     }
2415 
2416     {
2417         std::vector<std::string> labels {"try_begin", "try_end", "catch_begin"};
2418         std::vector<std::string> label_names {"try block begin", "try block end", "catch block begin"};
2419 
2420         for (size_t i = 0; i < labels.size(); i++) {
2421             std::string s = ".catch Exception";
2422 
2423             {
2424                 std::string directive = s;
2425                 for (size_t j = 0; j < labels.size(); j++) {
2426                     directive += i == j ? " $ " : " , ";
2427                     directive += labels[j];
2428                 }
2429 
2430                 std::vector<std::vector<panda::pandasm::Token>> v;
2431                 Lexer l;
2432                 Parser p;
2433 
2434                 v.push_back(l.TokenizeString(".record Exception {}").first);
2435                 v.push_back(l.TokenizeString(".function void main() {").first);
2436                 v.push_back(l.TokenizeString(directive).first);
2437                 v.push_back(l.TokenizeString("}").first);
2438 
2439                 p.Parse(v);
2440 
2441                 Error e = p.ShowError();
2442 
2443                 ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_DIRECTIVE_DECLARATION) << "Test " << directive;
2444                 ASSERT_EQ(e.line_number, 3) << "Test " << directive;
2445                 ASSERT_EQ(e.pos, directive.find("$")) << "Test " << directive;
2446                 ASSERT_EQ(e.message, "Expected comma.") << "Test " << directive;
2447             }
2448 
2449             {
2450                 std::string directive = s;
2451                 for (size_t j = 0; j < labels.size(); j++) {
2452                     directive += " , ";
2453                     directive += i == j ? "$" : labels[j];
2454                 }
2455 
2456                 std::vector<std::vector<panda::pandasm::Token>> v;
2457                 Lexer l;
2458                 Parser p;
2459 
2460                 v.push_back(l.TokenizeString(".record Exception {}").first);
2461                 v.push_back(l.TokenizeString(".function void main() {").first);
2462                 v.push_back(l.TokenizeString(directive).first);
2463                 v.push_back(l.TokenizeString("}").first);
2464 
2465                 p.Parse(v);
2466 
2467                 Error e = p.ShowError();
2468 
2469                 ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_LABEL) << "Test " << directive;
2470                 ASSERT_EQ(e.line_number, 3) << "Test " << directive;
2471                 ASSERT_EQ(e.pos, directive.find("$")) << "Test " << directive;
2472                 ASSERT_EQ(e.message, std::string("Invalid name of the ") + label_names[i] + " label.")
2473                     << "Test " << directive;
2474             }
2475 
2476             {
2477                 std::stringstream ss;
2478                 ss << "Test " << labels[i] << " does not exists";
2479 
2480                 std::vector<std::vector<panda::pandasm::Token>> v;
2481                 Lexer l;
2482                 Parser p;
2483 
2484                 std::string catch_table = ".catch Exception, try_begin, try_end, catch_begin";
2485 
2486                 v.push_back(l.TokenizeString(".record Exception {}").first);
2487                 v.push_back(l.TokenizeString(".function void main() {").first);
2488                 for (size_t j = 0; j < labels.size(); j++) {
2489                     if (i != j) {
2490                         v.push_back(l.TokenizeString(labels[j] + ":").first);
2491                     }
2492                 }
2493                 v.push_back(l.TokenizeString(catch_table).first);
2494                 v.push_back(l.TokenizeString("}").first);
2495 
2496                 p.Parse(v);
2497 
2498                 Error e = p.ShowError();
2499 
2500                 ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_LABEL_EXT) << ss.str();
2501                 ASSERT_EQ(e.pos, catch_table.find(labels[i])) << ss.str();
2502                 ASSERT_EQ(e.message, "This label does not exist.") << ss.str();
2503             }
2504         }
2505     }
2506 
2507     {
2508         std::vector<std::vector<panda::pandasm::Token>> v;
2509         Lexer l;
2510         Parser p;
2511 
2512         std::string s = ".catch Exception, try_begin, try_end, catch_begin";
2513 
2514         v.push_back(l.TokenizeString(".record Exception {}").first);
2515         v.push_back(l.TokenizeString(".function void main() {").first);
2516         v.push_back(l.TokenizeString("try_begin:").first);
2517         v.push_back(l.TokenizeString("try_end:").first);
2518         v.push_back(l.TokenizeString("catch_begin:").first);
2519         v.push_back(l.TokenizeString(s).first);
2520         v.push_back(l.TokenizeString("}").first);
2521 
2522         auto res = p.Parse(v);
2523 
2524         Error e = p.ShowError();
2525 
2526         const auto sig_main = GetFunctionSignatureFromName("main", {});
2527 
2528         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
2529 
2530         auto &program = res.Value();
2531         auto &function = program.function_table.find(sig_main)->second;
2532 
2533         ASSERT_EQ(function.catch_blocks.size(), 1);
2534         ASSERT_EQ(function.catch_blocks[0].exception_record, "Exception");
2535         ASSERT_EQ(function.catch_blocks[0].try_begin_label, "try_begin");
2536         ASSERT_EQ(function.catch_blocks[0].try_end_label, "try_end");
2537         ASSERT_EQ(function.catch_blocks[0].catch_begin_label, "catch_begin");
2538         ASSERT_EQ(function.catch_blocks[0].catch_end_label, "catch_begin");
2539     }
2540 
2541     {
2542         std::vector<std::vector<panda::pandasm::Token>> v;
2543         Lexer l;
2544         Parser p;
2545 
2546         std::string s = ".catch Exception, try_begin, try_end, catch_begin, catch_end";
2547 
2548         v.push_back(l.TokenizeString(".record Exception {}").first);
2549         v.push_back(l.TokenizeString(".function void main() {").first);
2550         v.push_back(l.TokenizeString("try_begin:").first);
2551         v.push_back(l.TokenizeString("try_end:").first);
2552         v.push_back(l.TokenizeString("catch_begin:").first);
2553         v.push_back(l.TokenizeString("catch_end:").first);
2554         v.push_back(l.TokenizeString(s).first);
2555         v.push_back(l.TokenizeString("}").first);
2556 
2557         auto res = p.Parse(v);
2558 
2559         Error e = p.ShowError();
2560 
2561         const auto sig_main = GetFunctionSignatureFromName("main", {});
2562 
2563         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
2564 
2565         auto &program = res.Value();
2566         auto &function = program.function_table.find(sig_main)->second;
2567 
2568         ASSERT_EQ(function.catch_blocks.size(), 1);
2569         ASSERT_EQ(function.catch_blocks[0].exception_record, "Exception");
2570         ASSERT_EQ(function.catch_blocks[0].try_begin_label, "try_begin");
2571         ASSERT_EQ(function.catch_blocks[0].try_end_label, "try_end");
2572         ASSERT_EQ(function.catch_blocks[0].catch_begin_label, "catch_begin");
2573         ASSERT_EQ(function.catch_blocks[0].catch_end_label, "catch_end");
2574     }
2575 }
2576 
TEST(parsertests,parse_catchall_directive)2577 TEST(parsertests, parse_catchall_directive)
2578 {
2579     {
2580         std::vector<std::vector<panda::pandasm::Token>> v;
2581         Lexer l;
2582         Parser p;
2583 
2584         v.push_back(l.TokenizeString(".catchall try_begin, try_end, catch_begin").first);
2585 
2586         p.Parse(v);
2587 
2588         Error e = p.ShowError();
2589 
2590         ASSERT_EQ(e.err, Error::ErrorType::ERR_INCORRECT_DIRECTIVE_LOCATION);
2591         ASSERT_EQ(e.line_number, 1);
2592         ASSERT_EQ(e.message, ".catchall directive is located outside of a function body.");
2593     }
2594 
2595     {
2596         std::vector<std::string> directives {".catchall",        ".catchall t1",      ".catchall t1,",
2597                                              ".catchall t1, t2", ".catchall t1, t2,", ".catchall t1, t2, c,"};
2598 
2599         for (auto s : directives) {
2600             std::vector<std::vector<panda::pandasm::Token>> v;
2601             Lexer l;
2602             Parser p;
2603 
2604             v.push_back(l.TokenizeString(".function void main() {").first);
2605             v.push_back(l.TokenizeString(s).first);
2606             v.push_back(l.TokenizeString("}").first);
2607 
2608             p.Parse(v);
2609 
2610             Error e = p.ShowError();
2611 
2612             ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_DIRECTIVE_DECLARATION);
2613             ASSERT_EQ(e.line_number, 2);
2614             ASSERT_EQ(e.pos, 0);
2615             ASSERT_EQ(e.message,
2616                       "Incorrect catch block declaration. Must be in the format: .catchall <try_begin_label>, "
2617                       "<try_end_label>, <catch_begin_label>[, <catch_end_label>]");
2618         }
2619     }
2620 
2621     {
2622         std::vector<std::string> labels {"try_begin", "try_end", "catch_begin"};
2623         std::vector<std::string> label_names {"try block begin", "try block end", "catch block begin"};
2624 
2625         for (size_t i = 0; i < labels.size(); i++) {
2626             std::string s = ".catchall ";
2627 
2628             if (i != 0) {
2629                 std::string directive = s;
2630                 for (size_t j = 0; j < labels.size(); j++) {
2631                     if (j != 0) {
2632                         directive += i == j ? " $ " : " , ";
2633                     }
2634                     directive += labels[j];
2635                 }
2636 
2637                 std::vector<std::vector<panda::pandasm::Token>> v;
2638                 Lexer l;
2639                 Parser p;
2640 
2641                 v.push_back(l.TokenizeString(".function void main() {").first);
2642                 v.push_back(l.TokenizeString(directive).first);
2643                 v.push_back(l.TokenizeString("}").first);
2644 
2645                 p.Parse(v);
2646 
2647                 Error e = p.ShowError();
2648 
2649                 ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_DIRECTIVE_DECLARATION) << "Test " << directive;
2650                 ASSERT_EQ(e.line_number, 2) << "Test " << directive;
2651                 ASSERT_EQ(e.pos, directive.find("$")) << "Test " << directive;
2652                 ASSERT_EQ(e.message, "Expected comma.") << "Test " << directive;
2653             }
2654 
2655             {
2656                 std::string directive = s;
2657                 for (size_t j = 0; j < labels.size(); j++) {
2658                     if (j != 0) {
2659                         directive += " , ";
2660                     }
2661                     directive += i == j ? "$" : labels[j];
2662                 }
2663 
2664                 std::vector<std::vector<panda::pandasm::Token>> v;
2665                 Lexer l;
2666                 Parser p;
2667 
2668                 v.push_back(l.TokenizeString(".function void main() {").first);
2669                 v.push_back(l.TokenizeString(directive).first);
2670                 v.push_back(l.TokenizeString("}").first);
2671 
2672                 p.Parse(v);
2673 
2674                 Error e = p.ShowError();
2675 
2676                 ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_LABEL) << "Test " << directive;
2677                 ASSERT_EQ(e.line_number, 2) << "Test " << directive;
2678                 ASSERT_EQ(e.pos, directive.find("$")) << "Test " << directive;
2679                 ASSERT_EQ(e.message, std::string("Invalid name of the ") + label_names[i] + " label.")
2680                     << "Test " << directive;
2681             }
2682 
2683             {
2684                 std::stringstream ss;
2685                 ss << "Test " << labels[i] << " does not exists";
2686 
2687                 std::vector<std::vector<panda::pandasm::Token>> v;
2688                 Lexer l;
2689                 Parser p;
2690 
2691                 std::string catch_table = ".catchall try_begin, try_end, catch_begin";
2692 
2693                 v.push_back(l.TokenizeString(".function void main() {").first);
2694                 for (size_t j = 0; j < labels.size(); j++) {
2695                     if (i != j) {
2696                         v.push_back(l.TokenizeString(labels[j] + ":").first);
2697                     }
2698                 }
2699                 v.push_back(l.TokenizeString(catch_table).first);
2700                 v.push_back(l.TokenizeString("}").first);
2701 
2702                 p.Parse(v);
2703 
2704                 Error e = p.ShowError();
2705 
2706                 ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_LABEL_EXT) << ss.str();
2707                 ASSERT_EQ(e.pos, catch_table.find(labels[i])) << ss.str();
2708                 ASSERT_EQ(e.message, "This label does not exist.") << ss.str();
2709             }
2710         }
2711     }
2712 
2713     {
2714         std::vector<std::vector<panda::pandasm::Token>> v;
2715         Lexer l;
2716         Parser p;
2717 
2718         std::string s = ".catchall try_begin, try_end, catch_begin";
2719 
2720         v.push_back(l.TokenizeString(".function void main() {").first);
2721         v.push_back(l.TokenizeString("try_begin:").first);
2722         v.push_back(l.TokenizeString("try_end:").first);
2723         v.push_back(l.TokenizeString("catch_begin:").first);
2724         v.push_back(l.TokenizeString(s).first);
2725         v.push_back(l.TokenizeString("}").first);
2726 
2727         auto res = p.Parse(v);
2728 
2729         Error e = p.ShowError();
2730 
2731         const auto sig_main = GetFunctionSignatureFromName("main", {});
2732 
2733         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
2734 
2735         auto &program = res.Value();
2736         auto &function = program.function_table.find(sig_main)->second;
2737 
2738         ASSERT_EQ(function.catch_blocks.size(), 1);
2739         ASSERT_EQ(function.catch_blocks[0].exception_record, "");
2740         ASSERT_EQ(function.catch_blocks[0].try_begin_label, "try_begin");
2741         ASSERT_EQ(function.catch_blocks[0].try_end_label, "try_end");
2742         ASSERT_EQ(function.catch_blocks[0].catch_begin_label, "catch_begin");
2743     }
2744 }
2745 
TEST(parsertests,parse_numbers)2746 TEST(parsertests, parse_numbers)
2747 {
2748     const auto sig_main = GetFunctionSignatureFromName("main", {});
2749 
2750     {
2751         std::vector<std::vector<panda::pandasm::Token>> v;
2752         Lexer l;
2753         Parser p;
2754         v.push_back(l.TokenizeString(".function u8 main(){").first);
2755         v.push_back(l.TokenizeString("movi v0, 12345}").first);
2756         auto item = p.Parse(v);
2757         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(int64_t(12345)))
2758             << "12345 expected";
2759         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2760     }
2761 
2762     {
2763         std::vector<std::vector<panda::pandasm::Token>> v;
2764         Lexer l;
2765         Parser p;
2766         v.push_back(l.TokenizeString(".function u8 main(){").first);
2767         v.push_back(l.TokenizeString("movi v0, 0xFEFfe}").first);
2768         auto item = p.Parse(v);
2769         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(int64_t(0xFEFfe)))
2770             << "0xFEFfe expected";
2771         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2772     }
2773 
2774     {
2775         std::vector<std::vector<panda::pandasm::Token>> v;
2776         Lexer l;
2777         Parser p;
2778         v.push_back(l.TokenizeString(".function u8 main(){").first);
2779         v.push_back(l.TokenizeString("movi v0, 01237}").first);
2780         auto item = p.Parse(v);
2781         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(int64_t(01237)))
2782             << "01237 expected";
2783         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2784     }
2785 
2786     {
2787         std::vector<std::vector<panda::pandasm::Token>> v;
2788         Lexer l;
2789         Parser p;
2790         v.push_back(l.TokenizeString(".function u8 main(){").first);
2791         v.push_back(l.TokenizeString("movi v0, 0b10101}").first);
2792         auto item = p.Parse(v);
2793         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(int64_t(0b10101)))
2794             << "0b10101 expected";
2795         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2796     }
2797 
2798     {
2799         std::vector<std::vector<panda::pandasm::Token>> v;
2800         Lexer l;
2801         Parser p;
2802         v.push_back(l.TokenizeString(".function u8 main(){").first);
2803         v.push_back(l.TokenizeString("movi v0, -12345}").first);
2804         auto item = p.Parse(v);
2805         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(int64_t(-12345)))
2806             << "-12345 expected";
2807         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2808     }
2809 
2810     {
2811         std::vector<std::vector<panda::pandasm::Token>> v;
2812         Lexer l;
2813         Parser p;
2814         v.push_back(l.TokenizeString(".function u8 main(){").first);
2815         v.push_back(l.TokenizeString("movi v0, -0xFEFfe}").first);
2816         auto item = p.Parse(v);
2817         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(int64_t(-0xFEFfe)))
2818             << "12345 expected";
2819         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2820     }
2821 
2822     {
2823         std::vector<std::vector<panda::pandasm::Token>> v;
2824         Lexer l;
2825         Parser p;
2826         v.push_back(l.TokenizeString(".function u8 main(){").first);
2827         v.push_back(l.TokenizeString("movi v0, -01237}").first);
2828         auto item = p.Parse(v);
2829         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(int64_t(-01237)))
2830             << "12345 expected";
2831         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2832     }
2833 
2834     {
2835         std::vector<std::vector<panda::pandasm::Token>> v;
2836         Lexer l;
2837         Parser p;
2838         v.push_back(l.TokenizeString(".function u8 main(){").first);
2839         v.push_back(l.TokenizeString("movi v0, -0b10101}").first);
2840         auto item = p.Parse(v);
2841         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(int64_t(-0b10101)))
2842             << "-0b10101 expected";
2843         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2844     }
2845 
2846     {
2847         std::vector<std::vector<panda::pandasm::Token>> v;
2848         Lexer l;
2849         Parser p;
2850         v.push_back(l.TokenizeString(".function u8 main(){").first);
2851         v.push_back(l.TokenizeString("fmovi.64 v0, 1.0}").first);
2852         auto item = p.Parse(v);
2853         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(1.0)) << "1.0 expected";
2854         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2855     }
2856 
2857     {
2858         std::vector<std::vector<panda::pandasm::Token>> v;
2859         Lexer l;
2860         Parser p;
2861         v.push_back(l.TokenizeString(".function u8 main(){").first);
2862         v.push_back(l.TokenizeString("fmovi.64 v0, 1.}").first);
2863         auto item = p.Parse(v);
2864         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(1.)) << "1. expected";
2865         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2866     }
2867 
2868     {
2869         std::vector<std::vector<panda::pandasm::Token>> v;
2870         Lexer l;
2871         Parser p;
2872         v.push_back(l.TokenizeString(".function u8 main(){").first);
2873         v.push_back(l.TokenizeString("fmovi.64 v0, .1}").first);
2874         auto item = p.Parse(v);
2875         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(.1)) << ".0 expected";
2876         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2877     }
2878 
2879     {
2880         std::vector<std::vector<panda::pandasm::Token>> v;
2881         Lexer l;
2882         Parser p;
2883         v.push_back(l.TokenizeString(".function u8 main(){").first);
2884         v.push_back(l.TokenizeString("fmovi.64 v0, 1e10}").first);
2885         auto item = p.Parse(v);
2886         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(1e10)) << "1e10 expected";
2887         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2888     }
2889 
2890     {
2891         std::vector<std::vector<panda::pandasm::Token>> v;
2892         Lexer l;
2893         Parser p;
2894         v.push_back(l.TokenizeString(".function u8 main(){").first);
2895         v.push_back(l.TokenizeString("fmovi.64 v0, 1e+10}").first);
2896         auto item = p.Parse(v);
2897         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(1e+10)) << "1e+10 expected";
2898         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2899     }
2900 
2901     {
2902         std::vector<std::vector<panda::pandasm::Token>> v;
2903         Lexer l;
2904         Parser p;
2905         v.push_back(l.TokenizeString(".function u8 main(){").first);
2906         v.push_back(l.TokenizeString("fmovi.64 v0, 1e-10}").first);
2907         auto item = p.Parse(v);
2908         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(1e-10)) << "1e-10 expected";
2909         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2910     }
2911 
2912     {
2913         std::vector<std::vector<panda::pandasm::Token>> v;
2914         Lexer l;
2915         Parser p;
2916         v.push_back(l.TokenizeString(".function u8 main(){").first);
2917         v.push_back(l.TokenizeString("fmovi.64 v0, 1.0e10}").first);
2918         auto item = p.Parse(v);
2919         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(1.0e10)) << "1.0e10 expected";
2920         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2921     }
2922 
2923     {
2924         std::vector<std::vector<panda::pandasm::Token>> v;
2925         Lexer l;
2926         Parser p;
2927         v.push_back(l.TokenizeString(".function u8 main(){").first);
2928         v.push_back(l.TokenizeString("fmovi.64 v0, 1.0e+10}").first);
2929         auto item = p.Parse(v);
2930         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(1.0e+10)) << "1.0e+10 expected";
2931         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2932     }
2933 
2934     {
2935         std::vector<std::vector<panda::pandasm::Token>> v;
2936         Lexer l;
2937         Parser p;
2938         v.push_back(l.TokenizeString(".function u8 main(){").first);
2939         v.push_back(l.TokenizeString("fmovi.64 v0, 1.0e-10}").first);
2940         auto item = p.Parse(v);
2941         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(1.0e-10)) << "12345 expected";
2942         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2943     }
2944 
2945     {
2946         std::vector<std::vector<panda::pandasm::Token>> v;
2947         Lexer l;
2948         Parser p;
2949         v.push_back(l.TokenizeString(".function u8 main(){").first);
2950         v.push_back(l.TokenizeString("fmovi.64 v0, 1.e10}").first);
2951         auto item = p.Parse(v);
2952         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(1.e10)) << "1.e10 expected";
2953         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2954     }
2955 
2956     {
2957         std::vector<std::vector<panda::pandasm::Token>> v;
2958         Lexer l;
2959         Parser p;
2960         v.push_back(l.TokenizeString(".function u8 main(){").first);
2961         v.push_back(l.TokenizeString("fmovi.64 v0, 1.e+10}").first);
2962         auto item = p.Parse(v);
2963         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(1.e+10)) << "1.e+10 expected";
2964         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2965     }
2966 
2967     {
2968         std::vector<std::vector<panda::pandasm::Token>> v;
2969         Lexer l;
2970         Parser p;
2971         v.push_back(l.TokenizeString(".function u8 main(){").first);
2972         v.push_back(l.TokenizeString("fmovi.64 v0, 1.e-10}").first);
2973         auto item = p.Parse(v);
2974         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(1.e-10)) << "12345 expected";
2975         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2976     }
2977 
2978     {
2979         std::vector<std::vector<panda::pandasm::Token>> v;
2980         Lexer l;
2981         Parser p;
2982         v.push_back(l.TokenizeString(".function u8 main(){").first);
2983         v.push_back(l.TokenizeString("fmovi.64 v0, -1.0}").first);
2984         auto item = p.Parse(v);
2985         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(-1.0)) << "-1.0 expected";
2986         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2987     }
2988 
2989     {
2990         std::vector<std::vector<panda::pandasm::Token>> v;
2991         Lexer l;
2992         Parser p;
2993         v.push_back(l.TokenizeString(".function u8 main(){").first);
2994         v.push_back(l.TokenizeString("fmovi.64 v0, -1.}").first);
2995         auto item = p.Parse(v);
2996         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(-1.)) << "-1. expected";
2997         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
2998     }
2999 
3000     {
3001         std::vector<std::vector<panda::pandasm::Token>> v;
3002         Lexer l;
3003         Parser p;
3004         v.push_back(l.TokenizeString(".function u8 main(){").first);
3005         v.push_back(l.TokenizeString("fmovi.64 v0, -.1}").first);
3006         auto item = p.Parse(v);
3007         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(-.1)) << "-.0 expected";
3008         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
3009     }
3010 
3011     {
3012         std::vector<std::vector<panda::pandasm::Token>> v;
3013         Lexer l;
3014         Parser p;
3015         v.push_back(l.TokenizeString(".function u8 main(){").first);
3016         v.push_back(l.TokenizeString("fmovi.64 v0, -1e10}").first);
3017         auto item = p.Parse(v);
3018         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(-1e10)) << "-1e10 expected";
3019         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
3020     }
3021 
3022     {
3023         std::vector<std::vector<panda::pandasm::Token>> v;
3024         Lexer l;
3025         Parser p;
3026         v.push_back(l.TokenizeString(".function u8 main(){").first);
3027         v.push_back(l.TokenizeString("fmovi.64 v0, -1e+10}").first);
3028         auto item = p.Parse(v);
3029         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(-1e+10)) << "-1e+10 expected";
3030         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
3031     }
3032 
3033     {
3034         std::vector<std::vector<panda::pandasm::Token>> v;
3035         Lexer l;
3036         Parser p;
3037         v.push_back(l.TokenizeString(".function u8 main(){").first);
3038         v.push_back(l.TokenizeString("fmovi.64 v0, -1e-10}").first);
3039         auto item = p.Parse(v);
3040         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(-1e-10)) << "-1e-10 expected";
3041         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
3042     }
3043 
3044     {
3045         std::vector<std::vector<panda::pandasm::Token>> v;
3046         Lexer l;
3047         Parser p;
3048         v.push_back(l.TokenizeString(".function u8 main(){").first);
3049         v.push_back(l.TokenizeString("fmovi.64 v0, -1.0e10}").first);
3050         auto item = p.Parse(v);
3051         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(-1.0e10)) << "-1.0e10 expected";
3052         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
3053     }
3054 
3055     {
3056         std::vector<std::vector<panda::pandasm::Token>> v;
3057         Lexer l;
3058         Parser p;
3059         v.push_back(l.TokenizeString(".function u8 main(){").first);
3060         v.push_back(l.TokenizeString("fmovi.64 v0, -1.0e+10}").first);
3061         auto item = p.Parse(v);
3062         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(-1.0e+10)) << "-1.0e+10 expected";
3063         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
3064     }
3065 
3066     {
3067         std::vector<std::vector<panda::pandasm::Token>> v;
3068         Lexer l;
3069         Parser p;
3070         v.push_back(l.TokenizeString(".function u8 main(){").first);
3071         v.push_back(l.TokenizeString("fmovi.64 v0, -1.0e-10}").first);
3072         auto item = p.Parse(v);
3073         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(-1.0e-10)) << "-1.0e-10 expected";
3074         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
3075     }
3076 
3077     {
3078         std::vector<std::vector<panda::pandasm::Token>> v;
3079         Lexer l;
3080         Parser p;
3081         v.push_back(l.TokenizeString(".function u8 main(){").first);
3082         v.push_back(l.TokenizeString("fmovi.64 v0, -1.e10}").first);
3083         auto item = p.Parse(v);
3084         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(-1.e10)) << "-1.e10 expected";
3085         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
3086     }
3087 
3088     {
3089         std::vector<std::vector<panda::pandasm::Token>> v;
3090         Lexer l;
3091         Parser p;
3092         v.push_back(l.TokenizeString(".function u8 main(){").first);
3093         v.push_back(l.TokenizeString("fmovi.64 v0, -1.e+10}").first);
3094         auto item = p.Parse(v);
3095         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(-1.e+10)) << "-1.e+10 expected";
3096         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
3097     }
3098 
3099     {
3100         std::vector<std::vector<panda::pandasm::Token>> v;
3101         Lexer l;
3102         Parser p;
3103         v.push_back(l.TokenizeString(".function u8 main(){").first);
3104         v.push_back(l.TokenizeString("fmovi.64 v0, -1.e-10}").first);
3105         auto item = p.Parse(v);
3106         ASSERT_EQ(item.Value().function_table.at(sig_main).ins[0].imms[0], Ins::IType(-1.e-10)) << "-1.e-10 expected";
3107         ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
3108     }
3109 }
3110 
TEST(parsertests,field_value)3111 TEST(parsertests, field_value)
3112 {
3113     {
3114         std::vector<std::vector<panda::pandasm::Token>> v;
3115         Lexer l;
3116         Parser p;
3117 
3118         std::string s = "i32 f <value=A>";
3119 
3120         v.push_back(l.TokenizeString(".record A {").first);
3121         v.push_back(l.TokenizeString(s).first);
3122         v.push_back(l.TokenizeString("}").first);
3123 
3124         auto res = p.Parse(v);
3125 
3126         Error e = p.ShowError();
3127 
3128         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_METADATA_INVALID_VALUE);
3129         ASSERT_EQ(e.line_number, 2);
3130         ASSERT_EQ(e.pos, s.find("A"));
3131         ASSERT_EQ(e.message, "Excepted integer literal");
3132     }
3133 
3134     {
3135         std::vector<std::vector<panda::pandasm::Token>> v;
3136         Lexer l;
3137         Parser p;
3138 
3139         std::string s = "i32 f <value=10>";
3140 
3141         v.push_back(l.TokenizeString(".record A {").first);
3142         v.push_back(l.TokenizeString(s).first);
3143         v.push_back(l.TokenizeString("}").first);
3144 
3145         auto res = p.Parse(v);
3146 
3147         Error e = p.ShowError();
3148 
3149         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE) << e.message;
3150 
3151         auto &program = res.Value();
3152         auto &record = program.record_table.find("A")->second;
3153         auto &field = record.field_list[0];
3154 
3155         ASSERT_EQ(field.metadata->GetFieldType().GetName(), "i32");
3156         ASSERT_TRUE(field.metadata->GetValue());
3157         ASSERT_EQ(field.metadata->GetValue()->GetType(), Value::Type::I32);
3158         ASSERT_EQ(field.metadata->GetValue()->GetValue<int32_t>(), 10);
3159     }
3160 
3161     {
3162         std::vector<std::vector<panda::pandasm::Token>> v;
3163         Lexer l;
3164         Parser p;
3165 
3166         std::string s = "panda.String f <value=\"10\">";
3167 
3168         v.push_back(l.TokenizeString(".record A {").first);
3169         v.push_back(l.TokenizeString(s).first);
3170         v.push_back(l.TokenizeString("}").first);
3171 
3172         auto res = p.Parse(v);
3173 
3174         Error e = p.ShowError();
3175 
3176         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE) << e.message;
3177 
3178         auto &program = res.Value();
3179         auto &record = program.record_table.find("A")->second;
3180         auto &field = record.field_list[0];
3181 
3182         ASSERT_EQ(field.metadata->GetFieldType().GetName(), "panda.String");
3183         ASSERT_TRUE(field.metadata->GetValue());
3184         ASSERT_EQ(field.metadata->GetValue()->GetType(), Value::Type::STRING);
3185         ASSERT_EQ(field.metadata->GetValue()->GetValue<std::string>(), "10");
3186     }
3187 
3188     {
3189         std::vector<std::vector<panda::pandasm::Token>> v;
3190         Lexer l;
3191         Parser p;
3192 
3193         std::string s = "panda.String f";
3194 
3195         v.push_back(l.TokenizeString(".record A {").first);
3196         v.push_back(l.TokenizeString(s).first);
3197         v.push_back(l.TokenizeString("}").first);
3198 
3199         auto res = p.Parse(v);
3200 
3201         Error e = p.ShowError();
3202 
3203         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE) << e.message;
3204 
3205         auto &program = res.Value();
3206         auto &record = program.record_table.find("A")->second;
3207         auto &field = record.field_list[0];
3208 
3209         ASSERT_EQ(field.metadata->GetFieldType().GetName(), "panda.String");
3210         ASSERT_FALSE(field.metadata->GetValue());
3211     }
3212 }
3213 
TEST(parsertests,call_short_0args)3214 TEST(parsertests, call_short_0args)
3215 {
3216     {
3217         Parser p;
3218         std::string source = R"(
3219             .function void f() {
3220                 call.short
3221             }
3222         )";
3223 
3224         auto res = p.Parse(source);
3225 
3226         Error e = p.ShowError();
3227 
3228         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_NUMBER_OPERANDS);
3229     }
3230 }
3231 
TEST(parsertests,type_id_tests_lda)3232 TEST(parsertests, type_id_tests_lda)
3233 {
3234     {
3235         Parser p;
3236         std::string source = R"(
3237             .function void f() {
3238                 lda.type a
3239             }
3240         )";
3241 
3242         auto res = p.Parse(source);
3243 
3244         Error e = p.ShowError();
3245 
3246         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
3247     }
3248 
3249     {
3250         Parser p;
3251         std::string source = R"(
3252             .function void f() {
3253                 lda.type a[]
3254             }
3255         )";
3256 
3257         auto res = p.Parse(source);
3258 
3259         Error e = p.ShowError();
3260 
3261         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
3262     }
3263 
3264     {
3265         Parser p;
3266         std::string source = R"(
3267             .record a {}
3268             .function void f() {
3269                 lda.type a
3270             }
3271         )";
3272 
3273         auto res = p.Parse(source);
3274 
3275         Error e = p.ShowError();
3276 
3277         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
3278     }
3279 }
3280 
TEST(parsertests,type_id_tests_newarr)3281 TEST(parsertests, type_id_tests_newarr)
3282 {
3283     {
3284         Parser p;
3285         std::string source = R"(
3286             .function void f() {
3287                 newarr v0, v0, a
3288             }
3289         )";
3290 
3291         auto res = p.Parse(source);
3292 
3293         Error e = p.ShowError();
3294 
3295         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
3296     }
3297 
3298     {
3299         Parser p;
3300         std::string source = R"(
3301             .function void f() {
3302                 newarr v0, v0, a[]
3303             }
3304         )";
3305 
3306         auto res = p.Parse(source);
3307 
3308         Error e = p.ShowError();
3309 
3310         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
3311     }
3312 
3313     {
3314         Parser p;
3315         std::string source = R"(
3316             .record a {}
3317             .function void f() {
3318                 newarr v0, v0, a[]
3319             }
3320         )";
3321 
3322         auto res = p.Parse(source);
3323 
3324         Error e = p.ShowError();
3325 
3326         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
3327     }
3328 
3329     {
3330         Parser p;
3331         std::string source = R"(
3332             .record a {}
3333             .function void f() {
3334                 newarr v0, v0, a
3335             }
3336         )";
3337 
3338         auto res = p.Parse(source);
3339 
3340         Error e = p.ShowError();
3341         Error w = p.ShowWarnings()[0];
3342 
3343         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
3344         ASSERT_EQ(w.err, Error::ErrorType::WAR_UNEXPECTED_TYPE_ID);
3345     }
3346 }
3347 
TEST(parsertests,type_id_tests_newobj)3348 TEST(parsertests, type_id_tests_newobj)
3349 {
3350     {
3351         Parser p;
3352         std::string source = R"(
3353             .function void f() {
3354                 newobj v0, a
3355             }
3356         )";
3357 
3358         auto res = p.Parse(source);
3359 
3360         Error e = p.ShowError();
3361 
3362         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
3363     }
3364 
3365     {
3366         Parser p;
3367         std::string source = R"(
3368             .function void f() {
3369                 newobj v0, a[]
3370             }
3371         )";
3372 
3373         auto res = p.Parse(source);
3374 
3375         Error e = p.ShowError();
3376 
3377         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
3378     }
3379 
3380     {
3381         Parser p;
3382         std::string source = R"(
3383             .record a {}
3384             .function void f() {
3385                 newobj v0, a
3386             }
3387         )";
3388 
3389         auto res = p.Parse(source);
3390 
3391         Error e = p.ShowError();
3392 
3393         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
3394     }
3395 
3396     {
3397         Parser p;
3398         std::string source = R"(
3399             .record a {}
3400             .function void f() {
3401                 newobj v0, a[]
3402             }
3403         )";
3404 
3405         auto res = p.Parse(source);
3406 
3407         Error e = p.ShowError();
3408         Error w = p.ShowWarnings()[0];
3409 
3410         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
3411         ASSERT_EQ(w.err, Error::ErrorType::WAR_UNEXPECTED_TYPE_ID);
3412     }
3413 }
3414 
TEST(parsertests,type_id_tests_checkcast)3415 TEST(parsertests, type_id_tests_checkcast)
3416 {
3417     {
3418         Parser p;
3419         std::string source = R"(
3420             .function void f() {
3421                 checkcast a
3422             }
3423         )";
3424 
3425         auto res = p.Parse(source);
3426 
3427         Error e = p.ShowError();
3428 
3429         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
3430     }
3431 
3432     {
3433         Parser p;
3434         std::string source = R"(
3435             .function void f() {
3436                 checkcast a[]
3437             }
3438         )";
3439 
3440         auto res = p.Parse(source);
3441 
3442         Error e = p.ShowError();
3443 
3444         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
3445     }
3446 
3447     {
3448         Parser p;
3449         std::string source = R"(
3450             .record a {}
3451             .function void f() {
3452                 checkcast a
3453             }
3454         )";
3455 
3456         auto res = p.Parse(source);
3457 
3458         Error e = p.ShowError();
3459 
3460         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
3461     }
3462 }
3463 
TEST(parsertests,type_id_tests_isinstance)3464 TEST(parsertests, type_id_tests_isinstance)
3465 {
3466     {
3467         Parser p;
3468         std::string source = R"(
3469             .function void f() {
3470                 isinstance a
3471             }
3472         )";
3473 
3474         auto res = p.Parse(source);
3475 
3476         Error e = p.ShowError();
3477 
3478         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
3479     }
3480 
3481     {
3482         Parser p;
3483         std::string source = R"(
3484             .function void f() {
3485                 isinstance a[]
3486             }
3487         )";
3488 
3489         auto res = p.Parse(source);
3490 
3491         Error e = p.ShowError();
3492 
3493         ASSERT_EQ(e.err, Error::ErrorType::ERR_BAD_ID_RECORD);
3494     }
3495 
3496     {
3497         Parser p;
3498         std::string source = R"(
3499             .record a {}
3500             .function void f() {
3501                 isinstance a
3502             }
3503         )";
3504 
3505         auto res = p.Parse(source);
3506 
3507         Error e = p.ShowError();
3508 
3509         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
3510     }
3511 }
3512 
TEST(parsertests,test_fields_same_name)3513 TEST(parsertests, test_fields_same_name)
3514 {
3515     {
3516         Parser p;
3517         std::string source = R"(
3518             .record A {
3519                 i16 aaa
3520                 u8  aaa
3521                 i32 aaa
3522             }
3523         )";
3524 
3525         auto res = p.Parse(source);
3526         Error e = p.ShowError();
3527 
3528         ASSERT_EQ(e.err, Error::ErrorType::ERR_REPEATING_FIELD_NAME);
3529     }
3530 
3531     {
3532         Parser p;
3533         std::string source = R"(
3534             .function i32 main() {
3535                 ldobj.64 v0, A.aaa
3536                 ldai 0
3537                 return
3538             }
3539             .record A {
3540                 i16 aaa
3541             }
3542         )";
3543 
3544         auto res = p.Parse(source);
3545         Error e = p.ShowError();
3546 
3547         ASSERT_EQ(e.err, Error::ErrorType::ERR_NONE);
3548     }
3549 }
3550 
TEST(parsertests,test_array_integer_def)3551 TEST(parsertests, test_array_integer_def)
3552 {
3553     std::vector<std::vector<panda::pandasm::Token>> v;
3554     Lexer l;
3555     Parser p;
3556     v.push_back(l.TokenizeString(".array array {").first);
3557     v.push_back(l.TokenizeString("u1 1").first);
3558     v.push_back(l.TokenizeString("u8 2").first);
3559     v.push_back(l.TokenizeString("i8 -30").first);
3560     v.push_back(l.TokenizeString("u16 400").first);
3561     v.push_back(l.TokenizeString("i16 -5000").first);
3562     v.push_back(l.TokenizeString("u32 60000").first);
3563     v.push_back(l.TokenizeString("i32 -700000").first);
3564     v.push_back(l.TokenizeString("u64 8000000").first);
3565     v.push_back(l.TokenizeString("i64 -90000000").first);
3566     v.push_back(l.TokenizeString("}").first);
3567     auto item = p.Parse(v);
3568     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[0].tag_, panda::panda_file::LiteralTag::ARRAY_U1);
3569     ASSERT_EQ(std::get<bool>(item.Value().literalarray_table.at("array").literals_[0].value_), true);
3570     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[1].tag_, panda::panda_file::LiteralTag::ARRAY_U8);
3571     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array").literals_[1].value_), 2);
3572     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[2].tag_, panda::panda_file::LiteralTag::ARRAY_I8);
3573     ASSERT_EQ(static_cast<int8_t>(std::get<uint8_t>(item.Value().literalarray_table.at("array").literals_[2].value_)),
3574               -30);
3575     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[3].tag_, panda::panda_file::LiteralTag::ARRAY_U16);
3576     ASSERT_EQ(std::get<uint16_t>(item.Value().literalarray_table.at("array").literals_[3].value_), 400);
3577     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[4].tag_, panda::panda_file::LiteralTag::ARRAY_I16);
3578     ASSERT_EQ(static_cast<int16_t>(std::get<uint16_t>(item.Value().literalarray_table.at("array").literals_[4].value_)),
3579               -5000);
3580     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[5].tag_, panda::panda_file::LiteralTag::ARRAY_U32);
3581     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array").literals_[5].value_), 60000);
3582     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[6].tag_, panda::panda_file::LiteralTag::ARRAY_I32);
3583     ASSERT_EQ(static_cast<int32_t>(std::get<uint32_t>(item.Value().literalarray_table.at("array").literals_[6].value_)),
3584               -700000);
3585     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[7].tag_, panda::panda_file::LiteralTag::ARRAY_U64);
3586     ASSERT_EQ(std::get<uint64_t>(item.Value().literalarray_table.at("array").literals_[7].value_), 8000000);
3587     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[8].tag_, panda::panda_file::LiteralTag::ARRAY_I64);
3588     ASSERT_EQ(static_cast<int64_t>(std::get<uint64_t>(item.Value().literalarray_table.at("array").literals_[8].value_)),
3589               -90000000);
3590 }
3591 
TEST(parsertests,test_array_float_def)3592 TEST(parsertests, test_array_float_def)
3593 {
3594     std::vector<std::vector<panda::pandasm::Token>> v;
3595     Lexer l;
3596     Parser p;
3597     v.push_back(l.TokenizeString(".array array {").first);
3598     v.push_back(l.TokenizeString("f32 -123.4").first);
3599     v.push_back(l.TokenizeString("f64 -1234.5").first);
3600     v.push_back(l.TokenizeString("}").first);
3601     auto item = p.Parse(v);
3602 
3603     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[0].tag_, panda::panda_file::LiteralTag::ARRAY_F32);
3604     ASSERT_NEAR(std::get<float>(item.Value().literalarray_table.at("array").literals_[0].value_), -123.4, 0.01f);
3605     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[1].tag_, panda::panda_file::LiteralTag::ARRAY_F64);
3606     ASSERT_NEAR(std::get<double>(item.Value().literalarray_table.at("array").literals_[1].value_), -1234.5, 0.01f);
3607 }
3608 
TEST(parsertests,test_array_string_def)3609 TEST(parsertests, test_array_string_def)
3610 {
3611     std::vector<std::vector<panda::pandasm::Token>> v;
3612     Lexer l;
3613     Parser p;
3614     v.push_back(l.TokenizeString(".array array {").first);
3615     v.push_back(l.TokenizeString("panda.String \"a\"").first);
3616     v.push_back(l.TokenizeString("panda.String \"ab\"").first);
3617     v.push_back(l.TokenizeString("panda.String \"abc\"").first);
3618     v.push_back(l.TokenizeString("}").first);
3619     v.push_back(l.TokenizeString(".array array_static panda.String 3 { \"a\" \"ab\" \"abc\" }").first);
3620     auto item = p.Parse(v);
3621 
3622     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[0].tag_,
3623               panda::panda_file::LiteralTag::ARRAY_STRING);
3624     ASSERT_EQ(std::get<std::string>(item.Value().literalarray_table.at("array").literals_[0].value_), "a");
3625     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[1].tag_,
3626               panda::panda_file::LiteralTag::ARRAY_STRING);
3627     ASSERT_EQ(std::get<std::string>(item.Value().literalarray_table.at("array").literals_[1].value_), "ab");
3628     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[2].tag_,
3629               panda::panda_file::LiteralTag::ARRAY_STRING);
3630     ASSERT_EQ(std::get<std::string>(item.Value().literalarray_table.at("array").literals_[2].value_), "abc");
3631 
3632     // string intro literals
3633     ASSERT_EQ(item.Value().literalarray_table.at("array_static").literals_[0].tag_,
3634               panda::panda_file::LiteralTag::TAGVALUE);
3635     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_static").literals_[0].value_),
3636               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_STRING));
3637     ASSERT_EQ(item.Value().literalarray_table.at("array_static").literals_[1].tag_,
3638               panda::panda_file::LiteralTag::INTEGER);
3639     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_static").literals_[1].value_), 3);
3640 
3641     // string array elements
3642     ASSERT_EQ(item.Value().literalarray_table.at("array_static").literals_[2].tag_,
3643               panda::panda_file::LiteralTag::ARRAY_STRING);
3644     ASSERT_EQ(std::get<std::string>(item.Value().literalarray_table.at("array_static").literals_[2].value_), "a");
3645     ASSERT_EQ(item.Value().literalarray_table.at("array_static").literals_[3].tag_,
3646               panda::panda_file::LiteralTag::ARRAY_STRING);
3647     ASSERT_EQ(std::get<std::string>(item.Value().literalarray_table.at("array_static").literals_[3].value_), "ab");
3648     ASSERT_EQ(item.Value().literalarray_table.at("array_static").literals_[4].tag_,
3649               panda::panda_file::LiteralTag::ARRAY_STRING);
3650     ASSERT_EQ(std::get<std::string>(item.Value().literalarray_table.at("array_static").literals_[4].value_), "abc");
3651 }
3652 
TEST(parsertests,test_array_static_bool_def)3653 TEST(parsertests, test_array_static_bool_def)
3654 {
3655     std::vector<std::vector<panda::pandasm::Token>> v;
3656     Lexer l;
3657     Parser p;
3658     v.push_back(l.TokenizeString(".array array u1 3 { 1 0 1 }").first);
3659     auto item = p.Parse(v);
3660 
3661     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[0].tag_, panda::panda_file::LiteralTag::TAGVALUE);
3662     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array").literals_[0].value_),
3663               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_U1));
3664     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[1].tag_, panda::panda_file::LiteralTag::INTEGER);
3665     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array").literals_[1].value_), 3);
3666     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[2].tag_, panda::panda_file::LiteralTag::ARRAY_U1);
3667     ASSERT_EQ(std::get<bool>(item.Value().literalarray_table.at("array").literals_[2].value_), true);
3668     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[3].tag_, panda::panda_file::LiteralTag::ARRAY_U1);
3669     ASSERT_EQ(std::get<bool>(item.Value().literalarray_table.at("array").literals_[3].value_), false);
3670     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[4].tag_, panda::panda_file::LiteralTag::ARRAY_U1);
3671     ASSERT_EQ(std::get<bool>(item.Value().literalarray_table.at("array").literals_[4].value_), true);
3672 }
3673 
TEST(parsertests,test_array_static_integer_def)3674 TEST(parsertests, test_array_static_integer_def)
3675 {
3676     std::vector<std::vector<panda::pandasm::Token>> v;
3677     Lexer l;
3678     Parser p;
3679     v.push_back(l.TokenizeString(".array array_unsigned_byte u8 3 { 1 2 3 }").first);
3680     v.push_back(l.TokenizeString(".array array_byte i8 3 { -1 2 -3 }").first);
3681     v.push_back(l.TokenizeString(".array array_unsigned_short u16 3 { 100 200 300 }").first);
3682     v.push_back(l.TokenizeString(".array array_short i16 3 { 100 -200 300 }").first);
3683     v.push_back(l.TokenizeString(".array array_unsigned_int u32 3 { 1000 2000 3000 }").first);
3684     v.push_back(l.TokenizeString(".array array_int i32 3 { -1000 2000 -3000 }").first);
3685     v.push_back(l.TokenizeString(".array array_unsigned_long u64 3 { 10000 20000 30000 }").first);
3686     v.push_back(l.TokenizeString(".array array_long i64 3 { 10000 -20000 30000 }").first);
3687     auto item = p.Parse(v);
3688 
3689     // unsigned byte intro literals
3690     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_byte").literals_[0].tag_,
3691               panda::panda_file::LiteralTag::TAGVALUE);
3692     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_unsigned_byte").literals_[0].value_),
3693               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_U8));
3694     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_byte").literals_[1].tag_,
3695               panda::panda_file::LiteralTag::INTEGER);
3696     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_unsigned_byte").literals_[1].value_), 3);
3697 
3698     // unsigned byte array elements
3699     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_byte").literals_[2].tag_,
3700               panda::panda_file::LiteralTag::ARRAY_U8);
3701     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_unsigned_byte").literals_[2].value_), 1);
3702     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_byte").literals_[3].tag_,
3703               panda::panda_file::LiteralTag::ARRAY_U8);
3704     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_unsigned_byte").literals_[3].value_), 2);
3705     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_byte").literals_[4].tag_,
3706               panda::panda_file::LiteralTag::ARRAY_U8);
3707     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_unsigned_byte").literals_[4].value_), 3);
3708 
3709     // byte intro literals
3710     ASSERT_EQ(item.Value().literalarray_table.at("array_byte").literals_[0].tag_,
3711               panda::panda_file::LiteralTag::TAGVALUE);
3712     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_byte").literals_[0].value_),
3713               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_I8));
3714     ASSERT_EQ(item.Value().literalarray_table.at("array_byte").literals_[1].tag_,
3715               panda::panda_file::LiteralTag::INTEGER);
3716     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_byte").literals_[1].value_), 3);
3717 
3718     // byte array elements
3719     ASSERT_EQ(item.Value().literalarray_table.at("array_byte").literals_[2].tag_,
3720               panda::panda_file::LiteralTag::ARRAY_I8);
3721     ASSERT_EQ(
3722         static_cast<int8_t>(std::get<uint8_t>(item.Value().literalarray_table.at("array_byte").literals_[2].value_)),
3723         -1);
3724     ASSERT_EQ(item.Value().literalarray_table.at("array_byte").literals_[3].tag_,
3725               panda::panda_file::LiteralTag::ARRAY_I8);
3726     ASSERT_EQ(
3727         static_cast<int8_t>(std::get<uint8_t>(item.Value().literalarray_table.at("array_byte").literals_[3].value_)),
3728         2);
3729     ASSERT_EQ(item.Value().literalarray_table.at("array_byte").literals_[4].tag_,
3730               panda::panda_file::LiteralTag::ARRAY_I8);
3731     ASSERT_EQ(
3732         static_cast<int8_t>(std::get<uint8_t>(item.Value().literalarray_table.at("array_byte").literals_[4].value_)),
3733         -3);
3734 
3735     // unsigned short intro literals
3736     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_short").literals_[0].tag_,
3737               panda::panda_file::LiteralTag::TAGVALUE);
3738     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_unsigned_short").literals_[0].value_),
3739               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_U16));
3740     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_short").literals_[1].tag_,
3741               panda::panda_file::LiteralTag::INTEGER);
3742     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_unsigned_short").literals_[1].value_), 3);
3743 
3744     // unsigned short array elements
3745     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_short").literals_[2].tag_,
3746               panda::panda_file::LiteralTag::ARRAY_U16);
3747     ASSERT_EQ(std::get<uint16_t>(item.Value().literalarray_table.at("array_unsigned_short").literals_[2].value_), 100);
3748     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_short").literals_[3].tag_,
3749               panda::panda_file::LiteralTag::ARRAY_U16);
3750     ASSERT_EQ(std::get<uint16_t>(item.Value().literalarray_table.at("array_unsigned_short").literals_[3].value_), 200);
3751     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_short").literals_[4].tag_,
3752               panda::panda_file::LiteralTag::ARRAY_U16);
3753     ASSERT_EQ(std::get<uint16_t>(item.Value().literalarray_table.at("array_unsigned_short").literals_[4].value_), 300);
3754 
3755     // short intro literals
3756     ASSERT_EQ(item.Value().literalarray_table.at("array_short").literals_[0].tag_,
3757               panda::panda_file::LiteralTag::TAGVALUE);
3758     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_short").literals_[0].value_),
3759               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_I16));
3760     ASSERT_EQ(item.Value().literalarray_table.at("array_short").literals_[1].tag_,
3761               panda::panda_file::LiteralTag::INTEGER);
3762     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_short").literals_[1].value_), 3);
3763 
3764     // short array elements
3765     ASSERT_EQ(item.Value().literalarray_table.at("array_short").literals_[2].tag_,
3766               panda::panda_file::LiteralTag::ARRAY_I16);
3767     ASSERT_EQ(
3768         static_cast<int16_t>(std::get<uint16_t>(item.Value().literalarray_table.at("array_short").literals_[2].value_)),
3769         100);
3770     ASSERT_EQ(item.Value().literalarray_table.at("array_short").literals_[3].tag_,
3771               panda::panda_file::LiteralTag::ARRAY_I16);
3772     ASSERT_EQ(
3773         static_cast<int16_t>(std::get<uint16_t>(item.Value().literalarray_table.at("array_short").literals_[3].value_)),
3774         -200);
3775     ASSERT_EQ(item.Value().literalarray_table.at("array_short").literals_[4].tag_,
3776               panda::panda_file::LiteralTag::ARRAY_I16);
3777     ASSERT_EQ(
3778         static_cast<int16_t>(std::get<uint16_t>(item.Value().literalarray_table.at("array_short").literals_[4].value_)),
3779         300);
3780 
3781     // unsigned int intro literals
3782     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_int").literals_[0].tag_,
3783               panda::panda_file::LiteralTag::TAGVALUE);
3784     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_unsigned_int").literals_[0].value_),
3785               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_U32));
3786     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_int").literals_[1].tag_,
3787               panda::panda_file::LiteralTag::INTEGER);
3788     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_unsigned_int").literals_[1].value_), 3);
3789 
3790     // unsigned int array elements
3791     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_int").literals_[2].tag_,
3792               panda::panda_file::LiteralTag::ARRAY_U32);
3793     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_unsigned_int").literals_[2].value_), 1000);
3794     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_int").literals_[3].tag_,
3795               panda::panda_file::LiteralTag::ARRAY_U32);
3796     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_unsigned_int").literals_[3].value_), 2000);
3797     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_int").literals_[4].tag_,
3798               panda::panda_file::LiteralTag::ARRAY_U32);
3799     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_unsigned_int").literals_[4].value_), 3000);
3800 
3801     // int intro literals
3802     ASSERT_EQ(item.Value().literalarray_table.at("array_int").literals_[0].tag_,
3803               panda::panda_file::LiteralTag::TAGVALUE);
3804     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_int").literals_[0].value_),
3805               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_I32));
3806     ASSERT_EQ(item.Value().literalarray_table.at("array_int").literals_[1].tag_,
3807               panda::panda_file::LiteralTag::INTEGER);
3808     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_int").literals_[1].value_), 3);
3809 
3810     // int array elements
3811     ASSERT_EQ(item.Value().literalarray_table.at("array_int").literals_[2].tag_,
3812               panda::panda_file::LiteralTag::ARRAY_I32);
3813     ASSERT_EQ(
3814         static_cast<int32_t>(std::get<uint32_t>(item.Value().literalarray_table.at("array_int").literals_[2].value_)),
3815         -1000);
3816     ASSERT_EQ(item.Value().literalarray_table.at("array_int").literals_[3].tag_,
3817               panda::panda_file::LiteralTag::ARRAY_I32);
3818     ASSERT_EQ(
3819         static_cast<int32_t>(std::get<uint32_t>(item.Value().literalarray_table.at("array_int").literals_[3].value_)),
3820         2000);
3821     ASSERT_EQ(item.Value().literalarray_table.at("array_int").literals_[4].tag_,
3822               panda::panda_file::LiteralTag::ARRAY_I32);
3823     ASSERT_EQ(
3824         static_cast<int32_t>(std::get<uint32_t>(item.Value().literalarray_table.at("array_int").literals_[4].value_)),
3825         -3000);
3826 
3827     // unsigned long intro literals
3828     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_long").literals_[0].tag_,
3829               panda::panda_file::LiteralTag::TAGVALUE);
3830     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_unsigned_long").literals_[0].value_),
3831               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_U64));
3832     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_long").literals_[1].tag_,
3833               panda::panda_file::LiteralTag::INTEGER);
3834     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_unsigned_long").literals_[1].value_), 3);
3835 
3836     // unsigned long array elements
3837     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_long").literals_[2].tag_,
3838               panda::panda_file::LiteralTag::ARRAY_U64);
3839     ASSERT_EQ(std::get<uint64_t>(item.Value().literalarray_table.at("array_unsigned_long").literals_[2].value_), 10000);
3840     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_long").literals_[3].tag_,
3841               panda::panda_file::LiteralTag::ARRAY_U64);
3842     ASSERT_EQ(std::get<uint64_t>(item.Value().literalarray_table.at("array_unsigned_long").literals_[3].value_), 20000);
3843     ASSERT_EQ(item.Value().literalarray_table.at("array_unsigned_long").literals_[4].tag_,
3844               panda::panda_file::LiteralTag::ARRAY_U64);
3845     ASSERT_EQ(std::get<uint64_t>(item.Value().literalarray_table.at("array_unsigned_long").literals_[4].value_), 30000);
3846 
3847     // long intro literals
3848     ASSERT_EQ(item.Value().literalarray_table.at("array_long").literals_[0].tag_,
3849               panda::panda_file::LiteralTag::TAGVALUE);
3850     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_long").literals_[0].value_),
3851               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_I64));
3852     ASSERT_EQ(item.Value().literalarray_table.at("array_long").literals_[1].tag_,
3853               panda::panda_file::LiteralTag::INTEGER);
3854     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_long").literals_[1].value_), 3);
3855 
3856     // long array elements
3857     ASSERT_EQ(item.Value().literalarray_table.at("array_long").literals_[2].tag_,
3858               panda::panda_file::LiteralTag::ARRAY_I64);
3859     ASSERT_EQ(
3860         static_cast<int64_t>(std::get<uint64_t>(item.Value().literalarray_table.at("array_long").literals_[2].value_)),
3861         10000);
3862     ASSERT_EQ(item.Value().literalarray_table.at("array_long").literals_[3].tag_,
3863               panda::panda_file::LiteralTag::ARRAY_I64);
3864     ASSERT_EQ(
3865         static_cast<int64_t>(std::get<uint64_t>(item.Value().literalarray_table.at("array_long").literals_[3].value_)),
3866         -20000);
3867     ASSERT_EQ(item.Value().literalarray_table.at("array_long").literals_[4].tag_,
3868               panda::panda_file::LiteralTag::ARRAY_I64);
3869     ASSERT_EQ(
3870         static_cast<int64_t>(std::get<uint64_t>(item.Value().literalarray_table.at("array_long").literals_[4].value_)),
3871         30000);
3872 }
3873 
TEST(parsertests,test_array_static_float_def)3874 TEST(parsertests, test_array_static_float_def)
3875 {
3876     std::vector<std::vector<panda::pandasm::Token>> v;
3877     Lexer l;
3878     Parser p;
3879     v.push_back(l.TokenizeString(".array array_float f32 3 { 12.3 -12.34 12.345 }").first);
3880     v.push_back(l.TokenizeString(".array array_double f64 3 { -120.3 120.34 -120.345 }").first);
3881     auto item = p.Parse(v);
3882 
3883     // float intro literals
3884     ASSERT_EQ(item.Value().literalarray_table.at("array_float").literals_[0].tag_,
3885               panda::panda_file::LiteralTag::TAGVALUE);
3886     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_float").literals_[0].value_),
3887               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_F32));
3888     ASSERT_EQ(item.Value().literalarray_table.at("array_float").literals_[1].tag_,
3889               panda::panda_file::LiteralTag::INTEGER);
3890     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_float").literals_[1].value_), 3);
3891 
3892     // float array elements
3893     ASSERT_EQ(item.Value().literalarray_table.at("array_float").literals_[2].tag_,
3894               panda::panda_file::LiteralTag::ARRAY_F32);
3895     ASSERT_NEAR(std::get<float>(item.Value().literalarray_table.at("array_float").literals_[2].value_), 12.3, 0.01f);
3896     ASSERT_EQ(item.Value().literalarray_table.at("array_float").literals_[3].tag_,
3897               panda::panda_file::LiteralTag::ARRAY_F32);
3898     ASSERT_NEAR(std::get<float>(item.Value().literalarray_table.at("array_float").literals_[3].value_), -12.34, 0.001f);
3899     ASSERT_EQ(item.Value().literalarray_table.at("array_float").literals_[4].tag_,
3900               panda::panda_file::LiteralTag::ARRAY_F32);
3901     ASSERT_NEAR(std::get<float>(item.Value().literalarray_table.at("array_float").literals_[4].value_), 12.345,
3902                 0.0001f);
3903 
3904     // double intro literals
3905     ASSERT_EQ(item.Value().literalarray_table.at("array_double").literals_[0].tag_,
3906               panda::panda_file::LiteralTag::TAGVALUE);
3907     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array_double").literals_[0].value_),
3908               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_F64));
3909     ASSERT_EQ(item.Value().literalarray_table.at("array_double").literals_[1].tag_,
3910               panda::panda_file::LiteralTag::INTEGER);
3911     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array_double").literals_[1].value_), 3);
3912 
3913     // double array elements
3914     ASSERT_EQ(item.Value().literalarray_table.at("array_double").literals_[2].tag_,
3915               panda::panda_file::LiteralTag::ARRAY_F64);
3916     ASSERT_NEAR(std::get<double>(item.Value().literalarray_table.at("array_double").literals_[2].value_), -120.3,
3917                 0.01f);
3918     ASSERT_EQ(item.Value().literalarray_table.at("array_double").literals_[3].tag_,
3919               panda::panda_file::LiteralTag::ARRAY_F64);
3920     ASSERT_NEAR(std::get<double>(item.Value().literalarray_table.at("array_double").literals_[3].value_), 120.34,
3921                 0.001f);
3922     ASSERT_EQ(item.Value().literalarray_table.at("array_double").literals_[4].tag_,
3923               panda::panda_file::LiteralTag::ARRAY_F64);
3924     ASSERT_NEAR(std::get<double>(item.Value().literalarray_table.at("array_double").literals_[4].value_), -120.345,
3925                 0.0001f);
3926 }
3927 
TEST(parsertests,test_array_static_string_def)3928 TEST(parsertests, test_array_static_string_def)
3929 {
3930     std::vector<std::vector<panda::pandasm::Token>> v;
3931     Lexer l;
3932     Parser p;
3933     v.push_back(l.TokenizeString(".array array panda.String 3 { \"a\" \"ab\" \"abc\" }").first);
3934     auto item = p.Parse(v);
3935 
3936     // string intro literals
3937     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[0].tag_, panda::panda_file::LiteralTag::TAGVALUE);
3938     ASSERT_EQ(std::get<uint8_t>(item.Value().literalarray_table.at("array").literals_[0].value_),
3939               static_cast<uint8_t>(panda::panda_file::LiteralTag::ARRAY_STRING));
3940     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[1].tag_, panda::panda_file::LiteralTag::INTEGER);
3941     ASSERT_EQ(std::get<uint32_t>(item.Value().literalarray_table.at("array").literals_[1].value_), 3);
3942 
3943     // string array elements
3944     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[2].tag_,
3945               panda::panda_file::LiteralTag::ARRAY_STRING);
3946     ASSERT_EQ(std::get<std::string>(item.Value().literalarray_table.at("array").literals_[2].value_), "a");
3947     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[3].tag_,
3948               panda::panda_file::LiteralTag::ARRAY_STRING);
3949     ASSERT_EQ(std::get<std::string>(item.Value().literalarray_table.at("array").literals_[3].value_), "ab");
3950     ASSERT_EQ(item.Value().literalarray_table.at("array").literals_[4].tag_,
3951               panda::panda_file::LiteralTag::ARRAY_STRING);
3952     ASSERT_EQ(std::get<std::string>(item.Value().literalarray_table.at("array").literals_[4].value_), "abc");
3953 }
3954 
TEST(parsertests,test_array_string_use)3955 TEST(parsertests, test_array_string_use)
3956 {
3957     std::vector<std::vector<panda::pandasm::Token>> v;
3958     Lexer l;
3959     Parser p;
3960     v.push_back(l.TokenizeString(".record Asm1 {").first);
3961     v.push_back(l.TokenizeString("void f").first);
3962     v.push_back(l.TokenizeString("}").first);
3963 
3964     v.push_back(l.TokenizeString(".array array {").first);
3965     v.push_back(l.TokenizeString("panda.String \"a\"").first);
3966     v.push_back(l.TokenizeString("panda.String \"ab\"").first);
3967     v.push_back(l.TokenizeString("panda.String \"abc\"").first);
3968     v.push_back(l.TokenizeString("}").first);
3969     v.push_back(l.TokenizeString(".array array_static panda.String 3 { \"a\" \"ab\" \"abc\" }").first);
3970 
3971     v.push_back(l.TokenizeString(".function void f() {").first);
3972     v.push_back(l.TokenizeString("lda.const v0, array").first);
3973     v.push_back(l.TokenizeString("lda.const v1, array_static").first);
3974     v.push_back(l.TokenizeString("}").first);
3975 
3976     auto item = p.Parse(v);
3977 
3978     const auto sig_f = GetFunctionSignatureFromName("f", {});
3979 
3980     ASSERT_EQ(item.Value().function_table.at(sig_f).ins[0].opcode, Opcode::LDA_CONST);
3981     ASSERT_EQ(item.Value().function_table.at(sig_f).ins[0].ids[0], "array");
3982 
3983     ASSERT_EQ(item.Value().function_table.at(sig_f).ins[1].opcode, Opcode::LDA_CONST);
3984     ASSERT_EQ(item.Value().function_table.at(sig_f).ins[1].ids[0], "array_static");
3985 }
3986 
TEST(parsertests,test_function_overloading_1)3987 TEST(parsertests, test_function_overloading_1)
3988 {
3989     Parser p;
3990     std::string source = R"(
3991             .function u1 f() {}
3992             .function u1 f(i8 a0) {}
3993         )";
3994 
3995     auto res = p.Parse(source);
3996 
3997     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
3998 
3999     auto &program = res.Value();
4000 
4001     std::vector<Function::Parameter> params;
4002     panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
4003     params.emplace_back(Type {"i8", 0}, language);
4004     const auto sig_f = GetFunctionSignatureFromName("f", {});
4005     const auto sig_fi8 = GetFunctionSignatureFromName("f", params);
4006 
4007     ASSERT_TRUE(program.function_table.find(sig_f) != program.function_table.end());
4008     ASSERT_TRUE(program.function_table.find(sig_fi8) != program.function_table.end());
4009 }
4010 
TEST(parsertests,test_function_overloading_2)4011 TEST(parsertests, test_function_overloading_2)
4012 {
4013     Parser p;
4014     std::string source = R"(
4015             .function u1 f(i8 a0) {}
4016             .function i8 f(i8 a0) {}
4017         )";
4018 
4019     auto res = p.Parse(source);
4020 
4021     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_ID_FUNCTION);
4022 }
4023 
TEST(parsertests,test_function_overloading_3)4024 TEST(parsertests, test_function_overloading_3)
4025 {
4026     Parser p;
4027     std::string source = R"(
4028             .function u1 f() {}
4029             .function u1 f(i8 a0) {}
4030 
4031             .function void main(u1 a0) {
4032                 call f
4033             }
4034         )";
4035 
4036     auto res = p.Parse(source);
4037 
4038     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_FUNCTION_MULTIPLE_ALTERNATIVES);
4039 }
4040 
TEST(parsertests,test_function_overloading_4)4041 TEST(parsertests, test_function_overloading_4)
4042 {
4043     Parser p;
4044     std::string source = R"(
4045             .function u1 f() {}
4046             .function u1 f(i8 a0) {}
4047 
4048             .function void main(u1 a0) {
4049                 call f:(), a0
4050                 call f:(i8), a0
4051             }
4052         )";
4053 
4054     auto res = p.Parse(source);
4055 
4056     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
4057 }
4058 
TEST(parsertests,test_function_overloading_5)4059 TEST(parsertests, test_function_overloading_5)
4060 {
4061     Parser p;
4062     std::string source = R"(
4063             .function u1 f() {}
4064 
4065             .function void main(u1 a0) {
4066                 call f:()
4067                 call f
4068             }
4069         )";
4070 
4071     auto res = p.Parse(source);
4072 
4073     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
4074 
4075     std::vector<Function::Parameter> params;
4076     panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
4077     params.emplace_back(Type {"u1", 0}, language);
4078     const auto sig_f = GetFunctionSignatureFromName("f", {});
4079     const auto sig_main = GetFunctionSignatureFromName("main", params);
4080 
4081     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
4082     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[1].ids[0], sig_f);
4083     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[0].ids[0], sig_f);
4084 }
4085 
TEST(parsertests,test_function_overloading_6)4086 TEST(parsertests, test_function_overloading_6)
4087 {
4088     Parser p;
4089     std::string source = R"(
4090             .function u1 f() {}
4091             .function u1 f(i8 a0) {}
4092 
4093             .function void main(u1 a0) {
4094                 call f:(u1)
4095             }
4096         )";
4097 
4098     auto res = p.Parse(source);
4099 
4100     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_ID_FUNCTION);
4101 }
4102 
TEST(parsertests,test_function_overloading_7)4103 TEST(parsertests, test_function_overloading_7)
4104 {
4105     Parser p;
4106     std::string source = R"(
4107             .function u1 f() {}
4108             .function u1 f(i8 a0) {}
4109 
4110             .function void main(u1 a0) {
4111                 call f:(u1,)
4112             }
4113         )";
4114 
4115     auto res = p.Parse(source);
4116 
4117     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_SIGNATURE_PARAMETERS);
4118 }
4119 
TEST(parsertests,test_function_overloading_8)4120 TEST(parsertests, test_function_overloading_8)
4121 {
4122     Parser p;
4123     std::string source = R"(
4124             .function u1 f(u1 a0) {}
4125             .function u1 f(i8 a0, u8 a1) {}
4126 
4127             .function void main(u1 a0) {
4128                 call f:(i8, u8), a0
4129             }
4130         )";
4131 
4132     auto res = p.Parse(source);
4133 
4134     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_FUNCTION_ARGUMENT_MISMATCH);
4135 }
4136 
TEST(parsertests,test_function_overloading_9)4137 TEST(parsertests, test_function_overloading_9)
4138 {
4139     Parser p;
4140     std::string source = R"(
4141             .function u1 f(i8 a0) {}
4142 
4143             .function void main(u1 a0) {
4144                 call f:(i8), a0
4145                 call f, v1
4146             }
4147         )";
4148 
4149     auto res = p.Parse(source);
4150 
4151     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
4152 
4153     panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
4154     std::vector<Function::Parameter> params_main;
4155     params_main.emplace_back(Type {"u1", 0}, language);
4156     std::vector<Function::Parameter> params_f;
4157     params_f.emplace_back(Type {"i8", 0}, language);
4158     const auto sig_f = GetFunctionSignatureFromName("f", params_f);
4159     const auto sig_main = GetFunctionSignatureFromName("main", params_main);
4160 
4161     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
4162     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[1].ids[0], sig_f);
4163     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[1].regs[0], 1);  //  v0, [v1], a0
4164     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[0].ids[0], sig_f);
4165     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[0].regs[0], 2);  //  v0,  v1, [a0]
4166 }
4167 
TEST(parsertests,test_function_overloading_10)4168 TEST(parsertests, test_function_overloading_10)
4169 {
4170     Parser p;
4171     std::string source = R"(
4172             .function u1 f() {}
4173             .function u1 f(i8 a0) {}
4174 
4175             .function void main(u1 a0) {
4176                 call f:(i8, u1
4177             }
4178         )";
4179 
4180     auto res = p.Parse(source);
4181 
4182     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_SIGNATURE);
4183 }
4184 
TEST(parsertests,test_function_overloading_11)4185 TEST(parsertests, test_function_overloading_11)
4186 {
4187     Parser p;
4188     std::string source = R"(
4189             .function u1 f() {}
4190             .function u1 f(i8 a0) {}
4191 
4192             .function void main(u1 a0) {
4193                 call f:
4194             }
4195         )";
4196 
4197     auto res = p.Parse(source);
4198 
4199     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_SIGNATURE);
4200 }
4201 
TEST(parsertests,test_function_overloading_12)4202 TEST(parsertests, test_function_overloading_12)
4203 {
4204     Parser p;
4205     std::string source = R"(
4206             .function u1 f(i8 a0) {}
4207             .function u1 f() {}
4208             .function u1 f(u8 a0) {}
4209             .function u1 f(i8 a0, u8 a1) {}
4210 
4211             .function void main(u1 a0) {
4212                 call f:(i8), a0
4213                 call f, a0
4214             }
4215         )";
4216 
4217     auto res = p.Parse(source);
4218 
4219     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_FUNCTION_MULTIPLE_ALTERNATIVES);
4220 }
4221 
TEST(parsertests,test_function_overloading_13)4222 TEST(parsertests, test_function_overloading_13)
4223 {
4224     Parser p;
4225     std::string source = R"(
4226             .function u1 f(i8 a0) {}
4227             .function u1 f() {}
4228             .function u1 f(u8 a0) {}
4229             .function u1 f(i8 a0, u8 a1) {}
4230 
4231             .function void main(u1 a0) {
4232                 call f:(i8), a0
4233                 call f:(), v1
4234                 call f:(u8), v2
4235                 call f:(i8, u8), v3, v4
4236             }
4237         )";
4238 
4239     auto res = p.Parse(source);
4240 
4241     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE);
4242 
4243     auto &program = res.Value();
4244 
4245     panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
4246     std::vector<Function::Parameter> params_main;
4247     params_main.emplace_back(Type {"u1", 0}, language);
4248     std::vector<Function::Parameter> params_fi8;
4249     params_fi8.emplace_back(Type {"i8", 0}, language);
4250     std::vector<Function::Parameter> params_fu8;
4251     params_fu8.emplace_back(Type {"u8", 0}, language);
4252     std::vector<Function::Parameter> params_fi8u8;
4253     params_fi8u8.emplace_back(Type {"i8", 0}, language);
4254     params_fi8u8.emplace_back(Type {"u8", 0}, language);
4255     const auto sig_f = GetFunctionSignatureFromName("f", {});
4256     const auto sig_fi8 = GetFunctionSignatureFromName("f", params_fi8);
4257     const auto sig_fu8 = GetFunctionSignatureFromName("f", params_fu8);
4258     const auto sig_fi8u8 = GetFunctionSignatureFromName("f", params_fi8u8);
4259     const auto sig_main = GetFunctionSignatureFromName("main", params_main);
4260 
4261     ASSERT_TRUE(program.function_table.find(sig_main) != program.function_table.end());
4262     ASSERT_TRUE(program.function_table.find(sig_f) != program.function_table.end());
4263     ASSERT_TRUE(program.function_table.find(sig_fi8) != program.function_table.end());
4264     ASSERT_TRUE(program.function_table.find(sig_fu8) != program.function_table.end());
4265     ASSERT_TRUE(program.function_table.find(sig_fi8u8) != program.function_table.end());
4266 
4267     // f:(i8)
4268     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[0].ids[0], sig_fi8);
4269     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[0].regs[0], 5);
4270 
4271     // f:()
4272     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[1].ids[0], sig_f);
4273     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[1].regs[0], 1);
4274 
4275     // f:(u8)
4276     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[2].ids[0], sig_fu8);
4277     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[2].regs[0], 2);
4278 
4279     // f:(i8u8)
4280     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[3].ids[0], sig_fi8u8);
4281     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[3].regs[0], 3);
4282     ASSERT_EQ(res.Value().function_table.at(sig_main).ins[3].regs[1], 4);
4283 }
4284 
TEST(parsertests,test_function_doesnt_exist)4285 TEST(parsertests, test_function_doesnt_exist)
4286 {
4287     Parser p;
4288     std::string source = R"(
4289         .function void gg(u1 a0) {}
4290         .function void f() {
4291             call g, v0
4292         }
4293         )";
4294 
4295     auto res = p.Parse(source);
4296 
4297     ASSERT_EQ(p.ShowError().err, Error::ErrorType::ERR_BAD_ID_FUNCTION);
4298 }
4299