aboutsummaryrefslogtreecommitdiff
path: root/MoonParser/main.cpp
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2017-07-19 11:05:45 +0800
committerLi Jin <dragon-fly@qq.com>2017-07-19 11:05:45 +0800
commit65dd230959dbab99b52b99fd807534c254fb4ed9 (patch)
treefb5b2718be96bf1f67bf8b015fcc8e2b1dfd5d7e /MoonParser/main.cpp
parent2531792fa8da2a2f2ae218c43937f88028d26888 (diff)
downloadyuescript-65dd230959dbab99b52b99fd807534c254fb4ed9.tar.gz
yuescript-65dd230959dbab99b52b99fd807534c254fb4ed9.tar.bz2
yuescript-65dd230959dbab99b52b99fd807534c254fb4ed9.zip
add codes.
Diffstat (limited to 'MoonParser/main.cpp')
-rw-r--r--MoonParser/main.cpp1652
1 files changed, 0 insertions, 1652 deletions
diff --git a/MoonParser/main.cpp b/MoonParser/main.cpp
deleted file mode 100644
index d0ef5c8..0000000
--- a/MoonParser/main.cpp
+++ /dev/null
@@ -1,1652 +0,0 @@
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
842class Exp_t;
843
844AST_NODE(ImportName)
845 ast_ptr<ast_node> name; // colon_import_name_t | Name_t
846AST_END(ImportName)
847
848AST_NODE(Import)
849 ast_ptr<Seperator_t> sep;
850 ast_list<ImportName_t> names;
851 ast_ptr<Exp_t> exp;
852 virtual void visit(void* ud) override
853 {
854 Data* data = static_cast<Data*>(ud);
855 std::vector<std::tuple<const std::string*, bool>> nameItems;
856 nameItems.reserve(names.objects().size());
857 for (ImportName_t* importName : names.objects())
858 {
859 if (Name_t* name = ast_cast<Name_t>(importName->name))
860 {
861 nameItems.push_back(std::make_tuple(&name->name->getValue(), false));
862 }
863 else
864 {
865 colon_import_name_t* colonName = ast_cast<colon_import_name_t>(importName->name);
866 nameItems.push_back(std::make_tuple(&colonName->name->name->getValue(), true));
867 }
868 }
869 data->buffer << "local ";
870 for (const auto& item : nameItems)
871 {
872 data->buffer << *std::get<0>(item);
873 if (&item != &nameItems.back())
874 {
875 data->buffer << ", ";
876 }
877 }
878 data->endLine();
879
880 data->beginLine();
881 data->pushScope();
882 data->buffer << "do";
883 data->endLine();
884
885 std::string fromObj = data->getNewLocalObj();
886
887 data->beginLine();
888 data->buffer << "local " << fromObj << " = ";
889 ((ast_node*)exp.get())->visit(ud);
890 data->endLine();
891
892 data->beginLine();
893 for (const auto& item : nameItems)
894 {
895 data->buffer << *std::get<0>(item);
896 if (&item != &nameItems.back())
897 {
898 data->buffer << ", ";
899 }
900 }
901 data->buffer << " = ";
902 for (const auto& item : nameItems)
903 {
904 if (std::get<1>(item))
905 {
906 data->pushScope();
907 data->buffer << "(function()";
908 data->endLine();
909
910 std::string varBase = data->getNewLocalBase();
911
912 data->beginLine();
913 data->buffer << "local " << varBase << " = " << fromObj;
914 data->endLine();
915
916 std::string varFn = data->getNewLocalFn();
917
918 data->beginLine();
919 data->buffer << "local " << varFn << " = " << varBase << '.' << *std::get<0>(item);
920 data->endLine();
921
922 data->beginLine();
923 data->buffer << "return function(...)";
924 data->endLine();
925
926 data->beginLine();
927 data->pushScope();
928 data->buffer << varFn << '(' << varBase << ", ...)";
929 data->endLine();
930
931 data->beginLine();
932 data->buffer << "end";
933 data->popScope();
934 data->endLine();
935
936 data->beginLine();
937 data->buffer << "end)()";
938 data->popScope();
939 }
940 else
941 {
942 data->buffer << fromObj << '.' << *std::get<0>(item);
943 }
944 if (&item != &nameItems.back())
945 {
946 data->buffer << ", ";
947 }
948 }
949 data->endLine();
950
951 data->beginLine();
952 data->buffer << "end";
953 data->popScope();
954 }
955AST_END(Import)
956
957AST_NODE(ExpListLow)
958 ast_ptr<Seperator_t> sep;
959 ast_list<Exp_t> exprs;
960 virtual void visit(void* ud) override
961 {
962 Data* data = static_cast<Data*>(ud);
963 for (Exp_t* expr : exprs.objects())
964 {
965 ((ast_node*)expr)->visit(ud);
966 if (expr != exprs.objects().back())
967 {
968 data->buffer << ", ";
969 }
970 }
971 }
972AST_END(ExpListLow)
973
974AST_NODE(ExpList)
975 ast_ptr<Seperator_t> sep;
976 ast_list<Exp_t> exprs;
977 virtual void visit(void* ud) override
978 {
979 Data* data = static_cast<Data*>(ud);
980 for (Exp_t* expr : exprs.objects())
981 {
982 ((ast_node*)expr)->visit(ud);
983 if (expr != exprs.objects().back())
984 {
985 data->buffer << ", ";
986 }
987 }
988 }
989AST_END(ExpList)
990
991AST_NODE(Return)
992 ast_ptr<ExpListLow_t, true> valueList;
993 virtual void visit(void* ud) override
994 {
995 Data* data = static_cast<Data*>(ud);
996 data->buffer << "return";
997 if (valueList && !valueList->exprs.objects().empty())
998 {
999 data->buffer << ' ';
1000 valueList->visit(ud);
1001 }
1002 }
1003AST_END(Return)
1004
1005class Assign_t;
1006class Body_t;
1007
1008AST_NODE(With)
1009 ast_ptr<ExpList_t> valueList;
1010 ast_ptr<Assign_t, true> assigns;
1011 ast_ptr<Body_t> body;
1012 /*
1013 (function()
1014 do
1015 local _with_0 = Something()
1016 _with_0:write("hello world")
1017 return _with_0
1018 end
1019 end)()
1020 */
1021 virtual void visit(void* ud) override
1022 {
1023 }
1024AST_END(With)
1025
1026AST_NODE(SwitchCase)
1027 ast_ptr<ExpList_t> valueList;
1028 ast_ptr<Body_t> body;
1029AST_END(SwitchCase)
1030
1031AST_NODE(Switch)
1032 ast_ptr<Exp_t> target;
1033 ast_ptr<Seperator_t> sep;
1034 ast_list<SwitchCase_t> branches;
1035 ast_ptr<Body_t, true> lastBranch;
1036AST_END(Switch)
1037
1038AST_NODE(IfCond)
1039 ast_ptr<Exp_t> condition;
1040 ast_ptr<Assign_t, true> assign;
1041AST_END(IfCond)
1042
1043AST_NODE(IfElseIf)
1044 ast_ptr<IfCond_t> condition;
1045 ast_ptr<Body_t> body;
1046AST_END(IfElseIf)
1047
1048AST_NODE(If)
1049 ast_ptr<IfCond_t> firstCondition;
1050 ast_ptr<Body_t> firstBody;
1051 ast_ptr<Seperator_t> sep;
1052 ast_list<IfElseIf_t> branches;
1053 ast_ptr<Body_t, true> lastBranch;
1054AST_END(If)
1055
1056AST_NODE(Unless)
1057 ast_ptr<IfCond_t> firstCondition;
1058 ast_ptr<Body_t> firstBody;
1059 ast_ptr<Seperator_t> sep;
1060 ast_list<IfElseIf_t> branches;
1061 ast_ptr<Body_t, true> lastBranch;
1062AST_END(Unless)
1063
1064AST_NODE(While)
1065 ast_ptr<Exp_t> condition;
1066 ast_ptr<Body_t> body;
1067AST_END(While)
1068
1069AST_NODE(for_step_value)
1070 ast_ptr<Exp_t> value;
1071AST_END(for_step_value)
1072
1073AST_NODE(For)
1074 ast_ptr<Name_t> varName;
1075 ast_ptr<Exp_t> startValue;
1076 ast_ptr<Exp_t> stopValue;
1077 ast_ptr<for_step_value_t, true> stepValue;
1078 ast_ptr<Body_t> body;
1079AST_END(For)
1080
1081class AssignableNameList_t;
1082
1083AST_NODE(ForEach)
1084 ast_ptr<AssignableNameList_t> nameList;
1085 ast_ptr<ast_node> loopValue; // Exp_t | ExpList_t
1086 ast_ptr<Body_t> body;
1087AST_END(ForEach)
1088
1089AST_NODE(Do)
1090 ast_ptr<Body_t> body;
1091AST_END(Do)
1092
1093class CompInner_t;
1094
1095AST_NODE(Comprehension)
1096 ast_ptr<Exp_t> value;
1097 ast_ptr<CompInner_t> forLoop;
1098AST_END(Comprehension)
1099
1100AST_NODE(comp_value)
1101 ast_ptr<Exp_t> value;
1102AST_END(comp_value)
1103
1104AST_NODE(TblComprehension)
1105 ast_ptr<Exp_t> key;
1106 ast_ptr<comp_value_t, true> value;
1107 ast_ptr<CompInner_t> forLoop;
1108AST_END(TblComprehension)
1109
1110AST_NODE(star_exp)
1111 ast_ptr<Exp_t> value;
1112AST_END(star_exp)
1113
1114AST_NODE(CompForEach)
1115 ast_ptr<AssignableNameList_t> nameList;
1116 ast_ptr<ast_node> loopValue; // star_exp_t | Exp_t
1117AST_END(CompForEach)
1118
1119AST_NODE(CompFor)
1120 ast_ptr<Name_t> varName;
1121 ast_ptr<Exp_t> startValue;
1122 ast_ptr<Exp_t> stopValue;
1123 ast_ptr<for_step_value_t, true> stepValue;
1124AST_END(CompFor)
1125
1126AST_NODE(CompClause)
1127 ast_ptr<ast_node> nestExp; // CompFor_t | CompForEach_t | Exp_t
1128AST_END(CompClause)
1129
1130AST_NODE(CompInner)
1131 ast_ptr<ast_node> compFor; // CompFor_t | CompForEach_t
1132 ast_ptr<Seperator_t> sep;
1133 ast_list<CompClause_t> clauses;
1134AST_END(CompInner)
1135
1136class TableBlock_t;
1137
1138AST_NODE(Assign)
1139 ast_ptr<ast_node> value; // With_t | If_t | Switch_t | TableBlock_t | ExpListLow_t
1140AST_END(Assign)
1141
1142AST_LEAF(update_op)
1143AST_END(update_op)
1144
1145AST_NODE(Update)
1146 ast_ptr<update_op_t> op;
1147 ast_ptr<Exp_t> value;
1148AST_END(Update)
1149
1150AST_LEAF(BinaryOperator)
1151AST_END(BinaryOperator)
1152
1153class Chain_t;
1154
1155AST_NODE(Assignable)
1156 ast_ptr<ast_node> item; // Chain_t | Name_t | SelfName_t
1157AST_END(Assignable)
1158
1159class Value_t;
1160
1161AST_NODE(exp_op_value)
1162 ast_ptr<BinaryOperator_t> op;
1163 ast_ptr<Value_t> value;
1164AST_END(exp_op_value)
1165
1166AST_NODE(Exp)
1167 ast_ptr<Value_t> value;
1168 ast_list<exp_op_value_t> opValues;
1169AST_END(Exp)
1170
1171AST_NODE(Callable)
1172 ast_ptr<ast_node> item; // Name_t | SelfName_t | VarArg_t | Parens_t
1173AST_END(Callable)
1174
1175class InvokeArgs_t;
1176
1177AST_NODE(ChainValue)
1178 ast_ptr<ast_node> caller; // Chain_t | Callable_t
1179 ast_ptr<InvokeArgs_t, true> arguments;
1180
1181 virtual void visit(void* ud) override
1182 {
1183
1184 }
1185AST_END(ChainValue)
1186
1187class KeyValue_t;
1188
1189AST_NODE(simple_table)
1190 ast_ptr<Seperator_t> sep;
1191 ast_list<KeyValue_t> pairs;
1192AST_END(simple_table)
1193
1194class String_t;
1195
1196AST_NODE(SimpleValue)
1197 ast_ptr<ast_node> value; /*
1198 const_value_t |
1199 If_t | Unless_t | Switch_t | With_t | ClassDecl_t | ForEach_t | For_t | While_t | Do_t |
1200 unary_exp_t |
1201 TblComprehension_t | TableLit_t | Comprehension_t | FunLit_t | Num_t;
1202 */
1203AST_END(SimpleValue)
1204
1205AST_NODE(Chain)
1206 ast_ptr<ast_node> item; // chain_call_t | chain_item_t | chain_dot_chain_t | ColonChain_t
1207AST_END(Chain)
1208
1209AST_NODE(Value)
1210 ast_ptr<ast_node> item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t
1211 virtual ast_node* get_flattened() override
1212 {
1213 if (SimpleValue_t* simpleValue = ast_cast<SimpleValue_t>(item))
1214 {
1215 return simpleValue->value;
1216 }
1217 else if (simple_table_t* simple_table = ast_cast<simple_table_t>(item))
1218 {
1219 return simple_table;
1220 }
1221 else if (ChainValue_t* chainValue = ast_cast<ChainValue_t>(item))
1222 {
1223 if (chainValue->arguments)
1224 {
1225 return chainValue;
1226 }
1227 else
1228 {
1229 if (Chain_t* chain = ast_cast<Chain_t>(chainValue->caller))
1230 {
1231 return chain->item;
1232 }
1233 else if (Callable_t* callable = ast_cast<Callable_t>(chainValue->caller))
1234 {
1235 return callable->item;
1236 }
1237 }
1238 }
1239 return item;
1240 }
1241AST_END(Value)
1242
1243AST_LEAF(LuaString)
1244AST_END(LuaString)
1245
1246AST_LEAF(SingleString)
1247AST_END(SingleString)
1248
1249AST_LEAF(double_string_inner)
1250AST_END(double_string_inner)
1251
1252AST_NODE(double_string_content)
1253 ast_ptr<ast_node> content; // double_string_inner_t | Exp_t
1254AST_END(double_string_content)
1255
1256AST_NODE(DoubleString)
1257 ast_ptr<Seperator_t> sep;
1258 ast_list<double_string_content_t> segments;
1259AST_END(DoubleString)
1260
1261AST_NODE(String)
1262 ast_ptr<ast_node> str; // DoubleString_t | SingleString_t | LuaString_t
1263AST_END(String)
1264
1265AST_NODE(Parens)
1266 ast_ptr<Exp_t> expr;
1267AST_END(Parens)
1268
1269AST_NODE(FnArgs)
1270 ast_ptr<Seperator_t> sep;
1271 ast_list<Exp_t> args;
1272AST_END(FnArgs)
1273
1274class ChainItems_t;
1275
1276AST_NODE(chain_call)
1277 ast_ptr<ast_node> caller; // Callable_t | String_t
1278 ast_ptr<ChainItems_t> chain;
1279AST_END(chain_call)
1280
1281AST_NODE(chain_item)
1282 ast_ptr<ChainItems_t> chain;
1283AST_END(chain_item)
1284
1285AST_NODE(DotChainItem)
1286 ast_ptr<_Name_t> name;
1287AST_END(DotChainItem)
1288
1289AST_NODE(ColonChainItem)
1290 ast_ptr<_Name_t> name;
1291AST_END(ColonChainItem)
1292
1293AST_NODE(chain_dot_chain)
1294 ast_ptr<DotChainItem_t> caller;
1295 ast_ptr<ChainItems_t, true> chain;
1296AST_END(chain_dot_chain)
1297
1298class ColonChain_t;
1299
1300class Invoke_t;
1301class Slice_t;
1302
1303AST_NODE(ChainItem)
1304 ast_ptr<ast_node> item; // Invoke_t | DotChainItem_t | Slice_t | [Exp_t]
1305AST_END(ChainItem)
1306
1307AST_NODE(ChainItems)
1308 ast_ptr<Seperator_t> sep;
1309 ast_list<ChainItem_t> simpleChain;
1310 ast_ptr<ColonChain_t, true> colonChain;
1311AST_END(ChainItems)
1312
1313AST_NODE(invoke_chain)
1314 ast_ptr<Invoke_t> invoke;
1315 ast_ptr<ChainItems_t, true> chain;
1316AST_END(invoke_chain)
1317
1318AST_NODE(ColonChain)
1319 ast_ptr<ColonChainItem_t> colonChain;
1320 ast_ptr<invoke_chain_t, true> invokeChain;
1321AST_END(ColonChain)
1322
1323AST_LEAF(default_value)
1324AST_END(default_value)
1325
1326AST_NODE(Slice)
1327 ast_ptr<ast_node> startValue; // Exp_t | default_value_t
1328 ast_ptr<ast_node> stopValue; // Exp_t | default_value_t
1329 ast_ptr<ast_node> stepValue; // Exp_t | default_value_t
1330AST_END(Slice)
1331
1332AST_NODE(Invoke)
1333 ast_ptr<ast_node> argument; // FnArgs_t | SingleString_t | DoubleString_t | LuaString_t
1334AST_END(Invoke)
1335
1336class KeyValue_t;
1337
1338AST_NODE(TableValue)
1339 ast_ptr<ast_node> value; // KeyValue_t | Exp_t
1340AST_END(TableValue)
1341
1342AST_NODE(TableLit)
1343 ast_ptr<Seperator_t> sep;
1344 ast_list<TableValue_t> values;
1345AST_END(TableLit)
1346
1347AST_NODE(TableBlock)
1348 ast_ptr<Seperator_t> sep;
1349 ast_list<KeyValue_t> values;
1350AST_END(TableBlock)
1351
1352AST_NODE(class_member_list)
1353 ast_ptr<Seperator_t> sep;
1354 ast_list<KeyValue_t> values;
1355AST_END(class_member_list)
1356
1357AST_NODE(ClassLine)
1358 ast_ptr<ast_node> content; // class_member_list_t | Statement_t | Exp_t
1359AST_END(ClassLine)
1360
1361AST_NODE(ClassBlock)
1362 ast_ptr<Seperator_t> sep;
1363 ast_list<ClassLine_t> lines;
1364AST_END(ClassBlock)
1365
1366AST_NODE(ClassDecl)
1367 ast_ptr<Assignable_t, true> name;
1368 ast_ptr<Exp_t, true> extend;
1369 ast_ptr<ClassBlock_t, true> body;
1370AST_END(ClassDecl)
1371
1372AST_NODE(export_values)
1373 ast_ptr<NameList_t> nameList;
1374 ast_ptr<ExpListLow_t, true> valueList;
1375AST_END(export_values)
1376
1377AST_LEAF(export_op)
1378AST_END(export_op)
1379
1380AST_NODE(Export)
1381 ast_ptr<ast_node> item; // ClassDecl_t | export_op_t | export_values_t
1382AST_END(Export)
1383
1384AST_NODE(variable_pair)
1385 ast_ptr<Name_t> name;
1386AST_END(variable_pair)
1387
1388AST_NODE(normal_pair)
1389 ast_ptr<ast_node> key; // KeyName_t | [Exp_t] | DoubleString_t | SingleString_t
1390 ast_ptr<ast_node> value; // Exp_t | TableBlock_t
1391AST_END(normal_pair)
1392
1393AST_NODE(KeyValue)
1394 ast_ptr<ast_node> item; // variable_pair_t | normal_pair_t
1395AST_END(KeyValue)
1396
1397AST_NODE(FnArgDef)
1398 ast_ptr<ast_node> name; // Name_t | SelfName_t
1399 ast_ptr<Exp_t, true> defaultValue;
1400AST_END(FnArgDef)
1401
1402AST_NODE(FnArgDefList)
1403 ast_ptr<Seperator_t> sep;
1404 ast_list<FnArgDef_t> definitions;
1405 ast_ptr<VarArg_t, true> varArg;
1406AST_END(FnArgDefList)
1407
1408AST_NODE(outer_var_shadow)
1409 ast_ptr<NameList_t, true> varList;
1410AST_END(outer_var_shadow)
1411
1412AST_NODE(FnArgsDef)
1413 ast_ptr<FnArgDefList_t, true> defList;
1414 ast_ptr<outer_var_shadow_t, true> shadowOption;
1415AST_END(FnArgsDef)
1416
1417AST_LEAF(fn_arrow)
1418AST_END(fn_arrow)
1419
1420AST_NODE(FunLit)
1421 ast_ptr<FnArgsDef_t, true> argsDef;
1422 ast_ptr<fn_arrow_t> arrow;
1423 ast_ptr<Body_t, true> body;
1424AST_END(FunLit)
1425
1426AST_NODE(NameOrDestructure)
1427 ast_ptr<ast_node> item; // Name_t | TableLit_t
1428AST_END(NameOrDestructure)
1429
1430AST_NODE(AssignableNameList)
1431 ast_ptr<Seperator_t> sep;
1432 ast_list<NameOrDestructure_t> items;
1433AST_END(AssignableNameList)
1434
1435AST_NODE(ArgBlock)
1436 ast_ptr<Seperator_t> sep;
1437 ast_list<Exp_t> arguments;
1438AST_END(ArgBlock)
1439
1440AST_NODE(invoke_args_with_table)
1441 ast_ptr<ArgBlock_t, true> argBlock;
1442 ast_ptr<TableBlock_t, true> tableBlock;
1443AST_END(invoke_args_with_table)
1444
1445AST_NODE(InvokeArgs)
1446 ast_ptr<ExpList_t, true> argsList;
1447 ast_ptr<invoke_args_with_table_t, true> argsTableBlock;
1448 ast_ptr<TableBlock_t, true> tableBlock;
1449AST_END(InvokeArgs)
1450
1451AST_LEAF(const_value)
1452AST_END(const_value)
1453
1454AST_NODE(unary_exp)
1455 ast_ptr<Exp_t> item;
1456AST_END(unary_exp)
1457
1458AST_NODE(Assignment)
1459 ast_ptr<ExpList_t> assignable;
1460 ast_ptr<ast_node> target; // Update_t | Assign_t
1461AST_END(Assignment)
1462
1463AST_NODE(if_else_line)
1464 ast_ptr<Exp_t> condition;
1465 ast_ptr<ast_node> elseExpr; // Exp_t | default_value_t
1466AST_END(if_else_line)
1467
1468AST_NODE(unless_line)
1469 ast_ptr<Exp_t> condition;
1470AST_END(unless_line)
1471
1472AST_NODE(statement_appendix)
1473 ast_ptr<ast_node> item; // if_else_line_t | unless_line_t | CompInner_t
1474AST_END(statement_appendix)
1475
1476AST_LEAF(BreakLoop)
1477AST_END(BreakLoop)
1478
1479AST_NODE(Statement)
1480 ast_ptr<ast_node> content; /*
1481 Import_t | While_t | With_t | For_t | ForEach_t |
1482 Switch_t | Return_t | Local_t | Export_t | BreakLoop_t |
1483 Assignment_t | ExpList_t
1484 */
1485 ast_ptr<statement_appendix_t, true> appendix;
1486
1487 virtual void construct(ast_stack& st) override
1488 {
1489 std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> conv;
1490 value = conv.to_bytes(&*m_begin.m_it, &*m_end.m_it);
1491 ast_container::construct(st);
1492 }
1493
1494 virtual void visit(void* ud) override
1495 {
1496 std::cout << value << '\n';
1497 }
1498 std::string value;
1499AST_END(Statement)
1500
1501class Block_t;
1502
1503AST_NODE(Body)
1504 ast_ptr<ast_node> content; // Block | Statement
1505 virtual void visit(void* ud) override
1506 {
1507 Data* data = static_cast<Data*>(ud);
1508 data->pushScope();
1509 content->visit(ud);
1510 data->popScope();
1511 }
1512AST_END(Body)
1513
1514AST_NODE(Line)
1515 ast_ptr<Statement_t, true> statment;
1516 int line;
1517
1518 virtual void construct(ast_stack& st) override
1519 {
1520 ast_container::construct(st);
1521 line = m_begin.m_line;
1522 }
1523
1524 virtual void visit(void* ud) override
1525 {
1526 if (statment)
1527 {
1528 std::cout << line << ": ";
1529 statment->visit(ud);
1530 }
1531 }
1532AST_END(Line)
1533
1534AST_NODE(Block)
1535 ast_ptr<Seperator_t> sep;
1536 ast_list<Line_t> lines;
1537 virtual void visit(void* ud) override
1538 {
1539 Data* data = static_cast<Data*>(ud);
1540 const auto& objs = lines.objects();
1541 for (auto it = objs.begin(); it != objs.end(); ++it)
1542 {
1543 Line_t* line = *it;
1544 if (!line->statment) continue;
1545 if (Local_t* local = ast_cast<Local_t>(line->statment->content))
1546 {
1547 if (local_flag_t* local_flag = ast_cast<local_flag_t>(local->name))
1548 {
1549 std::vector<const std::string*> names;
1550 for (auto cur = it; cur != objs.end(); ++cur)
1551 {
1552 Line_t* item = *cur;
1553 if (!item->statment) continue;
1554 if (Assignment_t* assignment = ast_cast<Assignment_t>(item->statment->content))
1555 {
1556 for (Exp_t* expr : assignment->assignable->exprs.objects())
1557 {
1558 if (ChainValue_t* chainValue = ast_cast<ChainValue_t>(expr->value->item))
1559 if (Callable_t* callable = ast_cast<Callable_t>(chainValue->caller))
1560 if (Name_t* name = ast_cast<Name_t>(callable->item))
1561 {
1562 const std::string& value = name->name->getValue();
1563 if (local_flag->getValue() == "*")
1564 {
1565 names.push_back(&value);
1566 }
1567 else if (std::isupper(value[0]))
1568 {
1569 names.push_back(&value);
1570 }
1571 }
1572 }
1573 }
1574 }
1575 if (!names.empty())
1576 {
1577 data->beginLine(line->m_begin.m_line);
1578 data->buffer << "local ";
1579 auto nameIt = names.begin();
1580 auto name = *(*nameIt);
1581 data->putLocal(name);
1582 data->buffer << name;
1583 nameIt++;
1584 for (; nameIt != names.end(); ++nameIt)
1585 {
1586 auto name = *(*nameIt);
1587 data->putLocal(name);
1588 data->buffer << ", ";
1589 data->buffer << name;
1590 }
1591 data->endLine();
1592 }
1593 }
1594 else
1595 {
1596 NameList_t* nameList = static_cast<NameList_t*>(local->name.get());
1597 data->beginLine(line->m_begin.m_line);
1598 data->buffer << "local ";
1599 nameList->visit(ud);
1600 for (Name_t* name : nameList->names.objects())
1601 {
1602 data->putLocal(name->name->getValue());
1603 }
1604 data->endLine();
1605 }
1606 }
1607 else
1608 {
1609 line->visit(ud);
1610 }
1611 }
1612 }
1613AST_END(Block)
1614
1615AST_NODE(BlockEnd)
1616 ast_ptr<Block_t> block;
1617 virtual void visit(void* ud) override
1618 {
1619 Data* data = static_cast<Data*>(ud);
1620 data->pushScope();
1621 block->visit(ud);
1622 data->popScope();
1623 }
1624AST_END(BlockEnd)
1625
1626int main()
1627{
1628 std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> conv;
1629 std::string s = R"baddog(import \x, func, \memFunc from require "utils")baddog";
1630 input i = conv.from_bytes(s);
1631
1632 error_list el;
1633 Import_t* root = nullptr;
1634 State st;
1635 if (parse(i, Import, el, root, &st))
1636 {
1637 std::cout << "matched!\n";
1638 Data data;
1639 root->visit(&data);
1640 }
1641 else
1642 {
1643 std::cout << "not matched!\n";
1644 for (error_list::iterator it = el.begin(); it != el.end(); ++it)
1645 {
1646 const error& err = *it;
1647 std::cout << "line " << err.m_begin.m_line << ", col " << err.m_begin.m_col << ": syntax error\n";
1648 }
1649 }
1650 system("pause");
1651 return 0;
1652}