aboutsummaryrefslogtreecommitdiff
path: root/MoonParser/moon_ast.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'MoonParser/moon_ast.cpp')
-rw-r--r--MoonParser/moon_ast.cpp1659
1 files changed, 1659 insertions, 0 deletions
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp
new file mode 100644
index 0000000..1595220
--- /dev/null
+++ b/MoonParser/moon_ast.cpp
@@ -0,0 +1,1659 @@
1#include <iostream>
2#include <string>
3#include <codecvt>
4#include <unordered_set>
5#include <stack>
6#include <algorithm>
7#include <sstream>
8#include <vector>
9#include "parserlib.hpp"
10using namespace parserlib;
11
12template<class Facet>
13struct deletable_facet : Facet
14{
15 template<class ...Args>
16 deletable_facet(Args&& ...args): Facet(std::forward<Args>(args)...) {}
17 ~deletable_facet() {}
18};
19typedef std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> Converter;
20
21static inline std::string& trim(std::string& s)
22{
23 s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch)
24 {
25 return !std::isspace(ch);
26 }));
27 s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch)
28 {
29 return !std::isspace(ch);
30 }).base(), s.end());
31 return s;
32}
33
34#define p(expr) user(expr, [](const item_t& item) \
35{ \
36 stringstream stream; \
37 for (input_it i = item.begin; i != item.end; ++i) stream << static_cast<char>(*i); \
38 cout << #expr << ": [" << stream.str() << "]\n"; \
39 return true; \
40})
41
42struct State
43{
44 State()
45 {
46 indents.push(0);
47 stringOpen = -1;
48 }
49 std::stringstream buffer;
50 size_t stringOpen;
51 std::stack<int> indents;
52 std::stack<bool> doStack;
53 std::unordered_set<std::string> keywords = {
54 "and", "while", "else", "using", "continue",
55 "local", "not", "then", "return", "from",
56 "extends", "for", "do", "or", "export",
57 "class", "in", "unless", "when", "elseif",
58 "switch", "break", "if", "with", "import"
59 };
60};
61
62class Data
63{
64public:
65 Data()
66 {
67 indent = 0;
68 callerStack.push(false);
69 }
70
71 Converter conv;
72 std::stringstream temp;
73 std::stringstream buffer;
74 std::vector<int> lineTable;
75 std::stack<bool> callerStack;
76 std::stack<std::string> withStack;
77
78 void beginLine(int line = -1)
79 {
80 for (int i = 0; i < indent; i++)
81 {
82 buffer << '\t';
83 }
84 lineTable.push_back(line == -1 ? lineTable.back() : line);
85 }
86
87 void endLine()
88 {
89 buffer << '\n';
90 }
91
92 int indent;
93 struct Scope
94 {
95 Scope()
96 {
97 localObjIndex = 0;
98 localFnIndex = 0;
99 localBaseIndex = 0;
100 localWithIndex = 0;
101 }
102 int localObjIndex;
103 int localFnIndex;
104 int localBaseIndex;
105 int localWithIndex;
106 std::vector<std::string> locals;
107 };
108
109 std::string getNewLocalObj()
110 {
111 temp << "_obj_" << scope().localObjIndex;
112 scope().localObjIndex++;
113 std::string local = temp.str();
114 temp.str("");
115 temp.clear();
116 return local;
117 }
118
119 std::string getNewLocalFn()
120 {
121 temp << "_fn_" << scope().localObjIndex;
122 scope().localFnIndex++;
123 std::string local = temp.str();
124 temp.str("");
125 temp.clear();
126 return local;
127 }
128
129 std::string getNewLocalBase()
130 {
131 temp << "_base_" << scope().localBaseIndex;
132 scope().localBaseIndex++;
133 std::string local = temp.str();
134 temp.str("");
135 temp.clear();
136 return local;
137 }
138
139 bool isLocal(const std::string& var)
140 {
141 return _localVars.find(var) != _localVars.end();
142 }
143
144 void putLocal(const std::string& var)
145 {
146 if (_localVars.find(var) == _localVars.end())
147 {
148 _localVars.insert(var);
149 _scopeStack.top().locals.push_back(var);
150 }
151 }
152
153 void pushScope()
154 {
155 int lastWithIndex = scope().localWithIndex;
156 _scopeStack.emplace();
157 scope().localWithIndex = lastWithIndex + 1;
158 indent++;
159 }
160
161 Scope& scope()
162 {
163 return _scopeStack.top();
164 }
165
166 void popScope()
167 {
168 const auto& scope = _scopeStack.top();
169 for (const auto& var : scope.locals)
170 {
171 _localVars.erase(var);
172 }
173 _scopeStack.pop();
174 indent--;
175 }
176private:
177 std::unordered_set<std::string> _localVars;
178 std::stack<Scope> _scopeStack;
179};
180
181rule Any = any();
182rule plain_space = *set(" \t");
183rule Break = nl(-expr('\r') >> '\n');
184rule White = *(set(" \t") | Break);
185rule Stop = Break | eof();
186rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop);
187rule Indent = *set(" \t");
188rule Space = plain_space >> -Comment;
189rule SomeSpace = +set(" \t") >> -Comment;
190rule SpaceBreak = Space >> Break;
191rule EmptyLine = SpaceBreak;
192rule AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_';
193rule _Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum;
194rule SpaceName = Space >> _Name;
195rule _Num =
196 (
197 "0x" >>
198 +(range('0', '9') | range('a', 'f') | range('A', 'F')) >>
199 -(-set("uU") >> set("lL") >> set("lL"))
200 ) | (
201 +range('0', '9') >> -set("uU") >> set("lL") >> set("lL")
202 ) | (
203 (
204 (+range('0', '9') >> -('.' >> +range('0', '9'))) |
205 ('.' >> +range('0', '9'))
206 ) >> -(set("eE") >> -expr('-') >> +range('0', '9'))
207 );
208rule Num = Space >> _Num;
209rule Cut = false_();
210rule Seperator = true_();
211
212#define sym(str) (Space >> str)
213#define symx(str) expr(str)
214#define ensure(patt, finally) (((patt) >> (finally)) | ((finally) >> (Cut)))
215#define key(str) (Space >> str >> not_(AlphaNum))
216#define opWord(str) (Space >> str >> not_(AlphaNum))
217#define op(str) (Space >> str)
218
219rule Name = user(SpaceName, [](const item_t& item)
220{
221 State* st = reinterpret_cast<State*>(item.user_data);
222 for (auto it = item.begin; it != item.end; ++it) st->buffer << static_cast<char>(*it);
223 std::string name;
224 st->buffer >> name;
225 st->buffer.str("");
226 st->buffer.clear();
227 auto it = st->keywords.find(name);
228 return it == st->keywords.end();
229});
230
231rule self = expr('@');
232rule self_name = '@' >> _Name;
233rule self_class = expr("@@");
234rule self_class_name = "@@" >> _Name;
235
236rule SelfName = Space >> (self_class_name | self_class | self_name | self);
237rule KeyName = SelfName | Space >> _Name;
238rule VarArg = Space >> "...";
239
240rule check_indent = user(Indent, [](const item_t& item)
241{
242 int indent = 0;
243 for (input_it i = item.begin; i != item.end; ++i)
244 {
245 switch (*i)
246 {
247 case ' ': indent++; break;
248 case '\t': indent += 4; break;
249 }
250 }
251 State* st = reinterpret_cast<State*>(item.user_data);
252 return st->indents.top() == indent;
253});
254rule CheckIndent = and_(check_indent);
255
256rule advance = user(Indent, [](const item_t& item)
257{
258 int indent = 0;
259 for (input_it i = item.begin; i != item.end; ++i)
260 {
261 switch (*i)
262 {
263 case ' ': indent++; break;
264 case '\t': indent += 4; break;
265 }
266 }
267 State* st = reinterpret_cast<State*>(item.user_data);
268 int top = st->indents.top();
269 if (top != -1 && indent > top)
270 {
271 st->indents.push(indent);
272 return true;
273 }
274 return false;
275});
276rule Advance = and_(advance);
277
278rule push_indent = user(Indent, [](const item_t& item)
279{
280 int indent = 0;
281 for (input_it i = item.begin; i != item.end; ++i)
282 {
283 switch (*i)
284 {
285 case ' ': indent++; break;
286 case '\t': indent += 4; break;
287 }
288 }
289 State* st = reinterpret_cast<State*>(item.user_data);
290 st->indents.push(indent);
291 return true;
292});
293rule PushIndent = and_(push_indent);
294
295rule PreventIndent = user(true_(), [](const item_t& item)
296{
297 State* st = reinterpret_cast<State*>(item.user_data);
298 st->indents.push(-1);
299 return true;
300});
301
302rule PopIndent = user(true_(), [](const item_t& item)
303{
304 State* st = reinterpret_cast<State*>(item.user_data);
305 st->indents.pop();
306 return true;
307});
308
309extern rule Block;
310
311rule InBlock = Advance >> Block >> PopIndent;
312
313extern rule NameList;
314
315rule local_flag = op('*') | op('^');
316rule Local = key("local") >> (local_flag | NameList);
317
318rule colon_import_name = sym('\\') >> Name;
319rule ImportName = colon_import_name | Name;
320rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName);
321
322extern rule Exp;
323
324rule Import = key("import") >> ImportNameList >> *SpaceBreak >> key("from") >> Exp;
325rule BreakLoop = key("break") | key("continue");
326
327extern rule ExpListLow, ExpList, Assign;
328
329rule Return = key("return") >> -ExpListLow;
330rule WithExp = ExpList >> -Assign;
331
332extern rule DisableDo, PopDo, Body;
333
334rule With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body;
335rule SwitchCase = key("when") >> ExpList >> -key("then") >> Body;
336rule SwitchElse = key("else") >> Body;
337
338rule SwitchBlock = *EmptyLine >>
339 Advance >> Seperator >>
340 SwitchCase >>
341 *(+Break >> SwitchCase) >>
342 -(+Break >> SwitchElse) >>
343 PopIndent;
344
345rule Switch = key("switch") >>
346 DisableDo >> ensure(Exp, PopDo) >>
347 -key("do") >> -Space >> Break >> SwitchBlock;
348
349rule IfCond = Exp >> -Assign;
350rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body;
351rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body;
352rule If = key("if") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse;
353rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse;
354
355rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body;
356
357rule for_step_value = sym(',') >> Exp;
358rule for_args = Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
359
360rule For = key("for") >> DisableDo >>
361 ensure(for_args, PopDo) >>
362 -key("do") >> Body;
363
364extern rule AssignableNameList;
365
366rule for_in = sym('*') >> Exp | ExpList;
367
368rule ForEach = key("for") >> AssignableNameList >> key("in") >>
369 DisableDo >> ensure(for_in, PopDo) >>
370 -key("do") >> Body;
371
372rule Do = user(key("do") >> Body, [](const item_t& item)
373{
374 State* st = reinterpret_cast<State*>(item.user_data);
375 return st->doStack.empty() || st->doStack.top();
376});
377
378rule DisableDo = user(true_(), [](const item_t& item)
379{
380 State* st = reinterpret_cast<State*>(item.user_data);
381 st->doStack.push(false);
382 return true;
383});
384
385rule PopDo = user(true_(), [](const item_t& item)
386{
387 State* st = reinterpret_cast<State*>(item.user_data);
388 st->doStack.pop();
389 return true;
390});
391
392extern rule CompInner;
393
394rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']');
395rule comp_value = sym(',') >> Exp;
396rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}');
397
398extern rule CompForEach, CompFor, CompClause;
399
400rule CompInner = (CompForEach | CompFor) >> Seperator >> *CompClause;
401rule star_exp = sym('*') >> Exp;
402rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp);
403rule CompFor = key("for") >> Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
404rule CompClause = CompFor | CompForEach | key("when") >> Exp;
405
406extern rule TableBlock;
407
408rule Assign = sym('=') >> (With | If | Switch | TableBlock | ExpListLow);
409
410rule update_op =
411 sym("..=") |
412 sym("+=") |
413 sym("-=") |
414 sym("*=") |
415 sym("/=") |
416 sym("%=") |
417 sym("or=") |
418 sym("and=") |
419 sym("&=") |
420 sym("|=") |
421 sym(">>=") |
422 sym("<<=");
423
424rule Update = update_op >> Exp;
425
426rule CharOperators = Space >> set("+-*/%^><|&");
427rule WordOperators =
428 opWord("or") |
429 opWord("and") |
430 op("<=") |
431 op(">=") |
432 op("~=") |
433 op("!=") |
434 op("==") |
435 op("..") |
436 op("<<") |
437 op(">>") |
438 op("//");
439
440rule BinaryOperator = (WordOperators | CharOperators) >> *SpaceBreak;
441
442extern rule Chain;
443
444rule Assignable = Chain | Name | SelfName;
445
446extern rule Value;
447
448rule exp_op_value = BinaryOperator >> Value;
449rule Exp = Value >> *exp_op_value;
450
451extern rule Callable, InvokeArgs;
452
453rule ChainValue = (Chain | Callable) >> -InvokeArgs;
454
455extern rule KeyValue, String, SimpleValue;
456
457rule simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
458rule Value = SimpleValue | simple_table | ChainValue | String;
459
460extern rule LuaString;
461
462rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any;
463rule SingleString = symx('\'') >> *single_string_inner >> sym('\'');
464rule interp = symx("#{") >> Exp >> sym('}');
465rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any;
466rule double_string_inner = +(not_(interp) >> double_string_plain);
467rule double_string_content = double_string_inner | interp;
468rule DoubleString = symx('"') >> Seperator >> *double_string_content >> sym('"');
469rule String = Space >> (DoubleString | SingleString | LuaString);
470
471rule lua_string_open = '[' >> *expr('=') >> '[';
472rule lua_string_close = ']' >> *expr('=') >> ']';
473
474rule LuaStringOpen = user(lua_string_open, [](const item_t& item)
475{
476 size_t count = std::distance(item.begin, item.end);
477 State* st = reinterpret_cast<State*>(item.user_data);
478 st->stringOpen = count;
479 return true;
480});
481
482rule LuaStringClose = user(lua_string_close, [](const item_t& item)
483{
484 size_t count = std::distance(item.begin, item.end);
485 State* st = reinterpret_cast<State*>(item.user_data);
486 return st->stringOpen == count;
487});
488
489rule LuaStringContent = *(not_(LuaStringClose) >> (Break | Any));
490
491rule LuaString = user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item)
492{
493 State* st = reinterpret_cast<State*>(item.user_data);
494 st->stringOpen = -1;
495 return true;
496});
497
498rule Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')');
499rule Callable = Name | SelfName | VarArg | Parens;
500rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp);
501
502rule FnArgs = Seperator >>
503(
504 (
505 symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')
506 ) | (
507 sym('!') >> not_(expr('='))
508 )
509);
510
511extern rule ChainItems, DotChainItem, ColonChain;
512
513rule chain_call = (Callable | String) >> ChainItems;
514rule chain_item = not_(set(".\\")) >> ChainItems;
515rule chain_dot_chain = DotChainItem >> -ChainItems;
516
517rule Chain =
518 chain_call |
519 chain_item |
520 Space >> (chain_dot_chain | ColonChain);
521
522extern rule ChainItem;
523
524rule chain_with_colon = +ChainItem >> -ColonChain;
525rule ChainItems = Seperator >> (chain_with_colon | ColonChain);
526
527extern rule Invoke, Slice;
528
529rule Index = symx('[') >> Exp >> sym(']');
530rule ChainItem = Invoke | DotChainItem | Slice | Index;
531rule DotChainItem = symx('.') >> _Name;
532rule ColonChainItem = symx('\\') >> _Name;
533rule invoke_chain = Invoke >> -ChainItems;
534rule ColonChain = ColonChainItem >> -invoke_chain;
535
536rule default_value = true_();
537rule Slice =
538 symx('[') >>
539 (Exp | default_value) >>
540 sym(',') >>
541 (Exp | default_value) >>
542 (sym(',') >> Exp | default_value) >>
543 sym(']');
544
545rule Invoke =
546 FnArgs |
547 SingleString |
548 DoubleString |
549 and_(expr('[')) >> LuaString;
550
551extern rule TableValueList, TableLitLine;
552
553rule TableValue = KeyValue | Exp;
554
555rule table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(',');
556
557rule TableLit =
558 sym('{') >> Seperator >>
559 -TableValueList >>
560 -sym(',') >>
561 -table_lit_lines >>
562 White >> sym('}');
563
564rule TableValueList = TableValue >> *(sym(',') >> TableValue);
565
566rule TableLitLine =
567(
568 PushIndent >> (TableValueList >> PopIndent | PopIndent)
569) | (
570 Space
571);
572
573extern rule KeyValueLine;
574
575rule TableBlockInner = Seperator >> KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine);
576rule TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent);
577
578extern rule Statement;
579
580rule class_member_list = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
581rule ClassLine = CheckIndent >> (class_member_list | Statement | Exp) >> -sym(',');
582rule ClassBlock = +(SpaceBreak) >> Advance >>Seperator >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent;
583
584rule ClassDecl =
585 key("class") >> not_(expr(':')) >>
586 -Assignable >>
587 -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >>
588 -ClassBlock;
589
590rule export_values = NameList >> -(sym('=') >> ExpListLow);
591rule export_op = op('*') | op('^');
592rule Export = key("export") >> (ClassDecl | export_op | export_values);
593
594rule variable_pair = sym(':') >> not_(SomeSpace) >> Name;
595
596rule normal_pair =
597(
598 KeyName |
599 sym('[') >> Exp >> sym(']') |
600 Space >> DoubleString |
601 Space >> SingleString
602) >>
603symx(':') >>
604(Exp | TableBlock | +(SpaceBreak) >> Exp);
605
606rule KeyValue = variable_pair | normal_pair;
607
608rule KeyValueList = KeyValue >> *(sym(',') >> KeyValue);
609rule KeyValueLine = CheckIndent >> KeyValueList >> -sym(',');
610
611rule FnArgDef = (Name | SelfName) >> -(sym('=') >> Exp);
612
613rule FnArgDefList = Seperator >>
614(
615 (
616 FnArgDef >>
617 *((sym(',') | Break) >> White >> FnArgDef) >>
618 -((sym(',') | Break) >> White >> VarArg)
619 ) | (
620 VarArg
621 )
622);
623
624rule outer_var_shadow = key("using") >> (NameList | Space >> expr("nil"));
625
626rule FnArgsDef = sym('(') >> White >> -FnArgDefList >> -outer_var_shadow >> White >> sym(')');
627rule fn_arrow = sym("->") | sym("=>");
628rule FunLit = -FnArgsDef >> fn_arrow >> -Body;
629
630rule NameList = Seperator >> Name >> *(sym(',') >> Name);
631rule NameOrDestructure = Name | TableLit;
632rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure);
633
634rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp);
635rule ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp);
636
637rule ArgLine = CheckIndent >> Exp >> *(sym(',') >> Exp);
638rule ArgBlock = Seperator >> ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent;
639
640rule invoke_args_with_table =
641 sym(',') >>
642 (
643 TableBlock |
644 SpaceBreak >> Advance >> ArgBlock >> -TableBlock
645 );
646
647rule InvokeArgs =
648 not_(expr('-')) >>
649 (
650 ExpList >> -(invoke_args_with_table | TableBlock) |
651 TableBlock
652 );
653
654rule const_value = key("nil") | key("true") | key("false");
655rule minus_exp = sym('-') >> not_(SomeSpace) >> Exp;
656rule sharp_exp = sym('#') >> Exp;
657rule tilde_exp = sym('~') >> Exp;
658rule not_exp = key("not") >> Exp;
659rule unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp;
660
661rule SimpleValue =
662 const_value |
663 If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do |
664 unary_exp |
665 TblComprehension | TableLit | Comprehension | FunLit | Num;
666
667rule Assignment = ExpList >> (Update | Assign);
668
669rule if_else_line = key("if") >> Exp >> (key("else") >> Exp | default_value);
670rule unless_line = key("unless") >> Exp;
671
672rule statement_appendix = (if_else_line | unless_line | CompInner) >> Space;
673rule Statement =
674(
675 Import | While | With | For | ForEach |
676 Switch | Return | Local | Export | BreakLoop |
677 Assignment | ExpList
678) >> Space >>
679-statement_appendix;
680
681rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement;
682
683rule empty_line_stop = Space >> and_(Stop);
684rule Line = CheckIndent >> Statement | empty_line_stop;
685rule Block = Seperator >> Line >> *(+Break >> Line);
686rule BlockEnd = Block >> eof();
687
688class AstLeaf : public ast_node
689{
690public:
691 const std::string& getValue()
692 {
693 if (_value.empty())
694 {
695 for (auto it = m_begin.m_it; it != m_end.m_it; ++it)
696 {
697 char ch = static_cast<char>(*it);
698 _value.append(&ch, 1);
699 }
700 return trim(_value);
701 }
702 return _value;
703 }
704private:
705 std::string _value;
706};
707
708#define AST_LEAF(type) \
709class type##_t : public AstLeaf \
710{ \
711public: \
712 virtual int get_type() override { return ast_type<type##_t>(); }
713
714#define AST_NODE(type) \
715class type##_t : public ast_container \
716{ \
717public: \
718 virtual int get_type() override { return ast_type<type##_t>(); }
719
720#define AST_END(type) \
721}; \
722ast<type##_t> __##type##_t(type);
723
724AST_LEAF(Num)
725 virtual void visit(void* ud) override
726 {
727 Data* data = static_cast<Data*>(ud);
728 std::string str = data->conv.to_bytes(&*m_begin.m_it, &*m_end.m_it);
729 data->buffer << trim(str);
730 }
731AST_END(Num)
732
733AST_LEAF(_Name)
734 virtual void visit(void* ud) override
735 {
736 Data* data = static_cast<Data*>(ud);
737 data->buffer << getValue();
738 }
739AST_END(_Name)
740
741AST_NODE(Name)
742 ast_ptr<_Name_t> name;
743 virtual void visit(void* ud) override
744 {
745 name->visit(ud);
746 }
747AST_END(Name)
748
749AST_LEAF(self)
750 virtual void visit(void* ud) override
751 {
752 Data* data = static_cast<Data*>(ud);
753 data->buffer << "self";
754 }
755AST_END(self)
756
757AST_NODE(self_name)
758 ast_ptr<_Name_t> name;
759 virtual void visit(void* ud) override
760 {
761 Data* data = static_cast<Data*>(ud);
762 data->buffer << (data->callerStack.top() ? "self:" : "self.");
763 name->visit(ud);
764 }
765AST_END(self_name)
766
767AST_LEAF(self_class)
768 virtual void visit(void* ud) override
769 {
770 Data* data = static_cast<Data*>(ud);
771 data->buffer << "self.__class";
772 }
773AST_END(self_class)
774
775AST_NODE(self_class_name)
776 ast_ptr<_Name_t> name;
777 virtual void visit(void* ud) override
778 {
779 Data* data = static_cast<Data*>(ud);
780 data->buffer << (data->callerStack.top() ? "self.__class:" : "self.__class.");
781 name->visit(ud);
782 }
783AST_END(self_class_name)
784
785AST_NODE(SelfName)
786 ast_ptr<ast_node> name; // self_class_name_t | self_class_t | self_name_t | self_t
787 virtual void visit(void* ud) override
788 {
789 name->visit(ud);
790 }
791AST_END(SelfName)
792
793AST_NODE(KeyName)
794 ast_ptr<ast_node> name; // SelfName_t | _Name_t
795 virtual void visit(void* ud) override
796 {
797 name->visit(ud);
798 }
799AST_END(KeyName)
800
801AST_LEAF(VarArg)
802 virtual void visit(void* ud) override
803 {
804 Data* data = static_cast<Data*>(ud);
805 data->buffer << "...";
806 }
807AST_END(VarArg)
808
809AST_LEAF(local_flag)
810AST_END(local_flag)
811
812AST_LEAF(Seperator)
813AST_END(Seperator)
814
815AST_NODE(NameList)
816 ast_ptr<Seperator_t> sep;
817 ast_list<Name_t> names;
818 virtual void visit(void* ud) override
819 {
820 Data* data = static_cast<Data*>(ud);
821 auto it = names.objects().begin();
822 Name_t* name = *it;
823 name->visit(ud);
824 ++it;
825 for (; it != names.objects().end(); ++it)
826 {
827 name = *it;
828 data->buffer << ", ";
829 name->visit(ud);
830 }
831 }
832AST_END(NameList)
833
834AST_NODE(Local)
835 ast_ptr<ast_node> name; // local_flag_t | NameList_t
836AST_END(Local)
837
838AST_NODE(colon_import_name)
839 ast_ptr<Name_t> name;
840AST_END(colon_import_name)
841
842AST_NODE(Exp)
843 ast_ptr<Value_t> value;
844 ast_list<exp_op_value_t> opValues;
845AST_END(Exp)
846
847AST_NODE(ImportName)
848 ast_ptr<ast_node> name; // colon_import_name_t | Name_t
849AST_END(ImportName)
850
851AST_NODE(Import)
852 ast_ptr<Seperator_t> sep;
853 ast_list<ImportName_t> names;
854 ast_ptr<Exp_t> exp;
855 virtual void visit(void* ud) override
856 {
857 Data* data = static_cast<Data*>(ud);
858 std::vector<std::tuple<const std::string*, bool>> nameItems;
859 nameItems.reserve(names.objects().size());
860 for (ImportName_t* importName : names.objects())
861 {
862 if (Name_t* name = ast_cast<Name_t>(importName->name))
863 {
864 nameItems.push_back(std::make_tuple(&name->name->getValue(), false));
865 }
866 else
867 {
868 colon_import_name_t* colonName = ast_cast<colon_import_name_t>(importName->name);
869 nameItems.push_back(std::make_tuple(&colonName->name->name->getValue(), true));
870 }
871 }
872 data->buffer << "local ";
873 for (const auto& item : nameItems)
874 {
875 data->buffer << *std::get<0>(item);
876 if (&item != &nameItems.back())
877 {
878 data->buffer << ", ";
879 }
880 }
881 data->endLine();
882
883 data->beginLine();
884 data->pushScope();
885 data->buffer << "do";
886 data->endLine();
887
888 std::string fromObj = data->getNewLocalObj();
889
890 data->beginLine();
891 data->buffer << "local " << fromObj << " = ";
892 ((ast_node*)exp.get())->visit(ud);
893 data->endLine();
894
895 data->beginLine();
896 for (const auto& item : nameItems)
897 {
898 data->buffer << *std::get<0>(item);
899 if (&item != &nameItems.back())
900 {
901 data->buffer << ", ";
902 }
903 }
904 data->buffer << " = ";
905 for (const auto& item : nameItems)
906 {
907 if (std::get<1>(item))
908 {
909 data->pushScope();
910 data->buffer << "(function()";
911 data->endLine();
912
913 std::string varBase = data->getNewLocalBase();
914
915 data->beginLine();
916 data->buffer << "local " << varBase << " = " << fromObj;
917 data->endLine();
918
919 std::string varFn = data->getNewLocalFn();
920
921 data->beginLine();
922 data->buffer << "local " << varFn << " = " << varBase << '.' << *std::get<0>(item);
923 data->endLine();
924
925 data->beginLine();
926 data->buffer << "return function(...)";
927 data->endLine();
928
929 data->beginLine();
930 data->pushScope();
931 data->buffer << varFn << '(' << varBase << ", ...)";
932 data->endLine();
933
934 data->beginLine();
935 data->buffer << "end";
936 data->popScope();
937 data->endLine();
938
939 data->beginLine();
940 data->buffer << "end)()";
941 data->popScope();
942 }
943 else
944 {
945 data->buffer << fromObj << '.' << *std::get<0>(item);
946 }
947 if (&item != &nameItems.back())
948 {
949 data->buffer << ", ";
950 }
951 }
952 data->endLine();
953
954 data->beginLine();
955 data->buffer << "end";
956 data->popScope();
957 }
958AST_END(Import)
959
960AST_NODE(ExpListLow)
961 ast_ptr<Seperator_t> sep;
962 ast_list<Exp_t> exprs;
963 virtual void visit(void* ud) override
964 {
965 Data* data = static_cast<Data*>(ud);
966 for (Exp_t* expr : exprs.objects())
967 {
968 ((ast_node*)expr)->visit(ud);
969 if (expr != exprs.objects().back())
970 {
971 data->buffer << ", ";
972 }
973 }
974 }
975AST_END(ExpListLow)
976
977AST_NODE(ExpList)
978 ast_ptr<Seperator_t> sep;
979 ast_list<Exp_t> exprs;
980 virtual void visit(void* ud) override
981 {
982 Data* data = static_cast<Data*>(ud);
983 for (Exp_t* expr : exprs.objects())
984 {
985 ((ast_node*)expr)->visit(ud);
986 if (expr != exprs.objects().back())
987 {
988 data->buffer << ", ";
989 }
990 }
991 }
992AST_END(ExpList)
993
994AST_NODE(Return)
995 ast_ptr<ExpListLow_t, true> valueList;
996 virtual void visit(void* ud) override
997 {
998 Data* data = static_cast<Data*>(ud);
999 data->buffer << "return";
1000 if (valueList && !valueList->exprs.objects().empty())
1001 {
1002 data->buffer << ' ';
1003 valueList->visit(ud);
1004 }
1005 }
1006AST_END(Return)
1007
1008class Assign_t;
1009class Body_t;
1010
1011AST_NODE(With)
1012 ast_ptr<ExpList_t> valueList;
1013 ast_ptr<Assign_t, true> assigns;
1014 ast_ptr<Body_t> body;
1015 /*
1016 (function()
1017 do
1018 local _with_0 = Something()
1019 _with_0:write("hello world")
1020 return _with_0
1021 end
1022 end)()
1023 */
1024 virtual void visit(void* ud) override
1025 {
1026 Data* data = static_cast<Data*>(ud);
1027 for (Exp_t* expr : valueList->exprs.objects())
1028 {
1029 }
1030 ((ast_node*)expr)->visit(ud);
1031 if (expr != exprs.objects().back())
1032 {
1033 data->buffer << ", ";
1034 }
1035 }
1036AST_END(With)
1037
1038AST_NODE(SwitchCase)
1039 ast_ptr<ExpList_t> valueList;
1040 ast_ptr<Body_t> body;
1041AST_END(SwitchCase)
1042
1043AST_NODE(Switch)
1044 ast_ptr<Exp_t> target;
1045 ast_ptr<Seperator_t> sep;
1046 ast_list<SwitchCase_t> branches;
1047 ast_ptr<Body_t, true> lastBranch;
1048AST_END(Switch)
1049
1050AST_NODE(IfCond)
1051 ast_ptr<Exp_t> condition;
1052 ast_ptr<Assign_t, true> assign;
1053AST_END(IfCond)
1054
1055AST_NODE(IfElseIf)
1056 ast_ptr<IfCond_t> condition;
1057 ast_ptr<Body_t> body;
1058AST_END(IfElseIf)
1059
1060AST_NODE(If)
1061 ast_ptr<IfCond_t> firstCondition;
1062 ast_ptr<Body_t> firstBody;
1063 ast_ptr<Seperator_t> sep;
1064 ast_list<IfElseIf_t> branches;
1065 ast_ptr<Body_t, true> lastBranch;
1066AST_END(If)
1067
1068AST_NODE(Unless)
1069 ast_ptr<IfCond_t> firstCondition;
1070 ast_ptr<Body_t> firstBody;
1071 ast_ptr<Seperator_t> sep;
1072 ast_list<IfElseIf_t> branches;
1073 ast_ptr<Body_t, true> lastBranch;
1074AST_END(Unless)
1075
1076AST_NODE(While)
1077 ast_ptr<Exp_t> condition;
1078 ast_ptr<Body_t> body;
1079AST_END(While)
1080
1081AST_NODE(for_step_value)
1082 ast_ptr<Exp_t> value;
1083AST_END(for_step_value)
1084
1085AST_NODE(For)
1086 ast_ptr<Name_t> varName;
1087 ast_ptr<Exp_t> startValue;
1088 ast_ptr<Exp_t> stopValue;
1089 ast_ptr<for_step_value_t, true> stepValue;
1090 ast_ptr<Body_t> body;
1091AST_END(For)
1092
1093class AssignableNameList_t;
1094
1095AST_NODE(ForEach)
1096 ast_ptr<AssignableNameList_t> nameList;
1097 ast_ptr<ast_node> loopValue; // Exp_t | ExpList_t
1098 ast_ptr<Body_t> body;
1099AST_END(ForEach)
1100
1101AST_NODE(Do)
1102 ast_ptr<Body_t> body;
1103AST_END(Do)
1104
1105class CompInner_t;
1106
1107AST_NODE(Comprehension)
1108 ast_ptr<Exp_t> value;
1109 ast_ptr<CompInner_t> forLoop;
1110AST_END(Comprehension)
1111
1112AST_NODE(comp_value)
1113 ast_ptr<Exp_t> value;
1114AST_END(comp_value)
1115
1116AST_NODE(TblComprehension)
1117 ast_ptr<Exp_t> key;
1118 ast_ptr<comp_value_t, true> value;
1119 ast_ptr<CompInner_t> forLoop;
1120AST_END(TblComprehension)
1121
1122AST_NODE(star_exp)
1123 ast_ptr<Exp_t> value;
1124AST_END(star_exp)
1125
1126AST_NODE(CompForEach)
1127 ast_ptr<AssignableNameList_t> nameList;
1128 ast_ptr<ast_node> loopValue; // star_exp_t | Exp_t
1129AST_END(CompForEach)
1130
1131AST_NODE(CompFor)
1132 ast_ptr<Name_t> varName;
1133 ast_ptr<Exp_t> startValue;
1134 ast_ptr<Exp_t> stopValue;
1135 ast_ptr<for_step_value_t, true> stepValue;
1136AST_END(CompFor)
1137
1138AST_NODE(CompClause)
1139 ast_ptr<ast_node> nestExp; // CompFor_t | CompForEach_t | Exp_t
1140AST_END(CompClause)
1141
1142AST_NODE(CompInner)
1143 ast_ptr<ast_node> compFor; // CompFor_t | CompForEach_t
1144 ast_ptr<Seperator_t> sep;
1145 ast_list<CompClause_t> clauses;
1146AST_END(CompInner)
1147
1148class TableBlock_t;
1149
1150AST_NODE(Assign)
1151 ast_ptr<ast_node> value; // With_t | If_t | Switch_t | TableBlock_t | ExpListLow_t
1152AST_END(Assign)
1153
1154AST_LEAF(update_op)
1155AST_END(update_op)
1156
1157AST_NODE(Update)
1158 ast_ptr<update_op_t> op;
1159 ast_ptr<Exp_t> value;
1160AST_END(Update)
1161
1162AST_LEAF(BinaryOperator)
1163AST_END(BinaryOperator)
1164
1165class Chain_t;
1166
1167AST_NODE(Assignable)
1168 ast_ptr<ast_node> item; // Chain_t | Name_t | SelfName_t
1169AST_END(Assignable)
1170
1171class Value_t;
1172
1173AST_NODE(exp_op_value)
1174 ast_ptr<BinaryOperator_t> op;
1175 ast_ptr<Value_t> value;
1176AST_END(exp_op_value)
1177
1178AST_NODE(Callable)
1179 ast_ptr<ast_node> item; // Name_t | SelfName_t | VarArg_t | Parens_t
1180AST_END(Callable)
1181
1182class InvokeArgs_t;
1183
1184AST_NODE(ChainValue)
1185 ast_ptr<ast_node> caller; // Chain_t | Callable_t
1186 ast_ptr<InvokeArgs_t, true> arguments;
1187
1188 virtual void visit(void* ud) override
1189 {
1190
1191 }
1192AST_END(ChainValue)
1193
1194class KeyValue_t;
1195
1196AST_NODE(simple_table)
1197 ast_ptr<Seperator_t> sep;
1198 ast_list<KeyValue_t> pairs;
1199AST_END(simple_table)
1200
1201class String_t;
1202
1203AST_NODE(SimpleValue)
1204 ast_ptr<ast_node> value; /*
1205 const_value_t |
1206 If_t | Unless_t | Switch_t | With_t | ClassDecl_t | ForEach_t | For_t | While_t | Do_t |
1207 unary_exp_t |
1208 TblComprehension_t | TableLit_t | Comprehension_t | FunLit_t | Num_t;
1209 */
1210AST_END(SimpleValue)
1211
1212AST_NODE(Chain)
1213 ast_ptr<ast_node> item; // chain_call_t | chain_item_t | chain_dot_chain_t | ColonChain_t
1214AST_END(Chain)
1215
1216AST_NODE(Value)
1217 ast_ptr<ast_node> item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t
1218 ast_node* getFlattenedNode()
1219 {
1220 if (SimpleValue_t* simpleValue = ast_cast<SimpleValue_t>(item))
1221 {
1222 return simpleValue->value;
1223 }
1224 else if (simple_table_t* simple_table = ast_cast<simple_table_t>(item))
1225 {
1226 return simple_table;
1227 }
1228 else if (ChainValue_t* chainValue = ast_cast<ChainValue_t>(item))
1229 {
1230 if (chainValue->arguments)
1231 {
1232 return chainValue;
1233 }
1234 else
1235 {
1236 if (Chain_t* chain = ast_cast<Chain_t>(chainValue->caller))
1237 {
1238 return chain->item;
1239 }
1240 else if (Callable_t* callable = ast_cast<Callable_t>(chainValue->caller))
1241 {
1242 return callable->item;
1243 }
1244 }
1245 }
1246 return item;
1247 }
1248AST_END(Value)
1249
1250AST_LEAF(LuaString)
1251AST_END(LuaString)
1252
1253AST_LEAF(SingleString)
1254AST_END(SingleString)
1255
1256AST_LEAF(double_string_inner)
1257AST_END(double_string_inner)
1258
1259AST_NODE(double_string_content)
1260 ast_ptr<ast_node> content; // double_string_inner_t | Exp_t
1261AST_END(double_string_content)
1262
1263AST_NODE(DoubleString)
1264 ast_ptr<Seperator_t> sep;
1265 ast_list<double_string_content_t> segments;
1266AST_END(DoubleString)
1267
1268AST_NODE(String)
1269 ast_ptr<ast_node> str; // DoubleString_t | SingleString_t | LuaString_t
1270AST_END(String)
1271
1272AST_NODE(Parens)
1273 ast_ptr<Exp_t> expr;
1274AST_END(Parens)
1275
1276AST_NODE(FnArgs)
1277 ast_ptr<Seperator_t> sep;
1278 ast_list<Exp_t> args;
1279AST_END(FnArgs)
1280
1281class ChainItems_t;
1282
1283AST_NODE(chain_call)
1284 ast_ptr<ast_node> caller; // Callable_t | String_t
1285 ast_ptr<ChainItems_t> chain;
1286AST_END(chain_call)
1287
1288AST_NODE(chain_item)
1289 ast_ptr<ChainItems_t> chain;
1290AST_END(chain_item)
1291
1292AST_NODE(DotChainItem)
1293 ast_ptr<_Name_t> name;
1294AST_END(DotChainItem)
1295
1296AST_NODE(ColonChainItem)
1297 ast_ptr<_Name_t> name;
1298AST_END(ColonChainItem)
1299
1300AST_NODE(chain_dot_chain)
1301 ast_ptr<DotChainItem_t> caller;
1302 ast_ptr<ChainItems_t, true> chain;
1303AST_END(chain_dot_chain)
1304
1305class ColonChain_t;
1306
1307class Invoke_t;
1308class Slice_t;
1309
1310AST_NODE(ChainItem)
1311 ast_ptr<ast_node> item; // Invoke_t | DotChainItem_t | Slice_t | [Exp_t]
1312AST_END(ChainItem)
1313
1314AST_NODE(ChainItems)
1315 ast_ptr<Seperator_t> sep;
1316 ast_list<ChainItem_t> simpleChain;
1317 ast_ptr<ColonChain_t, true> colonChain;
1318AST_END(ChainItems)
1319
1320AST_NODE(invoke_chain)
1321 ast_ptr<Invoke_t> invoke;
1322 ast_ptr<ChainItems_t, true> chain;
1323AST_END(invoke_chain)
1324
1325AST_NODE(ColonChain)
1326 ast_ptr<ColonChainItem_t> colonChain;
1327 ast_ptr<invoke_chain_t, true> invokeChain;
1328AST_END(ColonChain)
1329
1330AST_LEAF(default_value)
1331AST_END(default_value)
1332
1333AST_NODE(Slice)
1334 ast_ptr<ast_node> startValue; // Exp_t | default_value_t
1335 ast_ptr<ast_node> stopValue; // Exp_t | default_value_t
1336 ast_ptr<ast_node> stepValue; // Exp_t | default_value_t
1337AST_END(Slice)
1338
1339AST_NODE(Invoke)
1340 ast_ptr<ast_node> argument; // FnArgs_t | SingleString_t | DoubleString_t | LuaString_t
1341AST_END(Invoke)
1342
1343class KeyValue_t;
1344
1345AST_NODE(TableValue)
1346 ast_ptr<ast_node> value; // KeyValue_t | Exp_t
1347AST_END(TableValue)
1348
1349AST_NODE(TableLit)
1350 ast_ptr<Seperator_t> sep;
1351 ast_list<TableValue_t> values;
1352AST_END(TableLit)
1353
1354AST_NODE(TableBlock)
1355 ast_ptr<Seperator_t> sep;
1356 ast_list<KeyValue_t> values;
1357AST_END(TableBlock)
1358
1359AST_NODE(class_member_list)
1360 ast_ptr<Seperator_t> sep;
1361 ast_list<KeyValue_t> values;
1362AST_END(class_member_list)
1363
1364AST_NODE(ClassLine)
1365 ast_ptr<ast_node> content; // class_member_list_t | Statement_t | Exp_t
1366AST_END(ClassLine)
1367
1368AST_NODE(ClassBlock)
1369 ast_ptr<Seperator_t> sep;
1370 ast_list<ClassLine_t> lines;
1371AST_END(ClassBlock)
1372
1373AST_NODE(ClassDecl)
1374 ast_ptr<Assignable_t, true> name;
1375 ast_ptr<Exp_t, true> extend;
1376 ast_ptr<ClassBlock_t, true> body;
1377AST_END(ClassDecl)
1378
1379AST_NODE(export_values)
1380 ast_ptr<NameList_t> nameList;
1381 ast_ptr<ExpListLow_t, true> valueList;
1382AST_END(export_values)
1383
1384AST_LEAF(export_op)
1385AST_END(export_op)
1386
1387AST_NODE(Export)
1388 ast_ptr<ast_node> item; // ClassDecl_t | export_op_t | export_values_t
1389AST_END(Export)
1390
1391AST_NODE(variable_pair)
1392 ast_ptr<Name_t> name;
1393AST_END(variable_pair)
1394
1395AST_NODE(normal_pair)
1396 ast_ptr<ast_node> key; // KeyName_t | [Exp_t] | DoubleString_t | SingleString_t
1397 ast_ptr<ast_node> value; // Exp_t | TableBlock_t
1398AST_END(normal_pair)
1399
1400AST_NODE(KeyValue)
1401 ast_ptr<ast_node> item; // variable_pair_t | normal_pair_t
1402AST_END(KeyValue)
1403
1404AST_NODE(FnArgDef)
1405 ast_ptr<ast_node> name; // Name_t | SelfName_t
1406 ast_ptr<Exp_t, true> defaultValue;
1407AST_END(FnArgDef)
1408
1409AST_NODE(FnArgDefList)
1410 ast_ptr<Seperator_t> sep;
1411 ast_list<FnArgDef_t> definitions;
1412 ast_ptr<VarArg_t, true> varArg;
1413AST_END(FnArgDefList)
1414
1415AST_NODE(outer_var_shadow)
1416 ast_ptr<NameList_t, true> varList;
1417AST_END(outer_var_shadow)
1418
1419AST_NODE(FnArgsDef)
1420 ast_ptr<FnArgDefList_t, true> defList;
1421 ast_ptr<outer_var_shadow_t, true> shadowOption;
1422AST_END(FnArgsDef)
1423
1424AST_LEAF(fn_arrow)
1425AST_END(fn_arrow)
1426
1427AST_NODE(FunLit)
1428 ast_ptr<FnArgsDef_t, true> argsDef;
1429 ast_ptr<fn_arrow_t> arrow;
1430 ast_ptr<Body_t, true> body;
1431AST_END(FunLit)
1432
1433AST_NODE(NameOrDestructure)
1434 ast_ptr<ast_node> item; // Name_t | TableLit_t
1435AST_END(NameOrDestructure)
1436
1437AST_NODE(AssignableNameList)
1438 ast_ptr<Seperator_t> sep;
1439 ast_list<NameOrDestructure_t> items;
1440AST_END(AssignableNameList)
1441
1442AST_NODE(ArgBlock)
1443 ast_ptr<Seperator_t> sep;
1444 ast_list<Exp_t> arguments;
1445AST_END(ArgBlock)
1446
1447AST_NODE(invoke_args_with_table)
1448 ast_ptr<ArgBlock_t, true> argBlock;
1449 ast_ptr<TableBlock_t, true> tableBlock;
1450AST_END(invoke_args_with_table)
1451
1452AST_NODE(InvokeArgs)
1453 ast_ptr<ExpList_t, true> argsList;
1454 ast_ptr<invoke_args_with_table_t, true> argsTableBlock;
1455 ast_ptr<TableBlock_t, true> tableBlock;
1456AST_END(InvokeArgs)
1457
1458AST_LEAF(const_value)
1459AST_END(const_value)
1460
1461AST_NODE(unary_exp)
1462 ast_ptr<Exp_t> item;
1463AST_END(unary_exp)
1464
1465AST_NODE(Assignment)
1466 ast_ptr<ExpList_t> assignable;
1467 ast_ptr<ast_node> target; // Update_t | Assign_t
1468AST_END(Assignment)
1469
1470AST_NODE(if_else_line)
1471 ast_ptr<Exp_t> condition;
1472 ast_ptr<ast_node> elseExpr; // Exp_t | default_value_t
1473AST_END(if_else_line)
1474
1475AST_NODE(unless_line)
1476 ast_ptr<Exp_t> condition;
1477AST_END(unless_line)
1478
1479AST_NODE(statement_appendix)
1480 ast_ptr<ast_node> item; // if_else_line_t | unless_line_t | CompInner_t
1481AST_END(statement_appendix)
1482
1483AST_LEAF(BreakLoop)
1484AST_END(BreakLoop)
1485
1486AST_NODE(Statement)
1487 ast_ptr<ast_node> content; /*
1488 Import_t | While_t | With_t | For_t | ForEach_t |
1489 Switch_t | Return_t | Local_t | Export_t | BreakLoop_t |
1490 Assignment_t | ExpList_t
1491 */
1492 ast_ptr<statement_appendix_t, true> appendix;
1493
1494 virtual void construct(ast_stack& st) override
1495 {
1496 std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> conv;
1497 value = conv.to_bytes(&*m_begin.m_it, &*m_end.m_it);
1498 ast_container::construct(st);
1499 }
1500
1501 virtual void visit(void* ud) override
1502 {
1503 std::cout << value << '\n';
1504 }
1505 std::string value;
1506AST_END(Statement)
1507
1508class Block_t;
1509
1510AST_NODE(Body)
1511 ast_ptr<ast_node> content; // Block | Statement
1512 virtual void visit(void* ud) override
1513 {
1514 Data* data = static_cast<Data*>(ud);
1515 data->pushScope();
1516 content->visit(ud);
1517 data->popScope();
1518 }
1519AST_END(Body)
1520
1521AST_NODE(Line)
1522 ast_ptr<Statement_t, true> statment;
1523 int line;
1524
1525 virtual void construct(ast_stack& st) override
1526 {
1527 ast_container::construct(st);
1528 line = m_begin.m_line;
1529 }
1530
1531 virtual void visit(void* ud) override
1532 {
1533 if (statment)
1534 {
1535 std::cout << line << ": ";
1536 statment->visit(ud);
1537 }
1538 }
1539AST_END(Line)
1540
1541AST_NODE(Block)
1542 ast_ptr<Seperator_t> sep;
1543 ast_list<Line_t> lines;
1544 virtual void visit(void* ud) override
1545 {
1546 Data* data = static_cast<Data*>(ud);
1547 const auto& objs = lines.objects();
1548 for (auto it = objs.begin(); it != objs.end(); ++it)
1549 {
1550 Line_t* line = *it;
1551 if (!line->statment) continue;
1552 if (Local_t* local = ast_cast<Local_t>(line->statment->content))
1553 {
1554 if (local_flag_t* local_flag = ast_cast<local_flag_t>(local->name))
1555 {
1556 std::vector<const std::string*> names;
1557 for (auto cur = it; cur != objs.end(); ++cur)
1558 {
1559 Line_t* item = *cur;
1560 if (!item->statment) continue;
1561 if (Assignment_t* assignment = ast_cast<Assignment_t>(item->statment->content))
1562 {
1563 for (Exp_t* expr : assignment->assignable->exprs.objects())
1564 {
1565 if (ChainValue_t* chainValue = ast_cast<ChainValue_t>(expr->value->item))
1566 if (Callable_t* callable = ast_cast<Callable_t>(chainValue->caller))
1567 if (Name_t* name = ast_cast<Name_t>(callable->item))
1568 {
1569 const std::string& value = name->name->getValue();
1570 if (local_flag->getValue() == "*")
1571 {
1572 names.push_back(&value);
1573 }
1574 else if (std::isupper(value[0]))
1575 {
1576 names.push_back(&value);
1577 }
1578 }
1579 }
1580 }
1581 }
1582 if (!names.empty())
1583 {
1584 data->beginLine();
1585 data->buffer << "local ";
1586 auto nameIt = names.begin();
1587 auto name = *(*nameIt);
1588 data->putLocal(name);
1589 data->buffer << name;
1590 nameIt++;
1591 for (; nameIt != names.end(); ++nameIt)
1592 {
1593 auto name = *(*nameIt);
1594 data->putLocal(name);
1595 data->buffer << ", ";
1596 data->buffer << name;
1597 }
1598 data->endLine(line->m_begin.m_line);
1599 }
1600 }
1601 else
1602 {
1603 NameList_t* nameList = static_cast<NameList_t*>(local->name.get());
1604 data->beginLine();
1605 data->buffer << "local ";
1606 nameList->visit(ud);
1607 for (Name_t* name : nameList->names.objects())
1608 {
1609 data->putLocal(name->name->getValue());
1610 }
1611 data->endLine(line->m_begin.m_line);
1612 }
1613 }
1614 else
1615 {
1616 line->visit(ud);
1617 }
1618 }
1619 }
1620AST_END(Block)
1621
1622AST_NODE(BlockEnd)
1623 ast_ptr<Block_t> block;
1624 virtual void visit(void* ud) override
1625 {
1626 Data* data = static_cast<Data*>(ud);
1627 data->pushScope();
1628 block->visit(ud);
1629 data->popScope();
1630 }
1631AST_END(BlockEnd)
1632
1633int main()
1634{
1635 std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> conv;
1636 std::string s = R"baddog(import \x, func, \memFunc from require "utils")baddog";
1637 input i = conv.from_bytes(s);
1638
1639 error_list el;
1640 Import_t* root = nullptr;
1641 State st;
1642 if (parse(i, Import, el, root, &st))
1643 {
1644 std::cout << "matched!\n";
1645 Data data;
1646 root->visit(&data);
1647 }
1648 else
1649 {
1650 std::cout << "not matched!\n";
1651 for (error_list::iterator it = el.begin(); it != el.end(); ++it)
1652 {
1653 const error& err = *it;
1654 std::cout << "line " << err.m_begin.m_line << ", col " << err.m_begin.m_col << ": syntax error\n";
1655 }
1656 }
1657 system("pause");
1658 return 0;
1659}