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