diff options
Diffstat (limited to 'MoonParser')
-rw-r--r-- | MoonParser/ast.hpp | 13 | ||||
-rw-r--r-- | MoonParser/moon_ast.cpp | 393 | ||||
-rw-r--r-- | MoonParser/moon_ast.h | 18 |
3 files changed, 14 insertions, 410 deletions
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp index 1b40e1b..955cdc0 100644 --- a/MoonParser/ast.hpp +++ b/MoonParser/ast.hpp | |||
@@ -80,11 +80,20 @@ private: | |||
80 | }; | 80 | }; |
81 | 81 | ||
82 | template<class T> | 82 | template<class T> |
83 | T* ast_cast(ast_node *node) | 83 | T* ast_cast(ast_node *node) { |
84 | { | ||
85 | return node && ast_type<T>() == node->get_type() ? static_cast<T*>(node) : nullptr; | 84 | return node && ast_type<T>() == node->get_type() ? static_cast<T*>(node) : nullptr; |
86 | } | 85 | } |
87 | 86 | ||
87 | template <class ...Args> | ||
88 | bool ast_is(ast_node* node) { | ||
89 | if (!node) return false; | ||
90 | bool result = false; | ||
91 | int type = node->get_type(); | ||
92 | using swallow = bool[]; | ||
93 | (void)swallow{result || (result = ast_type<Args>() == type)...}; | ||
94 | return result; | ||
95 | } | ||
96 | |||
88 | class ast_member; | 97 | class ast_member; |
89 | 98 | ||
90 | 99 | ||
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 | { |
diff --git a/MoonParser/moon_ast.h b/MoonParser/moon_ast.h index 4da4b8d..7a0e805 100644 --- a/MoonParser/moon_ast.h +++ b/MoonParser/moon_ast.h | |||
@@ -39,48 +39,38 @@ public: \ | |||
39 | }; | 39 | }; |
40 | 40 | ||
41 | AST_LEAF(Num) | 41 | AST_LEAF(Num) |
42 | virtual void visit(void* ud) override; | ||
43 | AST_END(Num) | 42 | AST_END(Num) |
44 | 43 | ||
45 | AST_LEAF(_Name) | 44 | AST_LEAF(_Name) |
46 | virtual void visit(void* ud) override; | ||
47 | AST_END(_Name) | 45 | AST_END(_Name) |
48 | 46 | ||
49 | AST_NODE(Name) | 47 | AST_NODE(Name) |
50 | ast_ptr<_Name_t> name; | 48 | ast_ptr<_Name_t> name; |
51 | virtual void visit(void* ud) override; | ||
52 | AST_END(Name) | 49 | AST_END(Name) |
53 | 50 | ||
54 | AST_LEAF(self) | 51 | AST_LEAF(self) |
55 | virtual void visit(void* ud) override; | ||
56 | AST_END(self) | 52 | AST_END(self) |
57 | 53 | ||
58 | AST_NODE(self_name) | 54 | AST_NODE(self_name) |
59 | ast_ptr<_Name_t> name; | 55 | ast_ptr<_Name_t> name; |
60 | virtual void visit(void* ud) override; | ||
61 | AST_END(self_name) | 56 | AST_END(self_name) |
62 | 57 | ||
63 | AST_LEAF(self_class) | 58 | AST_LEAF(self_class) |
64 | virtual void visit(void* ud) override; | ||
65 | AST_END(self_class) | 59 | AST_END(self_class) |
66 | 60 | ||
67 | AST_NODE(self_class_name) | 61 | AST_NODE(self_class_name) |
68 | ast_ptr<_Name_t> name; | 62 | ast_ptr<_Name_t> name; |
69 | virtual void visit(void* ud) override; | ||
70 | AST_END(self_class_name) | 63 | AST_END(self_class_name) |
71 | 64 | ||
72 | AST_NODE(SelfName) | 65 | AST_NODE(SelfName) |
73 | ast_ptr<ast_node> name; // self_class_name_t | self_class_t | self_name_t | self_t | 66 | ast_ptr<ast_node> name; // self_class_name_t | self_class_t | self_name_t | self_t |
74 | virtual void visit(void* ud) override; | ||
75 | AST_END(SelfName) | 67 | AST_END(SelfName) |
76 | 68 | ||
77 | AST_NODE(KeyName) | 69 | AST_NODE(KeyName) |
78 | ast_ptr<ast_node> name; // SelfName_t | _Name_t | 70 | ast_ptr<ast_node> name; // SelfName_t | _Name_t |
79 | virtual void visit(void* ud) override; | ||
80 | AST_END(KeyName) | 71 | AST_END(KeyName) |
81 | 72 | ||
82 | AST_LEAF(VarArg) | 73 | AST_LEAF(VarArg) |
83 | virtual void visit(void* ud) override; | ||
84 | AST_END(VarArg) | 74 | AST_END(VarArg) |
85 | 75 | ||
86 | AST_LEAF(local_flag) | 76 | AST_LEAF(local_flag) |
@@ -92,8 +82,6 @@ AST_END(Seperator) | |||
92 | AST_NODE(NameList) | 82 | AST_NODE(NameList) |
93 | ast_ptr<Seperator_t> sep; | 83 | ast_ptr<Seperator_t> sep; |
94 | ast_list<Name_t> names; | 84 | ast_list<Name_t> names; |
95 | |||
96 | virtual void visit(void* ud) override; | ||
97 | AST_END(NameList) | 85 | AST_END(NameList) |
98 | 86 | ||
99 | AST_NODE(Local) | 87 | AST_NODE(Local) |
@@ -114,24 +102,20 @@ AST_NODE(Import) | |||
114 | ast_ptr<Seperator_t> sep; | 102 | ast_ptr<Seperator_t> sep; |
115 | ast_list<ImportName_t> names; | 103 | ast_list<ImportName_t> names; |
116 | ast_ptr<Exp_t> exp; | 104 | ast_ptr<Exp_t> exp; |
117 | virtual void visit(void* ud) override; | ||
118 | AST_END(Import) | 105 | AST_END(Import) |
119 | 106 | ||
120 | AST_NODE(ExpListLow) | 107 | AST_NODE(ExpListLow) |
121 | ast_ptr<Seperator_t> sep; | 108 | ast_ptr<Seperator_t> sep; |
122 | ast_list<Exp_t> exprs; | 109 | ast_list<Exp_t> exprs; |
123 | virtual void visit(void* ud) override; | ||
124 | AST_END(ExpListLow) | 110 | AST_END(ExpListLow) |
125 | 111 | ||
126 | AST_NODE(ExpList) | 112 | AST_NODE(ExpList) |
127 | ast_ptr<Seperator_t> sep; | 113 | ast_ptr<Seperator_t> sep; |
128 | ast_list<Exp_t> exprs; | 114 | ast_list<Exp_t> exprs; |
129 | virtual void visit(void* ud) override; | ||
130 | AST_END(ExpList) | 115 | AST_END(ExpList) |
131 | 116 | ||
132 | AST_NODE(Return) | 117 | AST_NODE(Return) |
133 | ast_ptr<ExpListLow_t, true> valueList; | 118 | ast_ptr<ExpListLow_t, true> valueList; |
134 | virtual void visit(void* ud) override; | ||
135 | AST_END(Return) | 119 | AST_END(Return) |
136 | 120 | ||
137 | class Assign_t; | 121 | class Assign_t; |
@@ -141,7 +125,6 @@ AST_NODE(With) | |||
141 | ast_ptr<ExpList_t> valueList; | 125 | ast_ptr<ExpList_t> valueList; |
142 | ast_ptr<Assign_t, true> assigns; | 126 | ast_ptr<Assign_t, true> assigns; |
143 | ast_ptr<Body_t> body; | 127 | ast_ptr<Body_t> body; |
144 | virtual void visit(void* ud) override; | ||
145 | AST_END(With) | 128 | AST_END(With) |
146 | 129 | ||
147 | AST_NODE(SwitchCase) | 130 | AST_NODE(SwitchCase) |
@@ -324,7 +307,6 @@ AST_END(Chain) | |||
324 | 307 | ||
325 | AST_NODE(Value) | 308 | AST_NODE(Value) |
326 | ast_ptr<ast_node> item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t | 309 | ast_ptr<ast_node> item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t |
327 | ast_node* getFlattened(); | ||
328 | AST_END(Value) | 310 | AST_END(Value) |
329 | 311 | ||
330 | AST_LEAF(LuaString) | 312 | AST_LEAF(LuaString) |