diff options
Diffstat (limited to 'MoonParser/moon_ast.cpp')
-rw-r--r-- | MoonParser/moon_ast.cpp | 393 |
1 files changed, 3 insertions, 390 deletions
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp index 41d0c55..d8a0db9 100644 --- a/MoonParser/moon_ast.cpp +++ b/MoonParser/moon_ast.cpp | |||
@@ -7,125 +7,6 @@ | |||
7 | #include <vector> | 7 | #include <vector> |
8 | #include "moon_ast.h" | 8 | #include "moon_ast.h" |
9 | 9 | ||
10 | class Data | ||
11 | { | ||
12 | public: | ||
13 | Data() | ||
14 | { | ||
15 | indent = 0; | ||
16 | callerStack.push(false); | ||
17 | } | ||
18 | |||
19 | Converter conv; | ||
20 | std::stringstream temp; | ||
21 | std::stringstream buffer; | ||
22 | std::vector<int> lineTable; | ||
23 | std::stack<bool> callerStack; | ||
24 | std::stack<std::string> withStack; | ||
25 | |||
26 | void beginLine(int line = -1) | ||
27 | { | ||
28 | for (int i = 0; i < indent; i++) | ||
29 | { | ||
30 | buffer << '\t'; | ||
31 | } | ||
32 | lineTable.push_back(line == -1 ? lineTable.back() : line); | ||
33 | } | ||
34 | |||
35 | void endLine() | ||
36 | { | ||
37 | buffer << '\n'; | ||
38 | } | ||
39 | |||
40 | int indent; | ||
41 | struct Scope | ||
42 | { | ||
43 | Scope() | ||
44 | { | ||
45 | localObjIndex = 0; | ||
46 | localFnIndex = 0; | ||
47 | localBaseIndex = 0; | ||
48 | localWithIndex = 0; | ||
49 | } | ||
50 | int localObjIndex; | ||
51 | int localFnIndex; | ||
52 | int localBaseIndex; | ||
53 | int localWithIndex; | ||
54 | std::vector<std::string> locals; | ||
55 | }; | ||
56 | |||
57 | std::string getNewLocalObj() | ||
58 | { | ||
59 | temp << "_obj_" << scope().localObjIndex; | ||
60 | scope().localObjIndex++; | ||
61 | std::string local = temp.str(); | ||
62 | temp.str(""); | ||
63 | temp.clear(); | ||
64 | return local; | ||
65 | } | ||
66 | |||
67 | std::string getNewLocalFn() | ||
68 | { | ||
69 | temp << "_fn_" << scope().localObjIndex; | ||
70 | scope().localFnIndex++; | ||
71 | std::string local = temp.str(); | ||
72 | temp.str(""); | ||
73 | temp.clear(); | ||
74 | return local; | ||
75 | } | ||
76 | |||
77 | std::string getNewLocalBase() | ||
78 | { | ||
79 | temp << "_base_" << scope().localBaseIndex; | ||
80 | scope().localBaseIndex++; | ||
81 | std::string local = temp.str(); | ||
82 | temp.str(""); | ||
83 | temp.clear(); | ||
84 | return local; | ||
85 | } | ||
86 | |||
87 | bool isLocal(const std::string& var) | ||
88 | { | ||
89 | return _localVars.find(var) != _localVars.end(); | ||
90 | } | ||
91 | |||
92 | void putLocal(const std::string& var) | ||
93 | { | ||
94 | if (_localVars.find(var) == _localVars.end()) | ||
95 | { | ||
96 | _localVars.insert(var); | ||
97 | _scopeStack.top().locals.push_back(var); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | void pushScope() | ||
102 | { | ||
103 | int lastWithIndex = scope().localWithIndex; | ||
104 | _scopeStack.emplace(); | ||
105 | scope().localWithIndex = lastWithIndex + 1; | ||
106 | indent++; | ||
107 | } | ||
108 | |||
109 | Scope& scope() | ||
110 | { | ||
111 | return _scopeStack.top(); | ||
112 | } | ||
113 | |||
114 | void popScope() | ||
115 | { | ||
116 | const auto& scope = _scopeStack.top(); | ||
117 | for (const auto& var : scope.locals) | ||
118 | { | ||
119 | _localVars.erase(var); | ||
120 | } | ||
121 | _scopeStack.pop(); | ||
122 | indent--; | ||
123 | } | ||
124 | private: | ||
125 | std::unordered_set<std::string> _localVars; | ||
126 | std::stack<Scope> _scopeStack; | ||
127 | }; | ||
128 | |||
129 | std::string& trim(std::string& s) | 10 | std::string& trim(std::string& s) |
130 | { | 11 | { |
131 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) | 12 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) |
@@ -266,288 +147,20 @@ AST_IMPL(Line) | |||
266 | AST_IMPL(Block) | 147 | AST_IMPL(Block) |
267 | AST_IMPL(BlockEnd) | 148 | AST_IMPL(BlockEnd) |
268 | 149 | ||
269 | void Num_t::visit(void* ud) | ||
270 | { | ||
271 | Data* data = static_cast<Data*>(ud); | ||
272 | std::string str = data->conv.to_bytes(&*m_begin.m_it, &*m_end.m_it); | ||
273 | data->buffer << trim(str); | ||
274 | } | ||
275 | |||
276 | void _Name_t::visit(void* ud) | ||
277 | { | ||
278 | Data* data = static_cast<Data*>(ud); | ||
279 | data->buffer << getValue(); | ||
280 | } | ||
281 | |||
282 | void Name_t::visit(void* ud) | ||
283 | { | ||
284 | name->visit(ud); | ||
285 | } | ||
286 | |||
287 | void self_t::visit(void* ud) | ||
288 | { | ||
289 | Data* data = static_cast<Data*>(ud); | ||
290 | data->buffer << "self"; | ||
291 | } | ||
292 | |||
293 | void self_name_t::visit(void* ud) | ||
294 | { | ||
295 | Data* data = static_cast<Data*>(ud); | ||
296 | data->buffer << (data->callerStack.top() ? "self:" : "self."); | ||
297 | name->visit(ud); | ||
298 | } | ||
299 | |||
300 | void self_class_t::visit(void* ud) | ||
301 | { | ||
302 | Data* data = static_cast<Data*>(ud); | ||
303 | data->buffer << "self.__class"; | ||
304 | } | ||
305 | |||
306 | void self_class_name_t::visit(void* ud) | ||
307 | { | ||
308 | Data* data = static_cast<Data*>(ud); | ||
309 | data->buffer << (data->callerStack.top() ? "self.__class:" : "self.__class."); | ||
310 | name->visit(ud); | ||
311 | } | ||
312 | |||
313 | void SelfName_t::visit(void* ud) | ||
314 | { | ||
315 | name->visit(ud); | ||
316 | } | ||
317 | |||
318 | void KeyName_t::visit(void* ud) | ||
319 | { | ||
320 | name->visit(ud); | ||
321 | } | ||
322 | |||
323 | void VarArg_t::visit(void* ud) | ||
324 | { | ||
325 | Data* data = static_cast<Data*>(ud); | ||
326 | data->buffer << "..."; | ||
327 | } | ||
328 | |||
329 | void NameList_t::visit(void* ud) | ||
330 | { | ||
331 | Data* data = static_cast<Data*>(ud); | ||
332 | auto it = names.objects().begin(); | ||
333 | Name_t* name = *it; | ||
334 | name->visit(ud); | ||
335 | ++it; | ||
336 | for (; it != names.objects().end(); ++it) | ||
337 | { | ||
338 | name = *it; | ||
339 | data->buffer << ", "; | ||
340 | name->visit(ud); | ||
341 | } | ||
342 | } | ||
343 | |||
344 | void Import_t::visit(void* ud) | ||
345 | { | ||
346 | Data* data = static_cast<Data*>(ud); | ||
347 | std::vector<std::tuple<const std::string*, bool>> nameItems; | ||
348 | nameItems.reserve(names.objects().size()); | ||
349 | for (ImportName_t* importName : names.objects()) | ||
350 | { | ||
351 | if (Name_t* name = ast_cast<Name_t>(importName->name)) | ||
352 | { | ||
353 | nameItems.push_back(std::make_tuple(&name->name->getValue(), false)); | ||
354 | } | ||
355 | else | ||
356 | { | ||
357 | colon_import_name_t* colonName = ast_cast<colon_import_name_t>(importName->name); | ||
358 | nameItems.push_back(std::make_tuple(&colonName->name->name->getValue(), true)); | ||
359 | } | ||
360 | } | ||
361 | data->buffer << "local "; | ||
362 | for (const auto& item : nameItems) | ||
363 | { | ||
364 | data->buffer << *std::get<0>(item); | ||
365 | if (&item != &nameItems.back()) | ||
366 | { | ||
367 | data->buffer << ", "; | ||
368 | } | ||
369 | } | ||
370 | data->endLine(); | ||
371 | |||
372 | data->beginLine(); | ||
373 | data->pushScope(); | ||
374 | data->buffer << "do"; | ||
375 | data->endLine(); | ||
376 | |||
377 | std::string fromObj = data->getNewLocalObj(); | ||
378 | |||
379 | data->beginLine(); | ||
380 | data->buffer << "local " << fromObj << " = "; | ||
381 | exp->visit(ud); | ||
382 | data->endLine(); | ||
383 | |||
384 | data->beginLine(); | ||
385 | for (const auto& item : nameItems) | ||
386 | { | ||
387 | data->buffer << *std::get<0>(item); | ||
388 | if (&item != &nameItems.back()) | ||
389 | { | ||
390 | data->buffer << ", "; | ||
391 | } | ||
392 | } | ||
393 | data->buffer << " = "; | ||
394 | for (const auto& item : nameItems) | ||
395 | { | ||
396 | if (std::get<1>(item)) | ||
397 | { | ||
398 | data->pushScope(); | ||
399 | data->buffer << "(function()"; | ||
400 | data->endLine(); | ||
401 | |||
402 | std::string varBase = data->getNewLocalBase(); | ||
403 | |||
404 | data->beginLine(); | ||
405 | data->buffer << "local " << varBase << " = " << fromObj; | ||
406 | data->endLine(); | ||
407 | |||
408 | std::string varFn = data->getNewLocalFn(); | ||
409 | |||
410 | data->beginLine(); | ||
411 | data->buffer << "local " << varFn << " = " << varBase << '.' << *std::get<0>(item); | ||
412 | data->endLine(); | ||
413 | |||
414 | data->beginLine(); | ||
415 | data->buffer << "return function(...)"; | ||
416 | data->endLine(); | ||
417 | |||
418 | data->beginLine(); | ||
419 | data->pushScope(); | ||
420 | data->buffer << varFn << '(' << varBase << ", ...)"; | ||
421 | data->endLine(); | ||
422 | |||
423 | data->beginLine(); | ||
424 | data->buffer << "end"; | ||
425 | data->popScope(); | ||
426 | data->endLine(); | ||
427 | |||
428 | data->beginLine(); | ||
429 | data->buffer << "end)()"; | ||
430 | data->popScope(); | ||
431 | } | ||
432 | else | ||
433 | { | ||
434 | data->buffer << fromObj << '.' << *std::get<0>(item); | ||
435 | } | ||
436 | if (&item != &nameItems.back()) | ||
437 | { | ||
438 | data->buffer << ", "; | ||
439 | } | ||
440 | } | ||
441 | data->endLine(); | ||
442 | |||
443 | data->beginLine(); | ||
444 | data->buffer << "end"; | ||
445 | data->popScope(); | ||
446 | } | ||
447 | |||
448 | void ExpListLow_t::visit(void* ud) | ||
449 | { | ||
450 | Data* data = static_cast<Data*>(ud); | ||
451 | for (Exp_t* expr : exprs.objects()) | ||
452 | { | ||
453 | expr->visit(ud); | ||
454 | if (expr != exprs.objects().back()) | ||
455 | { | ||
456 | data->buffer << ", "; | ||
457 | } | ||
458 | } | ||
459 | } | ||
460 | |||
461 | void ExpList_t::visit(void* ud) | ||
462 | { | ||
463 | Data* data = static_cast<Data*>(ud); | ||
464 | for (Exp_t* expr : exprs.objects()) | ||
465 | { | ||
466 | expr->visit(ud); | ||
467 | if (expr != exprs.objects().back()) | ||
468 | { | ||
469 | data->buffer << ", "; | ||
470 | } | ||
471 | } | ||
472 | } | ||
473 | |||
474 | void Return_t::visit(void* ud) | ||
475 | { | ||
476 | Data* data = static_cast<Data*>(ud); | ||
477 | data->buffer << "return"; | ||
478 | if (valueList && !valueList->exprs.objects().empty()) | ||
479 | { | ||
480 | data->buffer << ' '; | ||
481 | valueList->visit(ud); | ||
482 | } | ||
483 | } | ||
484 | |||
485 | void With_t::visit(void* ud) | ||
486 | { | ||
487 | Data* data = static_cast<Data*>(ud); | ||
488 | data->buffer << "return"; | ||
489 | for (Exp_t* expr : valueList->exprs.objects()) | ||
490 | { | ||
491 | if (assigns && (!expr->opValues.objects().empty() || expr->value->getFlattened())) | ||
492 | { | ||
493 | throw std::logic_error("left hand expression is not assignable."); | ||
494 | } | ||
495 | // TODO | ||
496 | } | ||
497 | if (valueList && !valueList->exprs.objects().empty()) | ||
498 | { | ||
499 | data->buffer << ' '; | ||
500 | valueList->visit(ud); | ||
501 | } | ||
502 | } | ||
503 | |||
504 | ast_node* Value_t::getFlattened() | ||
505 | { | ||
506 | if (SimpleValue_t* simpleValue = ast_cast<SimpleValue_t>(item)) | ||
507 | { | ||
508 | return simpleValue->value; | ||
509 | } | ||
510 | else if (simple_table_t* simple_table = ast_cast<simple_table_t>(item)) | ||
511 | { | ||
512 | return simple_table; | ||
513 | } | ||
514 | else if (ChainValue_t* chainValue = ast_cast<ChainValue_t>(item)) | ||
515 | { | ||
516 | if (chainValue->arguments) | ||
517 | { | ||
518 | return chainValue; | ||
519 | } | ||
520 | else | ||
521 | { | ||
522 | if (Chain_t* chain = ast_cast<Chain_t>(chainValue->caller)) | ||
523 | { | ||
524 | return chain->item; | ||
525 | } | ||
526 | else if (Callable_t* callable = ast_cast<Callable_t>(chainValue->caller)) | ||
527 | { | ||
528 | return callable->item; | ||
529 | } | ||
530 | } | ||
531 | } | ||
532 | return item; | ||
533 | } | ||
534 | |||
535 | #include <iostream> | 150 | #include <iostream> |
536 | 151 | ||
537 | int main() | 152 | int main() |
538 | { | 153 | { |
539 | std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> conv; | 154 | std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> conv; |
540 | std::string s = R"baddog(import \x, func, \memFunc from require "utils")baddog"; | 155 | std::string s = R"TestCodesHere()TestCodesHere"; |
541 | input i = conv.from_bytes(s); | 156 | input i = conv.from_bytes(s); |
542 | 157 | ||
543 | error_list el; | 158 | error_list el; |
544 | Import_t* root = nullptr; | 159 | BlockEnd_t* root = nullptr; |
545 | State st; | 160 | State st; |
546 | if (parse(i, Import, el, root, &st)) | 161 | if (parse(i, BlockEnd, el, root, &st)) |
547 | { | 162 | { |
548 | std::cout << "matched!\n"; | 163 | std::cout << "matched!\n"; |
549 | Data data; | ||
550 | root->visit(&data); | ||
551 | } | 164 | } |
552 | else | 165 | else |
553 | { | 166 | { |