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