summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-01-30 16:06:32 +0800
committerLi Jin <dragon-fly@qq.com>2020-01-30 16:06:32 +0800
commitc62d9eb35a310e7663234526ce4b9fe3519ca7cf (patch)
tree56b4b418aadab90989e3e29e29e8ab7e04806e8d
parent240b1ec4a49128c00a787e6d0928865995b1d02e (diff)
downloadyuescript-c62d9eb35a310e7663234526ce4b9fe3519ca7cf.tar.gz
yuescript-c62d9eb35a310e7663234526ce4b9fe3519ca7cf.tar.bz2
yuescript-c62d9eb35a310e7663234526ce4b9fe3519ca7cf.zip
Separate MoonParser from MoonCompiler, make moonc compile multiple file in threads.
-rw-r--r--spec/inputs/backcall.moon10
-rw-r--r--src/MoonP/ast.cpp2
-rw-r--r--src/MoonP/ast.hpp24
-rw-r--r--src/MoonP/moon_ast.cpp120
-rw-r--r--src/MoonP/moon_ast.h5
-rw-r--r--src/MoonP/moon_compiler.cpp401
-rw-r--r--src/MoonP/moon_parser.cpp972
-rw-r--r--src/MoonP/moon_parser.h263
-rw-r--r--src/MoonP/parser.cpp50
-rw-r--r--src/MoonP/parser.hpp22
-rw-r--r--src/moonc.cpp155
11 files changed, 1043 insertions, 981 deletions
diff --git a/spec/inputs/backcall.moon b/spec/inputs/backcall.moon
index 355089a..7702059 100644
--- a/spec/inputs/backcall.moon
+++ b/spec/inputs/backcall.moon
@@ -31,17 +31,19 @@ f = ->
31998 |> func0("abc", 233) |> func1 |> func2 31998 |> func0("abc", 233) |> func1 |> func2
32 32
33do 33do
34 (data) <- http?.get "ajaxtest" 34 (data)<- http?.get "ajaxtest"
35 body[".result"]\html data 35 body[".result"]\html data
36 (processed) <- http.post "ajaxprocess", data 36 (processed)<- http.post "ajaxprocess", data
37 body[".result"]\append processed 37 body[".result"]\append processed
38 <- setTimeout 1000 38 <- setTimeout 1000
39 print "done" 39 print "done"
40 40
41do 41do
42 <- syncStatus 42 <- syncStatus
43 (err,data="nil") <- loadAsync "file.moon" 43 (err,data="nil")<- loadAsync "file.moon"
44 print err if err 44 if err
45 print err
46 return
45 (codes) <- compileAsync data 47 (codes) <- compileAsync data
46 func = loadstring codes 48 func = loadstring codes
47 func! 49 func!
diff --git a/src/MoonP/ast.cpp b/src/MoonP/ast.cpp
index cda2339..7cdefba 100644
--- a/src/MoonP/ast.cpp
+++ b/src/MoonP/ast.cpp
@@ -115,7 +115,7 @@ bool ast_container::visitChild(const std::function<bool (ast_node*)>& func) {
115 @return pointer to ast node created, or null if there was an error. 115 @return pointer to ast node created, or null if there was an error.
116 The return object must be deleted by the caller. 116 The return object must be deleted by the caller.
117 */ 117 */
118ast_node* _parse(input &i, rule &g, error_list &el, void* ud) { 118ast_node* parse(input &i, rule &g, error_list &el, void* ud) {
119 ast_stack st; 119 ast_stack st;
120 if (!parse(i, g, el, &st, ud)) { 120 if (!parse(i, g, el, &st, ud)) {
121 for (auto node : st) { 121 for (auto node : st) {
diff --git a/src/MoonP/ast.hpp b/src/MoonP/ast.hpp
index 0b5ffca..38141e2 100644
--- a/src/MoonP/ast.hpp
+++ b/src/MoonP/ast.hpp
@@ -522,7 +522,6 @@ public:
522 ast(rule& r) { 522 ast(rule& r) {
523 r.set_parse_proc(&_parse_proc); 523 r.set_parse_proc(&_parse_proc);
524 } 524 }
525
526private: 525private:
527 //parse proc 526 //parse proc
528 static void _parse_proc(const pos& b, const pos& e, void* d) { 527 static void _parse_proc(const pos& b, const pos& e, void* d) {
@@ -544,28 +543,7 @@ private:
544 @return pointer to ast node created, or null if there was an error. 543 @return pointer to ast node created, or null if there was an error.
545 The return object must be deleted by the caller. 544 The return object must be deleted by the caller.
546 */ 545 */
547ast_node* _parse(input& i, rule& g, error_list& el, void* ud); 546ast_node* parse(input& i, rule& g, error_list& el, void* ud);
548
549
550/** parses the given input.
551 @param i input.
552 @param g root rule of grammar.
553 @param el list of errors.
554 @param ud user data, passed to the parse procedures.
555 @return ast nodes.
556 */
557template <class T> ast_ptr<false, T> parse(input& i, rule& g, error_list& el, void* ud = nullptr) {
558 ast_node* node = _parse(i, g, el, ud);
559 T* ast = ast_cast<T>(node);
560 ast_ptr<false, T> ptr;
561 if (ast) {
562 ast_stack st{node};
563 ptr.construct(st);
564 } else if (node) {
565 delete node;
566 }
567 return ptr;
568}
569 547
570 548
571} //namespace parserlib 549} //namespace parserlib
diff --git a/src/MoonP/moon_ast.cpp b/src/MoonP/moon_ast.cpp
deleted file mode 100644
index f14fa74..0000000
--- a/src/MoonP/moon_ast.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
1/* Copyright (c) 2020 Jin Li, http://www.luvfight.me
2
3Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
5The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
7THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
8
9#include "MoonP/moon_ast.h"
10
11namespace MoonP {
12
13#define AST_IMPL(type) \
14 ast<type##_t> __##type##_t(type);
15
16AST_IMPL(Num)
17AST_IMPL(Name)
18AST_IMPL(Variable)
19AST_IMPL(LuaKeyword)
20AST_IMPL(self)
21AST_IMPL(self_name)
22AST_IMPL(self_class)
23AST_IMPL(self_class_name)
24AST_IMPL(SelfName)
25AST_IMPL(KeyName)
26AST_IMPL(VarArg)
27AST_IMPL(local_flag)
28AST_IMPL(Seperator)
29AST_IMPL(NameList)
30AST_IMPL(Local)
31AST_IMPL(colon_import_name)
32AST_IMPL(import_literal_inner)
33AST_IMPL(ImportLiteral)
34AST_IMPL(ImportFrom)
35AST_IMPL(ImportAs)
36AST_IMPL(Import)
37AST_IMPL(Backcall)
38AST_IMPL(ExpListLow)
39AST_IMPL(ExpList)
40AST_IMPL(Return)
41AST_IMPL(With)
42AST_IMPL(SwitchCase)
43AST_IMPL(Switch)
44AST_IMPL(IfCond)
45AST_IMPL(If)
46AST_IMPL(Unless)
47AST_IMPL(While)
48AST_IMPL(for_step_value)
49AST_IMPL(For)
50AST_IMPL(ForEach)
51AST_IMPL(Do)
52AST_IMPL(Comprehension)
53AST_IMPL(comp_value)
54AST_IMPL(TblComprehension)
55AST_IMPL(star_exp)
56AST_IMPL(CompForEach)
57AST_IMPL(CompFor)
58AST_IMPL(CompInner)
59AST_IMPL(Assign)
60AST_IMPL(update_op)
61AST_IMPL(Update)
62AST_IMPL(BinaryOperator)
63AST_IMPL(BackcallOperator)
64AST_IMPL(Assignable)
65AST_IMPL(AssignableChain)
66AST_IMPL(exp_op_value)
67AST_IMPL(Exp)
68AST_IMPL(Callable)
69AST_IMPL(ChainValue)
70AST_IMPL(simple_table)
71AST_IMPL(SimpleValue)
72AST_IMPL(Value)
73AST_IMPL(LuaStringOpen);
74AST_IMPL(LuaStringContent);
75AST_IMPL(LuaStringClose);
76AST_IMPL(LuaString)
77AST_IMPL(SingleString)
78AST_IMPL(double_string_inner)
79AST_IMPL(double_string_content)
80AST_IMPL(DoubleString)
81AST_IMPL(String)
82AST_IMPL(Parens)
83AST_IMPL(DotChainItem)
84AST_IMPL(ColonChainItem)
85AST_IMPL(default_value)
86AST_IMPL(Slice)
87AST_IMPL(Invoke)
88AST_IMPL(existential_op)
89AST_IMPL(TableLit)
90AST_IMPL(TableBlock)
91AST_IMPL(class_member_list)
92AST_IMPL(ClassBlock)
93AST_IMPL(ClassDecl)
94AST_IMPL(export_values)
95AST_IMPL(export_op)
96AST_IMPL(Export)
97AST_IMPL(variable_pair)
98AST_IMPL(normal_pair)
99AST_IMPL(FnArgDef)
100AST_IMPL(FnArgDefList)
101AST_IMPL(outer_var_shadow)
102AST_IMPL(FnArgsDef)
103AST_IMPL(fn_arrow)
104AST_IMPL(FunLit)
105AST_IMPL(NameOrDestructure)
106AST_IMPL(AssignableNameList)
107AST_IMPL(InvokeArgs)
108AST_IMPL(const_value)
109AST_IMPL(unary_exp)
110AST_IMPL(ExpListAssign)
111AST_IMPL(if_else_line)
112AST_IMPL(unless_line)
113AST_IMPL(statement_appendix)
114AST_IMPL(BreakLoop)
115AST_IMPL(Statement)
116AST_IMPL(Body)
117AST_IMPL(Block)
118AST_IMPL(File)
119
120} // namespace MoonP
diff --git a/src/MoonP/moon_ast.h b/src/MoonP/moon_ast.h
index 6969688..86f5ef3 100644
--- a/src/MoonP/moon_ast.h
+++ b/src/MoonP/moon_ast.h
@@ -8,12 +8,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
8 8
9#pragma once 9#pragma once
10 10
11#include "MoonP/moon_parser.h" 11#include "MoonP/ast.hpp"
12using namespace parserlib;
12 13
13namespace MoonP { 14namespace MoonP {
14 15
15#define AST_LEAF(type, id) \ 16#define AST_LEAF(type, id) \
16extern rule type; \
17class type##_t : public ast_node \ 17class type##_t : public ast_node \
18{ \ 18{ \
19public: \ 19public: \
@@ -21,7 +21,6 @@ public: \
21 virtual size_t getId() const override { return id; } \ 21 virtual size_t getId() const override { return id; } \
22 22
23#define AST_NODE(type, id) \ 23#define AST_NODE(type, id) \
24extern rule type; \
25class type##_t : public ast_container \ 24class type##_t : public ast_container \
26{ \ 25{ \
27public: \ 26public: \
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp
index caa7aaf..ceaff96 100644
--- a/src/MoonP/moon_compiler.cpp
+++ b/src/MoonP/moon_compiler.cpp
@@ -13,11 +13,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
13#include <vector> 13#include <vector>
14#include <numeric> 14#include <numeric>
15#include <memory> 15#include <memory>
16#include <sstream> 16#include "MoonP/moon_parser.h"
17#include <string_view>
18using namespace std::string_view_literals;
19#include "MoonP/parser.hpp"
20#include "MoonP/moon_ast.h"
21#include "MoonP/moon_compiler.h" 17#include "MoonP/moon_compiler.h"
22 18
23namespace MoonP { 19namespace MoonP {
@@ -40,25 +36,12 @@ class MoonCompiler {
40public: 36public:
41 std::pair<std::string,std::string> compile(const std::string& codes, const MoonConfig& config) { 37 std::pair<std::string,std::string> compile(const std::string& codes, const MoonConfig& config) {
42 _config = config; 38 _config = config;
43 try { 39 _info = _parser.parse<File_t>(codes);
44 _input = _converter.from_bytes(codes); 40 if (_info.node) {
45 } catch (const std::range_error&) {
46 return {Empty, "Invalid text encoding."};
47 }
48 error_list el;
49 State st;
50 ast_ptr<false, File_t> root;
51 try {
52 root = parse<File_t>(_input, File, el, &st);
53 } catch (const std::logic_error& error) {
54 clear();
55 return {Empty, error.what()};
56 }
57 if (root) {
58 try { 41 try {
59 str_list out; 42 str_list out;
60 pushScope(); 43 pushScope();
61 transformBlock(root->block, out, config.implicitReturnRoot); 44 transformBlock(_info.node.to<File_t>()->block, out, config.implicitReturnRoot);
62 popScope(); 45 popScope();
63 return {std::move(out.back()), Empty}; 46 return {std::move(out.back()), Empty};
64 } catch (const std::logic_error& error) { 47 } catch (const std::logic_error& error) {
@@ -66,14 +49,8 @@ public:
66 return {Empty, error.what()}; 49 return {Empty, error.what()};
67 } 50 }
68 } else { 51 } else {
69 clearBuf();
70 for (error_list::iterator it = el.begin(); it != el.end(); ++it) {
71 const error& err = *it;
72 _buf << debugInfo("Syntax error."sv, &err);
73 }
74 std::pair<std::string,std::string> result{Empty, clearBuf()};
75 clear(); 52 clear();
76 return result; 53 return {Empty, _info.error};
77 } 54 }
78 } 55 }
79 56
@@ -94,14 +71,13 @@ public:
94 _joinBuf.str(""); 71 _joinBuf.str("");
95 _joinBuf.clear(); 72 _joinBuf.clear();
96 _globals.clear(); 73 _globals.clear();
97 _input.clear();
98 } 74 }
99private: 75private:
100 MoonConfig _config; 76 MoonConfig _config;
77 MoonParser _parser;
78 ParseInfo _info;
101 int _indentOffset = 0; 79 int _indentOffset = 0;
102 Converter _converter; 80 std::list<std::unique_ptr<input>> _codeCache;
103 input _input;
104 std::list<input> _codeCache;
105 std::stack<std::string> _withVars; 81 std::stack<std::string> _withVars;
106 std::stack<std::string> _continueVars; 82 std::stack<std::string> _continueVars;
107 std::unordered_map<std::string,std::pair<int,int>> _globals; 83 std::unordered_map<std::string,std::pair<int,int>> _globals;
@@ -329,14 +305,6 @@ private:
329 return result; 305 return result;
330 } 306 }
331 307
332 std::string toString(ast_node* node) {
333 return _converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
334 }
335
336 std::string toString(input::iterator begin, input::iterator end) {
337 return _converter.to_bytes(std::wstring(begin, end));
338 }
339
340 Value_t* singleValueFrom(ast_node* item) const { 308 Value_t* singleValueFrom(ast_node* item) const {
341 Exp_t* exp = nullptr; 309 Exp_t* exp = nullptr;
342 switch (item->getId()) { 310 switch (item->getId()) {
@@ -400,26 +368,15 @@ private:
400 } 368 }
401 369
402 template <class T> 370 template <class T>
403 ast_ptr<false, T> toAst(std::string_view codes, rule& r, ast_node* parent) { 371 ast_ptr<false, T> toAst(std::string_view codes, ast_node* parent) {
404 _codeCache.push_back(_converter.from_bytes(s(codes))); 372 auto res = _parser.parse<T>(s(codes));
405 error_list el; 373 res.node->traverse([&](ast_node* node) {
406 State st;
407 auto ptr = parse<T>(_codeCache.back(), r, el, &st);
408 ptr->traverse([&](ast_node* node) {
409 node->m_begin.m_line = parent->m_begin.m_line; 374 node->m_begin.m_line = parent->m_begin.m_line;
410 node->m_end.m_line = parent->m_begin.m_line; 375 node->m_end.m_line = parent->m_begin.m_line;
411 return traversal::Continue; 376 return traversal::Continue;
412 }); 377 });
413 return ptr; 378 _codeCache.push_back(std::move(res.input));
414 } 379 return ast_ptr<false, T>(res.node.template to<T>());
415
416 bool matchAst(rule& r, std::string_view codes) {
417 error_list el;
418 State st;
419 input i = _converter.from_bytes(s(codes));
420 auto rEnd = rule(r >> eof());
421 ast_ptr<false, ast_node> result(_parse(i, rEnd, el, &st));
422 return result;
423 } 380 }
424 381
425 bool isChainValueCall(ChainValue_t* chainValue) const { 382 bool isChainValueCall(ChainValue_t* chainValue) const {
@@ -547,7 +504,7 @@ private:
547 for (auto exp_ : expList->exprs.objects()) { 504 for (auto exp_ : expList->exprs.objects()) {
548 Exp_t* exp = static_cast<Exp_t*>(exp_); 505 Exp_t* exp = static_cast<Exp_t*>(exp_);
549 if (!isAssignable(exp)) { 506 if (!isAssignable(exp)) {
550 throw std::logic_error(debugInfo("Left hand expression is not assignable."sv, exp)); 507 throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, exp));
551 } 508 }
552 } 509 }
553 } 510 }
@@ -567,40 +524,6 @@ private:
567 return backcall; 524 return backcall;
568 } 525 }
569 526
570 std::string debugInfo(std::string_view msg, const input_range* loc) const {
571 const int ASCII = 255;
572 int length = loc->m_begin.m_line;
573 auto begin = _input.begin();
574 auto end = _input.end();
575 int count = 0;
576 for (auto it = _input.begin(); it != _input.end(); ++it) {
577 if (*it == '\n') {
578 if (count + 1 == length) {
579 end = it;
580 break;
581 } else {
582 begin = it + 1;
583 }
584 count++;
585 }
586 }
587 auto line = Converter{}.to_bytes(std::wstring(begin, end));
588 int oldCol = loc->m_begin.m_col;
589 int col = std::max(0, oldCol - 1);
590 auto it = begin;
591 for (int i = 0; i < oldCol; ++i) {
592 if (*it > ASCII) {
593 ++col;
594 }
595 ++it;
596 }
597 replace(line, "\t"sv, " "sv);
598 std::ostringstream buf;
599 buf << loc->m_begin.m_line << ": "sv << msg <<
600 '\n' << line << '\n' << std::string(col, ' ') << "^"sv;
601 return buf.str();
602 }
603
604 void transformStatement(Statement_t* statement, str_list& out) { 527 void transformStatement(Statement_t* statement, str_list& out) {
605 auto x = statement; 528 auto x = statement;
606 if (statement->appendix) { 529 if (statement->appendix) {
@@ -761,7 +684,7 @@ private:
761 break; 684 break;
762 } 685 }
763 } 686 }
764 throw std::logic_error(debugInfo("Expression list must appear at the end of body block."sv, expList)); 687 throw std::logic_error(_info.errorMessage("Expression list must appear at the end of body block."sv, expList));
765 } 688 }
766 break; 689 break;
767 } 690 }
@@ -800,7 +723,7 @@ private:
800 BREAK_IF(!callable); 723 BREAK_IF(!callable);
801 std::string name; 724 std::string name;
802 if (auto var = callable->item.as<Variable_t>()) { 725 if (auto var = callable->item.as<Variable_t>()) {
803 name = toString(var); 726 name = _parser.toString(var);
804 } else if (auto self = callable->item.as<SelfName_t>()) { 727 } else if (auto self = callable->item.as<SelfName_t>()) {
805 if (self->name.is<self_t>()) name = "self"sv; 728 if (self->name.is<self_t>()) name = "self"sv;
806 } 729 }
@@ -811,7 +734,7 @@ private:
811 BLOCK_END 734 BLOCK_END
812 } 735 }
813 } else { 736 } else {
814 throw std::logic_error(debugInfo("Left hand expression is not assignable."sv, exp)); 737 throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, exp));
815 } 738 }
816 } 739 }
817 return preDefs; 740 return preDefs;
@@ -829,7 +752,7 @@ private:
829 BREAK_IF(!callable); 752 BREAK_IF(!callable);
830 std::string name; 753 std::string name;
831 if (auto var = callable->item.as<Variable_t>()) { 754 if (auto var = callable->item.as<Variable_t>()) {
832 name = toString(var); 755 name = _parser.toString(var);
833 } else if (auto self = callable->item.as<SelfName_t>()) { 756 } else if (auto self = callable->item.as<SelfName_t>()) {
834 if (self->name.is<self_t>()) name = "self"sv; 757 if (self->name.is<self_t>()) name = "self"sv;
835 } 758 }
@@ -840,7 +763,7 @@ private:
840 BLOCK_END 763 BLOCK_END
841 } 764 }
842 } else { 765 } else {
843 throw std::logic_error(debugInfo("Left hand expression is not assignable."sv, exp)); 766 throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, exp));
844 } 767 }
845 } 768 }
846 return preDefs; 769 return preDefs;
@@ -1071,7 +994,7 @@ private:
1071 _buf << pair.name << " = "sv << info.first.front().value << pair.structure << nll(assignment); 994 _buf << pair.name << " = "sv << info.first.front().value << pair.structure << nll(assignment);
1072 addToScope(pair.name); 995 addToScope(pair.name);
1073 temp.push_back(clearBuf()); 996 temp.push_back(clearBuf());
1074 } else if (matchAst(Name, destruct.value)) { 997 } else if (_parser.match<Name_t>(destruct.value)) {
1075 str_list defs, names, values; 998 str_list defs, names, values;
1076 for (const auto& item : destruct.items) { 999 for (const auto& item : destruct.items) {
1077 if (item.isVariable && addToScope(item.name)) { 1000 if (item.isVariable && addToScope(item.name)) {
@@ -1134,7 +1057,7 @@ private:
1134 const node_container* tableItems = nullptr; 1057 const node_container* tableItems = nullptr;
1135 if (ast_cast<Exp_t>(node)) { 1058 if (ast_cast<Exp_t>(node)) {
1136 auto item = singleValueFrom(node)->item.get(); 1059 auto item = singleValueFrom(node)->item.get();
1137 if (!item) throw std::logic_error(debugInfo("Invalid destructure value."sv, node)); 1060 if (!item) throw std::logic_error(_info.errorMessage("Invalid destructure value."sv, node));
1138 auto tbA = item->getByPath<TableLit_t>(); 1061 auto tbA = item->getByPath<TableLit_t>();
1139 if (tbA) { 1062 if (tbA) {
1140 tableItems = &tbA->values.objects(); 1063 tableItems = &tbA->values.objects();
@@ -1152,7 +1075,7 @@ private:
1152 case "Exp"_id: { 1075 case "Exp"_id: {
1153 ++index; 1076 ++index;
1154 if (!isAssignable(static_cast<Exp_t*>(pair))) { 1077 if (!isAssignable(static_cast<Exp_t*>(pair))) {
1155 throw std::logic_error(debugInfo("Can't destructure value."sv, pair)); 1078 throw std::logic_error(_info.errorMessage("Can't destructure value."sv, pair));
1156 } 1079 }
1157 auto value = singleValueFrom(pair); 1080 auto value = singleValueFrom(pair);
1158 auto item = value->item.get(); 1081 auto item = value->item.get();
@@ -1185,8 +1108,8 @@ private:
1185 } 1108 }
1186 case "variable_pair"_id: { 1109 case "variable_pair"_id: {
1187 auto vp = static_cast<variable_pair_t*>(pair); 1110 auto vp = static_cast<variable_pair_t*>(pair);
1188 auto name = toString(vp->name); 1111 auto name = _parser.toString(vp->name);
1189 if (State::keywords.find(name) != State::keywords.end()) { 1112 if (Keywords.find(name) != Keywords.end()) {
1190 pairs.push_back({true, name, s("[\""sv) + name + s("\"]"sv)}); 1113 pairs.push_back({true, name, s("[\""sv) + name + s("\"]"sv)});
1191 } else { 1114 } else {
1192 pairs.push_back({true, name, s("."sv) + name}); 1115 pairs.push_back({true, name, s("."sv) + name});
@@ -1196,16 +1119,16 @@ private:
1196 case "normal_pair"_id: { 1119 case "normal_pair"_id: {
1197 auto np = static_cast<normal_pair_t*>(pair); 1120 auto np = static_cast<normal_pair_t*>(pair);
1198 auto key = np->key->getByPath<Name_t>(); 1121 auto key = np->key->getByPath<Name_t>();
1199 if (!key) throw std::logic_error(debugInfo("Invalid key for destructure."sv, np)); 1122 if (!key) throw std::logic_error(_info.errorMessage("Invalid key for destructure."sv, np));
1200 if (auto exp = np->value.as<Exp_t>()) { 1123 if (auto exp = np->value.as<Exp_t>()) {
1201 if (!isAssignable(exp)) throw std::logic_error(debugInfo("Can't destructure value."sv, exp)); 1124 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("Can't destructure value."sv, exp));
1202 auto item = singleValueFrom(exp)->item.get(); 1125 auto item = singleValueFrom(exp)->item.get();
1203 if (ast_cast<simple_table_t>(item) || 1126 if (ast_cast<simple_table_t>(item) ||
1204 item->getByPath<TableLit_t>()) { 1127 item->getByPath<TableLit_t>()) {
1205 auto subPairs = destructFromExp(exp); 1128 auto subPairs = destructFromExp(exp);
1206 auto name = toString(key); 1129 auto name = _parser.toString(key);
1207 for (auto& p : subPairs) { 1130 for (auto& p : subPairs) {
1208 if (State::keywords.find(name) != State::keywords.end()) { 1131 if (Keywords.find(name) != Keywords.end()) {
1209 pairs.push_back({p.isVariable, p.name, 1132 pairs.push_back({p.isVariable, p.name,
1210 s("[\""sv) + name + s("\"]"sv) + p.structure}); 1133 s("[\""sv) + name + s("\"]"sv) + p.structure});
1211 } else { 1134 } else {
@@ -1224,8 +1147,8 @@ private:
1224 varName = std::move(temp.back()); 1147 varName = std::move(temp.back());
1225 } 1148 }
1226 _config.lintGlobalVariable = lintGlobal; 1149 _config.lintGlobalVariable = lintGlobal;
1227 auto name = toString(key); 1150 auto name = _parser.toString(key);
1228 if (State::keywords.find(name) != State::keywords.end()) { 1151 if (Keywords.find(name) != Keywords.end()) {
1229 pairs.push_back({ 1152 pairs.push_back({
1230 isVariable, 1153 isVariable,
1231 varName, 1154 varName,
@@ -1245,7 +1168,7 @@ private:
1245 auto subPairs = destructFromExp(pair); 1168 auto subPairs = destructFromExp(pair);
1246 for (auto& p : subPairs) { 1169 for (auto& p : subPairs) {
1247 pairs.push_back({p.isVariable, p.name, 1170 pairs.push_back({p.isVariable, p.name,
1248 s("."sv) + toString(key) + p.structure}); 1171 s("."sv) + _parser.toString(key) + p.structure});
1249 } 1172 }
1250 } 1173 }
1251 break; 1174 break;
@@ -1265,12 +1188,12 @@ private:
1265 size_t size = std::max(exprs.size(),values.size()); 1188 size_t size = std::max(exprs.size(),values.size());
1266 ast_ptr<false, Exp_t> var; 1189 ast_ptr<false, Exp_t> var;
1267 if (exprs.size() < size) { 1190 if (exprs.size() < size) {
1268 var = toAst<Exp_t>("_"sv, Exp, x); 1191 var = toAst<Exp_t>("_"sv, x);
1269 while (exprs.size() < size) exprs.emplace_back(var); 1192 while (exprs.size() < size) exprs.emplace_back(var);
1270 } 1193 }
1271 ast_ptr<false, Exp_t> nullNode; 1194 ast_ptr<false, Exp_t> nullNode;
1272 if (values.size() < size) { 1195 if (values.size() < size) {
1273 nullNode = toAst<Exp_t>("nil"sv, Exp, x); 1196 nullNode = toAst<Exp_t>("nil"sv, x);
1274 while (values.size() < size) values.emplace_back(nullNode); 1197 while (values.size() < size) values.emplace_back(nullNode);
1275 } 1198 }
1276 using iter = node_container::iterator; 1199 using iter = node_container::iterator;
@@ -1319,11 +1242,11 @@ private:
1319 auto action = assignment->action.get(); 1242 auto action = assignment->action.get();
1320 switch (action->getId()) { 1243 switch (action->getId()) {
1321 case "Update"_id: { 1244 case "Update"_id: {
1322 if (expList->exprs.size() > 1) throw std::logic_error(debugInfo("Can not apply update to multiple values."sv, expList)); 1245 if (expList->exprs.size() > 1) throw std::logic_error(_info.errorMessage("Can not apply update to multiple values."sv, expList));
1323 auto update = static_cast<Update_t*>(action); 1246 auto update = static_cast<Update_t*>(action);
1324 auto leftExp = static_cast<Exp_t*>(expList->exprs.objects().front()); 1247 auto leftExp = static_cast<Exp_t*>(expList->exprs.objects().front());
1325 auto leftValue = singleValueFrom(leftExp); 1248 auto leftValue = singleValueFrom(leftExp);
1326 if (!leftValue) throw std::logic_error(debugInfo("Left hand expression is not assignable."sv, leftExp)); 1249 if (!leftValue) throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, leftExp));
1327 if (auto chain = leftValue->getByPath<ChainValue_t>()) { 1250 if (auto chain = leftValue->getByPath<ChainValue_t>()) {
1328 auto tmpChain = x->new_ptr<ChainValue_t>(); 1251 auto tmpChain = x->new_ptr<ChainValue_t>();
1329 for (auto item : chain->items.objects()) { 1252 for (auto item : chain->items.objects()) {
@@ -1335,12 +1258,12 @@ private:
1335 BREAK_IF(!var.empty()); 1258 BREAK_IF(!var.empty());
1336 auto upVar = getUnusedName("_update_"sv); 1259 auto upVar = getUnusedName("_update_"sv);
1337 auto assignment = x->new_ptr<ExpListAssign_t>(); 1260 auto assignment = x->new_ptr<ExpListAssign_t>();
1338 assignment->expList.set(toAst<ExpList_t>(upVar, ExpList, x)); 1261 assignment->expList.set(toAst<ExpList_t>(upVar, x));
1339 auto assign = x->new_ptr<Assign_t>(); 1262 auto assign = x->new_ptr<Assign_t>();
1340 assign->values.push_back(exp); 1263 assign->values.push_back(exp);
1341 assignment->action.set(assign); 1264 assignment->action.set(assign);
1342 transformAssignment(assignment, temp); 1265 transformAssignment(assignment, temp);
1343 tmpChain->items.push_back(toAst<Exp_t>(upVar, Exp, x)); 1266 tmpChain->items.push_back(toAst<Exp_t>(upVar, x));
1344 itemAdded = true; 1267 itemAdded = true;
1345 BLOCK_END 1268 BLOCK_END
1346 if (!itemAdded) tmpChain->items.push_back(item); 1269 if (!itemAdded) tmpChain->items.push_back(item);
@@ -1358,7 +1281,7 @@ private:
1358 right = s("("sv) + right + s(")"sv); 1281 right = s("("sv) + right + s(")"sv);
1359 } 1282 }
1360 _buf << join(temp) << indent() << left << " = "sv << left << 1283 _buf << join(temp) << indent() << left << " = "sv << left <<
1361 " "sv << toString(update->op) << " "sv << right << nll(assignment); 1284 " "sv << _parser.toString(update->op) << " "sv << right << nll(assignment);
1362 out.push_back(clearBuf()); 1285 out.push_back(clearBuf());
1363 break; 1286 break;
1364 } 1287 }
@@ -1372,7 +1295,7 @@ private:
1372 switch (callable->item->getId()) { 1295 switch (callable->item->getId()) {
1373 case "Variable"_id: 1296 case "Variable"_id:
1374 for (const auto& def : defs) { 1297 for (const auto& def : defs) {
1375 if (def == toString(callable->item)) { 1298 if (def == _parser.toString(callable->item)) {
1376 return traversal::Stop; 1299 return traversal::Stop;
1377 } 1300 }
1378 } 1301 }
@@ -1510,7 +1433,7 @@ private:
1510 temp.push_back(indent() + s("do"sv) + nll(assign)); 1433 temp.push_back(indent() + s("do"sv) + nll(assign));
1511 pushScope(); 1434 pushScope();
1512 } 1435 }
1513 auto expList = toAst<ExpList_t>(desVar, ExpList, x); 1436 auto expList = toAst<ExpList_t>(desVar, x);
1514 auto assignment = x->new_ptr<ExpListAssign_t>(); 1437 auto assignment = x->new_ptr<ExpListAssign_t>();
1515 assignment->expList.set(expList); 1438 assignment->expList.set(expList);
1516 assignment->action.set(assign); 1439 assignment->action.set(assign);
@@ -1520,7 +1443,7 @@ private:
1520 auto expList = x->new_ptr<ExpList_t>(); 1443 auto expList = x->new_ptr<ExpList_t>();
1521 expList->exprs.push_back(exp); 1444 expList->exprs.push_back(exp);
1522 auto assignOne = x->new_ptr<Assign_t>(); 1445 auto assignOne = x->new_ptr<Assign_t>();
1523 auto valExp = toAst<Exp_t>(desVar, Exp, x); 1446 auto valExp = toAst<Exp_t>(desVar, x);
1524 assignOne->values.push_back(valExp); 1447 assignOne->values.push_back(valExp);
1525 auto assignment = x->new_ptr<ExpListAssign_t>(); 1448 auto assignment = x->new_ptr<ExpListAssign_t>();
1526 assignment->expList.set(expList); 1449 assignment->expList.set(expList);
@@ -1668,7 +1591,7 @@ private:
1668 } 1591 }
1669 return; 1592 return;
1670 } else { 1593 } else {
1671 throw std::logic_error(debugInfo("Backcall operator must be followed by chain value."sv, opValue->value)); 1594 throw std::logic_error(_info.errorMessage("Backcall operator must be followed by chain value."sv, opValue->value));
1672 } 1595 }
1673 } 1596 }
1674 } 1597 }
@@ -1762,7 +1685,7 @@ private:
1762 1685
1763 void transformFunLit(FunLit_t* funLit, str_list& out) { 1686 void transformFunLit(FunLit_t* funLit, str_list& out) {
1764 str_list temp; 1687 str_list temp;
1765 bool isFatArrow = toString(funLit->arrow) == "=>"sv; 1688 bool isFatArrow = _parser.toString(funLit->arrow) == "=>"sv;
1766 pushScope(); 1689 pushScope();
1767 if (isFatArrow) { 1690 if (isFatArrow) {
1768 forceAddToScope(s("self"sv)); 1691 forceAddToScope(s("self"sv));
@@ -1839,7 +1762,7 @@ private:
1839 body->content.set(block); 1762 body->content.set(block);
1840 auto funLit = x->new_ptr<FunLit_t>(); 1763 auto funLit = x->new_ptr<FunLit_t>();
1841 funLit->argsDef.set(backcall->argsDef); 1764 funLit->argsDef.set(backcall->argsDef);
1842 funLit->arrow.set(toAst<fn_arrow_t>("->"sv, fn_arrow, x)); 1765 funLit->arrow.set(toAst<fn_arrow_t>("->"sv, x));
1843 funLit->body.set(body); 1766 funLit->body.set(body);
1844 auto simpleValue = x->new_ptr<SimpleValue_t>(); 1767 auto simpleValue = x->new_ptr<SimpleValue_t>();
1845 simpleValue->value.set(funLit); 1768 simpleValue->value.set(funLit);
@@ -1878,7 +1801,7 @@ private:
1878 } 1801 }
1879 if (auto local = stmt->content.as<Local_t>()) { 1802 if (auto local = stmt->content.as<Local_t>()) {
1880 if (auto flag = local->name.as<local_flag_t>()) { 1803 if (auto flag = local->name.as<local_flag_t>()) {
1881 LocalMode newMode = toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; 1804 LocalMode newMode = _parser.toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital;
1882 if (int(newMode) > int(mode)) { 1805 if (int(newMode) > int(mode)) {
1883 mode = newMode; 1806 mode = newMode;
1884 } 1807 }
@@ -1891,7 +1814,7 @@ private:
1891 } else { 1814 } else {
1892 auto names = local->name.to<NameList_t>(); 1815 auto names = local->name.to<NameList_t>();
1893 for (auto name : names->names.objects()) { 1816 for (auto name : names->names.objects()) {
1894 local->forceDecls.push_back(toString(name)); 1817 local->forceDecls.push_back(_parser.toString(name));
1895 } 1818 }
1896 } 1819 }
1897 } else if (mode != LocalMode::None) { 1820 } else if (mode != LocalMode::None) {
@@ -1932,7 +1855,7 @@ private:
1932 } 1855 }
1933 if (classDecl) { 1856 if (classDecl) {
1934 if (auto variable = classDecl->name->item.as<Variable_t>()) { 1857 if (auto variable = classDecl->name->item.as<Variable_t>()) {
1935 auto className = toString(variable); 1858 auto className = _parser.toString(variable);
1936 if (!className.empty()) { 1859 if (!className.empty()) {
1937 if (std::isupper(className[0]) && capital) { 1860 if (std::isupper(className[0]) && capital) {
1938 capital->decls.push_back(className); 1861 capital->decls.push_back(className);
@@ -2066,7 +1989,7 @@ private:
2066 markVarShadowed(); 1989 markVarShadowed();
2067 if (shadow->varList) { 1990 if (shadow->varList) {
2068 for (auto name : shadow->varList->names.objects()) { 1991 for (auto name : shadow->varList->names.objects()) {
2069 addToAllowList(toString(name)); 1992 addToAllowList(_parser.toString(name));
2070 } 1993 }
2071 } 1994 }
2072 } 1995 }
@@ -2085,14 +2008,14 @@ private:
2085 auto def = static_cast<FnArgDef_t*>(_def); 2008 auto def = static_cast<FnArgDef_t*>(_def);
2086 auto& arg = argItems.emplace_back(); 2009 auto& arg = argItems.emplace_back();
2087 switch (def->name->getId()) { 2010 switch (def->name->getId()) {
2088 case "Variable"_id: arg.name = toString(def->name); break; 2011 case "Variable"_id: arg.name = _parser.toString(def->name); break;
2089 case "SelfName"_id: { 2012 case "SelfName"_id: {
2090 assignSelf = true; 2013 assignSelf = true;
2091 auto selfName = static_cast<SelfName_t*>(def->name.get()); 2014 auto selfName = static_cast<SelfName_t*>(def->name.get());
2092 switch (selfName->name->getId()) { 2015 switch (selfName->name->getId()) {
2093 case "self_class_name"_id: { 2016 case "self_class_name"_id: {
2094 auto clsName = static_cast<self_class_name_t*>(selfName->name.get()); 2017 auto clsName = static_cast<self_class_name_t*>(selfName->name.get());
2095 arg.name = toString(clsName->name); 2018 arg.name = _parser.toString(clsName->name);
2096 arg.assignSelf = s("self.__class."sv) + arg.name; 2019 arg.assignSelf = s("self.__class."sv) + arg.name;
2097 break; 2020 break;
2098 } 2021 }
@@ -2102,7 +2025,7 @@ private:
2102 case "self_name"_id: { 2025 case "self_name"_id: {
2103 2026
2104 auto sfName = static_cast<self_name_t*>(selfName->name.get()); 2027 auto sfName = static_cast<self_name_t*>(selfName->name.get());
2105 arg.name = toString(sfName->name); 2028 arg.name = _parser.toString(sfName->name);
2106 arg.assignSelf = s("self."sv) + arg.name; 2029 arg.assignSelf = s("self."sv) + arg.name;
2107 break; 2030 break;
2108 } 2031 }
@@ -2117,7 +2040,7 @@ private:
2117 forceAddToScope(arg.name); 2040 forceAddToScope(arg.name);
2118 if (def->defaultValue) { 2041 if (def->defaultValue) {
2119 pushScope(); 2042 pushScope();
2120 auto expList = toAst<ExpList_t>(arg.name, ExpList, x); 2043 auto expList = toAst<ExpList_t>(arg.name, x);
2121 auto assign = x->new_ptr<Assign_t>(); 2044 auto assign = x->new_ptr<Assign_t>();
2122 assign->values.push_back(def->defaultValue.get()); 2045 assign->values.push_back(def->defaultValue.get());
2123 auto assignment = x->new_ptr<ExpListAssign_t>(); 2046 auto assignment = x->new_ptr<ExpListAssign_t>();
@@ -2164,15 +2087,15 @@ private:
2164 switch (name->getId()) { 2087 switch (name->getId()) {
2165 case "self_class_name"_id: { 2088 case "self_class_name"_id: {
2166 auto clsName = static_cast<self_class_name_t*>(name); 2089 auto clsName = static_cast<self_class_name_t*>(name);
2167 auto nameStr = toString(clsName->name); 2090 auto nameStr = _parser.toString(clsName->name);
2168 if (State::luaKeywords.find(nameStr) != State::luaKeywords.end()) { 2091 if (LuaKeywords.find(nameStr) != LuaKeywords.end()) {
2169 out.push_back(s("self.__class[\""sv) + nameStr + s("\"]")); 2092 out.push_back(s("self.__class[\""sv) + nameStr + s("\"]"));
2170 if (invoke) { 2093 if (invoke) {
2171 if (auto invokePtr = invoke.as<Invoke_t>()) { 2094 if (auto invokePtr = invoke.as<Invoke_t>()) {
2172 invokePtr->args.push_front(toAst<Exp_t>("self.__class"sv, Exp, x)); 2095 invokePtr->args.push_front(toAst<Exp_t>("self.__class"sv, x));
2173 } else { 2096 } else {
2174 auto invokeArgsPtr = invoke.as<InvokeArgs_t>(); 2097 auto invokeArgsPtr = invoke.as<InvokeArgs_t>();
2175 invokeArgsPtr->args.push_front(toAst<Exp_t>("self.__class"sv, Exp, x)); 2098 invokeArgsPtr->args.push_front(toAst<Exp_t>("self.__class"sv, x));
2176 } 2099 }
2177 } 2100 }
2178 } else { 2101 } else {
@@ -2185,15 +2108,15 @@ private:
2185 break; 2108 break;
2186 case "self_name"_id: { 2109 case "self_name"_id: {
2187 auto sfName = static_cast<self_class_name_t*>(name); 2110 auto sfName = static_cast<self_class_name_t*>(name);
2188 auto nameStr = toString(sfName->name); 2111 auto nameStr = _parser.toString(sfName->name);
2189 if (State::luaKeywords.find(nameStr) != State::luaKeywords.end()) { 2112 if (LuaKeywords.find(nameStr) != LuaKeywords.end()) {
2190 out.push_back(s("self[\""sv) + nameStr + s("\"]")); 2113 out.push_back(s("self[\""sv) + nameStr + s("\"]"));
2191 if (invoke) { 2114 if (invoke) {
2192 if (auto invokePtr = invoke.as<Invoke_t>()) { 2115 if (auto invokePtr = invoke.as<Invoke_t>()) {
2193 invokePtr->args.push_front(toAst<Exp_t>("self"sv, Exp, x)); 2116 invokePtr->args.push_front(toAst<Exp_t>("self"sv, x));
2194 } else { 2117 } else {
2195 auto invokeArgsPtr = invoke.as<InvokeArgs_t>(); 2118 auto invokeArgsPtr = invoke.as<InvokeArgs_t>();
2196 invokeArgsPtr->args.push_front(toAst<Exp_t>("self"sv, Exp, x)); 2119 invokeArgsPtr->args.push_front(toAst<Exp_t>("self"sv, x));
2197 } 2120 }
2198 } 2121 }
2199 } else { 2122 } else {
@@ -2220,8 +2143,8 @@ private:
2220 auto value = x->new_ptr<Value_t>(); 2143 auto value = x->new_ptr<Value_t>();
2221 value->item.set(chainValue); 2144 value->item.set(chainValue);
2222 auto opValue = x->new_ptr<exp_op_value_t>(); 2145 auto opValue = x->new_ptr<exp_op_value_t>();
2223 opValue->op.set(toAst<BinaryOperator_t>("!="sv, BinaryOperator, x)); 2146 opValue->op.set(toAst<BinaryOperator_t>("!="sv, x));
2224 opValue->value.set(toAst<Value_t>("nil"sv, Value, x)); 2147 opValue->value.set(toAst<Value_t>("nil"sv, x));
2225 auto exp = x->new_ptr<Exp_t>(); 2148 auto exp = x->new_ptr<Exp_t>();
2226 exp->value.set(value); 2149 exp->value.set(value);
2227 exp->opValues.push_back(opValue); 2150 exp->opValues.push_back(opValue);
@@ -2281,7 +2204,7 @@ private:
2281 auto colonItem = x->new_ptr<ColonChainItem_t>(); 2204 auto colonItem = x->new_ptr<ColonChainItem_t>();
2282 colonItem->name.set(sname->name); 2205 colonItem->name.set(sname->name);
2283 partOne->items.pop_back(); 2206 partOne->items.pop_back();
2284 partOne->items.push_back(toAst<Callable_t>("@"sv, Callable, x)); 2207 partOne->items.push_back(toAst<Callable_t>("@"sv, x));
2285 partOne->items.push_back(colonItem); 2208 partOne->items.push_back(colonItem);
2286 break; 2209 break;
2287 } 2210 }
@@ -2289,7 +2212,7 @@ private:
2289 auto colonItem = x->new_ptr<ColonChainItem_t>(); 2212 auto colonItem = x->new_ptr<ColonChainItem_t>();
2290 colonItem->name.set(cname->name); 2213 colonItem->name.set(cname->name);
2291 partOne->items.pop_back(); 2214 partOne->items.pop_back();
2292 partOne->items.push_back(toAst<Callable_t>("@@"sv, Callable, x)); 2215 partOne->items.push_back(toAst<Callable_t>("@@"sv, x));
2293 partOne->items.push_back(colonItem); 2216 partOne->items.push_back(colonItem);
2294 break; 2217 break;
2295 } 2218 }
@@ -2303,9 +2226,9 @@ private:
2303 chainValue->items.pop_back(); 2226 chainValue->items.pop_back();
2304 if (chainValue->items.empty()) { 2227 if (chainValue->items.empty()) {
2305 if (_withVars.empty()) { 2228 if (_withVars.empty()) {
2306 throw std::logic_error(debugInfo("Short dot/colon syntax must be called within a with block."sv, x)); 2229 throw std::logic_error(_info.errorMessage("Short dot/colon syntax must be called within a with block."sv, x));
2307 } 2230 }
2308 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), Callable, x)); 2231 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x));
2309 } 2232 }
2310 auto newObj = singleVariableFrom(chainValue); 2233 auto newObj = singleVariableFrom(chainValue);
2311 if (!newObj.empty()) { 2234 if (!newObj.empty()) {
@@ -2318,7 +2241,7 @@ private:
2318 auto assign = x->new_ptr<Assign_t>(); 2241 auto assign = x->new_ptr<Assign_t>();
2319 assign->values.push_back(exp); 2242 assign->values.push_back(exp);
2320 auto expListAssign = x->new_ptr<ExpListAssign_t>(); 2243 auto expListAssign = x->new_ptr<ExpListAssign_t>();
2321 expListAssign->expList.set(toAst<ExpList_t>(objVar, ExpList, x)); 2244 expListAssign->expList.set(toAst<ExpList_t>(objVar, x));
2322 expListAssign->action.set(assign); 2245 expListAssign->action.set(assign);
2323 transformAssignment(expListAssign, temp); 2246 transformAssignment(expListAssign, temp);
2324 } 2247 }
@@ -2329,16 +2252,16 @@ private:
2329 } 2252 }
2330 dotItem->name.set(name); 2253 dotItem->name.set(name);
2331 partOne->items.clear(); 2254 partOne->items.clear();
2332 partOne->items.push_back(toAst<Callable_t>(objVar, Callable, x)); 2255 partOne->items.push_back(toAst<Callable_t>(objVar, x));
2333 partOne->items.push_back(dotItem); 2256 partOne->items.push_back(dotItem);
2334 auto it = opIt; ++it; 2257 auto it = opIt; ++it;
2335 if (it != chainList.end() && ast_is<Invoke_t, InvokeArgs_t>(*it)) { 2258 if (it != chainList.end() && ast_is<Invoke_t, InvokeArgs_t>(*it)) {
2336 2259
2337 if (auto invoke = ast_cast<Invoke_t>(*it)) { 2260 if (auto invoke = ast_cast<Invoke_t>(*it)) {
2338 invoke->args.push_front(toAst<Exp_t>(objVar, Exp, x)); 2261 invoke->args.push_front(toAst<Exp_t>(objVar, x));
2339 } else { 2262 } else {
2340 auto invokeArgs = static_cast<InvokeArgs_t*>(*it); 2263 auto invokeArgs = static_cast<InvokeArgs_t*>(*it);
2341 invokeArgs->args.push_front(toAst<Exp_t>(objVar, Exp, x)); 2264 invokeArgs->args.push_front(toAst<Exp_t>(objVar, x));
2342 } 2265 }
2343 } 2266 }
2344 objVar = getUnusedName("_obj_"sv); 2267 objVar = getUnusedName("_obj_"sv);
@@ -2350,7 +2273,7 @@ private:
2350 auto assign = x->new_ptr<Assign_t>(); 2273 auto assign = x->new_ptr<Assign_t>();
2351 assign->values.push_back(exp); 2274 assign->values.push_back(exp);
2352 auto expListAssign = x->new_ptr<ExpListAssign_t>(); 2275 auto expListAssign = x->new_ptr<ExpListAssign_t>();
2353 expListAssign->expList.set(toAst<ExpList_t>(objVar, ExpList, x)); 2276 expListAssign->expList.set(toAst<ExpList_t>(objVar, x));
2354 expListAssign->action.set(assign); 2277 expListAssign->action.set(assign);
2355 transformAssignment(expListAssign, temp); 2278 transformAssignment(expListAssign, temp);
2356 } 2279 }
@@ -2358,7 +2281,7 @@ private:
2358 temp.push_back(clearBuf()); 2281 temp.push_back(clearBuf());
2359 pushScope(); 2282 pushScope();
2360 auto partTwo = x->new_ptr<ChainValue_t>(); 2283 auto partTwo = x->new_ptr<ChainValue_t>();
2361 partTwo->items.push_back(toAst<Callable_t>(objVar, Callable, x)); 2284 partTwo->items.push_back(toAst<Callable_t>(objVar, x));
2362 for (auto it = ++opIt;it != chainList.end();++it) { 2285 for (auto it = ++opIt;it != chainList.end();++it) {
2363 partTwo->items.push_back(*it); 2286 partTwo->items.push_back(*it);
2364 } 2287 }
@@ -2434,9 +2357,9 @@ private:
2434 case "DotChainItem"_id: 2357 case "DotChainItem"_id:
2435 case "ColonChainItem"_id: 2358 case "ColonChainItem"_id:
2436 if (_withVars.empty()) { 2359 if (_withVars.empty()) {
2437 throw std::logic_error(debugInfo("Short dot/colon syntax must be called within a with block."sv, chainList.front())); 2360 throw std::logic_error(_info.errorMessage("Short dot/colon syntax must be called within a with block."sv, chainList.front()));
2438 } else { 2361 } else {
2439 baseChain->items.push_back(toAst<Callable_t>(_withVars.top(), Callable, x)); 2362 baseChain->items.push_back(toAst<Callable_t>(_withVars.top(), x));
2440 } 2363 }
2441 break; 2364 break;
2442 } 2365 }
@@ -2445,7 +2368,7 @@ private:
2445 baseChain->items.push_back(*it); 2368 baseChain->items.push_back(*it);
2446 } 2369 }
2447 auto colonChainItem = static_cast<ColonChainItem_t*>(chainList.back()); 2370 auto colonChainItem = static_cast<ColonChainItem_t*>(chainList.back());
2448 auto funcName = toString(colonChainItem->name); 2371 auto funcName = _parser.toString(colonChainItem->name);
2449 auto baseVar = getUnusedName("_base_"sv); 2372 auto baseVar = getUnusedName("_base_"sv);
2450 auto fnVar = getUnusedName("_fn_"sv); 2373 auto fnVar = getUnusedName("_fn_"sv);
2451 { 2374 {
@@ -2456,19 +2379,19 @@ private:
2456 auto assign = x->new_ptr<Assign_t>(); 2379 auto assign = x->new_ptr<Assign_t>();
2457 assign->values.push_back(exp); 2380 assign->values.push_back(exp);
2458 auto assignment = x->new_ptr<ExpListAssign_t>(); 2381 auto assignment = x->new_ptr<ExpListAssign_t>();
2459 assignment->expList.set(toAst<ExpList_t>(baseVar, ExpList, x)); 2382 assignment->expList.set(toAst<ExpList_t>(baseVar, x));
2460 assignment->action.set(assign); 2383 assignment->action.set(assign);
2461 transformAssignment(assignment, temp); 2384 transformAssignment(assignment, temp);
2462 } 2385 }
2463 { 2386 {
2464 auto assign = x->new_ptr<Assign_t>(); 2387 auto assign = x->new_ptr<Assign_t>();
2465 assign->values.push_back(toAst<Exp_t>(baseVar + "." + funcName, Exp, x)); 2388 assign->values.push_back(toAst<Exp_t>(baseVar + "." + funcName, x));
2466 auto assignment = x->new_ptr<ExpListAssign_t>(); 2389 auto assignment = x->new_ptr<ExpListAssign_t>();
2467 assignment->expList.set(toAst<ExpList_t>(fnVar, ExpList, x)); 2390 assignment->expList.set(toAst<ExpList_t>(fnVar, x));
2468 assignment->action.set(assign); 2391 assignment->action.set(assign);
2469 transformAssignment(assignment, temp); 2392 transformAssignment(assignment, temp);
2470 } 2393 }
2471 auto funLit = toAst<Exp_t>(fnVar + s(" and (...)-> "sv) + fnVar + s(" "sv) + baseVar + s(", ..."sv), Exp, x); 2394 auto funLit = toAst<Exp_t>(fnVar + s(" and (...)-> "sv) + fnVar + s(" "sv) + baseVar + s(", ..."sv), x);
2472 switch (usage) { 2395 switch (usage) {
2473 case ExpUsage::Closure: 2396 case ExpUsage::Closure:
2474 case ExpUsage::Return: { 2397 case ExpUsage::Return: {
@@ -2516,7 +2439,7 @@ private:
2516 case "DotChainItem"_id: 2439 case "DotChainItem"_id:
2517 case "ColonChainItem"_id: 2440 case "ColonChainItem"_id:
2518 if (_withVars.empty()) { 2441 if (_withVars.empty()) {
2519 throw std::logic_error(debugInfo("Short dot/colon syntax must be called within a with block."sv, x)); 2442 throw std::logic_error(_info.errorMessage("Short dot/colon syntax must be called within a with block."sv, x));
2520 } else { 2443 } else {
2521 temp.push_back(_withVars.top()); 2444 temp.push_back(_withVars.top());
2522 } 2445 }
@@ -2548,7 +2471,7 @@ private:
2548 --next; 2471 --next;
2549 } 2472 }
2550 if (!ast_is<Invoke_t, InvokeArgs_t>(followItem)) { 2473 if (!ast_is<Invoke_t, InvokeArgs_t>(followItem)) {
2551 throw std::logic_error(debugInfo("Colon chain item must be followed by invoke arguments."sv, colonItem)); 2474 throw std::logic_error(_info.errorMessage("Colon chain item must be followed by invoke arguments."sv, colonItem));
2552 } 2475 }
2553 if (colonItem->name.is<LuaKeyword_t>()) { 2476 if (colonItem->name.is<LuaKeyword_t>()) {
2554 std::string callVar; 2477 std::string callVar;
@@ -2558,7 +2481,7 @@ private:
2558 switch (chainList.front()->getId()) { 2481 switch (chainList.front()->getId()) {
2559 case "DotChainItem"_id: 2482 case "DotChainItem"_id:
2560 case "ColonChainItem"_id: 2483 case "ColonChainItem"_id:
2561 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), Callable, x)); 2484 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x));
2562 break; 2485 break;
2563 } 2486 }
2564 for (auto i = chainList.begin(); i != current; ++i) { 2487 for (auto i = chainList.begin(); i != current; ++i) {
@@ -2572,7 +2495,7 @@ private:
2572 if (callVar.empty()) { 2495 if (callVar.empty()) {
2573 callVar = getUnusedName(s("_call_"sv)); 2496 callVar = getUnusedName(s("_call_"sv));
2574 auto assignment = x->new_ptr<ExpListAssign_t>(); 2497 auto assignment = x->new_ptr<ExpListAssign_t>();
2575 assignment->expList.set(toAst<ExpList_t>(callVar, ExpList, x)); 2498 assignment->expList.set(toAst<ExpList_t>(callVar, x));
2576 auto assign = x->new_ptr<Assign_t>(); 2499 auto assign = x->new_ptr<Assign_t>();
2577 assign->values.push_back(exp); 2500 assign->values.push_back(exp);
2578 assignment->action.set(assign); 2501 assignment->action.set(assign);
@@ -2582,18 +2505,18 @@ private:
2582 } 2505 }
2583 } 2506 }
2584 { 2507 {
2585 auto name = toString(colonItem->name); 2508 auto name = _parser.toString(colonItem->name);
2586 auto chainValue = x->new_ptr<ChainValue_t>(); 2509 auto chainValue = x->new_ptr<ChainValue_t>();
2587 chainValue->items.push_back(toAst<Callable_t>(callVar, Callable, x)); 2510 chainValue->items.push_back(toAst<Callable_t>(callVar, x));
2588 if (ast_is<existential_op_t>(*current)) { 2511 if (ast_is<existential_op_t>(*current)) {
2589 chainValue->items.push_back(x->new_ptr<existential_op_t>()); 2512 chainValue->items.push_back(x->new_ptr<existential_op_t>());
2590 } 2513 }
2591 chainValue->items.push_back(toAst<Exp_t>(s("\""sv) + name + s("\""sv), Exp, x)); 2514 chainValue->items.push_back(toAst<Exp_t>(s("\""sv) + name + s("\""sv), x));
2592 if (auto invoke = ast_cast<Invoke_t>(followItem)) { 2515 if (auto invoke = ast_cast<Invoke_t>(followItem)) {
2593 invoke->args.push_front(toAst<Exp_t>(callVar, Exp, x)); 2516 invoke->args.push_front(toAst<Exp_t>(callVar, x));
2594 } else { 2517 } else {
2595 auto invokeArgs = static_cast<InvokeArgs_t*>(followItem); 2518 auto invokeArgs = static_cast<InvokeArgs_t*>(followItem);
2596 invokeArgs->args.push_front(toAst<Exp_t>(callVar, Exp, x)); 2519 invokeArgs->args.push_front(toAst<Exp_t>(callVar, x));
2597 } 2520 }
2598 for (auto i = next; i != chainList.end(); ++i) { 2521 for (auto i = next; i != chainList.end(); ++i) {
2599 chainValue->items.push_back(*i); 2522 chainValue->items.push_back(*i);
@@ -2629,7 +2552,7 @@ private:
2629 } 2552 }
2630 auto body = x->new_ptr<Body_t>(); 2553 auto body = x->new_ptr<Body_t>();
2631 body->content.set(block); 2554 body->content.set(block);
2632 auto funLit = toAst<FunLit_t>("->"sv, FunLit, x); 2555 auto funLit = toAst<FunLit_t>("->"sv, x);
2633 funLit->body.set(body); 2556 funLit->body.set(body);
2634 auto simpleValue = x->new_ptr<SimpleValue_t>(); 2557 auto simpleValue = x->new_ptr<SimpleValue_t>();
2635 simpleValue->value.set(funLit); 2558 simpleValue->value.set(funLit);
@@ -2708,8 +2631,8 @@ private:
2708 } 2631 }
2709 2632
2710 void transformDotChainItem(DotChainItem_t* dotChainItem, str_list& out) { 2633 void transformDotChainItem(DotChainItem_t* dotChainItem, str_list& out) {
2711 auto name = toString(dotChainItem->name); 2634 auto name = _parser.toString(dotChainItem->name);
2712 if (State::keywords.find(name) != State::keywords.end()) { 2635 if (Keywords.find(name) != Keywords.end()) {
2713 out.push_back(s("[\""sv) + name + s("\"]"sv)); 2636 out.push_back(s("[\""sv) + name + s("\"]"sv));
2714 } else { 2637 } else {
2715 out.push_back(s("."sv) + name); 2638 out.push_back(s("."sv) + name);
@@ -2717,12 +2640,12 @@ private:
2717 } 2640 }
2718 2641
2719 void transformColonChainItem(ColonChainItem_t* colonChainItem, str_list& out) { 2642 void transformColonChainItem(ColonChainItem_t* colonChainItem, str_list& out) {
2720 auto name = toString(colonChainItem->name); 2643 auto name = _parser.toString(colonChainItem->name);
2721 out.push_back(s(colonChainItem->switchToDot ? "."sv : ":"sv) + name); 2644 out.push_back(s(colonChainItem->switchToDot ? "."sv : ":"sv) + name);
2722 } 2645 }
2723 2646
2724 void transformSlice(Slice_t* slice, str_list&) { 2647 void transformSlice(Slice_t* slice, str_list&) {
2725 throw std::logic_error(debugInfo("Slice syntax not supported here."sv, slice)); 2648 throw std::logic_error(_info.errorMessage("Slice syntax not supported here."sv, slice));
2726 } 2649 }
2727 2650
2728 void transformInvoke(Invoke_t* invoke, str_list& out) { 2651 void transformInvoke(Invoke_t* invoke, str_list& out) {
@@ -2740,18 +2663,18 @@ private:
2740 } 2663 }
2741 2664
2742 void transform_unary_exp(unary_exp_t* unary_exp, str_list& out) { 2665 void transform_unary_exp(unary_exp_t* unary_exp, str_list& out) {
2743 std::string op = toString(unary_exp->m_begin.m_it, unary_exp->item->m_begin.m_it); 2666 std::string op = _parser.toString(unary_exp->m_begin.m_it, unary_exp->item->m_begin.m_it);
2744 str_list temp{op + (op == "not"sv ? s(" "sv) : Empty)}; 2667 str_list temp{op + (op == "not"sv ? s(" "sv) : Empty)};
2745 transformExp(unary_exp->item, temp, ExpUsage::Closure); 2668 transformExp(unary_exp->item, temp, ExpUsage::Closure);
2746 out.push_back(join(temp)); 2669 out.push_back(join(temp));
2747 } 2670 }
2748 2671
2749 void transformVariable(Variable_t* name, str_list& out) { 2672 void transformVariable(Variable_t* name, str_list& out) {
2750 out.push_back(toString(name)); 2673 out.push_back(_parser.toString(name));
2751 } 2674 }
2752 2675
2753 void transformNum(Num_t* num, str_list& out) { 2676 void transformNum(Num_t* num, str_list& out) {
2754 out.push_back(toString(num)); 2677 out.push_back(_parser.toString(num));
2755 } 2678 }
2756 2679
2757 void transformTableLit(TableLit_t* table, str_list& out) { 2680 void transformTableLit(TableLit_t* table, str_list& out) {
@@ -2830,7 +2753,7 @@ private:
2830 } 2753 }
2831 } 2754 }
2832 { 2755 {
2833 auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), ExpList, x); 2756 auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), x);
2834 auto assign = x->new_ptr<Assign_t>(); 2757 auto assign = x->new_ptr<Assign_t>();
2835 assign->values.push_back(comp->value); 2758 assign->values.push_back(comp->value);
2836 auto assignment = x->new_ptr<ExpListAssign_t>(); 2759 auto assignment = x->new_ptr<ExpListAssign_t>();
@@ -2865,7 +2788,7 @@ private:
2865 case ExpUsage::Assignment: { 2788 case ExpUsage::Assignment: {
2866 out.push_back(clearBuf()); 2789 out.push_back(clearBuf());
2867 auto assign = x->new_ptr<Assign_t>(); 2790 auto assign = x->new_ptr<Assign_t>();
2868 assign->values.push_back(toAst<Exp_t>(accumVar, Exp, x)); 2791 assign->values.push_back(toAst<Exp_t>(accumVar, x));
2869 auto assignment = x->new_ptr<ExpListAssign_t>(); 2792 auto assignment = x->new_ptr<ExpListAssign_t>();
2870 assignment->expList.set(assignList); 2793 assignment->expList.set(assignList);
2871 assignment->action.set(assign); 2794 assignment->action.set(assign);
@@ -2900,7 +2823,7 @@ private:
2900 break; 2823 break;
2901 case "TableLit"_id: { 2824 case "TableLit"_id: {
2902 auto desVar = getUnusedName("_des_"sv); 2825 auto desVar = getUnusedName("_des_"sv);
2903 destructPairs.emplace_back(item, toAst<Exp_t>(desVar, Exp, x)); 2826 destructPairs.emplace_back(item, toAst<Exp_t>(desVar, x));
2904 vars.push_back(desVar); 2827 vars.push_back(desVar);
2905 varAfter.push_back(desVar); 2828 varAfter.push_back(desVar);
2906 break; 2829 break;
@@ -2915,7 +2838,7 @@ private:
2915 auto indexVar = getUnusedName("_index_"); 2838 auto indexVar = getUnusedName("_index_");
2916 varAfter.push_back(indexVar); 2839 varAfter.push_back(indexVar);
2917 auto value = singleValueFrom(star_exp->value); 2840 auto value = singleValueFrom(star_exp->value);
2918 if (!value) throw std::logic_error(debugInfo("Invalid star syntax."sv, star_exp)); 2841 if (!value) throw std::logic_error(_info.errorMessage("Invalid star syntax."sv, star_exp));
2919 bool endWithSlice = false; 2842 bool endWithSlice = false;
2920 BLOCK_START 2843 BLOCK_START
2921 auto chainValue = value->item.as<ChainValue_t>(); 2844 auto chainValue = value->item.as<ChainValue_t>();
@@ -3049,7 +2972,7 @@ private:
3049 2972
3050 void transformForHead(For_t* forNode, str_list& out) { 2973 void transformForHead(For_t* forNode, str_list& out) {
3051 str_list temp; 2974 str_list temp;
3052 std::string varName = toString(forNode->varName); 2975 std::string varName = _parser.toString(forNode->varName);
3053 transformExp(forNode->startValue, temp, ExpUsage::Closure); 2976 transformExp(forNode->startValue, temp, ExpUsage::Closure);
3054 transformExp(forNode->stopValue, temp, ExpUsage::Closure); 2977 transformExp(forNode->stopValue, temp, ExpUsage::Closure);
3055 if (forNode->stepValue) { 2978 if (forNode->stepValue) {
@@ -3075,7 +2998,7 @@ private:
3075 case "ForEach"_id: 2998 case "ForEach"_id:
3076 return traversal::Return; 2999 return traversal::Return;
3077 case "BreakLoop"_id: { 3000 case "BreakLoop"_id: {
3078 return toString(node) == "continue"sv ? 3001 return _parser.toString(node) == "continue"sv ?
3079 traversal::Stop : traversal::Return; 3002 traversal::Stop : traversal::Return;
3080 } 3003 }
3081 default: 3004 default:
@@ -3128,7 +3051,7 @@ private:
3128 _buf << indent() << "local "sv << len << " = 1"sv << nll(forNode); 3051 _buf << indent() << "local "sv << len << " = 1"sv << nll(forNode);
3129 out.push_back(clearBuf()); 3052 out.push_back(clearBuf());
3130 transformForHead(forNode, out); 3053 transformForHead(forNode, out);
3131 auto expList = toAst<ExpList_t>(accum + s("["sv) + len + s("]"sv), ExpList, x); 3054 auto expList = toAst<ExpList_t>(accum + s("["sv) + len + s("]"sv), x);
3132 assignLastExplist(expList, forNode->body); 3055 assignLastExplist(expList, forNode->body);
3133 auto lenLine = len + s(" = "sv) + len + s(" + 1"sv) + nlr(forNode->body); 3056 auto lenLine = len + s(" = "sv) + len + s(" + 1"sv) + nlr(forNode->body);
3134 transformLoopBody(forNode->body, out, lenLine); 3057 transformLoopBody(forNode->body, out, lenLine);
@@ -3156,7 +3079,7 @@ private:
3156 pushScope(); 3079 pushScope();
3157 auto accum = transformForInner(forNode, temp); 3080 auto accum = transformForInner(forNode, temp);
3158 auto assign = x->new_ptr<Assign_t>(); 3081 auto assign = x->new_ptr<Assign_t>();
3159 assign->values.push_back(toAst<Exp_t>(accum, Exp, x)); 3082 assign->values.push_back(toAst<Exp_t>(accum, x));
3160 auto assignment = x->new_ptr<ExpListAssign_t>(); 3083 auto assignment = x->new_ptr<ExpListAssign_t>();
3161 assignment->expList.set(assignExpList); 3084 assignment->expList.set(assignExpList);
3162 assignment->action.set(assign); 3085 assignment->action.set(assign);
@@ -3166,7 +3089,7 @@ private:
3166 } else { 3089 } else {
3167 auto accum = transformForInner(forNode, temp); 3090 auto accum = transformForInner(forNode, temp);
3168 auto returnNode = x->new_ptr<Return_t>(); 3091 auto returnNode = x->new_ptr<Return_t>();
3169 auto expListLow = toAst<ExpListLow_t>(accum, ExpListLow, x); 3092 auto expListLow = toAst<ExpListLow_t>(accum, x);
3170 returnNode->valueList.set(expListLow); 3093 returnNode->valueList.set(expListLow);
3171 transformReturn(returnNode, temp); 3094 transformReturn(returnNode, temp);
3172 } 3095 }
@@ -3174,7 +3097,7 @@ private:
3174 } 3097 }
3175 3098
3176 void transformBinaryOperator(BinaryOperator_t* node, str_list& out) { 3099 void transformBinaryOperator(BinaryOperator_t* node, str_list& out) {
3177 auto op = toString(node); 3100 auto op = _parser.toString(node);
3178 out.push_back(op == "!="sv ? s("~="sv) : op); 3101 out.push_back(op == "!="sv ? s("~="sv) : op);
3179 } 3102 }
3180 3103
@@ -3196,7 +3119,7 @@ private:
3196 _buf << indent() << "local "sv << len << " = 1"sv << nll(forEach); 3119 _buf << indent() << "local "sv << len << " = 1"sv << nll(forEach);
3197 out.push_back(clearBuf()); 3120 out.push_back(clearBuf());
3198 transformForEachHead(forEach->nameList, forEach->loopValue, out); 3121 transformForEachHead(forEach->nameList, forEach->loopValue, out);
3199 auto expList = toAst<ExpList_t>(accum + s("["sv) + len + s("]"sv), ExpList, x); 3122 auto expList = toAst<ExpList_t>(accum + s("["sv) + len + s("]"sv), x);
3200 assignLastExplist(expList, forEach->body); 3123 assignLastExplist(expList, forEach->body);
3201 auto lenLine = len + s(" = "sv) + len + s(" + 1"sv) + nlr(forEach->body); 3124 auto lenLine = len + s(" = "sv) + len + s(" + 1"sv) + nlr(forEach->body);
3202 transformLoopBody(forEach->body, out, lenLine); 3125 transformLoopBody(forEach->body, out, lenLine);
@@ -3224,7 +3147,7 @@ private:
3224 pushScope(); 3147 pushScope();
3225 auto accum = transformForEachInner(forEach, temp); 3148 auto accum = transformForEachInner(forEach, temp);
3226 auto assign = x->new_ptr<Assign_t>(); 3149 auto assign = x->new_ptr<Assign_t>();
3227 assign->values.push_back(toAst<Exp_t>(accum, Exp, x)); 3150 assign->values.push_back(toAst<Exp_t>(accum, x));
3228 auto assignment = x->new_ptr<ExpListAssign_t>(); 3151 auto assignment = x->new_ptr<ExpListAssign_t>();
3229 assignment->expList.set(assignExpList); 3152 assignment->expList.set(assignExpList);
3230 assignment->action.set(assign); 3153 assignment->action.set(assign);
@@ -3234,7 +3157,7 @@ private:
3234 } else { 3157 } else {
3235 auto accum = transformForEachInner(forEach, temp); 3158 auto accum = transformForEachInner(forEach, temp);
3236 auto returnNode = x->new_ptr<Return_t>(); 3159 auto returnNode = x->new_ptr<Return_t>();
3237 auto expListLow = toAst<ExpListLow_t>(accum, ExpListLow, x); 3160 auto expListLow = toAst<ExpListLow_t>(accum, x);
3238 returnNode->valueList.set(expListLow); 3161 returnNode->valueList.set(expListLow);
3239 transformReturn(returnNode, temp); 3162 transformReturn(returnNode, temp);
3240 } 3163 }
@@ -3242,7 +3165,7 @@ private:
3242 } 3165 }
3243 3166
3244 void transform_variable_pair(variable_pair_t* pair, str_list& out) { 3167 void transform_variable_pair(variable_pair_t* pair, str_list& out) {
3245 auto name = toString(pair->name); 3168 auto name = _parser.toString(pair->name);
3246 out.push_back(name + s(" = "sv) + name); 3169 out.push_back(name + s(" = "sv) + name);
3247 } 3170 }
3248 3171
@@ -3252,7 +3175,7 @@ private:
3252 switch (key->getId()) { 3175 switch (key->getId()) {
3253 case "KeyName"_id: { 3176 case "KeyName"_id: {
3254 transformKeyName(static_cast<KeyName_t*>(key), temp); 3177 transformKeyName(static_cast<KeyName_t*>(key), temp);
3255 if (State::luaKeywords.find(temp.back()) != State::luaKeywords.end()) { 3178 if (LuaKeywords.find(temp.back()) != LuaKeywords.end()) {
3256 temp.back() = s("[\""sv) + temp.back() + s("\"]"); 3179 temp.back() = s("[\""sv) + temp.back() + s("\"]");
3257 } 3180 }
3258 break; 3181 break;
@@ -3283,30 +3206,22 @@ private:
3283 auto name = keyName->name.get(); 3206 auto name = keyName->name.get();
3284 switch (name->getId()) { 3207 switch (name->getId()) {
3285 case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(name), out); break; 3208 case "SelfName"_id: transformSelfName(static_cast<SelfName_t*>(name), out); break;
3286 case "Name"_id: out.push_back(toString(name)); break; 3209 case "Name"_id: out.push_back(_parser.toString(name)); break;
3287 default: break; 3210 default: break;
3288 } 3211 }
3289 } 3212 }
3290 3213
3291 void replace(std::string& str, std::string_view from, std::string_view to) const {
3292 size_t start_pos = 0;
3293 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
3294 str.replace(start_pos, from.size(), to);
3295 start_pos += to.size();
3296 }
3297 }
3298
3299 void transformLuaString(LuaString_t* luaString, str_list& out) { 3214 void transformLuaString(LuaString_t* luaString, str_list& out) {
3300 auto content = toString(luaString->content); 3215 auto content = _parser.toString(luaString->content);
3301 replace(content, "\r"sv, ""); 3216 Utils::replace(content, "\r"sv, "");
3302 if (content[0] == '\n') content.erase(content.begin()); 3217 if (content[0] == '\n') content.erase(content.begin());
3303 out.push_back(toString(luaString->open) + content + toString(luaString->close)); 3218 out.push_back(_parser.toString(luaString->open) + content + _parser.toString(luaString->close));
3304 } 3219 }
3305 3220
3306 void transformSingleString(SingleString_t* singleString, str_list& out) { 3221 void transformSingleString(SingleString_t* singleString, str_list& out) {
3307 auto str = toString(singleString); 3222 auto str = _parser.toString(singleString);
3308 replace(str, "\r"sv, ""); 3223 Utils::replace(str, "\r"sv, "");
3309 replace(str, "\n"sv, "\\n"sv); 3224 Utils::replace(str, "\n"sv, "\\n"sv);
3310 out.push_back(str); 3225 out.push_back(str);
3311 } 3226 }
3312 3227
@@ -3317,9 +3232,9 @@ private:
3317 auto content = seg->content.get(); 3232 auto content = seg->content.get();
3318 switch (content->getId()) { 3233 switch (content->getId()) {
3319 case "double_string_inner"_id: { 3234 case "double_string_inner"_id: {
3320 auto str = toString(content); 3235 auto str = _parser.toString(content);
3321 replace(str, "\r"sv, ""); 3236 Utils::replace(str, "\r"sv, "");
3322 replace(str, "\n"sv, "\\n"sv); 3237 Utils::replace(str, "\n"sv, "\\n"sv);
3323 temp.push_back(s("\""sv) + str + s("\""sv)); 3238 temp.push_back(s("\""sv) + str + s("\""sv));
3324 break; 3239 break;
3325 } 3240 }
@@ -3345,7 +3260,7 @@ private:
3345 3260
3346 std::pair<std::string,bool> defineClassVariable(Assignable_t* assignable) { 3261 std::pair<std::string,bool> defineClassVariable(Assignable_t* assignable) {
3347 if (auto variable = assignable->item.as<Variable_t>()) { 3262 if (auto variable = assignable->item.as<Variable_t>()) {
3348 auto name = toString(variable); 3263 auto name = _parser.toString(variable);
3349 if (addToScope(name)) { 3264 if (addToScope(name)) {
3350 return {name, true}; 3265 return {name, true};
3351 } else { 3266 } else {
@@ -3375,7 +3290,7 @@ private:
3375 std::string assignItem; 3290 std::string assignItem;
3376 if (assignable) { 3291 if (assignable) {
3377 if (!isAssignable(assignable)) { 3292 if (!isAssignable(assignable)) {
3378 throw std::logic_error(debugInfo("Left hand expression is not assignable."sv, assignable)); 3293 throw std::logic_error(_info.errorMessage("Left hand expression is not assignable."sv, assignable));
3379 } 3294 }
3380 bool newDefined = false; 3295 bool newDefined = false;
3381 std::tie(className, newDefined) = defineClassVariable(assignable); 3296 std::tie(className, newDefined) = defineClassVariable(assignable);
@@ -3385,7 +3300,7 @@ private:
3385 if (className.empty()) { 3300 if (className.empty()) {
3386 if (auto chain = ast_cast<AssignableChain_t>(assignable->item)) { 3301 if (auto chain = ast_cast<AssignableChain_t>(assignable->item)) {
3387 if (auto dotChain = ast_cast<DotChainItem_t>(chain->items.back())) { 3302 if (auto dotChain = ast_cast<DotChainItem_t>(chain->items.back())) {
3388 className = s("\""sv) + toString(dotChain->name) + s("\""sv); 3303 className = s("\""sv) + _parser.toString(dotChain->name) + s("\""sv);
3389 } else if (auto index = ast_cast<Exp_t>(chain->items.back())) { 3304 } else if (auto index = ast_cast<Exp_t>(chain->items.back())) {
3390 if (auto name = index->getByPath<Value_t, String_t>()) { 3305 if (auto name = index->getByPath<Value_t, String_t>()) {
3391 transformString(name, temp); 3306 transformString(name, temp);
@@ -3517,7 +3432,7 @@ private:
3517 str_list tmp; 3432 str_list tmp;
3518 if (usage == ExpUsage::Assignment) { 3433 if (usage == ExpUsage::Assignment) {
3519 auto assign = x->new_ptr<Assign_t>(); 3434 auto assign = x->new_ptr<Assign_t>();
3520 assign->values.push_back(toAst<Exp_t>(classVar, Exp, x)); 3435 assign->values.push_back(toAst<Exp_t>(classVar, x));
3521 auto assignment = x->new_ptr<ExpListAssign_t>(); 3436 auto assignment = x->new_ptr<ExpListAssign_t>();
3522 assignment->expList.set(expList); 3437 assignment->expList.set(expList);
3523 assignment->action.set(assign); 3438 assignment->action.set(assign);
@@ -3616,16 +3531,16 @@ private:
3616 if (selfName) { 3531 if (selfName) {
3617 type = MemType::Property; 3532 type = MemType::Property;
3618 auto name = ast_cast<self_name_t>(selfName->name); 3533 auto name = ast_cast<self_name_t>(selfName->name);
3619 if (!name) throw std::logic_error(debugInfo("Invalid class poperty name."sv, selfName->name)); 3534 if (!name) throw std::logic_error(_info.errorMessage("Invalid class poperty name."sv, selfName->name));
3620 newSuperCall = classVar + s(".__parent."sv) + toString(name->name); 3535 newSuperCall = classVar + s(".__parent."sv) + _parser.toString(name->name);
3621 } else { 3536 } else {
3622 auto x = keyName; 3537 auto x = keyName;
3623 auto nameNode = keyName->name.as<Name_t>(); 3538 auto nameNode = keyName->name.as<Name_t>();
3624 if (!nameNode) break; 3539 if (!nameNode) break;
3625 auto name = toString(nameNode); 3540 auto name = _parser.toString(nameNode);
3626 if (name == "new"sv) { 3541 if (name == "new"sv) {
3627 type = MemType::Builtin; 3542 type = MemType::Builtin;
3628 keyName->name.set(toAst<Name_t>("__init"sv, Name, x)); 3543 keyName->name.set(toAst<Name_t>("__init"sv, x));
3629 newSuperCall = classVar + s(".__parent.__init"sv); 3544 newSuperCall = classVar + s(".__parent.__init"sv);
3630 } else { 3545 } else {
3631 newSuperCall = classVar + s(".__parent.__base."sv) + name; 3546 newSuperCall = classVar + s(".__parent.__base."sv) + name;
@@ -3636,18 +3551,18 @@ private:
3636 if (auto chainValue = ast_cast<ChainValue_t>(node)) { 3551 if (auto chainValue = ast_cast<ChainValue_t>(node)) {
3637 if (auto callable = ast_cast<Callable_t>(chainValue->items.front())) { 3552 if (auto callable = ast_cast<Callable_t>(chainValue->items.front())) {
3638 auto var = callable->item.get(); 3553 auto var = callable->item.get();
3639 if (toString(var) == "super"sv) { 3554 if (_parser.toString(var) == "super"sv) {
3640 auto insertSelfToArguments = [&](ast_node* item) { 3555 auto insertSelfToArguments = [&](ast_node* item) {
3641 auto x = item; 3556 auto x = item;
3642 switch (item->getId()) { 3557 switch (item->getId()) {
3643 case "InvokeArgs"_id: { 3558 case "InvokeArgs"_id: {
3644 auto invoke = static_cast<InvokeArgs_t*>(item); 3559 auto invoke = static_cast<InvokeArgs_t*>(item);
3645 invoke->args.push_front(toAst<Exp_t>("self"sv, Exp, x)); 3560 invoke->args.push_front(toAst<Exp_t>("self"sv, x));
3646 return true; 3561 return true;
3647 } 3562 }
3648 case "Invoke"_id: { 3563 case "Invoke"_id: {
3649 auto invoke = static_cast<Invoke_t*>(item); 3564 auto invoke = static_cast<Invoke_t*>(item);
3650 invoke->args.push_front(toAst<Exp_t>("self"sv, Exp, x)); 3565 invoke->args.push_front(toAst<Exp_t>("self"sv, x));
3651 return true; 3566 return true;
3652 } 3567 }
3653 default: 3568 default:
@@ -3669,7 +3584,7 @@ private:
3669 } else { 3584 } else {
3670 newSuperCall = classVar + s(".__parent"sv); 3585 newSuperCall = classVar + s(".__parent"sv);
3671 } 3586 }
3672 auto newChain = toAst<ChainValue_t>(newSuperCall, ChainValue, chainValue); 3587 auto newChain = toAst<ChainValue_t>(newSuperCall, chainValue);
3673 chainValue->items.pop_front(); 3588 chainValue->items.pop_front();
3674 const auto& items = newChain->items.objects(); 3589 const auto& items = newChain->items.objects();
3675 for (auto it = items.rbegin(); it != items.rend(); ++it) { 3590 for (auto it = items.rbegin(); it != items.rend(); ++it) {
@@ -3742,7 +3657,7 @@ private:
3742 if (withVar.empty()) { 3657 if (withVar.empty()) {
3743 withVar = getUnusedName("_with_"sv); 3658 withVar = getUnusedName("_with_"sv);
3744 auto assignment = x->new_ptr<ExpListAssign_t>(); 3659 auto assignment = x->new_ptr<ExpListAssign_t>();
3745 assignment->expList.set(toAst<ExpList_t>(withVar, ExpList, x)); 3660 assignment->expList.set(toAst<ExpList_t>(withVar, x));
3746 auto assign = x->new_ptr<Assign_t>(); 3661 auto assign = x->new_ptr<Assign_t>();
3747 assign->values.push_back(with->assigns->values.objects().front()); 3662 assign->values.push_back(with->assigns->values.objects().front());
3748 assignment->action.set(assign); 3663 assignment->action.set(assign);
@@ -3756,7 +3671,7 @@ private:
3756 auto assignment = x->new_ptr<ExpListAssign_t>(); 3671 auto assignment = x->new_ptr<ExpListAssign_t>();
3757 assignment->expList.set(with->valueList); 3672 assignment->expList.set(with->valueList);
3758 auto assign = x->new_ptr<Assign_t>(); 3673 auto assign = x->new_ptr<Assign_t>();
3759 assign->values.push_back(toAst<Exp_t>(withVar, Exp, x)); 3674 assign->values.push_back(toAst<Exp_t>(withVar, x));
3760 bool skipFirst = true; 3675 bool skipFirst = true;
3761 for (auto value : with->assigns->values.objects()) { 3676 for (auto value : with->assigns->values.objects()) {
3762 if (skipFirst) { 3677 if (skipFirst) {
@@ -3784,7 +3699,7 @@ private:
3784 if (withVar.empty()) { 3699 if (withVar.empty()) {
3785 withVar = getUnusedName("_with_"sv); 3700 withVar = getUnusedName("_with_"sv);
3786 auto assignment = x->new_ptr<ExpListAssign_t>(); 3701 auto assignment = x->new_ptr<ExpListAssign_t>();
3787 assignment->expList.set(toAst<ExpList_t>(withVar, ExpList, x)); 3702 assignment->expList.set(toAst<ExpList_t>(withVar, x));
3788 auto assign = x->new_ptr<Assign_t>(); 3703 auto assign = x->new_ptr<Assign_t>();
3789 assign->values.dup(with->valueList->exprs); 3704 assign->values.dup(with->valueList->exprs);
3790 assignment->action.set(assign); 3705 assignment->action.set(assign);
@@ -3829,7 +3744,7 @@ private:
3829 } 3744 }
3830 if (clsDecl) { 3745 if (clsDecl) {
3831 auto variable = clsDecl->name.as<Variable_t>(); 3746 auto variable = clsDecl->name.as<Variable_t>();
3832 if (!isDefined(toString(variable))) return traversal::Stop; 3747 if (!isDefined(_parser.toString(variable))) return traversal::Stop;
3833 } 3748 }
3834 return traversal::Return; 3749 return traversal::Return;
3835 } 3750 }
@@ -3848,7 +3763,7 @@ private:
3848 auto assignment = x->new_ptr<ExpListAssign_t>(); 3763 auto assignment = x->new_ptr<ExpListAssign_t>();
3849 assignment->expList.set(assignList); 3764 assignment->expList.set(assignList);
3850 auto assign = x->new_ptr<Assign_t>(); 3765 auto assign = x->new_ptr<Assign_t>();
3851 assign->values.push_back(toAst<Exp_t>(withVar, Exp, x)); 3766 assign->values.push_back(toAst<Exp_t>(withVar, x));
3852 assignment->action.set(assign); 3767 assignment->action.set(assign);
3853 transformAssignment(assignment, temp); 3768 transformAssignment(assignment, temp);
3854 } 3769 }
@@ -3866,7 +3781,7 @@ private:
3866 } 3781 }
3867 3782
3868 void transform_const_value(const_value_t* const_value, str_list& out) { 3783 void transform_const_value(const_value_t* const_value, str_list& out) {
3869 out.push_back(toString(const_value)); 3784 out.push_back(_parser.toString(const_value));
3870 } 3785 }
3871 3786
3872 void transformExport(Export_t* exportNode, str_list& out) { 3787 void transformExport(Export_t* exportNode, str_list& out) {
@@ -3877,13 +3792,13 @@ private:
3877 auto classDecl = static_cast<ClassDecl_t*>(item); 3792 auto classDecl = static_cast<ClassDecl_t*>(item);
3878 if (classDecl->name && classDecl->name->item->getId() == "Variable"_id) { 3793 if (classDecl->name && classDecl->name->item->getId() == "Variable"_id) {
3879 markVarExported(ExportMode::Any, true); 3794 markVarExported(ExportMode::Any, true);
3880 addExportedVar(toString(classDecl->name->item)); 3795 addExportedVar(_parser.toString(classDecl->name->item));
3881 } 3796 }
3882 transformClassDecl(classDecl, out, ExpUsage::Common); 3797 transformClassDecl(classDecl, out, ExpUsage::Common);
3883 break; 3798 break;
3884 } 3799 }
3885 case "export_op"_id: 3800 case "export_op"_id:
3886 if (toString(item) == "*"sv) { 3801 if (_parser.toString(item) == "*"sv) {
3887 markVarExported(ExportMode::Any, false); 3802 markVarExported(ExportMode::Any, false);
3888 } else { 3803 } else {
3889 markVarExported(ExportMode::Capital, false); 3804 markVarExported(ExportMode::Capital, false);
@@ -3895,7 +3810,7 @@ private:
3895 if (values->valueList) { 3810 if (values->valueList) {
3896 auto expList = x->new_ptr<ExpList_t>(); 3811 auto expList = x->new_ptr<ExpList_t>();
3897 for (auto name : values->nameList->names.objects()) { 3812 for (auto name : values->nameList->names.objects()) {
3898 addExportedVar(toString(name)); 3813 addExportedVar(_parser.toString(name));
3899 auto callable = x->new_ptr<Callable_t>(); 3814 auto callable = x->new_ptr<Callable_t>();
3900 callable->item.set(name); 3815 callable->item.set(name);
3901 auto chainValue = x->new_ptr<ChainValue_t>(); 3816 auto chainValue = x->new_ptr<ChainValue_t>();
@@ -3914,7 +3829,7 @@ private:
3914 transformAssignment(assignment, out); 3829 transformAssignment(assignment, out);
3915 } else { 3830 } else {
3916 for (auto name : values->nameList->names.objects()) { 3831 for (auto name : values->nameList->names.objects()) {
3917 addExportedVar(toString(name)); 3832 addExportedVar(_parser.toString(name));
3918 } 3833 }
3919 } 3834 }
3920 break; 3835 break;
@@ -4011,7 +3926,7 @@ private:
4011 case ExpUsage::Assignment: { 3926 case ExpUsage::Assignment: {
4012 out.push_back(clearBuf()); 3927 out.push_back(clearBuf());
4013 auto assign = x->new_ptr<Assign_t>(); 3928 auto assign = x->new_ptr<Assign_t>();
4014 assign->values.push_back(toAst<Exp_t>(tbl, Exp, x)); 3929 assign->values.push_back(toAst<Exp_t>(tbl, x));
4015 auto assignment = x->new_ptr<ExpListAssign_t>(); 3930 auto assignment = x->new_ptr<ExpListAssign_t>();
4016 assignment->expList.set(assignList); 3931 assignment->expList.set(assignList);
4017 assignment->action.set(assign); 3932 assignment->action.set(assign);
@@ -4032,7 +3947,7 @@ private:
4032 3947
4033 void transformCompFor(CompFor_t* comp, str_list& out) { 3948 void transformCompFor(CompFor_t* comp, str_list& out) {
4034 str_list temp; 3949 str_list temp;
4035 std::string varName = toString(comp->varName); 3950 std::string varName = _parser.toString(comp->varName);
4036 transformExp(comp->startValue, temp, ExpUsage::Closure); 3951 transformExp(comp->startValue, temp, ExpUsage::Closure);
4037 transformExp(comp->stopValue, temp, ExpUsage::Closure); 3952 transformExp(comp->stopValue, temp, ExpUsage::Closure);
4038 if (comp->stepValue) { 3953 if (comp->stepValue) {
@@ -4081,7 +3996,7 @@ private:
4081 ast_ptr<false, ExpListAssign_t> objAssign; 3996 ast_ptr<false, ExpListAssign_t> objAssign;
4082 if (objVar.empty()) { 3997 if (objVar.empty()) {
4083 objVar = getUnusedName("_obj_"sv); 3998 objVar = getUnusedName("_obj_"sv);
4084 auto expList = toAst<ExpList_t>(objVar, ExpList, x); 3999 auto expList = toAst<ExpList_t>(objVar, x);
4085 auto assign = x->new_ptr<Assign_t>(); 4000 auto assign = x->new_ptr<Assign_t>();
4086 assign->values.push_back(import->exp); 4001 assign->values.push_back(import->exp);
4087 auto assignment = x->new_ptr<ExpListAssign_t>(); 4002 auto assignment = x->new_ptr<ExpListAssign_t>();
@@ -4096,7 +4011,7 @@ private:
4096 case "Variable"_id: { 4011 case "Variable"_id: {
4097 auto var = ast_to<Variable_t>(name); 4012 auto var = ast_to<Variable_t>(name);
4098 { 4013 {
4099 auto callable = toAst<Callable_t>(objVar, Callable, x); 4014 auto callable = toAst<Callable_t>(objVar, x);
4100 auto dotChainItem = x->new_ptr<DotChainItem_t>(); 4015 auto dotChainItem = x->new_ptr<DotChainItem_t>();
4101 dotChainItem->name.set(var->name); 4016 dotChainItem->name.set(var->name);
4102 auto chainValue = x->new_ptr<ChainValue_t>(); 4017 auto chainValue = x->new_ptr<ChainValue_t>();
@@ -4123,7 +4038,7 @@ private:
4123 auto var = static_cast<colon_import_name_t*>(name)->name.get(); 4038 auto var = static_cast<colon_import_name_t*>(name)->name.get();
4124 { 4039 {
4125 auto nameNode = var->name.get(); 4040 auto nameNode = var->name.get();
4126 auto callable = toAst<Callable_t>(objVar, Callable, x); 4041 auto callable = toAst<Callable_t>(objVar, x);
4127 auto colonChain = x->new_ptr<ColonChainItem_t>(); 4042 auto colonChain = x->new_ptr<ColonChainItem_t>();
4128 colonChain->name.set(nameNode); 4043 colonChain->name.set(nameNode);
4129 auto chainValue = x->new_ptr<ChainValue_t>(); 4044 auto chainValue = x->new_ptr<ChainValue_t>();
@@ -4171,10 +4086,10 @@ private:
4171 void transformImportAs(ImportAs_t* import, str_list& out) { 4086 void transformImportAs(ImportAs_t* import, str_list& out) {
4172 auto x = import; 4087 auto x = import;
4173 if (!import->target) { 4088 if (!import->target) {
4174 auto name = toString(import->literal->inners.back()); 4089 auto name = _parser.toString(import->literal->inners.back());
4175 replace(name, "-"sv, "_"sv); 4090 Utils::replace(name, "-"sv, "_"sv);
4176 replace(name, " "sv, "_"sv); 4091 Utils::replace(name, " "sv, "_"sv);
4177 import->target.set(toAst<Variable_t>(name, Variable, x)); 4092 import->target.set(toAst<Variable_t>(name, x));
4178 } 4093 }
4179 auto target = import->target.get(); 4094 auto target = import->target.get();
4180 auto value = x->new_ptr<Value_t>(); 4095 auto value = x->new_ptr<Value_t>();
@@ -4195,7 +4110,7 @@ private:
4195 auto assignList = x->new_ptr<ExpList_t>(); 4110 auto assignList = x->new_ptr<ExpList_t>();
4196 assignList->exprs.push_back(exp); 4111 assignList->exprs.push_back(exp);
4197 auto assign = x->new_ptr<Assign_t>(); 4112 auto assign = x->new_ptr<Assign_t>();
4198 assign->values.push_back(toAst<Exp_t>(s("require ") + toString(import->literal), Exp, x)); 4113 assign->values.push_back(toAst<Exp_t>(s("require ") + _parser.toString(import->literal), x));
4199 auto assignment = x->new_ptr<ExpListAssign_t>(); 4114 auto assignment = x->new_ptr<ExpListAssign_t>();
4200 assignment->expList.set(assignList); 4115 assignment->expList.set(assignList);
4201 assignment->action.set(assign); 4116 assignment->action.set(assign);
@@ -4232,7 +4147,7 @@ private:
4232 transformExp(whileNode->condition, temp, ExpUsage::Closure); 4147 transformExp(whileNode->condition, temp, ExpUsage::Closure);
4233 temp.back() = indent() + s("while "sv) + temp.back() + s(" do"sv) + nll(whileNode); 4148 temp.back() = indent() + s("while "sv) + temp.back() + s(" do"sv) + nll(whileNode);
4234 pushScope(); 4149 pushScope();
4235 auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), ExpList, x); 4150 auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), x);
4236 assignLastExplist(assignLeft, whileNode->body); 4151 assignLastExplist(assignLeft, whileNode->body);
4237 auto lenLine = lenVar + s(" = "sv) + lenVar + s(" + 1"sv) + nlr(whileNode); 4152 auto lenLine = lenVar + s(" = "sv) + lenVar + s(" + 1"sv) + nlr(whileNode);
4238 transformLoopBody(whileNode->body, temp, lenLine); 4153 transformLoopBody(whileNode->body, temp, lenLine);
@@ -4240,7 +4155,7 @@ private:
4240 temp.push_back(indent() + s("end"sv) + nlr(whileNode)); 4155 temp.push_back(indent() + s("end"sv) + nlr(whileNode));
4241 if (expList) { 4156 if (expList) {
4242 auto assign = x->new_ptr<Assign_t>(); 4157 auto assign = x->new_ptr<Assign_t>();
4243 assign->values.push_back(toAst<Exp_t>(accumVar, Exp, x)); 4158 assign->values.push_back(toAst<Exp_t>(accumVar, x));
4244 auto assignment = x->new_ptr<ExpListAssign_t>(); 4159 auto assignment = x->new_ptr<ExpListAssign_t>();
4245 assignment->expList.set(expList); 4160 assignment->expList.set(expList);
4246 assignment->action.set(assign); 4161 assignment->action.set(assign);
@@ -4269,7 +4184,7 @@ private:
4269 transformExp(whileNode->condition, temp, ExpUsage::Closure); 4184 transformExp(whileNode->condition, temp, ExpUsage::Closure);
4270 temp.back() = indent() + s("while "sv) + temp.back() + s(" do"sv) + nll(whileNode); 4185 temp.back() = indent() + s("while "sv) + temp.back() + s(" do"sv) + nll(whileNode);
4271 pushScope(); 4186 pushScope();
4272 auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), ExpList, x); 4187 auto assignLeft = toAst<ExpList_t>(accumVar + s("["sv) + lenVar + s("]"sv), x);
4273 assignLastExplist(assignLeft, whileNode->body); 4188 assignLastExplist(assignLeft, whileNode->body);
4274 auto lenLine = lenVar + s(" = "sv) + lenVar + s(" + 1"sv) + nlr(whileNode); 4189 auto lenLine = lenVar + s(" = "sv) + lenVar + s(" + 1"sv) + nlr(whileNode);
4275 transformLoopBody(whileNode->body, temp, lenLine); 4190 transformLoopBody(whileNode->body, temp, lenLine);
@@ -4363,12 +4278,12 @@ private:
4363 } 4278 }
4364 4279
4365 void transformBreakLoop(BreakLoop_t* breakLoop, str_list& out) { 4280 void transformBreakLoop(BreakLoop_t* breakLoop, str_list& out) {
4366 auto keyword = toString(breakLoop); 4281 auto keyword = _parser.toString(breakLoop);
4367 if (keyword == "break"sv) { 4282 if (keyword == "break"sv) {
4368 out.push_back(indent() + keyword + nll(breakLoop)); 4283 out.push_back(indent() + keyword + nll(breakLoop));
4369 return; 4284 return;
4370 } 4285 }
4371 if (_continueVars.empty()) throw std::logic_error(debugInfo("Continue is not inside a loop."sv, breakLoop)); 4286 if (_continueVars.empty()) throw std::logic_error(_info.errorMessage("Continue is not inside a loop."sv, breakLoop));
4372 _buf << indent() << _continueVars.top() << " = true"sv << nll(breakLoop); 4287 _buf << indent() << _continueVars.top() << " = true"sv << nll(breakLoop);
4373 _buf << indent() << "break"sv << nll(breakLoop); 4288 _buf << indent() << "break"sv << nll(breakLoop);
4374 out.push_back(clearBuf()); 4289 out.push_back(clearBuf());
diff --git a/src/MoonP/moon_parser.cpp b/src/MoonP/moon_parser.cpp
index baea9bf..60096af 100644
--- a/src/MoonP/moon_parser.cpp
+++ b/src/MoonP/moon_parser.cpp
@@ -12,7 +12,7 @@ namespace pl = parserlib;
12 12
13namespace MoonP { 13namespace MoonP {
14 14
15std::unordered_set<std::string> State::luaKeywords = { 15std::unordered_set<std::string> LuaKeywords = {
16 "and", "break", "do", "else", "elseif", 16 "and", "break", "do", "else", "elseif",
17 "end", "false", "for", "function", "if", 17 "end", "false", "for", "function", "if",
18 "in", "local", "nil", "not", "or", 18 "in", "local", "nil", "not", "or",
@@ -20,7 +20,7 @@ std::unordered_set<std::string> State::luaKeywords = {
20 "while" 20 "while"
21}; 21};
22 22
23std::unordered_set<std::string> State::keywords = { 23std::unordered_set<std::string> Keywords = {
24 "and", "break", "do", "else", "elseif", 24 "and", "break", "do", "else", "elseif",
25 "end", "false", "for", "function", "if", 25 "end", "false", "for", "function", "if",
26 "in", "local", "nil", "not", "or", 26 "in", "local", "nil", "not", "or",
@@ -31,513 +31,561 @@ std::unordered_set<std::string> State::keywords = {
31 "when", "with" // Moon keywords 31 "when", "with" // Moon keywords
32}; 32};
33 33
34rule plain_space = *set(" \t"); 34MoonParser::MoonParser() {
35rule Break = nl(-expr('\r') >> '\n'); 35 plain_space = *set(" \t");
36rule Any = Break | any(); 36 Break = nl(-expr('\r') >> '\n');
37rule White = *(set(" \t") | Break); 37 Any = Break | any();
38rule Stop = Break | eof(); 38 White = *(set(" \t") | Break);
39rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); 39 Stop = Break | eof();
40rule multi_line_open = expr("--[["); 40 Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop);
41rule multi_line_close = expr("]]"); 41 multi_line_open = expr("--[[");
42rule multi_line_content = *(not_(multi_line_close) >> Any); 42 multi_line_close = expr("]]");
43rule MultiLineComment = multi_line_open >> multi_line_content >> multi_line_close; 43 multi_line_content = *(not_(multi_line_close) >> Any);
44rule Indent = plain_space; 44 MultiLineComment = multi_line_open >> multi_line_content >> multi_line_close;
45rule EscapeNewLine = expr('\\') >> plain_space >> -Comment >> Break; 45 Indent = plain_space;
46rule Space = *(set(" \t") | MultiLineComment | EscapeNewLine) >> -Comment; 46 EscapeNewLine = expr('\\') >> plain_space >> -Comment >> Break;
47rule SomeSpace = +set(" \t") >> -Comment; 47 Space = *(set(" \t") | MultiLineComment | EscapeNewLine) >> -Comment;
48rule SpaceBreak = Space >> Break; 48 SomeSpace = +set(" \t") >> -Comment;
49rule EmptyLine = SpaceBreak; 49 SpaceBreak = Space >> Break;
50rule AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_'; 50 EmptyLine = SpaceBreak;
51rule Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum; 51 AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_';
52rule Num = 52 Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum;
53( 53 Num =
54 "0x" >>
55 +(range('0', '9') | range('a', 'f') | range('A', 'F')) >>
56 -(-set("uU") >> set("lL") >> set("lL"))
57) | (
58 +range('0', '9') >> -set("uU") >> set("lL") >> set("lL")
59) | (
60 ( 54 (
61 (+range('0', '9') >> -('.' >> +range('0', '9'))) | 55 "0x" >>
62 ('.' >> +range('0', '9')) 56 +(range('0', '9') | range('a', 'f') | range('A', 'F')) >>
63 ) >> -(set("eE") >> -expr('-') >> +range('0', '9')) 57 -(-set("uU") >> set("lL") >> set("lL"))
64); 58 ) | (
65rule Cut = false_(); 59 +range('0', '9') >> -set("uU") >> set("lL") >> set("lL")
66rule Seperator = true_(); 60 ) | (
67 61 (
68#define sym(str) (Space >> str) 62 (+range('0', '9') >> -('.' >> +range('0', '9'))) |
69#define symx(str) expr(str) 63 ('.' >> +range('0', '9'))
70#define ensure(patt, finally) (((patt) >> (finally)) | ((finally) >> (Cut))) 64 ) >> -(set("eE") >> -expr('-') >> +range('0', '9'))
71#define key(str) (Space >> str >> not_(AlphaNum)) 65 );
72 66 Cut = false_();
73rule Variable = pl::user(Name, [](const item_t& item) { 67 Seperator = true_();
74 State* st = reinterpret_cast<State*>(item.user_data); 68
75 for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it); 69 #define sym(str) (Space >> str)
76 auto it = State::keywords.find(st->buffer); 70 #define symx(str) expr(str)
77 st->buffer.clear(); 71 #define ensure(patt, finally) (((patt) >> (finally)) | ((finally) >> (Cut)))
78 return it == State::keywords.end(); 72 #define key(str) (Space >> str >> not_(AlphaNum))
79}); 73
80 74 Variable = pl::user(Name, [](const item_t& item) {
81rule LuaKeyword = pl::user(Name, [](const item_t& item) { 75 State* st = reinterpret_cast<State*>(item.user_data);
82 State* st = reinterpret_cast<State*>(item.user_data); 76 for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it);
83 for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it); 77 auto it = Keywords.find(st->buffer);
84 auto it = State::luaKeywords.find(st->buffer); 78 st->buffer.clear();
85 st->buffer.clear(); 79 return it == Keywords.end();
86 return it != State::luaKeywords.end(); 80 });
87}); 81
88 82 LuaKeyword = pl::user(Name, [](const item_t& item) {
89rule self = expr('@'); 83 State* st = reinterpret_cast<State*>(item.user_data);
90rule self_name = '@' >> Name; 84 for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it);
91rule self_class = expr("@@"); 85 auto it = LuaKeywords.find(st->buffer);
92rule self_class_name = "@@" >> Name; 86 st->buffer.clear();
93 87 return it != LuaKeywords.end();
94rule SelfName = Space >> (self_class_name | self_class | self_name | self); 88 });
95rule KeyName = SelfName | Space >> Name; 89
96rule VarArg = Space >> "..."; 90 self = expr('@');
97 91 self_name = '@' >> Name;
98rule check_indent = pl::user(Indent, [](const item_t& item) { 92 self_class = expr("@@");
99 int indent = 0; 93 self_class_name = "@@" >> Name;
100 for (input_it i = item.begin; i != item.end; ++i) { 94
101 switch (*i) { 95 SelfName = Space >> (self_class_name | self_class | self_name | self);
102 case ' ': indent++; break; 96 KeyName = SelfName | Space >> Name;
103 case '\t': indent += 4; break; 97 VarArg = Space >> "...";
98
99 check_indent = pl::user(Indent, [](const item_t& item) {
100 int indent = 0;
101 for (input_it i = item.begin; i != item.end; ++i) {
102 switch (*i) {
103 case ' ': indent++; break;
104 case '\t': indent += 4; break;
105 }
104 } 106 }
105 } 107 State* st = reinterpret_cast<State*>(item.user_data);
106 State* st = reinterpret_cast<State*>(item.user_data); 108 return st->indents.top() == indent;
107 return st->indents.top() == indent; 109 });
108}); 110 CheckIndent = and_(check_indent);
109rule CheckIndent = and_(check_indent); 111
110 112 advance = pl::user(Indent, [](const item_t& item) {
111rule advance = pl::user(Indent, [](const item_t& item) { 113 int indent = 0;
112 int indent = 0; 114 for (input_it i = item.begin; i != item.end; ++i) {
113 for (input_it i = item.begin; i != item.end; ++i) { 115 switch (*i) {
114 switch (*i) { 116 case ' ': indent++; break;
115 case ' ': indent++; break; 117 case '\t': indent += 4; break;
116 case '\t': indent += 4; break; 118 }
117 } 119 }
118 } 120 State* st = reinterpret_cast<State*>(item.user_data);
119 State* st = reinterpret_cast<State*>(item.user_data); 121 int top = st->indents.top();
120 int top = st->indents.top(); 122 if (top != -1 && indent > top) {
121 if (top != -1 && indent > top) { 123 st->indents.push(indent);
124 return true;
125 }
126 return false;
127 });
128 Advance = and_(advance);
129
130 push_indent = pl::user(Indent, [](const item_t& item) {
131 int indent = 0;
132 for (input_it i = item.begin; i != item.end; ++i) {
133 switch (*i) {
134 case ' ': indent++; break;
135 case '\t': indent += 4; break;
136 }
137 }
138 State* st = reinterpret_cast<State*>(item.user_data);
122 st->indents.push(indent); 139 st->indents.push(indent);
123 return true; 140 return true;
124 } 141 });
125 return false; 142 PushIndent = and_(push_indent);
126});
127rule Advance = and_(advance);
128
129rule push_indent = pl::user(Indent, [](const item_t& item) {
130 int indent = 0;
131 for (input_it i = item.begin; i != item.end; ++i) {
132 switch (*i) {
133 case ' ': indent++; break;
134 case '\t': indent += 4; break;
135 }
136 }
137 State* st = reinterpret_cast<State*>(item.user_data);
138 st->indents.push(indent);
139 return true;
140});
141rule PushIndent = and_(push_indent);
142
143rule PreventIndent = pl::user(true_(), [](const item_t& item) {
144 State* st = reinterpret_cast<State*>(item.user_data);
145 st->indents.push(-1);
146 return true;
147});
148
149rule PopIndent = pl::user(true_(), [](const item_t& item) {
150 State* st = reinterpret_cast<State*>(item.user_data);
151 st->indents.pop();
152 return true;
153});
154
155extern rule Block;
156
157rule InBlock = Advance >> Block >> PopIndent;
158
159extern rule NameList;
160
161rule local_flag = expr('*') | expr('^');
162rule Local = key("local") >> ((Space >> local_flag) | NameList);
163
164rule colon_import_name = sym('\\') >> Space >> Variable;
165rule ImportName = colon_import_name | Space >> Variable;
166rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName);
167
168extern rule Exp, TableLit;
169
170rule import_literal_inner = (range('a', 'z') | range('A', 'Z') | set("_-")) >> *(AlphaNum | '-');
171rule import_literal_chain = Seperator >> import_literal_inner >> *(expr('.') >> import_literal_inner);
172rule ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"');
173
174rule ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp;
175rule ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | TableLit));
176
177rule Import = key("import") >> (ImportAs | ImportFrom);
178rule BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum);
179
180extern rule ExpListLow, ExpList, Assign;
181
182rule Return = key("return") >> -ExpListLow;
183rule WithExp = ExpList >> -Assign;
184
185extern rule DisableDo, PopDo, Body;
186
187rule With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body;
188rule SwitchCase = key("when") >> ExpList >> -key("then") >> Body;
189rule SwitchElse = key("else") >> Body;
190
191rule SwitchBlock = *EmptyLine >>
192 Advance >> Seperator >>
193 SwitchCase >>
194 *(+SpaceBreak >> SwitchCase) >>
195 -(+SpaceBreak >> SwitchElse) >>
196 PopIndent;
197
198rule Switch = key("switch") >>
199 DisableDo >> ensure(Exp, PopDo) >>
200 -key("do") >> -Space >> Break >> SwitchBlock;
201
202rule IfCond = Exp >> -Assign;
203rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body;
204rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body;
205rule If = key("if") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse;
206rule Unless = key("unless") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse;
207
208rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body;
209
210rule for_step_value = sym(',') >> Exp;
211rule for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
212
213rule For = key("for") >> DisableDo >>
214 ensure(for_args, PopDo) >>
215 -key("do") >> Body;
216
217extern rule AssignableNameList;
218 143
219extern rule star_exp; 144 PreventIndent = pl::user(true_(), [](const item_t& item) {
220 145 State* st = reinterpret_cast<State*>(item.user_data);
221rule for_in = star_exp | ExpList; 146 st->indents.push(-1);
222 147 return true;
223rule ForEach = key("for") >> AssignableNameList >> key("in") >> 148 });
224 DisableDo >> ensure(for_in, PopDo) >>
225 -key("do") >> Body;
226
227rule Do = pl::user(key("do") >> Body, [](const item_t& item)
228{
229 State* st = reinterpret_cast<State*>(item.user_data);
230 return st->doStack.empty() || st->doStack.top();
231});
232
233rule DisableDo = pl::user(true_(), [](const item_t& item)
234{
235 State* st = reinterpret_cast<State*>(item.user_data);
236 st->doStack.push(false);
237 return true;
238});
239 149
240rule PopDo = pl::user(true_(), [](const item_t& item) 150 PopIndent = pl::user(true_(), [](const item_t& item) {
241{ 151 State* st = reinterpret_cast<State*>(item.user_data);
242 State* st = reinterpret_cast<State*>(item.user_data); 152 st->indents.pop();
243 st->doStack.pop(); 153 return true;
244 return true; 154 });
245});
246 155
247extern rule CompInner; 156 InBlock = Advance >> Block >> PopIndent;
248 157
249rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); 158 local_flag = expr('*') | expr('^');
250rule comp_value = sym(',') >> Exp; 159 Local = key("local") >> ((Space >> local_flag) | NameList);
251rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}');
252 160
253extern rule CompForEach, CompFor, CompClause; 161 colon_import_name = sym('\\') >> Space >> Variable;
162 ImportName = colon_import_name | Space >> Variable;
163 ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName);
254 164
255rule CompInner = Seperator >> (CompForEach | CompFor) >> *CompClause; 165 import_literal_inner = (range('a', 'z') | range('A', 'Z') | set("_-")) >> *(AlphaNum | '-');
256rule star_exp = sym('*') >> Exp; 166 import_literal_chain = Seperator >> import_literal_inner >> *(expr('.') >> import_literal_inner);
257rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp); 167 ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"');
258rule CompFor = key("for") >> Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
259rule CompClause = CompFor | CompForEach | key("when") >> Exp;
260 168
261extern rule TableBlock; 169 ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp;
170 ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | TableLit));
262 171
263rule Assign = sym('=') >> Seperator >> (With | If | Switch | TableBlock | Exp >> *((sym(',') | sym(';')) >> Exp)); 172 Import = key("import") >> (ImportAs | ImportFrom);
173 BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum);
264 174
265rule update_op = 175 Return = key("return") >> -ExpListLow;
266 expr("..") | 176 WithExp = ExpList >> -Assign;
267 expr("+") |
268 expr("-") |
269 expr("*") |
270 expr("/") |
271 expr("%") |
272 expr("or") |
273 expr("and") |
274 expr("&") |
275 expr("|") |
276 expr(">>") |
277 expr("<<");
278 177
279rule Update = Space >> update_op >> expr("=") >> Exp; 178 With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body;
179 SwitchCase = key("when") >> ExpList >> -key("then") >> Body;
180 SwitchElse = key("else") >> Body;
280 181
281rule BinaryOperator = 182 SwitchBlock = *EmptyLine >>
282 (expr("or") >> not_(AlphaNum)) | 183 Advance >> Seperator >>
283 (expr("and") >> not_(AlphaNum)) | 184 SwitchCase >>
284 expr("<=") | 185 *(+SpaceBreak >> SwitchCase) >>
285 expr(">=") | 186 -(+SpaceBreak >> SwitchElse) >>
286 expr("~=") | 187 PopIndent;
287 expr("!=") |
288 expr("==") |
289 expr("..") |
290 expr("<<") |
291 expr(">>") |
292 expr("//") |
293 set("+-*/%^><|&");
294
295rule BackcallOperator = expr("|>");
296
297extern rule AssignableChain;
298
299rule Assignable = AssignableChain | Space >> Variable | SelfName;
300
301extern rule Value;
302
303rule exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value;
304rule Exp = Value >> *exp_op_value;
305 188
306extern rule Chain, Callable, InvokeArgs, existential_op; 189 Switch = key("switch") >>
190 DisableDo >> ensure(Exp, PopDo) >>
191 -key("do") >> -Space >> Break >> SwitchBlock;
307 192
308rule ChainValue = Seperator >> (Chain | Callable) >> -existential_op >> -InvokeArgs; 193 IfCond = Exp >> -Assign;
194 IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body;
195 IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body;
196 If = key("if") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse;
197 Unless = key("unless") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse;
309 198
310extern rule KeyValue, String, SimpleValue; 199 While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body;
311
312rule simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
313rule Value = SimpleValue | simple_table | ChainValue | String;
314
315extern rule LuaString;
316 200
317rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any; 201 for_step_value = sym(',') >> Exp;
318rule SingleString = symx('\'') >> *single_string_inner >> symx('\''); 202 for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
319rule interp = symx("#{") >> Exp >> sym('}');
320rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any;
321rule double_string_inner = +(not_(interp) >> double_string_plain);
322rule double_string_content = double_string_inner | interp;
323rule DoubleString = symx('"') >> Seperator >> *double_string_content >> symx('"');
324rule String = Space >> (DoubleString | SingleString | LuaString);
325
326rule lua_string_open = '[' >> *expr('=') >> '[';
327rule lua_string_close = ']' >> *expr('=') >> ']';
328
329rule LuaStringOpen = pl::user(lua_string_open, [](const item_t& item)
330{
331 size_t count = std::distance(item.begin, item.end);
332 State* st = reinterpret_cast<State*>(item.user_data);
333 st->stringOpen = count;
334 return true;
335});
336
337rule LuaStringClose = pl::user(lua_string_close, [](const item_t& item)
338{
339 size_t count = std::distance(item.begin, item.end);
340 State* st = reinterpret_cast<State*>(item.user_data);
341 return st->stringOpen == count;
342});
343 203
344rule LuaStringContent = *(not_(LuaStringClose) >> Any); 204 For = key("for") >> DisableDo >>
205 ensure(for_args, PopDo) >>
206 -key("do") >> Body;
345 207
346rule LuaString = pl::user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item) 208 for_in = star_exp | ExpList;
347{
348 State* st = reinterpret_cast<State*>(item.user_data);
349 st->stringOpen = -1;
350 return true;
351});
352
353rule Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')');
354rule Callable = Space >> Variable | SelfName | VarArg | Parens;
355rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp);
356
357rule FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) |
358 (sym('!') >> not_(expr('=')));
359
360extern rule ChainItems, DotChainItem, ColonChain;
361
362rule existential_op = expr('?');
363rule chain_call = (Callable | String) >> -existential_op >> ChainItems;
364rule chain_item = and_(set(".\\")) >> ChainItems;
365rule chain_dot_chain = DotChainItem >> -existential_op >> -ChainItems;
366
367rule Chain = chain_call | chain_item |
368 Space >> (chain_dot_chain | ColonChain);
369
370rule AssignableChain = Seperator >> Chain;
371 209
372extern rule ChainItem; 210 ForEach = key("for") >> AssignableNameList >> key("in") >>
211 DisableDo >> ensure(for_in, PopDo) >>
212 -key("do") >> Body;
373 213
374rule chain_with_colon = +ChainItem >> -ColonChain; 214 Do = pl::user(key("do") >> Body, [](const item_t& item)
375rule ChainItems = chain_with_colon | ColonChain; 215 {
216 State* st = reinterpret_cast<State*>(item.user_data);
217 return st->doStack.empty() || st->doStack.top();
218 });
376 219
377extern rule Invoke, Slice; 220 DisableDo = pl::user(true_(), [](const item_t& item)
221 {
222 State* st = reinterpret_cast<State*>(item.user_data);
223 st->doStack.push(false);
224 return true;
225 });
378 226
379rule Index = symx('[') >> Exp >> sym(']'); 227 PopDo = pl::user(true_(), [](const item_t& item)
380rule ChainItem = Invoke >> -existential_op | DotChainItem >> -existential_op | Slice | Index >> -existential_op; 228 {
381rule DotChainItem = symx('.') >> Name; 229 State* st = reinterpret_cast<State*>(item.user_data);
382rule ColonChainItem = symx('\\') >> (LuaKeyword | Name); 230 st->doStack.pop();
383rule invoke_chain = Invoke >> -existential_op >> -ChainItems; 231 return true;
384rule ColonChain = ColonChainItem >> -existential_op >> -invoke_chain; 232 });
233
234 Comprehension = sym('[') >> Exp >> CompInner >> sym(']');
235 comp_value = sym(',') >> Exp;
236 TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}');
237
238 CompInner = Seperator >> (CompForEach | CompFor) >> *CompClause;
239 star_exp = sym('*') >> Exp;
240 CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp);
241 CompFor = key("for") >> Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value;
242 CompClause = CompFor | CompForEach | key("when") >> Exp;
243
244 Assign = sym('=') >> Seperator >> (With | If | Switch | TableBlock | Exp >> *((sym(',') | sym(';')) >> Exp));
245
246 update_op =
247 expr("..") |
248 expr("+") |
249 expr("-") |
250 expr("*") |
251 expr("/") |
252 expr("%") |
253 expr("or") |
254 expr("and") |
255 expr("&") |
256 expr("|") |
257 expr(">>") |
258 expr("<<");
259
260 Update = Space >> update_op >> expr("=") >> Exp;
261
262 BinaryOperator =
263 (expr("or") >> not_(AlphaNum)) |
264 (expr("and") >> not_(AlphaNum)) |
265 expr("<=") |
266 expr(">=") |
267 expr("~=") |
268 expr("!=") |
269 expr("==") |
270 expr("..") |
271 expr("<<") |
272 expr(">>") |
273 expr("//") |
274 set("+-*/%^><|&");
275
276 BackcallOperator = expr("|>");
277
278 Assignable = AssignableChain | Space >> Variable | SelfName;
279
280 exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value;
281 Exp = Value >> *exp_op_value;
282
283 ChainValue = Seperator >> (Chain | Callable) >> -existential_op >> -InvokeArgs;
284
285 simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
286 Value = SimpleValue | simple_table | ChainValue | String;
287
288 single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any;
289 SingleString = symx('\'') >> *single_string_inner >> symx('\'');
290 interp = symx("#{") >> Exp >> sym('}');
291 double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any;
292 double_string_inner = +(not_(interp) >> double_string_plain);
293 double_string_content = double_string_inner | interp;
294 DoubleString = symx('"') >> Seperator >> *double_string_content >> symx('"');
295 String = Space >> (DoubleString | SingleString | LuaString);
296
297 lua_string_open = '[' >> *expr('=') >> '[';
298 lua_string_close = ']' >> *expr('=') >> ']';
299
300 LuaStringOpen = pl::user(lua_string_open, [](const item_t& item) {
301 size_t count = std::distance(item.begin, item.end);
302 State* st = reinterpret_cast<State*>(item.user_data);
303 st->stringOpen = count;
304 return true;
305 });
385 306
386rule default_value = true_(); 307 LuaStringClose = pl::user(lua_string_close, [](const item_t& item) {
387rule Slice = 308 size_t count = std::distance(item.begin, item.end);
388 symx('[') >> 309 State* st = reinterpret_cast<State*>(item.user_data);
389 (Exp | default_value) >> 310 return st->stringOpen == count;
390 sym(',') >> 311 });
391 (Exp | default_value) >>
392 (sym(',') >> Exp | default_value) >>
393 sym(']');
394 312
395rule Invoke = Seperator >> ( 313 LuaStringContent = *(not_(LuaStringClose) >> Any);
396 FnArgs |
397 SingleString |
398 DoubleString |
399 and_(expr('[')) >> LuaString);
400 314
401extern rule TableValueList, TableLitLine; 315 LuaString = pl::user(LuaStringOpen >> -Break >> LuaStringContent >> LuaStringClose, [](const item_t& item) {
316 State* st = reinterpret_cast<State*>(item.user_data);
317 st->stringOpen = -1;
318 return true;
319 });
402 320
403rule TableValue = KeyValue | Exp; 321 Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')');
322 Callable = Space >> Variable | SelfName | VarArg | Parens;
323 FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp);
404 324
405rule table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(','); 325 FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) |
326 (sym('!') >> not_(expr('=')));
406 327
407rule TableLit = 328 existential_op = expr('?');
408 sym('{') >> Seperator >> 329 chain_call = (Callable | String) >> -existential_op >> ChainItems;
409 -TableValueList >> 330 chain_item = and_(set(".\\")) >> ChainItems;
410 -sym(',') >> 331 chain_dot_chain = DotChainItem >> -existential_op >> -ChainItems;
411 -table_lit_lines >>
412 White >> sym('}');
413
414rule TableValueList = TableValue >> *(sym(',') >> TableValue);
415
416rule TableLitLine =
417(
418 PushIndent >> (TableValueList >> PopIndent | PopIndent)
419) | (
420 Space
421);
422 332
423extern rule KeyValueLine; 333 Chain = chain_call | chain_item |
334 Space >> (chain_dot_chain | ColonChain);
424 335
425rule TableBlockInner = Seperator >> KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine); 336 AssignableChain = Seperator >> Chain;
426rule TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent);
427 337
428extern rule Statement; 338 chain_with_colon = +ChainItem >> -ColonChain;
429 339 ChainItems = chain_with_colon | ColonChain;
430rule class_member_list = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
431rule ClassLine = CheckIndent >> (class_member_list | Statement) >> -sym(',');
432rule ClassBlock = +(SpaceBreak) >> Advance >>Seperator >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent;
433 340
434rule ClassDecl = 341 Index = symx('[') >> Exp >> sym(']');
435 key("class") >> not_(expr(':')) >> 342 ChainItem = Invoke >> -existential_op | DotChainItem >> -existential_op | Slice | Index >> -existential_op;
436 -Assignable >> 343 DotChainItem = symx('.') >> Name;
437 -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >> 344 ColonChainItem = symx('\\') >> (LuaKeyword | Name);
438 -ClassBlock; 345 invoke_chain = Invoke >> -existential_op >> -ChainItems;
346 ColonChain = ColonChainItem >> -existential_op >> -invoke_chain;
439 347
440rule export_values = NameList >> -(sym('=') >> ExpListLow); 348 default_value = true_();
441rule export_op = expr('*') | expr('^'); 349 Slice =
442rule Export = key("export") >> (ClassDecl | (Space >> export_op) | export_values); 350 symx('[') >>
351 (Exp | default_value) >>
352 sym(',') >>
353 (Exp | default_value) >>
354 (sym(',') >> Exp | default_value) >>
355 sym(']');
443 356
444rule variable_pair = sym(':') >> not_(SomeSpace) >> Space >> Variable; 357 Invoke = Seperator >> (
358 FnArgs |
359 SingleString |
360 DoubleString |
361 and_(expr('[')) >> LuaString);
445 362
446rule normal_pair = 363 TableValue = KeyValue | Exp;
447(
448 KeyName |
449 sym('[') >> Exp >> sym(']') |
450 Space >> DoubleString |
451 Space >> SingleString
452) >>
453symx(':') >>
454(Exp | TableBlock | +(SpaceBreak) >> Exp);
455 364
456rule KeyValue = variable_pair | normal_pair; 365 table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(',');
457 366
458rule KeyValueList = KeyValue >> *(sym(',') >> KeyValue); 367 TableLit =
459rule KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); 368 sym('{') >> Seperator >>
369 -TableValueList >>
370 -sym(',') >>
371 -table_lit_lines >>
372 White >> sym('}');
460 373
461rule FnArgDef = (Space >> Variable | SelfName) >> -(sym('=') >> Exp); 374 TableValueList = TableValue >> *(sym(',') >> TableValue);
462 375
463rule FnArgDefList = Seperator >> 376 TableLitLine = (
464( 377 PushIndent >> (TableValueList >> PopIndent | PopIndent)
465 (
466 FnArgDef >>
467 *((sym(',') | Break) >> White >> FnArgDef) >>
468 -((sym(',') | Break) >> White >> VarArg)
469 ) | ( 378 ) | (
470 VarArg 379 Space
471 )
472);
473
474rule outer_var_shadow = key("using") >> (NameList | Space >> expr("nil"));
475
476rule FnArgsDef = sym('(') >> White >> -FnArgDefList >> -outer_var_shadow >> White >> sym(')');
477rule fn_arrow = expr("->") | expr("=>");
478rule FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body;
479
480rule NameList = Seperator >> Space >> Variable >> *(sym(',') >> Space >> Variable);
481rule NameOrDestructure = Space >> Variable | TableLit;
482rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure);
483
484rule Backcall = -FnArgsDef >> Space >> symx("<-") >> Space >> ChainValue;
485
486rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp);
487rule ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp);
488
489rule ArgLine = CheckIndent >> Exp >> *(sym(',') >> Exp);
490rule ArgBlock = ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent;
491
492rule invoke_args_with_table =
493 sym(',') >>
494 (
495 TableBlock |
496 SpaceBreak >> Advance >> ArgBlock >> -TableBlock
497 ); 380 );
498 381
499rule InvokeArgs = 382 TableBlockInner = Seperator >> KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine);
500 not_(expr('-')) >> Seperator >> 383 TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent);
501 ( 384
502 Exp >> *(sym(',') >> Exp) >> -(invoke_args_with_table | TableBlock) | 385 class_member_list = Seperator >> KeyValue >> *(sym(',') >> KeyValue);
503 TableBlock 386 ClassLine = CheckIndent >> (class_member_list | Statement) >> -sym(',');
387 ClassBlock = +(SpaceBreak) >> Advance >>Seperator >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent;
388
389 ClassDecl =
390 key("class") >> not_(expr(':')) >>
391 -Assignable >>
392 -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >>
393 -ClassBlock;
394
395 export_values = NameList >> -(sym('=') >> ExpListLow);
396 export_op = expr('*') | expr('^');
397 Export = key("export") >> (ClassDecl | (Space >> export_op) | export_values);
398
399 variable_pair = sym(':') >> not_(SomeSpace) >> Space >> Variable;
400
401 normal_pair = (
402 KeyName |
403 sym('[') >> Exp >> sym(']') |
404 Space >> DoubleString |
405 Space >> SingleString
406 ) >>
407 symx(':') >>
408 (Exp | TableBlock | +(SpaceBreak) >> Exp);
409
410 KeyValue = variable_pair | normal_pair;
411
412 KeyValueList = KeyValue >> *(sym(',') >> KeyValue);
413 KeyValueLine = CheckIndent >> KeyValueList >> -sym(',');
414
415 FnArgDef = (Space >> Variable | SelfName) >> -(sym('=') >> Exp);
416
417 FnArgDefList = Seperator >> (
418 (
419 FnArgDef >>
420 *((sym(',') | Break) >> White >> FnArgDef) >>
421 -((sym(',') | Break) >> White >> VarArg)
422 ) | (
423 VarArg
424 )
504 ); 425 );
505 426
506rule const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum); 427 outer_var_shadow = key("using") >> (NameList | Space >> expr("nil"));
507rule minus_exp = expr('-') >> not_(SomeSpace) >> Exp; 428
508rule sharp_exp = expr('#') >> Exp; 429 FnArgsDef = sym('(') >> White >> -FnArgDefList >> -outer_var_shadow >> White >> sym(')');
509rule tilde_exp = expr('~') >> Exp; 430 fn_arrow = expr("->") | expr("=>");
510rule not_exp = expr("not") >> not_(AlphaNum) >> Exp; 431 FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body;
511rule unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp; 432
512 433 NameList = Seperator >> Space >> Variable >> *(sym(',') >> Space >> Variable);
513rule SimpleValue = 434 NameOrDestructure = Space >> Variable | TableLit;
514 (Space >> const_value) | 435 AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure);
515 If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do | 436
516 (Space >> unary_exp) | 437 Backcall = -FnArgsDef >> Space >> symx("<-") >> Space >> ChainValue;
517 TblComprehension | TableLit | Comprehension | FunLit | 438
518 (Space >> Num); 439 ExpList = Seperator >> Exp >> *(sym(',') >> Exp);
519 440 ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp);
520rule ExpListAssign = ExpList >> -(Update | Assign); 441
521 442 ArgLine = CheckIndent >> Exp >> *(sym(',') >> Exp);
522rule if_else_line = key("if") >> Exp >> -Assign >> (key("else") >> Exp | default_value); 443 ArgBlock = ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent;
523rule unless_line = key("unless") >> Exp; 444
524 445 invoke_args_with_table =
525rule statement_appendix = (if_else_line | unless_line | CompInner) >> Space; 446 sym(',') >>
526rule Statement = 447 (
527( 448 TableBlock |
528 Import | While | For | ForEach | 449 SpaceBreak >> Advance >> ArgBlock >> -TableBlock
529 Return | Local | Export | Space >> BreakLoop | 450 );
530 Backcall | ExpListAssign 451
531) >> Space >> 452 InvokeArgs =
532-statement_appendix; 453 not_(expr('-')) >> Seperator >>
533 454 (
534rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement; 455 Exp >> *(sym(',') >> Exp) >> -(invoke_args_with_table | TableBlock) |
535 456 TableBlock
536rule empty_line_stop = Space >> and_(Stop); 457 );
537rule Line = CheckIndent >> Statement | empty_line_stop; 458
538rule Block = Seperator >> Line >> *(+Break >> Line); 459 const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum);
539 460 minus_exp = expr('-') >> not_(SomeSpace) >> Exp;
540rule Shebang = expr("#!") >> *(not_(Stop) >> Any); 461 sharp_exp = expr('#') >> Exp;
541rule File = White >> -Shebang >> Block >> eof(); 462 tilde_exp = expr('~') >> Exp;
463 not_exp = expr("not") >> not_(AlphaNum) >> Exp;
464 unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp;
465
466 SimpleValue =
467 (Space >> const_value) |
468 If | Unless | Switch | With | ClassDecl | ForEach | For | While | Do |
469 (Space >> unary_exp) |
470 TblComprehension | TableLit | Comprehension | FunLit |
471 (Space >> Num);
472
473 ExpListAssign = ExpList >> -(Update | Assign);
474
475 if_else_line = key("if") >> Exp >> -Assign >> (key("else") >> Exp | default_value);
476 unless_line = key("unless") >> Exp;
477
478 statement_appendix = (if_else_line | unless_line | CompInner) >> Space;
479 Statement = (
480 Import | While | For | ForEach |
481 Return | Local | Export | Space >> BreakLoop |
482 Backcall | ExpListAssign
483 ) >> Space >>
484 -statement_appendix;
485
486 Body = -Space >> Break >> *EmptyLine >> InBlock | Statement;
487
488 empty_line_stop = Space >> and_(Stop);
489 Line = CheckIndent >> Statement | empty_line_stop;
490 Block = Seperator >> Line >> *(+Break >> Line);
491
492 Shebang = expr("#!") >> *(not_(Stop) >> Any);
493 File = White >> -Shebang >> Block >> eof();
494}
495
496ParseInfo MoonParser::parse(const std::string& codes, rule& r) {
497 ParseInfo res;
498 try {
499 res.input = std::make_unique<input>();
500 *(res.input) = _converter.from_bytes(codes);
501 } catch (const std::range_error&) {
502 res.error = "Invalid text encoding."sv;
503 return res;
504 }
505 error_list errors;
506 try {
507 State state;
508 res.node.set(pl::parse(*(res.input), r, errors, &state));
509 } catch (const std::logic_error& err) {
510 res.error = err.what();
511 return res;
512 }
513 if (!errors.empty()) {
514 std::ostringstream buf;
515 for (error_list::iterator it = errors.begin(); it != errors.end(); ++it) {
516 const error& err = *it;
517 switch (err.m_type) {
518 case ERROR_TYPE::ERROR_SYNTAX_ERROR:
519 buf << res.errorMessage("Syntax error."sv, &err);
520 break;
521 case ERROR_TYPE::ERROR_INVALID_EOF:
522 buf << res.errorMessage("Invalid EOF."sv, &err);
523 break;
524 }
525 }
526 res.error = buf.str();
527 }
528 return res;
529}
530
531std::string MoonParser::toString(ast_node* node) {
532 return _converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
533}
534
535std::string MoonParser::toString(input::iterator begin, input::iterator end) {
536 return _converter.to_bytes(std::wstring(begin, end));
537}
538
539input MoonParser::encode(std::string_view input) {
540 return _converter.from_bytes(std::string(input));
541}
542
543std::string MoonParser::decode(const input& input) {
544 return _converter.to_bytes(input);
545}
546
547namespace Utils {
548 void replace(std::string& str, std::string_view from, std::string_view to) {
549 size_t start_pos = 0;
550 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
551 str.replace(start_pos, from.size(), to);
552 start_pos += to.size();
553 }
554 }
555}
556
557std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc) const {
558 const int ASCII = 255;
559 int length = loc->m_begin.m_line;
560 auto begin = input->begin();
561 auto end = input->end();
562 int count = 0;
563 for (auto it = input->begin(); it != input->end(); ++it) {
564 if (*it == '\n') {
565 if (count + 1 == length) {
566 end = it;
567 break;
568 } else {
569 begin = it + 1;
570 }
571 count++;
572 }
573 }
574 auto line = Converter{}.to_bytes(std::wstring(begin, end));
575 int oldCol = loc->m_begin.m_col;
576 int col = std::max(0, oldCol - 1);
577 auto it = begin;
578 for (int i = 0; i < oldCol; ++i) {
579 if (*it > ASCII) {
580 ++col;
581 }
582 ++it;
583 }
584 Utils::replace(line, "\t"sv, " "sv);
585 std::ostringstream buf;
586 buf << loc->m_begin.m_line << ": "sv << msg <<
587 '\n' << line << '\n' << std::string(col, ' ') << "^"sv;
588 return buf.str();
589}
542 590
543} // namespace MoonP 591} // namespace MoonP
diff --git a/src/MoonP/moon_parser.h b/src/MoonP/moon_parser.h
index fc4ee55..933aa7a 100644
--- a/src/MoonP/moon_parser.h
+++ b/src/MoonP/moon_parser.h
@@ -9,27 +9,266 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
9#pragma once 9#pragma once
10 10
11#include <string> 11#include <string>
12#include <codecvt>
13#include <unordered_set> 12#include <unordered_set>
14#include <stack> 13#include <stack>
15#include <algorithm> 14#include <algorithm>
16#include <vector> 15#include <vector>
16#include <sstream>
17#include <string_view>
18using namespace std::string_view_literals;
17#include "MoonP/ast.hpp" 19#include "MoonP/ast.hpp"
18using namespace parserlib; 20#include "MoonP/moon_ast.h"
19 21
20namespace MoonP { 22namespace MoonP {
21 23
22struct State { 24struct ParseInfo {
23 State() { 25 ast_ptr<false,ast_node> node;
24 indents.push(0); 26 std::string error;
25 stringOpen = -1; 27 std::unique_ptr<input> input;
28 std::string errorMessage(std::string_view msg, const input_range* loc) const;
29};
30
31#define AST_RULE(type) \
32 rule type; \
33 ast<type##_t> type##_impl = type; \
34 template<> inline rule& getRule<type##_t>() { return type; }
35
36extern std::unordered_set<std::string> LuaKeywords;
37extern std::unordered_set<std::string> Keywords;
38
39class MoonParser {
40public:
41 MoonParser();
42
43 template<class AST>
44 ParseInfo parse(const std::string& codes) {
45 error_list errors;
46 auto res = parse(codes, getRule<AST>());
47 if (res.node.template is<AST>()) {
48 return res;
49 }
50 return res;
51 }
52
53 template <class AST>
54 bool match(const std::string& codes) {
55 auto rEnd = rule(getRule<AST>() >> eof());
56 return parse(codes, rEnd).node;
57 }
58
59 std::string toString(ast_node* node);
60 std::string toString(input::iterator begin, input::iterator end);
61
62 input encode(std::string_view input);
63 std::string decode(const input& input);
64
65protected:
66 ParseInfo parse(const std::string& codes, rule& r);
67
68 struct State {
69 State() {
70 indents.push(0);
71 stringOpen = -1;
72 }
73 std::string buffer;
74 size_t stringOpen;
75 std::stack<int> indents;
76 std::stack<bool> doStack;
77 };
78
79private:
80 Converter _converter;
81
82 template <class T>
83 inline rule& getRule() {
84 assert(false);
85 return Cut;
26 } 86 }
27 std::string buffer; 87
28 size_t stringOpen; 88 rule plain_space;
29 std::stack<int> indents; 89 rule Break;
30 std::stack<bool> doStack; 90 rule Any;
31 static std::unordered_set<std::string> luaKeywords; 91 rule White;
32 static std::unordered_set<std::string> keywords; 92 rule Stop;
93 rule Comment;
94 rule multi_line_open;
95 rule multi_line_close;
96 rule multi_line_content;
97 rule MultiLineComment;
98 rule Indent;
99 rule EscapeNewLine;
100 rule Space;
101 rule SomeSpace;
102 rule SpaceBreak;
103 rule EmptyLine;
104 rule AlphaNum;
105 rule Cut;
106 rule check_indent;
107 rule CheckIndent;
108 rule advance;
109 rule Advance;
110 rule push_indent;
111 rule PushIndent;
112 rule PreventIndent;
113 rule PopIndent;
114 rule InBlock;
115 rule ImportName;
116 rule ImportNameList;
117 rule import_literal_chain;
118 rule WithExp;
119 rule PopDo;
120 rule DisableDo;
121 rule SwitchElse;
122 rule SwitchBlock;
123 rule IfElseIf;
124 rule IfElse;
125 rule for_args;
126 rule for_in;
127 rule CompClause;
128 rule Chain;
129 rule KeyValue;
130 rule single_string_inner;
131 rule interp;
132 rule double_string_plain;
133 rule lua_string_open;
134 rule lua_string_close;
135 rule FnArgsExpList;
136 rule FnArgs;
137 rule chain_call;
138 rule chain_item;
139 rule ChainItems;
140 rule chain_dot_chain;
141 rule ColonChain;
142 rule chain_with_colon;
143 rule ChainItem;
144 rule Index;
145 rule invoke_chain;
146 rule TableValue;
147 rule table_lit_lines;
148 rule TableLitLine;
149 rule TableValueList;
150 rule TableBlockInner;
151 rule ClassLine;
152 rule KeyValueLine;
153 rule KeyValueList;
154 rule ArgLine;
155 rule ArgBlock;
156 rule invoke_args_with_table;
157 rule minus_exp;
158 rule sharp_exp;
159 rule tilde_exp;
160 rule not_exp;
161 rule empty_line_stop;
162 rule Line;
163 rule Shebang;
164
165 AST_RULE(Num)
166 AST_RULE(Name)
167 AST_RULE(Variable)
168 AST_RULE(LuaKeyword)
169 AST_RULE(self)
170 AST_RULE(self_name)
171 AST_RULE(self_class)
172 AST_RULE(self_class_name)
173 AST_RULE(SelfName)
174 AST_RULE(KeyName)
175 AST_RULE(VarArg)
176 AST_RULE(local_flag)
177 AST_RULE(Seperator)
178 AST_RULE(NameList)
179 AST_RULE(Local)
180 AST_RULE(colon_import_name)
181 AST_RULE(import_literal_inner)
182 AST_RULE(ImportLiteral)
183 AST_RULE(ImportFrom)
184 AST_RULE(ImportAs)
185 AST_RULE(Import)
186 AST_RULE(Backcall)
187 AST_RULE(ExpListLow)
188 AST_RULE(ExpList)
189 AST_RULE(Return)
190 AST_RULE(With)
191 AST_RULE(SwitchCase)
192 AST_RULE(Switch)
193 AST_RULE(IfCond)
194 AST_RULE(If)
195 AST_RULE(Unless)
196 AST_RULE(While)
197 AST_RULE(for_step_value)
198 AST_RULE(For)
199 AST_RULE(ForEach)
200 AST_RULE(Do)
201 AST_RULE(Comprehension)
202 AST_RULE(comp_value)
203 AST_RULE(TblComprehension)
204 AST_RULE(star_exp)
205 AST_RULE(CompForEach)
206 AST_RULE(CompFor)
207 AST_RULE(CompInner)
208 AST_RULE(Assign)
209 AST_RULE(update_op)
210 AST_RULE(Update)
211 AST_RULE(BinaryOperator)
212 AST_RULE(BackcallOperator)
213 AST_RULE(Assignable)
214 AST_RULE(AssignableChain)
215 AST_RULE(exp_op_value)
216 AST_RULE(Exp)
217 AST_RULE(Callable)
218 AST_RULE(ChainValue)
219 AST_RULE(simple_table)
220 AST_RULE(SimpleValue)
221 AST_RULE(Value)
222 AST_RULE(LuaStringOpen);
223 AST_RULE(LuaStringContent);
224 AST_RULE(LuaStringClose);
225 AST_RULE(LuaString)
226 AST_RULE(SingleString)
227 AST_RULE(double_string_inner)
228 AST_RULE(double_string_content)
229 AST_RULE(DoubleString)
230 AST_RULE(String)
231 AST_RULE(Parens)
232 AST_RULE(DotChainItem)
233 AST_RULE(ColonChainItem)
234 AST_RULE(default_value)
235 AST_RULE(Slice)
236 AST_RULE(Invoke)
237 AST_RULE(existential_op)
238 AST_RULE(TableLit)
239 AST_RULE(TableBlock)
240 AST_RULE(class_member_list)
241 AST_RULE(ClassBlock)
242 AST_RULE(ClassDecl)
243 AST_RULE(export_values)
244 AST_RULE(export_op)
245 AST_RULE(Export)
246 AST_RULE(variable_pair)
247 AST_RULE(normal_pair)
248 AST_RULE(FnArgDef)
249 AST_RULE(FnArgDefList)
250 AST_RULE(outer_var_shadow)
251 AST_RULE(FnArgsDef)
252 AST_RULE(fn_arrow)
253 AST_RULE(FunLit)
254 AST_RULE(NameOrDestructure)
255 AST_RULE(AssignableNameList)
256 AST_RULE(InvokeArgs)
257 AST_RULE(const_value)
258 AST_RULE(unary_exp)
259 AST_RULE(ExpListAssign)
260 AST_RULE(if_else_line)
261 AST_RULE(unless_line)
262 AST_RULE(statement_appendix)
263 AST_RULE(BreakLoop)
264 AST_RULE(Statement)
265 AST_RULE(Body)
266 AST_RULE(Block)
267 AST_RULE(File)
268};
269
270namespace Utils {
271 void replace(std::string& str, std::string_view from, std::string_view to);
33}; 272};
34 273
35} // namespace MoonP 274} // namespace MoonP
diff --git a/src/MoonP/parser.cpp b/src/MoonP/parser.cpp
index 94f80af..cb896c2 100644
--- a/src/MoonP/parser.cpp
+++ b/src/MoonP/parser.cpp
@@ -21,25 +21,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21namespace parserlib { 21namespace parserlib {
22 22
23 23
24//internal map from rules to parse procs
25typedef std::unordered_map<rule *, parse_proc> _parse_proc_map_t;
26
27//on exit, it deletes the parse proc map
28static _parse_proc_map_t& _get_parse_proc_map() {
29 static _parse_proc_map_t _parse_proc_map;
30 return _parse_proc_map;
31}
32
33
34//get the parse proc from the map
35static parse_proc _get_parse_proc(rule *r) {
36 _parse_proc_map_t& _parse_proc_map = _get_parse_proc_map();
37 _parse_proc_map_t::iterator it = _parse_proc_map.find(r);
38 if (it == _parse_proc_map.end()) return 0;
39 return it->second;
40}
41
42
43//internal private class that manages access to the public classes' internals. 24//internal private class that manages access to the public classes' internals.
44class _private { 25class _private {
45public: 26public:
@@ -1175,14 +1156,19 @@ bool error::operator < (const error &e) const {
1175 return m_begin.m_it < e.m_begin.m_it; 1156 return m_begin.m_it < e.m_begin.m_it;
1176} 1157}
1177 1158
1159rule::rule() :
1160 m_expr(nullptr),
1161 m_parse_proc(nullptr)
1162{
1163}
1178 1164
1179/** character terminal constructor. 1165/** character terminal constructor.
1180 @param c character. 1166 @param c character.
1181 */ 1167 */
1182rule::rule(char c) : 1168rule::rule(char c) :
1183 m_expr(new _char(c)) 1169 m_expr(new _char(c)),
1170 m_parse_proc(nullptr)
1184{ 1171{
1185 m_parse_proc = _get_parse_proc(this);
1186} 1172}
1187 1173
1188 1174
@@ -1190,9 +1176,9 @@ rule::rule(char c) :
1190 @param s null-terminated string. 1176 @param s null-terminated string.
1191 */ 1177 */
1192rule::rule(const char *s) : 1178rule::rule(const char *s) :
1193 m_expr(new _string(s)) 1179 m_expr(new _string(s)),
1180 m_parse_proc(nullptr)
1194{ 1181{
1195 m_parse_proc = _get_parse_proc(this);
1196} 1182}
1197 1183
1198 1184
@@ -1200,9 +1186,9 @@ rule::rule(const char *s) :
1200 @param e expression. 1186 @param e expression.
1201 */ 1187 */
1202rule::rule(const expr &e) : 1188rule::rule(const expr &e) :
1203 m_expr(_private::get_expr(e)) 1189 m_expr(_private::get_expr(e)),
1190 m_parse_proc(nullptr)
1204{ 1191{
1205 m_parse_proc = _get_parse_proc(this);
1206} 1192}
1207 1193
1208 1194
@@ -1211,11 +1197,19 @@ rule::rule(const expr &e) :
1211 */ 1197 */
1212rule::rule(rule &r) : 1198rule::rule(rule &r) :
1213 m_expr(new _ref(r)), 1199 m_expr(new _ref(r)),
1214 m_parse_proc(0) 1200 m_parse_proc(nullptr)
1215{ 1201{
1216 m_parse_proc = _get_parse_proc(this);
1217} 1202}
1218 1203
1204rule& rule::operator = (rule & r) {
1205 m_expr = new _ref(r);
1206 return *this;
1207}
1208
1209rule &rule::operator = (const expr & e) {
1210 m_expr = _private::get_expr(e);
1211 return *this;
1212}
1219 1213
1220/** invalid constructor from rule (required by gcc). 1214/** invalid constructor from rule (required by gcc).
1221 @exception std::logic_error always thrown. 1215 @exception std::logic_error always thrown.
@@ -1278,8 +1272,6 @@ expr rule::operator !() {
1278void rule::set_parse_proc(parse_proc p) { 1272void rule::set_parse_proc(parse_proc p) {
1279 assert(p); 1273 assert(p);
1280 m_parse_proc = p; 1274 m_parse_proc = p;
1281 _parse_proc_map_t& _parse_proc_map = _get_parse_proc_map();
1282 _parse_proc_map[this] = p;
1283} 1275}
1284 1276
1285 1277
diff --git a/src/MoonP/parser.hpp b/src/MoonP/parser.hpp
index 9739465..b419e8c 100644
--- a/src/MoonP/parser.hpp
+++ b/src/MoonP/parser.hpp
@@ -28,16 +28,13 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
28namespace parserlib { 28namespace parserlib {
29 29
30// const str hash helper functions 30// const str hash helper functions
31inline constexpr size_t hash(char const* input) 31inline constexpr size_t hash(char const* input) {
32{
33 return *input ? *input + 33ull * hash(input + 1) : 5381; 32 return *input ? *input + 33ull * hash(input + 1) : 5381;
34} 33}
35inline size_t hash(const char* input, int size, int index) 34inline size_t hash(const char* input, int size, int index) {
36{
37 return index < size ? input[index] + 33ull * hash(input, size, index + 1) : 5381; 35 return index < size ? input[index] + 33ull * hash(input, size, index + 1) : 5381;
38} 36}
39inline size_t constexpr operator"" _id(const char* s, size_t) 37inline size_t constexpr operator"" _id(const char* s, size_t) {
40{
41 return hash(s); 38 return hash(s);
42} 39}
43 40
@@ -52,8 +49,7 @@ class _context;
52class rule; 49class rule;
53 50
54 51
55struct item_t 52struct item_t {
56{
57 input_it begin; 53 input_it begin;
58 input_it end; 54 input_it end;
59 void* user_data; 55 void* user_data;
@@ -74,7 +70,7 @@ public:
74 int m_col; 70 int m_col;
75 71
76 ///null constructor. 72 ///null constructor.
77 pos():m_line(-1),m_col(0) {} 73 pos():m_line(0),m_col(0) {}
78 74
79 /** constructor from input. 75 /** constructor from input.
80 @param i input. 76 @param i input.
@@ -216,6 +212,7 @@ public:
216 /** character terminal constructor. 212 /** character terminal constructor.
217 @param c character. 213 @param c character.
218 */ 214 */
215 rule();
219 rule(char c); 216 rule(char c);
220 217
221 /** null-terminated string terminal constructor. 218 /** null-terminated string terminal constructor.
@@ -278,6 +275,10 @@ public:
278 */ 275 */
279 rule *this_ptr() { return this; } 276 rule *this_ptr() { return this; }
280 277
278 rule &operator = (rule &);
279
280 rule &operator = (const expr &);
281
281private: 282private:
282 //mode 283 //mode
283 enum _MODE { 284 enum _MODE {
@@ -308,9 +309,6 @@ private:
308 //state 309 //state
309 _state m_state; 310 _state m_state;
310 311
311 //assignment not allowed
312 rule &operator = (rule &);
313
314 friend class _private; 312 friend class _private;
315 friend class _context; 313 friend class _context;
316}; 314};
diff --git a/src/moonc.cpp b/src/moonc.cpp
index 4498bee..d04ce47 100644
--- a/src/moonc.cpp
+++ b/src/moonc.cpp
@@ -9,9 +9,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
9#include <iomanip> 9#include <iomanip>
10#include <fstream> 10#include <fstream>
11#include <chrono> 11#include <chrono>
12#include <future>
12#include "MoonP/moon_compiler.h" 13#include "MoonP/moon_compiler.h"
13#include "MoonP/parser.hpp" 14#include "MoonP/moon_parser.h"
14#include "MoonP/moon_ast.h"
15 15
16int main(int narg, const char** args) { 16int main(int narg, const char** args) {
17 const char* help = 17 const char* help =
@@ -82,87 +82,98 @@ int main(int narg, const char** args) {
82 std::cout << "Error: -o can not be used with multiple input files.\n"; 82 std::cout << "Error: -o can not be used with multiple input files.\n";
83 std::cout << help; 83 std::cout << help;
84 } 84 }
85 if (targetPath.back() != '/' && targetPath.back() != '\\') {
86 targetPath.append("/");
87 }
88 std::list<std::future<std::result_of_t<std::decay_t<int()>()>>> results;
85 for (const auto& file : files) { 89 for (const auto& file : files) {
86 std::ifstream input(file, input.in); 90 auto task = std::async(std::launch::async, [=]() {
87 if (input) { 91 std::ifstream input(file, input.in);
88 std::string s( 92 if (input) {
89 (std::istreambuf_iterator<char>(input)), 93 std::string s(
90 std::istreambuf_iterator<char>()); 94 (std::istreambuf_iterator<char>(input)),
91 if (dumpCompileTime) { 95 std::istreambuf_iterator<char>());
92 auto start = std::chrono::high_resolution_clock::now(); 96 if (dumpCompileTime) {
97 auto start = std::chrono::high_resolution_clock::now();
98 auto result = MoonP::moonCompile(s, config);
99 auto end = std::chrono::high_resolution_clock::now();
100 if (!std::get<0>(result).empty()) {
101 std::chrono::duration<double> diff = end - start;
102 start = std::chrono::high_resolution_clock::now();
103 MoonP::MoonParser{}.parse<MoonP::File_t>(s);
104 end = std::chrono::high_resolution_clock::now();
105 std::chrono::duration<double> parseDiff = end - start;
106 std::cout << file << " \n";
107 std::cout << "Parse time: " << std::setprecision(5) << parseDiff.count() * 1000 << " ms\n";
108 std::cout << "Compile time: " << std::setprecision(5) << (diff.count() - parseDiff.count()) * 1000 << " ms\n\n";
109 return 0;
110 } else {
111 std::cout << "Fail to compile: " << file << ".\n";
112 std::cout << std::get<1>(result) << '\n';
113 return 1;
114 }
115 }
93 auto result = MoonP::moonCompile(s, config); 116 auto result = MoonP::moonCompile(s, config);
94 auto end = std::chrono::high_resolution_clock::now();
95 if (!std::get<0>(result).empty()) { 117 if (!std::get<0>(result).empty()) {
96 std::chrono::duration<double> diff = end - start; 118 if (!writeToFile) {
97 error_list el; 119 std::cout << std::get<0>(result) << '\n';
98 MoonP::State st; 120 return 1;
99 start = std::chrono::high_resolution_clock::now(); 121 } else {
100 auto input = Converter{}.from_bytes(s); 122 std::string targetFile;
101 parserlib::parse<MoonP::File_t>(input, MoonP::File, el, &st); 123 if (resultFile.empty()) {
102 end = std::chrono::high_resolution_clock::now(); 124 std::string ext;
103 std::chrono::duration<double> parseDiff = end - start; 125 targetFile = file;
104 std::cout << file << " \n"; 126 size_t pos = file.rfind('.');
105 std::cout << "Parse time: " << std::setprecision(5) << parseDiff.count() * 1000 << " ms\n"; 127 if (pos != std::string::npos) {
106 std::cout << "Compile time: " << std::setprecision(5) << (diff.count() - parseDiff.count()) * 1000 << " ms\n\n"; 128 ext = file.substr(pos + 1);
107 } else { 129 for (size_t i = 0; i < ext.length(); i++) {
108 std::cout << "Fail to compile: " << file << ".\n"; 130 ext[i] = static_cast<char>(tolower(ext[i]));
109 std::cout << std::get<1>(result) << '\n'; 131 }
110 return 1; 132 targetFile = file.substr(0, pos) + ".lua";
111 }
112 continue;
113 }
114 auto result = MoonP::moonCompile(s, config);
115 if (!std::get<0>(result).empty()) {
116 if (!writeToFile) {
117 std::cout << std::get<0>(result) << '\n';
118 } else {
119 std::string targetFile;
120 if (resultFile.empty()) {
121 std::string ext;
122 targetFile = file;
123 size_t pos = file.rfind('.');
124 if (pos != std::string::npos) {
125 ext = file.substr(pos + 1);
126 for (size_t i = 0; i < ext.length(); i++) {
127 ext[i] = static_cast<char>(tolower(ext[i]));
128 }
129 targetFile = file.substr(0, pos) + ".lua";
130 }
131 if (!targetPath.empty()) {
132 std::string name;
133 pos = targetFile.find_last_of("/\\");
134 if (pos == std::string::npos) {
135 name = targetFile;
136 } else {
137 name = targetFile.substr(pos + 1);
138 } 133 }
139 if (targetPath.back() != '/' && targetPath.back() != '\\') { 134 if (!targetPath.empty()) {
140 targetPath.append("/"); 135 std::string name;
136 pos = targetFile.find_last_of("/\\");
137 if (pos == std::string::npos) {
138 name = targetFile;
139 } else {
140 name = targetFile.substr(pos + 1);
141 }
142 targetFile = targetPath + name;
141 } 143 }
142 targetFile = targetPath + name; 144 } else {
145 targetFile = resultFile;
146 }
147 std::ofstream output(targetFile, output.trunc | output.out);
148 if (output) {
149 const auto& codes = std::get<0>(result);
150 output.write(codes.c_str(), codes.size());
151 std::cout << "Built " << file << '\n';
152 return 0;
153 } else {
154 std::cout << "Fail to write file: " << targetFile << ".\n";
155 return 1;
143 } 156 }
144 } else {
145 targetFile = resultFile;
146 }
147 std::ofstream output(targetFile, output.trunc | output.out);
148 if (output) {
149 const auto& codes = std::get<0>(result);
150 output.write(codes.c_str(), codes.size());
151 std::cout << "Built " << file << '\n';
152 } else {
153 std::cout << "Fail to write file: " << targetFile << ".\n";
154 return 1;
155 } 157 }
158 } else {
159 std::cout << "Fail to compile: " << file << ".\n";
160 std::cout << std::get<1>(result) << '\n';
161 return 1;
156 } 162 }
157 } else { 163 } else {
158 std::cout << "Fail to compile: " << file << ".\n"; 164 std::cout << "Fail to read file: " << file << ".\n";
159 std::cout << std::get<1>(result) << '\n';
160 return 1; 165 return 1;
161 } 166 }
162 } else { 167 });
163 std::cout << "Fail to read file: " << file << ".\n"; 168 results.push_back(std::move(task));
164 return 1; 169 }
170 int ret = 0;
171 for (auto& result : results) {
172 int val = result.get();
173 if (val != 0) {
174 ret = val;
165 } 175 }
166 } 176 }
167 return 0; 177 return ret;
168} 178}
179