aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MoonParser.xcodeproj/project.pbxproj10
-rw-r--r--MoonParser/ast.hpp2
-rw-r--r--MoonParser/main.cpp1652
-rw-r--r--MoonParser/moon_ast.cpp1718
-rw-r--r--MoonParser/moon_ast.h589
-rw-r--r--MoonParser/moon_parser.cpp508
-rw-r--r--MoonParser/moon_parser.h31
7 files changed, 1444 insertions, 3066 deletions
diff --git a/MoonParser.xcodeproj/project.pbxproj b/MoonParser.xcodeproj/project.pbxproj
index 782ec62..fe4dd22 100644
--- a/MoonParser.xcodeproj/project.pbxproj
+++ b/MoonParser.xcodeproj/project.pbxproj
@@ -9,7 +9,7 @@
9/* Begin PBXBuildFile section */ 9/* Begin PBXBuildFile section */
10 3C3B1C601F1EF0AB0052A206 /* moon_ast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C3B1C5E1F1EF0AB0052A206 /* moon_ast.cpp */; }; 10 3C3B1C601F1EF0AB0052A206 /* moon_ast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C3B1C5E1F1EF0AB0052A206 /* moon_ast.cpp */; };
11 3C6FFA331F16F97400541BCA /* ast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C6FFA2D1F16F97400541BCA /* ast.cpp */; }; 11 3C6FFA331F16F97400541BCA /* ast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C6FFA2D1F16F97400541BCA /* ast.cpp */; };
12 3C6FFA341F16F97400541BCA /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C6FFA2F1F16F97400541BCA /* main.cpp */; }; 12 3C6FFA341F16F97400541BCA /* moon_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C6FFA2F1F16F97400541BCA /* moon_parser.cpp */; };
13 3C6FFA351F16F97400541BCA /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C6FFA301F16F97400541BCA /* parser.cpp */; }; 13 3C6FFA351F16F97400541BCA /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C6FFA301F16F97400541BCA /* parser.cpp */; };
14/* End PBXBuildFile section */ 14/* End PBXBuildFile section */
15 15
@@ -29,9 +29,10 @@
29 3C0F0F6C1EF3781E000EADDB /* MoonParser */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = MoonParser; sourceTree = BUILT_PRODUCTS_DIR; }; 29 3C0F0F6C1EF3781E000EADDB /* MoonParser */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = MoonParser; sourceTree = BUILT_PRODUCTS_DIR; };
30 3C3B1C5E1F1EF0AB0052A206 /* moon_ast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moon_ast.cpp; sourceTree = "<group>"; }; 30 3C3B1C5E1F1EF0AB0052A206 /* moon_ast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moon_ast.cpp; sourceTree = "<group>"; };
31 3C3B1C5F1F1EF0AB0052A206 /* moon_ast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = moon_ast.h; sourceTree = "<group>"; }; 31 3C3B1C5F1F1EF0AB0052A206 /* moon_ast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = moon_ast.h; sourceTree = "<group>"; };
32 3C3B1C611F1EFC810052A206 /* moon_parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = moon_parser.h; sourceTree = "<group>"; };
32 3C6FFA2D1F16F97400541BCA /* ast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ast.cpp; sourceTree = "<group>"; }; 33 3C6FFA2D1F16F97400541BCA /* ast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ast.cpp; sourceTree = "<group>"; };
33 3C6FFA2E1F16F97400541BCA /* ast.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ast.hpp; sourceTree = "<group>"; }; 34 3C6FFA2E1F16F97400541BCA /* ast.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ast.hpp; sourceTree = "<group>"; };
34 3C6FFA2F1F16F97400541BCA /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; }; 35 3C6FFA2F1F16F97400541BCA /* moon_parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moon_parser.cpp; sourceTree = "<group>"; };
35 3C6FFA301F16F97400541BCA /* parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser.cpp; sourceTree = "<group>"; }; 36 3C6FFA301F16F97400541BCA /* parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser.cpp; sourceTree = "<group>"; };
36 3C6FFA311F16F97400541BCA /* parser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = parser.hpp; sourceTree = "<group>"; }; 37 3C6FFA311F16F97400541BCA /* parser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = parser.hpp; sourceTree = "<group>"; };
37 3C6FFA321F16F97400541BCA /* parserlib.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = parserlib.hpp; sourceTree = "<group>"; }; 38 3C6FFA321F16F97400541BCA /* parserlib.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = parserlib.hpp; sourceTree = "<group>"; };
@@ -53,7 +54,8 @@
53 children = ( 54 children = (
54 3C6FFA2D1F16F97400541BCA /* ast.cpp */, 55 3C6FFA2D1F16F97400541BCA /* ast.cpp */,
55 3C6FFA2E1F16F97400541BCA /* ast.hpp */, 56 3C6FFA2E1F16F97400541BCA /* ast.hpp */,
56 3C6FFA2F1F16F97400541BCA /* main.cpp */, 57 3C6FFA2F1F16F97400541BCA /* moon_parser.cpp */,
58 3C3B1C611F1EFC810052A206 /* moon_parser.h */,
57 3C3B1C5E1F1EF0AB0052A206 /* moon_ast.cpp */, 59 3C3B1C5E1F1EF0AB0052A206 /* moon_ast.cpp */,
58 3C3B1C5F1F1EF0AB0052A206 /* moon_ast.h */, 60 3C3B1C5F1F1EF0AB0052A206 /* moon_ast.h */,
59 3C6FFA301F16F97400541BCA /* parser.cpp */, 61 3C6FFA301F16F97400541BCA /* parser.cpp */,
@@ -136,7 +138,7 @@
136 isa = PBXSourcesBuildPhase; 138 isa = PBXSourcesBuildPhase;
137 buildActionMask = 2147483647; 139 buildActionMask = 2147483647;
138 files = ( 140 files = (
139 3C6FFA341F16F97400541BCA /* main.cpp in Sources */, 141 3C6FFA341F16F97400541BCA /* moon_parser.cpp in Sources */,
140 3C3B1C601F1EF0AB0052A206 /* moon_ast.cpp in Sources */, 142 3C3B1C601F1EF0AB0052A206 /* moon_ast.cpp in Sources */,
141 3C6FFA351F16F97400541BCA /* parser.cpp in Sources */, 143 3C6FFA351F16F97400541BCA /* parser.cpp in Sources */,
142 3C6FFA331F16F97400541BCA /* ast.cpp in Sources */, 144 3C6FFA331F16F97400541BCA /* ast.cpp in Sources */,
diff --git a/MoonParser/ast.hpp b/MoonParser/ast.hpp
index a9c2db7..1b40e1b 100644
--- a/MoonParser/ast.hpp
+++ b/MoonParser/ast.hpp
@@ -69,8 +69,6 @@ public:
69 virtual void visit(void* user_data) {} 69 virtual void visit(void* user_data) {}
70 70
71 virtual int get_type() { return ast_type<ast_node>(); } 71 virtual int get_type() { return ast_type<ast_node>(); }
72
73 virtual ast_node* get_flattened() { return this; }
74private: 72private:
75 //parent 73 //parent
76 ast_node *m_parent; 74 ast_node *m_parent;
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}
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp
index 1595220..41d0c55 100644
--- a/MoonParser/moon_ast.cpp
+++ b/MoonParser/moon_ast.cpp
@@ -1,4 +1,3 @@
1#include <iostream>
2#include <string> 1#include <string>
3#include <codecvt> 2#include <codecvt>
4#include <unordered_set> 3#include <unordered_set>
@@ -6,58 +5,7 @@
6#include <algorithm> 5#include <algorithm>
7#include <sstream> 6#include <sstream>
8#include <vector> 7#include <vector>
9#include "parserlib.hpp" 8#include "moon_ast.h"
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 9
62class Data 10class Data
63{ 11{
@@ -178,1457 +126,413 @@ private:
178 std::stack<Scope> _scopeStack; 126 std::stack<Scope> _scopeStack;
179}; 127};
180 128
181rule Any = any(); 129std::string& trim(std::string& s)
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{ 130{
242 int indent = 0; 131 s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch)
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 { 132 {
261 switch (*i) 133 return !std::isspace(ch);
262 { 134 }));
263 case ' ': indent++; break; 135 s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch)
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 { 136 {
271 st->indents.push(indent); 137 return !std::isspace(ch);
272 return true; 138 }).base(), s.end());
273 } 139 return s;
274 return false; 140}
275});
276rule Advance = and_(advance);
277 141
278rule push_indent = user(Indent, [](const item_t& item) 142const std::string& AstLeaf::getValue()
279{ 143{
280 int indent = 0; 144 if (_value.empty())
281 for (input_it i = item.begin; i != item.end; ++i)
282 { 145 {
283 switch (*i) 146 for (auto it = m_begin.m_it; it != m_end.m_it; ++it)
284 { 147 {
285 case ' ': indent++; break; 148 char ch = static_cast<char>(*it);
286 case '\t': indent += 4; break; 149 _value.append(&ch, 1);
287 } 150 }
151 return trim(_value);
288 } 152 }
289 State* st = reinterpret_cast<State*>(item.user_data); 153 return _value;
290 st->indents.push(indent); 154}
291 return true;
292});
293rule PushIndent = and_(push_indent);
294 155
295rule PreventIndent = user(true_(), [](const item_t& item) 156#define AST_IMPL(type) \
157 ast<type##_t> __##type##_t(type);
158
159AST_IMPL(Num)
160AST_IMPL(_Name)
161AST_IMPL(Name)
162AST_IMPL(self)
163AST_IMPL(self_name)
164AST_IMPL(self_class)
165AST_IMPL(self_class_name)
166AST_IMPL(SelfName)
167AST_IMPL(KeyName)
168AST_IMPL(VarArg)
169AST_IMPL(local_flag)
170AST_IMPL(Seperator)
171AST_IMPL(NameList)
172AST_IMPL(Local)
173AST_IMPL(colon_import_name)
174AST_IMPL(ImportName)
175AST_IMPL(Import)
176AST_IMPL(ExpListLow)
177AST_IMPL(ExpList)
178AST_IMPL(Return)
179AST_IMPL(With)
180AST_IMPL(SwitchCase)
181AST_IMPL(Switch)
182AST_IMPL(IfCond)
183AST_IMPL(IfElseIf)
184AST_IMPL(If)
185AST_IMPL(Unless)
186AST_IMPL(While)
187AST_IMPL(for_step_value)
188AST_IMPL(For)
189AST_IMPL(ForEach)
190AST_IMPL(Do)
191AST_IMPL(Comprehension)
192AST_IMPL(comp_value)
193AST_IMPL(TblComprehension)
194AST_IMPL(star_exp)
195AST_IMPL(CompForEach)
196AST_IMPL(CompFor)
197AST_IMPL(CompClause)
198AST_IMPL(CompInner)
199AST_IMPL(Assign)
200AST_IMPL(update_op)
201AST_IMPL(Update)
202AST_IMPL(BinaryOperator)
203AST_IMPL(Assignable)
204AST_IMPL(exp_op_value)
205AST_IMPL(Exp)
206AST_IMPL(Callable)
207AST_IMPL(ChainValue)
208AST_IMPL(simple_table)
209AST_IMPL(SimpleValue)
210AST_IMPL(Chain)
211AST_IMPL(Value)
212AST_IMPL(LuaString)
213AST_IMPL(SingleString)
214AST_IMPL(double_string_inner)
215AST_IMPL(double_string_content)
216AST_IMPL(DoubleString)
217AST_IMPL(String)
218AST_IMPL(Parens)
219AST_IMPL(FnArgs)
220AST_IMPL(chain_call)
221AST_IMPL(chain_item)
222AST_IMPL(DotChainItem)
223AST_IMPL(ColonChainItem)
224AST_IMPL(chain_dot_chain)
225AST_IMPL(ChainItem)
226AST_IMPL(ChainItems)
227AST_IMPL(invoke_chain)
228AST_IMPL(ColonChain)
229AST_IMPL(default_value)
230AST_IMPL(Slice)
231AST_IMPL(Invoke)
232AST_IMPL(TableValue)
233AST_IMPL(TableLit)
234AST_IMPL(TableBlock)
235AST_IMPL(class_member_list)
236AST_IMPL(ClassLine)
237AST_IMPL(ClassBlock)
238AST_IMPL(ClassDecl)
239AST_IMPL(export_values)
240AST_IMPL(export_op)
241AST_IMPL(Export)
242AST_IMPL(variable_pair)
243AST_IMPL(normal_pair)
244AST_IMPL(KeyValue)
245AST_IMPL(FnArgDef)
246AST_IMPL(FnArgDefList)
247AST_IMPL(outer_var_shadow)
248AST_IMPL(FnArgsDef)
249AST_IMPL(fn_arrow)
250AST_IMPL(FunLit)
251AST_IMPL(NameOrDestructure)
252AST_IMPL(AssignableNameList)
253AST_IMPL(ArgBlock)
254AST_IMPL(invoke_args_with_table)
255AST_IMPL(InvokeArgs)
256AST_IMPL(const_value)
257AST_IMPL(unary_exp)
258AST_IMPL(Assignment)
259AST_IMPL(if_else_line)
260AST_IMPL(unless_line)
261AST_IMPL(statement_appendix)
262AST_IMPL(BreakLoop)
263AST_IMPL(Statement)
264AST_IMPL(Body)
265AST_IMPL(Line)
266AST_IMPL(Block)
267AST_IMPL(BlockEnd)
268
269void Num_t::visit(void* ud)
296{ 270{
297 State* st = reinterpret_cast<State*>(item.user_data); 271 Data* data = static_cast<Data*>(ud);
298 st->indents.push(-1); 272 std::string str = data->conv.to_bytes(&*m_begin.m_it, &*m_end.m_it);
299 return true; 273 data->buffer << trim(str);
300}); 274}
301 275
302rule PopIndent = user(true_(), [](const item_t& item) 276void _Name_t::visit(void* ud)
303{ 277{
304 State* st = reinterpret_cast<State*>(item.user_data); 278 Data* data = static_cast<Data*>(ud);
305 st->indents.pop(); 279 data->buffer << getValue();
306 return true; 280}
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 281
372rule Do = user(key("do") >> Body, [](const item_t& item) 282void Name_t::visit(void* ud)
373{ 283{
374 State* st = reinterpret_cast<State*>(item.user_data); 284 name->visit(ud);
375 return st->doStack.empty() || st->doStack.top(); 285}
376});
377 286
378rule DisableDo = user(true_(), [](const item_t& item) 287void self_t::visit(void* ud)
379{ 288{
380 State* st = reinterpret_cast<State*>(item.user_data); 289 Data* data = static_cast<Data*>(ud);
381 st->doStack.push(false); 290 data->buffer << "self";
382 return true; 291}
383});
384 292
385rule PopDo = user(true_(), [](const item_t& item) 293void self_name_t::visit(void* ud)
386{ 294{
387 State* st = reinterpret_cast<State*>(item.user_data); 295 Data* data = static_cast<Data*>(ud);
388 st->doStack.pop(); 296 data->buffer << (data->callerStack.top() ? "self:" : "self.");
389 return true; 297 name->visit(ud);
390}); 298}
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 299
474rule LuaStringOpen = user(lua_string_open, [](const item_t& item) 300void self_class_t::visit(void* ud)
475{ 301{
476 size_t count = std::distance(item.begin, item.end); 302 Data* data = static_cast<Data*>(ud);
477 State* st = reinterpret_cast<State*>(item.user_data); 303 data->buffer << "self.__class";
478 st->stringOpen = count; 304}
479 return true;
480});
481 305
482rule LuaStringClose = user(lua_string_close, [](const item_t& item) 306void self_class_name_t::visit(void* ud)
483{ 307{
484 size_t count = std::distance(item.begin, item.end); 308 Data* data = static_cast<Data*>(ud);
485 State* st = reinterpret_cast<State*>(item.user_data); 309 data->buffer << (data->callerStack.top() ? "self.__class:" : "self.__class.");
486 return st->stringOpen == count; 310 name->visit(ud);
487}); 311}
488
489rule LuaStringContent = *(not_(LuaStringClose) >> (Break | Any));
490 312
491rule LuaString = user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item) 313void SelfName_t::visit(void* ud)
492{ 314{
493 State* st = reinterpret_cast<State*>(item.user_data); 315 name->visit(ud);
494 st->stringOpen = -1; 316}
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 317
688class AstLeaf : public ast_node 318void KeyName_t::visit(void* ud)
689{ 319{
690public: 320 name->visit(ud);
691 const std::string& getValue() 321}
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 322
785AST_NODE(SelfName) 323void VarArg_t::visit(void* ud)
786 ast_ptr<ast_node> name; // self_class_name_t | self_class_t | self_name_t | self_t 324{
787 virtual void visit(void* ud) override 325 Data* data = static_cast<Data*>(ud);
788 { 326 data->buffer << "...";
789 name->visit(ud); 327}
790 }
791AST_END(SelfName)
792 328
793AST_NODE(KeyName) 329void NameList_t::visit(void* ud)
794 ast_ptr<ast_node> name; // SelfName_t | _Name_t 330{
795 virtual void visit(void* ud) override 331 Data* data = static_cast<Data*>(ud);
796 { 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 << ", ";
797 name->visit(ud); 340 name->visit(ud);
798 } 341 }
799AST_END(KeyName) 342}
800 343
801AST_LEAF(VarArg) 344void Import_t::visit(void* ud)
802 virtual void visit(void* ud) override 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())
803 { 350 {
804 Data* data = static_cast<Data*>(ud); 351 if (Name_t* name = ast_cast<Name_t>(importName->name))
805 data->buffer << "..."; 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 }
806 } 360 }
807AST_END(VarArg) 361 data->buffer << "local ";
808 362 for (const auto& item : nameItems)
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 { 363 {
820 Data* data = static_cast<Data*>(ud); 364 data->buffer << *std::get<0>(item);
821 auto it = names.objects().begin(); 365 if (&item != &nameItems.back())
822 Name_t* name = *it;
823 name->visit(ud);
824 ++it;
825 for (; it != names.objects().end(); ++it)
826 { 366 {
827 name = *it;
828 data->buffer << ", "; 367 data->buffer << ", ";
829 name->visit(ud);
830 } 368 }
831 } 369 }
832AST_END(NameList) 370 data->endLine();
833 371
834AST_NODE(Local) 372 data->beginLine();
835 ast_ptr<ast_node> name; // local_flag_t | NameList_t 373 data->pushScope();
836AST_END(Local) 374 data->buffer << "do";
375 data->endLine();
837 376
838AST_NODE(colon_import_name) 377 std::string fromObj = data->getNewLocalObj();
839 ast_ptr<Name_t> name;
840AST_END(colon_import_name)
841 378
842AST_NODE(Exp) 379 data->beginLine();
843 ast_ptr<Value_t> value; 380 data->buffer << "local " << fromObj << " = ";
844 ast_list<exp_op_value_t> opValues; 381 exp->visit(ud);
845AST_END(Exp) 382 data->endLine();
846 383
847AST_NODE(ImportName) 384 data->beginLine();
848 ast_ptr<ast_node> name; // colon_import_name_t | Name_t 385 for (const auto& item : nameItems)
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 { 386 {
857 Data* data = static_cast<Data*>(ud); 387 data->buffer << *std::get<0>(item);
858 std::vector<std::tuple<const std::string*, bool>> nameItems; 388 if (&item != &nameItems.back())
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 { 389 {
898 data->buffer << *std::get<0>(item); 390 data->buffer << ", ";
899 if (&item != &nameItems.back())
900 {
901 data->buffer << ", ";
902 }
903 } 391 }
904 data->buffer << " = "; 392 }
905 for (const auto& item : nameItems) 393 data->buffer << " = ";
394 for (const auto& item : nameItems)
395 {
396 if (std::get<1>(item))
906 { 397 {
907 if (std::get<1>(item)) 398 data->pushScope();
908 { 399 data->buffer << "(function()";
909 data->pushScope(); 400 data->endLine();
910 data->buffer << "(function()";
911 data->endLine();
912 401
913 std::string varBase = data->getNewLocalBase(); 402 std::string varBase = data->getNewLocalBase();
914 403
915 data->beginLine(); 404 data->beginLine();
916 data->buffer << "local " << varBase << " = " << fromObj; 405 data->buffer << "local " << varBase << " = " << fromObj;
917 data->endLine(); 406 data->endLine();
918 407
919 std::string varFn = data->getNewLocalFn(); 408 std::string varFn = data->getNewLocalFn();
920 409
921 data->beginLine(); 410 data->beginLine();
922 data->buffer << "local " << varFn << " = " << varBase << '.' << *std::get<0>(item); 411 data->buffer << "local " << varFn << " = " << varBase << '.' << *std::get<0>(item);
923 data->endLine(); 412 data->endLine();
924 413
925 data->beginLine(); 414 data->beginLine();
926 data->buffer << "return function(...)"; 415 data->buffer << "return function(...)";
927 data->endLine(); 416 data->endLine();
928 417
929 data->beginLine(); 418 data->beginLine();
930 data->pushScope(); 419 data->pushScope();
931 data->buffer << varFn << '(' << varBase << ", ...)"; 420 data->buffer << varFn << '(' << varBase << ", ...)";
932 data->endLine(); 421 data->endLine();
933 422
934 data->beginLine(); 423 data->beginLine();
935 data->buffer << "end"; 424 data->buffer << "end";
936 data->popScope(); 425 data->popScope();
937 data->endLine(); 426 data->endLine();
938 427
939 data->beginLine(); 428 data->beginLine();
940 data->buffer << "end)()"; 429 data->buffer << "end)()";
941 data->popScope(); 430 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 } 431 }
952 data->endLine(); 432 else
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 { 433 {
968 ((ast_node*)expr)->visit(ud); 434 data->buffer << fromObj << '.' << *std::get<0>(item);
969 if (expr != exprs.objects().back())
970 {
971 data->buffer << ", ";
972 }
973 } 435 }
974 } 436 if (&item != &nameItems.back())
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 { 437 {
985 ((ast_node*)expr)->visit(ud); 438 data->buffer << ", ";
986 if (expr != exprs.objects().back())
987 {
988 data->buffer << ", ";
989 }
990 } 439 }
991 } 440 }
992AST_END(ExpList) 441 data->endLine();
442
443 data->beginLine();
444 data->buffer << "end";
445 data->popScope();
446}
993 447
994AST_NODE(Return) 448void ExpListLow_t::visit(void* ud)
995 ast_ptr<ExpListLow_t, true> valueList; 449{
996 virtual void visit(void* ud) override 450 Data* data = static_cast<Data*>(ud);
451 for (Exp_t* expr : exprs.objects())
997 { 452 {
998 Data* data = static_cast<Data*>(ud); 453 expr->visit(ud);
999 data->buffer << "return"; 454 if (expr != exprs.objects().back())
1000 if (valueList && !valueList->exprs.objects().empty())
1001 { 455 {
1002 data->buffer << ' '; 456 data->buffer << ", ";
1003 valueList->visit(ud);
1004 } 457 }
1005 } 458 }
1006AST_END(Return) 459}
1007
1008class Assign_t;
1009class Body_t;
1010 460
1011AST_NODE(With) 461void ExpList_t::visit(void* ud)
1012 ast_ptr<ExpList_t> valueList; 462{
1013 ast_ptr<Assign_t, true> assigns; 463 Data* data = static_cast<Data*>(ud);
1014 ast_ptr<Body_t> body; 464 for (Exp_t* expr : exprs.objects())
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 { 465 {
1026 Data* data = static_cast<Data*>(ud); 466 expr->visit(ud);
1027 for (Exp_t* expr : valueList->exprs.objects()) 467 if (expr != exprs.objects().back())
1028 { 468 {
469 data->buffer << ", ";
1029 } 470 }
1030 ((ast_node*)expr)->visit(ud);
1031 if (expr != exprs.objects().back())
1032 {
1033 data->buffer << ", ";
1034 }
1035 } 471 }
1036AST_END(With) 472}
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 473
1188 virtual void visit(void* ud) override 474void Return_t::visit(void* ud)
475{
476 Data* data = static_cast<Data*>(ud);
477 data->buffer << "return";
478 if (valueList && !valueList->exprs.objects().empty())
1189 { 479 {
1190 480 data->buffer << ' ';
481 valueList->visit(ud);
1191 } 482 }
1192AST_END(ChainValue) 483}
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 484
1216AST_NODE(Value) 485void With_t::visit(void* ud)
1217 ast_ptr<ast_node> item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t 486{
1218 ast_node* getFlattenedNode() 487 Data* data = static_cast<Data*>(ud);
488 data->buffer << "return";
489 for (Exp_t* expr : valueList->exprs.objects())
1219 { 490 {
1220 if (SimpleValue_t* simpleValue = ast_cast<SimpleValue_t>(item)) 491 if (assigns && (!expr->opValues.objects().empty() || expr->value->getFlattened()))
1221 { 492 {
1222 return simpleValue->value; 493 throw std::logic_error("left hand expression is not assignable.");
1223 } 494 }
1224 else if (simple_table_t* simple_table = ast_cast<simple_table_t>(item)) 495 // TODO
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 } 496 }
1500 497 if (valueList && !valueList->exprs.objects().empty())
1501 virtual void visit(void* ud) override
1502 { 498 {
1503 std::cout << value << '\n'; 499 data->buffer << ' ';
500 valueList->visit(ud);
1504 } 501 }
1505 std::string value; 502}
1506AST_END(Statement)
1507
1508class Block_t;
1509 503
1510AST_NODE(Body) 504ast_node* Value_t::getFlattened()
1511 ast_ptr<ast_node> content; // Block | Statement 505{
1512 virtual void visit(void* ud) override 506 if (SimpleValue_t* simpleValue = ast_cast<SimpleValue_t>(item))
1513 { 507 {
1514 Data* data = static_cast<Data*>(ud); 508 return simpleValue->value;
1515 data->pushScope();
1516 content->visit(ud);
1517 data->popScope();
1518 } 509 }
1519AST_END(Body) 510 else if (simple_table_t* simple_table = ast_cast<simple_table_t>(item))
1520
1521AST_NODE(Line)
1522 ast_ptr<Statement_t, true> statment;
1523 int line;
1524
1525 virtual void construct(ast_stack& st) override
1526 { 511 {
1527 ast_container::construct(st); 512 return simple_table;
1528 line = m_begin.m_line;
1529 } 513 }
1530 514 else if (ChainValue_t* chainValue = ast_cast<ChainValue_t>(item))
1531 virtual void visit(void* ud) override
1532 { 515 {
1533 if (statment) 516 if (chainValue->arguments)
1534 { 517 {
1535 std::cout << line << ": "; 518 return chainValue;
1536 statment->visit(ud);
1537 } 519 }
1538 } 520 else
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 { 521 {
1550 Line_t* line = *it; 522 if (Chain_t* chain = ast_cast<Chain_t>(chainValue->caller))
1551 if (!line->statment) continue;
1552 if (Local_t* local = ast_cast<Local_t>(line->statment->content))
1553 { 523 {
1554 if (local_flag_t* local_flag = ast_cast<local_flag_t>(local->name)) 524 return chain->item;
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 } 525 }
1614 else 526 else if (Callable_t* callable = ast_cast<Callable_t>(chainValue->caller))
1615 { 527 {
1616 line->visit(ud); 528 return callable->item;
1617 } 529 }
1618 } 530 }
1619 } 531 }
1620AST_END(Block) 532 return item;
533}
1621 534
1622AST_NODE(BlockEnd) 535#include <iostream>
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 536
1633int main() 537int main()
1634{ 538{
diff --git a/MoonParser/moon_ast.h b/MoonParser/moon_ast.h
index 942a2b6..4da4b8d 100644
--- a/MoonParser/moon_ast.h
+++ b/MoonParser/moon_ast.h
@@ -1,4 +1,591 @@
1#pragma once 1#pragma once
2 2
3#include "parserlib.hpp" 3#include "moon_parser.h"
4 4
5template<class Facet>
6struct deletable_facet : Facet
7{
8 template<class ...Args>
9 deletable_facet(Args&& ...args): Facet(std::forward<Args>(args)...) {}
10 ~deletable_facet() {}
11};
12typedef std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> Converter;
13
14std::string& trim(std::string& s);
15
16class AstLeaf : public ast_node
17{
18public:
19 const std::string& getValue();
20private:
21 std::string _value;
22};
23
24#define AST_LEAF(type) \
25extern rule type; \
26class type##_t : public AstLeaf \
27{ \
28public: \
29 virtual int get_type() override { return ast_type<type##_t>(); }
30
31#define AST_NODE(type) \
32extern rule type; \
33class type##_t : public ast_container \
34{ \
35public: \
36 virtual int get_type() override { return ast_type<type##_t>(); }
37
38#define AST_END(type) \
39};
40
41AST_LEAF(Num)
42 virtual void visit(void* ud) override;
43AST_END(Num)
44
45AST_LEAF(_Name)
46 virtual void visit(void* ud) override;
47AST_END(_Name)
48
49AST_NODE(Name)
50 ast_ptr<_Name_t> name;
51 virtual void visit(void* ud) override;
52AST_END(Name)
53
54AST_LEAF(self)
55 virtual void visit(void* ud) override;
56AST_END(self)
57
58AST_NODE(self_name)
59 ast_ptr<_Name_t> name;
60 virtual void visit(void* ud) override;
61AST_END(self_name)
62
63AST_LEAF(self_class)
64 virtual void visit(void* ud) override;
65AST_END(self_class)
66
67AST_NODE(self_class_name)
68 ast_ptr<_Name_t> name;
69 virtual void visit(void* ud) override;
70AST_END(self_class_name)
71
72AST_NODE(SelfName)
73 ast_ptr<ast_node> name; // self_class_name_t | self_class_t | self_name_t | self_t
74 virtual void visit(void* ud) override;
75AST_END(SelfName)
76
77AST_NODE(KeyName)
78 ast_ptr<ast_node> name; // SelfName_t | _Name_t
79 virtual void visit(void* ud) override;
80AST_END(KeyName)
81
82AST_LEAF(VarArg)
83 virtual void visit(void* ud) override;
84AST_END(VarArg)
85
86AST_LEAF(local_flag)
87AST_END(local_flag)
88
89AST_LEAF(Seperator)
90AST_END(Seperator)
91
92AST_NODE(NameList)
93 ast_ptr<Seperator_t> sep;
94 ast_list<Name_t> names;
95
96 virtual void visit(void* ud) override;
97AST_END(NameList)
98
99AST_NODE(Local)
100 ast_ptr<ast_node> name; // local_flag_t | NameList_t
101AST_END(Local)
102
103AST_NODE(colon_import_name)
104 ast_ptr<Name_t> name;
105AST_END(colon_import_name)
106
107class Exp_t;
108
109AST_NODE(ImportName)
110 ast_ptr<ast_node> name; // colon_import_name_t | Name_t
111AST_END(ImportName)
112
113AST_NODE(Import)
114 ast_ptr<Seperator_t> sep;
115 ast_list<ImportName_t> names;
116 ast_ptr<Exp_t> exp;
117 virtual void visit(void* ud) override;
118AST_END(Import)
119
120AST_NODE(ExpListLow)
121 ast_ptr<Seperator_t> sep;
122 ast_list<Exp_t> exprs;
123 virtual void visit(void* ud) override;
124AST_END(ExpListLow)
125
126AST_NODE(ExpList)
127 ast_ptr<Seperator_t> sep;
128 ast_list<Exp_t> exprs;
129 virtual void visit(void* ud) override;
130AST_END(ExpList)
131
132AST_NODE(Return)
133 ast_ptr<ExpListLow_t, true> valueList;
134 virtual void visit(void* ud) override;
135AST_END(Return)
136
137class Assign_t;
138class Body_t;
139
140AST_NODE(With)
141 ast_ptr<ExpList_t> valueList;
142 ast_ptr<Assign_t, true> assigns;
143 ast_ptr<Body_t> body;
144 virtual void visit(void* ud) override;
145AST_END(With)
146
147AST_NODE(SwitchCase)
148 ast_ptr<ExpList_t> valueList;
149 ast_ptr<Body_t> body;
150AST_END(SwitchCase)
151
152AST_NODE(Switch)
153 ast_ptr<Exp_t> target;
154 ast_ptr<Seperator_t> sep;
155 ast_list<SwitchCase_t> branches;
156 ast_ptr<Body_t, true> lastBranch;
157AST_END(Switch)
158
159AST_NODE(IfCond)
160 ast_ptr<Exp_t> condition;
161 ast_ptr<Assign_t, true> assign;
162AST_END(IfCond)
163
164AST_NODE(IfElseIf)
165 ast_ptr<IfCond_t> condition;
166 ast_ptr<Body_t> body;
167AST_END(IfElseIf)
168
169AST_NODE(If)
170 ast_ptr<IfCond_t> firstCondition;
171 ast_ptr<Body_t> firstBody;
172 ast_ptr<Seperator_t> sep;
173 ast_list<IfElseIf_t> branches;
174 ast_ptr<Body_t, true> lastBranch;
175AST_END(If)
176
177AST_NODE(Unless)
178 ast_ptr<IfCond_t> firstCondition;
179 ast_ptr<Body_t> firstBody;
180 ast_ptr<Seperator_t> sep;
181 ast_list<IfElseIf_t> branches;
182 ast_ptr<Body_t, true> lastBranch;
183AST_END(Unless)
184
185AST_NODE(While)
186 ast_ptr<Exp_t> condition;
187 ast_ptr<Body_t> body;
188AST_END(While)
189
190AST_NODE(for_step_value)
191 ast_ptr<Exp_t> value;
192AST_END(for_step_value)
193
194AST_NODE(For)
195 ast_ptr<Name_t> varName;
196 ast_ptr<Exp_t> startValue;
197 ast_ptr<Exp_t> stopValue;
198 ast_ptr<for_step_value_t, true> stepValue;
199 ast_ptr<Body_t> body;
200AST_END(For)
201
202class AssignableNameList_t;
203
204AST_NODE(ForEach)
205 ast_ptr<AssignableNameList_t> nameList;
206 ast_ptr<ast_node> loopValue; // Exp_t | ExpList_t
207 ast_ptr<Body_t> body;
208AST_END(ForEach)
209
210AST_NODE(Do)
211 ast_ptr<Body_t> body;
212AST_END(Do)
213
214class CompInner_t;
215
216AST_NODE(Comprehension)
217 ast_ptr<Exp_t> value;
218 ast_ptr<CompInner_t> forLoop;
219AST_END(Comprehension)
220
221AST_NODE(comp_value)
222 ast_ptr<Exp_t> value;
223AST_END(comp_value)
224
225AST_NODE(TblComprehension)
226 ast_ptr<Exp_t> key;
227 ast_ptr<comp_value_t, true> value;
228 ast_ptr<CompInner_t> forLoop;
229AST_END(TblComprehension)
230
231AST_NODE(star_exp)
232 ast_ptr<Exp_t> value;
233AST_END(star_exp)
234
235AST_NODE(CompForEach)
236 ast_ptr<AssignableNameList_t> nameList;
237 ast_ptr<ast_node> loopValue; // star_exp_t | Exp_t
238AST_END(CompForEach)
239
240AST_NODE(CompFor)
241 ast_ptr<Name_t> varName;
242 ast_ptr<Exp_t> startValue;
243 ast_ptr<Exp_t> stopValue;
244 ast_ptr<for_step_value_t, true> stepValue;
245AST_END(CompFor)
246
247AST_NODE(CompClause)
248 ast_ptr<ast_node> nestExp; // CompFor_t | CompForEach_t | Exp_t
249AST_END(CompClause)
250
251AST_NODE(CompInner)
252 ast_ptr<ast_node> compFor; // CompFor_t | CompForEach_t
253 ast_ptr<Seperator_t> sep;
254 ast_list<CompClause_t> clauses;
255AST_END(CompInner)
256
257class TableBlock_t;
258
259AST_NODE(Assign)
260 ast_ptr<ast_node> value; // With_t | If_t | Switch_t | TableBlock_t | ExpListLow_t
261AST_END(Assign)
262
263AST_LEAF(update_op)
264AST_END(update_op)
265
266AST_NODE(Update)
267 ast_ptr<update_op_t> op;
268 ast_ptr<Exp_t> value;
269AST_END(Update)
270
271AST_LEAF(BinaryOperator)
272AST_END(BinaryOperator)
273
274class Chain_t;
275
276AST_NODE(Assignable)
277 ast_ptr<ast_node> item; // Chain_t | Name_t | SelfName_t
278AST_END(Assignable)
279
280class Value_t;
281
282AST_NODE(exp_op_value)
283 ast_ptr<BinaryOperator_t> op;
284 ast_ptr<Value_t> value;
285AST_END(exp_op_value)
286
287AST_NODE(Exp)
288 ast_ptr<Value_t> value;
289 ast_list<exp_op_value_t> opValues;
290AST_END(Exp)
291
292AST_NODE(Callable)
293 ast_ptr<ast_node> item; // Name_t | SelfName_t | VarArg_t | Parens_t
294AST_END(Callable)
295
296class InvokeArgs_t;
297
298AST_NODE(ChainValue)
299 ast_ptr<ast_node> caller; // Chain_t | Callable_t
300 ast_ptr<InvokeArgs_t, true> arguments;
301AST_END(ChainValue)
302
303class KeyValue_t;
304
305AST_NODE(simple_table)
306 ast_ptr<Seperator_t> sep;
307 ast_list<KeyValue_t> pairs;
308AST_END(simple_table)
309
310class String_t;
311
312AST_NODE(SimpleValue)
313 ast_ptr<ast_node> value; /*
314 const_value_t |
315 If_t | Unless_t | Switch_t | With_t | ClassDecl_t | ForEach_t | For_t | While_t | Do_t |
316 unary_exp_t |
317 TblComprehension_t | TableLit_t | Comprehension_t | FunLit_t | Num_t;
318 */
319AST_END(SimpleValue)
320
321AST_NODE(Chain)
322 ast_ptr<ast_node> item; // chain_call_t | chain_item_t | chain_dot_chain_t | ColonChain_t
323AST_END(Chain)
324
325AST_NODE(Value)
326 ast_ptr<ast_node> item; // SimpleValue_t | simple_table_t | ChainValue_t | String_t
327 ast_node* getFlattened();
328AST_END(Value)
329
330AST_LEAF(LuaString)
331AST_END(LuaString)
332
333AST_LEAF(SingleString)
334AST_END(SingleString)
335
336AST_LEAF(double_string_inner)
337AST_END(double_string_inner)
338
339AST_NODE(double_string_content)
340 ast_ptr<ast_node> content; // double_string_inner_t | Exp_t
341AST_END(double_string_content)
342
343AST_NODE(DoubleString)
344 ast_ptr<Seperator_t> sep;
345 ast_list<double_string_content_t> segments;
346AST_END(DoubleString)
347
348AST_NODE(String)
349 ast_ptr<ast_node> str; // DoubleString_t | SingleString_t | LuaString_t
350AST_END(String)
351
352AST_NODE(Parens)
353 ast_ptr<Exp_t> expr;
354AST_END(Parens)
355
356AST_NODE(FnArgs)
357 ast_ptr<Seperator_t> sep;
358 ast_list<Exp_t> args;
359AST_END(FnArgs)
360
361class ChainItems_t;
362
363AST_NODE(chain_call)
364 ast_ptr<ast_node> caller; // Callable_t | String_t
365 ast_ptr<ChainItems_t> chain;
366AST_END(chain_call)
367
368AST_NODE(chain_item)
369 ast_ptr<ChainItems_t> chain;
370AST_END(chain_item)
371
372AST_NODE(DotChainItem)
373 ast_ptr<_Name_t> name;
374AST_END(DotChainItem)
375
376AST_NODE(ColonChainItem)
377 ast_ptr<_Name_t> name;
378AST_END(ColonChainItem)
379
380AST_NODE(chain_dot_chain)
381 ast_ptr<DotChainItem_t> caller;
382 ast_ptr<ChainItems_t, true> chain;
383AST_END(chain_dot_chain)
384
385class ColonChain_t;
386class Invoke_t;
387class Slice_t;
388
389AST_NODE(ChainItem)
390 ast_ptr<ast_node> item; // Invoke_t | DotChainItem_t | Slice_t | [Exp_t]
391AST_END(ChainItem)
392
393AST_NODE(ChainItems)
394 ast_ptr<Seperator_t> sep;
395 ast_list<ChainItem_t> simpleChain;
396 ast_ptr<ColonChain_t, true> colonChain;
397AST_END(ChainItems)
398
399AST_NODE(invoke_chain)
400 ast_ptr<Invoke_t> invoke;
401 ast_ptr<ChainItems_t, true> chain;
402AST_END(invoke_chain)
403
404AST_NODE(ColonChain)
405 ast_ptr<ColonChainItem_t> colonChain;
406 ast_ptr<invoke_chain_t, true> invokeChain;
407AST_END(ColonChain)
408
409AST_LEAF(default_value)
410AST_END(default_value)
411
412AST_NODE(Slice)
413 ast_ptr<ast_node> startValue; // Exp_t | default_value_t
414 ast_ptr<ast_node> stopValue; // Exp_t | default_value_t
415 ast_ptr<ast_node> stepValue; // Exp_t | default_value_t
416AST_END(Slice)
417
418AST_NODE(Invoke)
419 ast_ptr<ast_node> argument; // FnArgs_t | SingleString_t | DoubleString_t | LuaString_t
420AST_END(Invoke)
421
422class KeyValue_t;
423
424AST_NODE(TableValue)
425 ast_ptr<ast_node> value; // KeyValue_t | Exp_t
426AST_END(TableValue)
427
428AST_NODE(TableLit)
429 ast_ptr<Seperator_t> sep;
430 ast_list<TableValue_t> values;
431AST_END(TableLit)
432
433AST_NODE(TableBlock)
434 ast_ptr<Seperator_t> sep;
435 ast_list<KeyValue_t> values;
436AST_END(TableBlock)
437
438AST_NODE(class_member_list)
439 ast_ptr<Seperator_t> sep;
440 ast_list<KeyValue_t> values;
441AST_END(class_member_list)
442
443AST_NODE(ClassLine)
444 ast_ptr<ast_node> content; // class_member_list_t | Statement_t | Exp_t
445AST_END(ClassLine)
446
447AST_NODE(ClassBlock)
448 ast_ptr<Seperator_t> sep;
449 ast_list<ClassLine_t> lines;
450AST_END(ClassBlock)
451
452AST_NODE(ClassDecl)
453 ast_ptr<Assignable_t, true> name;
454 ast_ptr<Exp_t, true> extend;
455 ast_ptr<ClassBlock_t, true> body;
456AST_END(ClassDecl)
457
458AST_NODE(export_values)
459 ast_ptr<NameList_t> nameList;
460 ast_ptr<ExpListLow_t, true> valueList;
461AST_END(export_values)
462
463AST_LEAF(export_op)
464AST_END(export_op)
465
466AST_NODE(Export)
467 ast_ptr<ast_node> item; // ClassDecl_t | export_op_t | export_values_t
468AST_END(Export)
469
470AST_NODE(variable_pair)
471 ast_ptr<Name_t> name;
472AST_END(variable_pair)
473
474AST_NODE(normal_pair)
475 ast_ptr<ast_node> key; // KeyName_t | [Exp_t] | DoubleString_t | SingleString_t
476 ast_ptr<ast_node> value; // Exp_t | TableBlock_t
477AST_END(normal_pair)
478
479AST_NODE(KeyValue)
480 ast_ptr<ast_node> item; // variable_pair_t | normal_pair_t
481AST_END(KeyValue)
482
483AST_NODE(FnArgDef)
484 ast_ptr<ast_node> name; // Name_t | SelfName_t
485 ast_ptr<Exp_t, true> defaultValue;
486AST_END(FnArgDef)
487
488AST_NODE(FnArgDefList)
489 ast_ptr<Seperator_t> sep;
490 ast_list<FnArgDef_t> definitions;
491 ast_ptr<VarArg_t, true> varArg;
492AST_END(FnArgDefList)
493
494AST_NODE(outer_var_shadow)
495 ast_ptr<NameList_t, true> varList;
496AST_END(outer_var_shadow)
497
498AST_NODE(FnArgsDef)
499 ast_ptr<FnArgDefList_t, true> defList;
500 ast_ptr<outer_var_shadow_t, true> shadowOption;
501AST_END(FnArgsDef)
502
503AST_LEAF(fn_arrow)
504AST_END(fn_arrow)
505
506AST_NODE(FunLit)
507 ast_ptr<FnArgsDef_t, true> argsDef;
508 ast_ptr<fn_arrow_t> arrow;
509 ast_ptr<Body_t, true> body;
510AST_END(FunLit)
511
512AST_NODE(NameOrDestructure)
513 ast_ptr<ast_node> item; // Name_t | TableLit_t
514AST_END(NameOrDestructure)
515
516AST_NODE(AssignableNameList)
517 ast_ptr<Seperator_t> sep;
518 ast_list<NameOrDestructure_t> items;
519AST_END(AssignableNameList)
520
521AST_NODE(ArgBlock)
522 ast_ptr<Seperator_t> sep;
523 ast_list<Exp_t> arguments;
524AST_END(ArgBlock)
525
526AST_NODE(invoke_args_with_table)
527 ast_ptr<ArgBlock_t, true> argBlock;
528 ast_ptr<TableBlock_t, true> tableBlock;
529AST_END(invoke_args_with_table)
530
531AST_NODE(InvokeArgs)
532 ast_ptr<ExpList_t, true> argsList;
533 ast_ptr<invoke_args_with_table_t, true> argsTableBlock;
534 ast_ptr<TableBlock_t, true> tableBlock;
535AST_END(InvokeArgs)
536
537AST_LEAF(const_value)
538AST_END(const_value)
539
540AST_NODE(unary_exp)
541 ast_ptr<Exp_t> item;
542AST_END(unary_exp)
543
544AST_NODE(Assignment)
545 ast_ptr<ExpList_t> assignable;
546 ast_ptr<ast_node> target; // Update_t | Assign_t
547AST_END(Assignment)
548
549AST_NODE(if_else_line)
550 ast_ptr<Exp_t> condition;
551 ast_ptr<ast_node> elseExpr; // Exp_t | default_value_t
552AST_END(if_else_line)
553
554AST_NODE(unless_line)
555 ast_ptr<Exp_t> condition;
556AST_END(unless_line)
557
558AST_NODE(statement_appendix)
559 ast_ptr<ast_node> item; // if_else_line_t | unless_line_t | CompInner_t
560AST_END(statement_appendix)
561
562AST_LEAF(BreakLoop)
563AST_END(BreakLoop)
564
565AST_NODE(Statement)
566 ast_ptr<ast_node> content; /*
567 Import_t | While_t | With_t | For_t | ForEach_t |
568 Switch_t | Return_t | Local_t | Export_t | BreakLoop_t |
569 Assignment_t | ExpList_t
570 */
571 ast_ptr<statement_appendix_t, true> appendix;
572AST_END(Statement)
573
574class Block_t;
575
576AST_NODE(Body)
577 ast_ptr<ast_node> content; // Block | Statement
578AST_END(Body)
579
580AST_NODE(Line)
581 ast_ptr<Statement_t, true> statment;
582AST_END(Line)
583
584AST_NODE(Block)
585 ast_ptr<Seperator_t> sep;
586 ast_list<Line_t> lines;
587AST_END(Block)
588
589AST_NODE(BlockEnd)
590 ast_ptr<Block_t> block;
591AST_END(BlockEnd)
diff --git a/MoonParser/moon_parser.cpp b/MoonParser/moon_parser.cpp
new file mode 100644
index 0000000..3069659
--- /dev/null
+++ b/MoonParser/moon_parser.cpp
@@ -0,0 +1,508 @@
1#include "moon_parser.h"
2
3rule Any = any();
4rule plain_space = *set(" \t");
5rule Break = nl(-expr('\r') >> '\n');
6rule White = *(set(" \t") | Break);
7rule Stop = Break | eof();
8rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop);
9rule Indent = *set(" \t");
10rule Space = plain_space >> -Comment;
11rule SomeSpace = +set(" \t") >> -Comment;
12rule SpaceBreak = Space >> Break;
13rule EmptyLine = SpaceBreak;
14rule AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_';
15rule _Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum;
16rule SpaceName = Space >> _Name;
17rule _Num =
18 (
19 "0x" >>
20 +(range('0', '9') | range('a', 'f') | range('A', 'F')) >>
21 -(-set("uU") >> set("lL") >> set("lL"))
22 ) | (
23 +range('0', '9') >> -set("uU") >> set("lL") >> set("lL")
24 ) | (
25 (
26 (+range('0', '9') >> -('.' >> +range('0', '9'))) |
27 ('.' >> +range('0', '9'))
28 ) >> -(set("eE") >> -expr('-') >> +range('0', '9'))
29 );
30rule Num = Space >> _Num;
31rule Cut = false_();
32rule Seperator = true_();
33
34#define sym(str) (Space >> str)
35#define symx(str) expr(str)
36#define ensure(patt, finally) (((patt) >> (finally)) | ((finally) >> (Cut)))
37#define key(str) (Space >> str >> not_(AlphaNum))
38#define opWord(str) (Space >> str >> not_(AlphaNum))
39#define op(str) (Space >> str)
40
41rule Name = user(SpaceName, [](const item_t& item)
42{
43 State* st = reinterpret_cast<State*>(item.user_data);
44 for (auto it = item.begin; it != item.end; ++it) st->buffer << static_cast<char>(*it);
45 std::string name;
46 st->buffer >> name;
47 st->buffer.str("");
48 st->buffer.clear();
49 auto it = st->keywords.find(name);
50 return it == st->keywords.end();
51});
52
53rule self = expr('@');
54rule self_name = '@' >> _Name;
55rule self_class = expr("@@");
56rule self_class_name = "@@" >> _Name;
57
58rule SelfName = Space >> (self_class_name | self_class | self_name | self);
59rule KeyName = SelfName | Space >> _Name;
60rule VarArg = Space >> "...";
61
62rule check_indent = user(Indent, [](const item_t& item)
63{
64 int indent = 0;
65 for (input_it i = item.begin; i != item.end; ++i)
66 {
67 switch (*i)
68 {
69 case ' ': indent++; break;
70 case '\t': indent += 4; break;
71 }
72 }
73 State* st = reinterpret_cast<State*>(item.user_data);
74 return st->indents.top() == indent;
75});
76rule CheckIndent = and_(check_indent);
77
78rule advance = user(Indent, [](const item_t& item)
79{
80 int indent = 0;
81 for (input_it i = item.begin; i != item.end; ++i)
82 {
83 switch (*i)
84 {
85 case ' ': indent++; break;
86 case '\t': indent += 4; break;
87 }
88 }
89 State* st = reinterpret_cast<State*>(item.user_data);
90 int top = st->indents.top();
91 if (top != -1 && indent > top)
92 {
93 st->indents.push(indent);
94 return true;
95 }
96 return false;
97});
98rule Advance = and_(advance);
99
100rule push_indent = user(Indent, [](const item_t& item)
101{
102 int indent = 0;
103 for (input_it i = item.begin; i != item.end; ++i)
104 {
105 switch (*i)
106 {
107 case ' ': indent++; break;
108 case '\t': indent += 4; break;
109 }
110 }
111 State* st = reinterpret_cast<State*>(item.user_data);
112 st->indents.push(indent);
113 return true;
114});
115rule PushIndent = and_(push_indent);
116
117rule PreventIndent = user(true_(), [](const item_t& item)
118{
119 State* st = reinterpret_cast<State*>(item.user_data);
120 st->indents.push(-1);
121 return true;
122});
123
124rule PopIndent = user(true_(), [](const item_t& item)
125{
126 State* st = reinterpret_cast<State*>(item.user_data);
127 st->indents.pop();
128 return true;
129});
130
131extern rule Block;
132
133rule InBlock = Advance >> Block >> PopIndent;
134
135extern rule NameList;
136
137rule local_flag = op('*') | op('^');
138rule Local = key("local") >> (local_flag | NameList);
139
140rule colon_import_name = sym('\\') >> Name;
141rule ImportName = colon_import_name | Name;
142rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName);
143
144extern rule Exp;
145
146rule Import = key("import") >> ImportNameList >> *SpaceBreak >> key("from") >> Exp;
147rule BreakLoop = key("break") | key("continue");
148
149extern rule ExpListLow, ExpList, Assign;
150
151rule Return = key("return") >> -ExpListLow;
152rule WithExp = ExpList >> -Assign;
153
154extern rule DisableDo, PopDo, Body;
155
156rule With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body;
157rule SwitchCase = key("when") >> ExpList >> -key("then") >> Body;
158rule SwitchElse = key("else") >> Body;
159
160rule SwitchBlock = *EmptyLine >>
161 Advance >> Seperator >>
162 SwitchCase >>
163 *(+Break >> SwitchCase) >>
164 -(+Break >> SwitchElse) >>
165 PopIndent;
166
167rule Switch = key("switch") >>
168 DisableDo >> ensure(Exp, PopDo) >>
169 -key("do") >> -Space >> Break >> SwitchBlock;
170
171rule IfCond = Exp >> -Assign;
172rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body;
173rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body;
174rule If = key("if") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse;
175rule Unless = key("unless") >> IfCond >> -key("then") >> Body >> Seperator >> *IfElseIf >> -IfElse;
176
177rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body;
178
179rule for_step_value = sym(',') >> Exp;
180rule for_args = Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
181
182rule For = key("for") >> DisableDo >>
183 ensure(for_args, PopDo) >>
184 -key("do") >> Body;
185
186extern rule AssignableNameList;
187
188rule for_in = sym('*') >> Exp | ExpList;
189
190rule ForEach = key("for") >> AssignableNameList >> key("in") >>
191 DisableDo >> ensure(for_in, PopDo) >>
192 -key("do") >> Body;
193
194rule Do = user(key("do") >> Body, [](const item_t& item)
195{
196 State* st = reinterpret_cast<State*>(item.user_data);
197 return st->doStack.empty() || st->doStack.top();
198});
199
200rule DisableDo = user(true_(), [](const item_t& item)
201{
202 State* st = reinterpret_cast<State*>(item.user_data);
203 st->doStack.push(false);
204 return true;
205});
206
207rule PopDo = user(true_(), [](const item_t& item)
208{
209 State* st = reinterpret_cast<State*>(item.user_data);
210 st->doStack.pop();
211 return true;
212});
213
214extern rule CompInner;
215
216rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']');
217rule comp_value = sym(',') >> Exp;
218rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}');
219
220extern rule CompForEach, CompFor, CompClause;
221
222rule CompInner = (CompForEach | CompFor) >> Seperator >> *CompClause;
223rule star_exp = sym('*') >> Exp;
224rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp);
225rule CompFor = key("for") >> Name >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
226rule CompClause = CompFor | CompForEach | key("when") >> Exp;
227
228extern rule TableBlock;
229
230rule Assign = sym('=') >> (With | If | Switch | TableBlock | ExpListLow);
231
232rule update_op =
233 sym("..=") |
234 sym("+=") |
235 sym("-=") |
236 sym("*=") |
237 sym("/=") |
238 sym("%=") |
239 sym("or=") |
240 sym("and=") |
241 sym("&=") |
242 sym("|=") |
243 sym(">>=") |
244 sym("<<=");
245
246rule Update = update_op >> Exp;
247
248rule CharOperators = Space >> set("+-*/%^><|&");
249rule WordOperators =
250 opWord("or") |
251 opWord("and") |
252 op("<=") |
253 op(">=") |
254 op("~=") |
255 op("!=") |
256 op("==") |
257 op("..") |
258 op("<<") |
259 op(">>") |
260 op("//");
261
262rule BinaryOperator = (WordOperators | CharOperators) >> *SpaceBreak;
263
264extern rule Chain;
265
266rule Assignable = Chain | Name | SelfName;
267
268extern rule Value;
269
270rule exp_op_value = BinaryOperator >> Value;
271rule Exp = Value >> *exp_op_value;
272
273extern rule Callable, InvokeArgs;
274
275rule ChainValue = (Chain | Callable) >> -InvokeArgs;
276
277extern rule KeyValue, String, SimpleValue;
278
279rule simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
280rule Value = SimpleValue | simple_table | ChainValue | String;
281
282extern rule LuaString;
283
284rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any;
285rule SingleString = symx('\'') >> *single_string_inner >> sym('\'');
286rule interp = symx("#{") >> Exp >> sym('}');
287rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any;
288rule double_string_inner = +(not_(interp) >> double_string_plain);
289rule double_string_content = double_string_inner | interp;
290rule DoubleString = symx('"') >> Seperator >> *double_string_content >> sym('"');
291rule String = Space >> (DoubleString | SingleString | LuaString);
292
293rule lua_string_open = '[' >> *expr('=') >> '[';
294rule lua_string_close = ']' >> *expr('=') >> ']';
295
296rule LuaStringOpen = user(lua_string_open, [](const item_t& item)
297{
298 size_t count = std::distance(item.begin, item.end);
299 State* st = reinterpret_cast<State*>(item.user_data);
300 st->stringOpen = count;
301 return true;
302});
303
304rule LuaStringClose = user(lua_string_close, [](const item_t& item)
305{
306 size_t count = std::distance(item.begin, item.end);
307 State* st = reinterpret_cast<State*>(item.user_data);
308 return st->stringOpen == count;
309});
310
311rule LuaStringContent = *(not_(LuaStringClose) >> (Break | Any));
312
313rule LuaString = user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item)
314{
315 State* st = reinterpret_cast<State*>(item.user_data);
316 st->stringOpen = -1;
317 return true;
318});
319
320rule Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')');
321rule Callable = Name | SelfName | VarArg | Parens;
322rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp);
323
324rule FnArgs = Seperator >>
325(
326 (
327 symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')
328 ) | (
329 sym('!') >> not_(expr('='))
330 )
331);
332
333extern rule ChainItems, DotChainItem, ColonChain;
334
335rule chain_call = (Callable | String) >> ChainItems;
336rule chain_item = not_(set(".\\")) >> ChainItems;
337rule chain_dot_chain = DotChainItem >> -ChainItems;
338
339rule Chain =
340 chain_call |
341 chain_item |
342 Space >> (chain_dot_chain | ColonChain);
343
344extern rule ChainItem;
345
346rule chain_with_colon = +ChainItem >> -ColonChain;
347rule ChainItems = Seperator >> (chain_with_colon | ColonChain);
348
349extern rule Invoke, Slice;
350
351rule Index = symx('[') >> Exp >> sym(']');
352rule ChainItem = Invoke | DotChainItem | Slice | Index;
353rule DotChainItem = symx('.') >> _Name;
354rule ColonChainItem = symx('\\') >> _Name;
355rule invoke_chain = Invoke >> -ChainItems;
356rule ColonChain = ColonChainItem >> -invoke_chain;
357
358rule default_value = true_();
359rule Slice =
360 symx('[') >>
361 (Exp | default_value) >>
362 sym(',') >>
363 (Exp | default_value) >>
364 (sym(',') >> Exp | default_value) >>
365 sym(']');
366
367rule Invoke =
368 FnArgs |
369 SingleString |
370 DoubleString |
371 and_(expr('[')) >> LuaString;
372
373extern rule TableValueList, TableLitLine;
374
375rule TableValue = KeyValue | Exp;
376
377rule table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(',');
378
379rule TableLit =
380 sym('{') >> Seperator >>
381 -TableValueList >>
382 -sym(',') >>
383 -table_lit_lines >>
384 White >> sym('}');
385
386rule TableValueList = TableValue >> *(sym(',') >> TableValue);
387
388rule TableLitLine =
389(
390 PushIndent >> (TableValueList >> PopIndent | PopIndent)
391) | (
392 Space
393);
394
395extern rule KeyValueLine;
396
397rule TableBlockInner = Seperator >> KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine);
398rule TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent);
399
400extern rule Statement;
401
402rule class_member_list = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
403rule ClassLine = CheckIndent >> (class_member_list | Statement | Exp) >> -sym(',');
404rule ClassBlock = +(SpaceBreak) >> Advance >>Seperator >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent;
405
406rule ClassDecl =
407 key("class") >> not_(expr(':')) >>
408 -Assignable >>
409 -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >>
410 -ClassBlock;
411
412rule export_values = NameList >> -(sym('=') >> ExpListLow);
413rule export_op = op('*') | op('^');
414rule Export = key("export") >> (ClassDecl | export_op | export_values);
415
416rule variable_pair = sym(':') >> not_(SomeSpace) >> Name;
417
418rule normal_pair =
419(
420 KeyName |
421 sym('[') >> Exp >> sym(']') |
422 Space >> DoubleString |
423 Space >> SingleString
424) >>
425symx(':') >>
426(Exp | TableBlock | +(SpaceBreak) >> Exp);
427
428rule KeyValue = variable_pair | normal_pair;
429
430rule KeyValueList = KeyValue >> *(sym(',') >> KeyValue);
431rule KeyValueLine = CheckIndent >> KeyValueList >> -sym(',');
432
433rule FnArgDef = (Name | SelfName) >> -(sym('=') >> Exp);
434
435rule FnArgDefList = Seperator >>
436(
437 (
438 FnArgDef >>
439 *((sym(',') | Break) >> White >> FnArgDef) >>
440 -((sym(',') | Break) >> White >> VarArg)
441 ) | (
442 VarArg
443 )
444);
445
446rule outer_var_shadow = key("using") >> (NameList | Space >> expr("nil"));
447
448rule FnArgsDef = sym('(') >> White >> -FnArgDefList >> -outer_var_shadow >> White >> sym(')');
449rule fn_arrow = sym("->") | sym("=>");
450rule FunLit = -FnArgsDef >> fn_arrow >> -Body;
451
452rule NameList = Seperator >> Name >> *(sym(',') >> Name);
453rule NameOrDestructure = Name | TableLit;
454rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure);
455
456rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp);
457rule ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp);
458
459rule ArgLine = CheckIndent >> Exp >> *(sym(',') >> Exp);
460rule ArgBlock = Seperator >> ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent;
461
462rule invoke_args_with_table =
463 sym(',') >>
464 (
465 TableBlock |
466 SpaceBreak >> Advance >> ArgBlock >> -TableBlock
467 );
468
469rule InvokeArgs =
470 not_(expr('-')) >>
471 (
472 ExpList >> -(invoke_args_with_table | TableBlock) |
473 TableBlock
474 );
475
476rule const_value = key("nil") | key("true") | key("false");
477rule minus_exp = sym('-') >> not_(SomeSpace) >> Exp;
478rule sharp_exp = sym('#') >> Exp;
479rule tilde_exp = sym('~') >> Exp;
480rule not_exp = key("not") >> Exp;
481rule unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp;
482
483rule SimpleValue =
484 const_value |
485 If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do |
486 unary_exp |
487 TblComprehension | TableLit | Comprehension | FunLit | Num;
488
489rule Assignment = ExpList >> (Update | Assign);
490
491rule if_else_line = key("if") >> Exp >> (key("else") >> Exp | default_value);
492rule unless_line = key("unless") >> Exp;
493
494rule statement_appendix = (if_else_line | unless_line | CompInner) >> Space;
495rule Statement =
496(
497 Import | While | With | For | ForEach |
498 Switch | Return | Local | Export | BreakLoop |
499 Assignment | ExpList
500) >> Space >>
501-statement_appendix;
502
503rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement;
504
505rule empty_line_stop = Space >> and_(Stop);
506rule Line = CheckIndent >> Statement | empty_line_stop;
507rule Block = Seperator >> Line >> *(+Break >> Line);
508rule BlockEnd = Block >> eof();
diff --git a/MoonParser/moon_parser.h b/MoonParser/moon_parser.h
new file mode 100644
index 0000000..0c3f427
--- /dev/null
+++ b/MoonParser/moon_parser.h
@@ -0,0 +1,31 @@
1#pragma once
2
3#include <string>
4#include <codecvt>
5#include <unordered_set>
6#include <stack>
7#include <algorithm>
8#include <sstream>
9#include <vector>
10#include "parserlib.hpp"
11using namespace parserlib;
12
13struct State
14{
15 State()
16 {
17 indents.push(0);
18 stringOpen = -1;
19 }
20 std::stringstream buffer;
21 size_t stringOpen;
22 std::stack<int> indents;
23 std::stack<bool> doStack;
24 std::unordered_set<std::string> keywords = {
25 "and", "while", "else", "using", "continue",
26 "local", "not", "then", "return", "from",
27 "extends", "for", "do", "or", "export",
28 "class", "in", "unless", "when", "elseif",
29 "switch", "break", "if", "with", "import"
30 };
31};