diff options
author | Li Jin <dragon-fly@qq.com> | 2020-01-30 16:06:32 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2020-01-30 16:06:32 +0800 |
commit | c62d9eb35a310e7663234526ce4b9fe3519ca7cf (patch) | |
tree | 56b4b418aadab90989e3e29e29e8ab7e04806e8d | |
parent | 240b1ec4a49128c00a787e6d0928865995b1d02e (diff) | |
download | yuescript-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.moon | 10 | ||||
-rw-r--r-- | src/MoonP/ast.cpp | 2 | ||||
-rw-r--r-- | src/MoonP/ast.hpp | 24 | ||||
-rw-r--r-- | src/MoonP/moon_ast.cpp | 120 | ||||
-rw-r--r-- | src/MoonP/moon_ast.h | 5 | ||||
-rw-r--r-- | src/MoonP/moon_compiler.cpp | 401 | ||||
-rw-r--r-- | src/MoonP/moon_parser.cpp | 972 | ||||
-rw-r--r-- | src/MoonP/moon_parser.h | 263 | ||||
-rw-r--r-- | src/MoonP/parser.cpp | 50 | ||||
-rw-r--r-- | src/MoonP/parser.hpp | 22 | ||||
-rw-r--r-- | src/moonc.cpp | 155 |
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 = -> | |||
31 | 998 |> func0("abc", 233) |> func1 |> func2 | 31 | 998 |> func0("abc", 233) |> func1 |> func2 |
32 | 32 | ||
33 | do | 33 | do |
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 | ||
41 | do | 41 | do |
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 | */ |
118 | ast_node* _parse(input &i, rule &g, error_list &el, void* ud) { | 118 | ast_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 | |||
526 | private: | 525 | private: |
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 | */ |
547 | ast_node* _parse(input& i, rule& g, error_list& el, void* ud); | 546 | ast_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 | */ | ||
557 | template <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 | |||
3 | Permission 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 | |||
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
6 | |||
7 | THE 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 | |||
11 | namespace MoonP { | ||
12 | |||
13 | #define AST_IMPL(type) \ | ||
14 | ast<type##_t> __##type##_t(type); | ||
15 | |||
16 | AST_IMPL(Num) | ||
17 | AST_IMPL(Name) | ||
18 | AST_IMPL(Variable) | ||
19 | AST_IMPL(LuaKeyword) | ||
20 | AST_IMPL(self) | ||
21 | AST_IMPL(self_name) | ||
22 | AST_IMPL(self_class) | ||
23 | AST_IMPL(self_class_name) | ||
24 | AST_IMPL(SelfName) | ||
25 | AST_IMPL(KeyName) | ||
26 | AST_IMPL(VarArg) | ||
27 | AST_IMPL(local_flag) | ||
28 | AST_IMPL(Seperator) | ||
29 | AST_IMPL(NameList) | ||
30 | AST_IMPL(Local) | ||
31 | AST_IMPL(colon_import_name) | ||
32 | AST_IMPL(import_literal_inner) | ||
33 | AST_IMPL(ImportLiteral) | ||
34 | AST_IMPL(ImportFrom) | ||
35 | AST_IMPL(ImportAs) | ||
36 | AST_IMPL(Import) | ||
37 | AST_IMPL(Backcall) | ||
38 | AST_IMPL(ExpListLow) | ||
39 | AST_IMPL(ExpList) | ||
40 | AST_IMPL(Return) | ||
41 | AST_IMPL(With) | ||
42 | AST_IMPL(SwitchCase) | ||
43 | AST_IMPL(Switch) | ||
44 | AST_IMPL(IfCond) | ||
45 | AST_IMPL(If) | ||
46 | AST_IMPL(Unless) | ||
47 | AST_IMPL(While) | ||
48 | AST_IMPL(for_step_value) | ||
49 | AST_IMPL(For) | ||
50 | AST_IMPL(ForEach) | ||
51 | AST_IMPL(Do) | ||
52 | AST_IMPL(Comprehension) | ||
53 | AST_IMPL(comp_value) | ||
54 | AST_IMPL(TblComprehension) | ||
55 | AST_IMPL(star_exp) | ||
56 | AST_IMPL(CompForEach) | ||
57 | AST_IMPL(CompFor) | ||
58 | AST_IMPL(CompInner) | ||
59 | AST_IMPL(Assign) | ||
60 | AST_IMPL(update_op) | ||
61 | AST_IMPL(Update) | ||
62 | AST_IMPL(BinaryOperator) | ||
63 | AST_IMPL(BackcallOperator) | ||
64 | AST_IMPL(Assignable) | ||
65 | AST_IMPL(AssignableChain) | ||
66 | AST_IMPL(exp_op_value) | ||
67 | AST_IMPL(Exp) | ||
68 | AST_IMPL(Callable) | ||
69 | AST_IMPL(ChainValue) | ||
70 | AST_IMPL(simple_table) | ||
71 | AST_IMPL(SimpleValue) | ||
72 | AST_IMPL(Value) | ||
73 | AST_IMPL(LuaStringOpen); | ||
74 | AST_IMPL(LuaStringContent); | ||
75 | AST_IMPL(LuaStringClose); | ||
76 | AST_IMPL(LuaString) | ||
77 | AST_IMPL(SingleString) | ||
78 | AST_IMPL(double_string_inner) | ||
79 | AST_IMPL(double_string_content) | ||
80 | AST_IMPL(DoubleString) | ||
81 | AST_IMPL(String) | ||
82 | AST_IMPL(Parens) | ||
83 | AST_IMPL(DotChainItem) | ||
84 | AST_IMPL(ColonChainItem) | ||
85 | AST_IMPL(default_value) | ||
86 | AST_IMPL(Slice) | ||
87 | AST_IMPL(Invoke) | ||
88 | AST_IMPL(existential_op) | ||
89 | AST_IMPL(TableLit) | ||
90 | AST_IMPL(TableBlock) | ||
91 | AST_IMPL(class_member_list) | ||
92 | AST_IMPL(ClassBlock) | ||
93 | AST_IMPL(ClassDecl) | ||
94 | AST_IMPL(export_values) | ||
95 | AST_IMPL(export_op) | ||
96 | AST_IMPL(Export) | ||
97 | AST_IMPL(variable_pair) | ||
98 | AST_IMPL(normal_pair) | ||
99 | AST_IMPL(FnArgDef) | ||
100 | AST_IMPL(FnArgDefList) | ||
101 | AST_IMPL(outer_var_shadow) | ||
102 | AST_IMPL(FnArgsDef) | ||
103 | AST_IMPL(fn_arrow) | ||
104 | AST_IMPL(FunLit) | ||
105 | AST_IMPL(NameOrDestructure) | ||
106 | AST_IMPL(AssignableNameList) | ||
107 | AST_IMPL(InvokeArgs) | ||
108 | AST_IMPL(const_value) | ||
109 | AST_IMPL(unary_exp) | ||
110 | AST_IMPL(ExpListAssign) | ||
111 | AST_IMPL(if_else_line) | ||
112 | AST_IMPL(unless_line) | ||
113 | AST_IMPL(statement_appendix) | ||
114 | AST_IMPL(BreakLoop) | ||
115 | AST_IMPL(Statement) | ||
116 | AST_IMPL(Body) | ||
117 | AST_IMPL(Block) | ||
118 | AST_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" |
12 | using namespace parserlib; | ||
12 | 13 | ||
13 | namespace MoonP { | 14 | namespace MoonP { |
14 | 15 | ||
15 | #define AST_LEAF(type, id) \ | 16 | #define AST_LEAF(type, id) \ |
16 | extern rule type; \ | ||
17 | class type##_t : public ast_node \ | 17 | class type##_t : public ast_node \ |
18 | { \ | 18 | { \ |
19 | public: \ | 19 | public: \ |
@@ -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) \ |
24 | extern rule type; \ | ||
25 | class type##_t : public ast_container \ | 24 | class type##_t : public ast_container \ |
26 | { \ | 25 | { \ |
27 | public: \ | 26 | public: \ |
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> | ||
18 | using 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 | ||
23 | namespace MoonP { | 19 | namespace MoonP { |
@@ -40,25 +36,12 @@ class MoonCompiler { | |||
40 | public: | 36 | public: |
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 | } |
99 | private: | 75 | private: |
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 | ||
13 | namespace MoonP { | 13 | namespace MoonP { |
14 | 14 | ||
15 | std::unordered_set<std::string> State::luaKeywords = { | 15 | std::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 | ||
23 | std::unordered_set<std::string> State::keywords = { | 23 | std::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 | ||
34 | rule plain_space = *set(" \t"); | 34 | MoonParser::MoonParser() { |
35 | rule Break = nl(-expr('\r') >> '\n'); | 35 | plain_space = *set(" \t"); |
36 | rule Any = Break | any(); | 36 | Break = nl(-expr('\r') >> '\n'); |
37 | rule White = *(set(" \t") | Break); | 37 | Any = Break | any(); |
38 | rule Stop = Break | eof(); | 38 | White = *(set(" \t") | Break); |
39 | rule Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); | 39 | Stop = Break | eof(); |
40 | rule multi_line_open = expr("--[["); | 40 | Comment = "--" >> *(not_(set("\r\n")) >> Any) >> and_(Stop); |
41 | rule multi_line_close = expr("]]"); | 41 | multi_line_open = expr("--[["); |
42 | rule multi_line_content = *(not_(multi_line_close) >> Any); | 42 | multi_line_close = expr("]]"); |
43 | rule MultiLineComment = multi_line_open >> multi_line_content >> multi_line_close; | 43 | multi_line_content = *(not_(multi_line_close) >> Any); |
44 | rule Indent = plain_space; | 44 | MultiLineComment = multi_line_open >> multi_line_content >> multi_line_close; |
45 | rule EscapeNewLine = expr('\\') >> plain_space >> -Comment >> Break; | 45 | Indent = plain_space; |
46 | rule Space = *(set(" \t") | MultiLineComment | EscapeNewLine) >> -Comment; | 46 | EscapeNewLine = expr('\\') >> plain_space >> -Comment >> Break; |
47 | rule SomeSpace = +set(" \t") >> -Comment; | 47 | Space = *(set(" \t") | MultiLineComment | EscapeNewLine) >> -Comment; |
48 | rule SpaceBreak = Space >> Break; | 48 | SomeSpace = +set(" \t") >> -Comment; |
49 | rule EmptyLine = SpaceBreak; | 49 | SpaceBreak = Space >> Break; |
50 | rule AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_'; | 50 | EmptyLine = SpaceBreak; |
51 | rule Name = (range('a', 'z') | range('A', 'Z') | '_') >> *AlphaNum; | 51 | AlphaNum = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_'; |
52 | rule 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 | ) | ( |
65 | rule Cut = false_(); | 59 | +range('0', '9') >> -set("uU") >> set("lL") >> set("lL") |
66 | rule 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_(); | |
73 | rule 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) { | |
81 | rule 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) { | |
89 | rule self = expr('@'); | 83 | State* st = reinterpret_cast<State*>(item.user_data); |
90 | rule self_name = '@' >> Name; | 84 | for (auto it = item.begin; it != item.end; ++it) st->buffer += static_cast<char>(*it); |
91 | rule self_class = expr("@@"); | 85 | auto it = LuaKeywords.find(st->buffer); |
92 | rule self_class_name = "@@" >> Name; | 86 | st->buffer.clear(); |
93 | 87 | return it != LuaKeywords.end(); | |
94 | rule SelfName = Space >> (self_class_name | self_class | self_name | self); | 88 | }); |
95 | rule KeyName = SelfName | Space >> Name; | 89 | |
96 | rule VarArg = Space >> "..."; | 90 | self = expr('@'); |
97 | 91 | self_name = '@' >> Name; | |
98 | rule 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); |
109 | rule CheckIndent = and_(check_indent); | 111 | |
110 | 112 | advance = pl::user(Indent, [](const item_t& item) { | |
111 | rule 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 | }); | ||
127 | rule Advance = and_(advance); | ||
128 | |||
129 | rule 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 | }); | ||
141 | rule PushIndent = and_(push_indent); | ||
142 | |||
143 | rule 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 | |||
149 | rule 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 | |||
155 | extern rule Block; | ||
156 | |||
157 | rule InBlock = Advance >> Block >> PopIndent; | ||
158 | |||
159 | extern rule NameList; | ||
160 | |||
161 | rule local_flag = expr('*') | expr('^'); | ||
162 | rule Local = key("local") >> ((Space >> local_flag) | NameList); | ||
163 | |||
164 | rule colon_import_name = sym('\\') >> Space >> Variable; | ||
165 | rule ImportName = colon_import_name | Space >> Variable; | ||
166 | rule ImportNameList = Seperator >> *SpaceBreak >> ImportName >> *((+SpaceBreak | sym(',') >> *SpaceBreak) >> ImportName); | ||
167 | |||
168 | extern rule Exp, TableLit; | ||
169 | |||
170 | rule import_literal_inner = (range('a', 'z') | range('A', 'Z') | set("_-")) >> *(AlphaNum | '-'); | ||
171 | rule import_literal_chain = Seperator >> import_literal_inner >> *(expr('.') >> import_literal_inner); | ||
172 | rule ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"'); | ||
173 | |||
174 | rule ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp; | ||
175 | rule ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | TableLit)); | ||
176 | |||
177 | rule Import = key("import") >> (ImportAs | ImportFrom); | ||
178 | rule BreakLoop = (expr("break") | expr("continue")) >> not_(AlphaNum); | ||
179 | |||
180 | extern rule ExpListLow, ExpList, Assign; | ||
181 | |||
182 | rule Return = key("return") >> -ExpListLow; | ||
183 | rule WithExp = ExpList >> -Assign; | ||
184 | |||
185 | extern rule DisableDo, PopDo, Body; | ||
186 | |||
187 | rule With = key("with") >> DisableDo >> ensure(WithExp, PopDo) >> -key("do") >> Body; | ||
188 | rule SwitchCase = key("when") >> ExpList >> -key("then") >> Body; | ||
189 | rule SwitchElse = key("else") >> Body; | ||
190 | |||
191 | rule SwitchBlock = *EmptyLine >> | ||
192 | Advance >> Seperator >> | ||
193 | SwitchCase >> | ||
194 | *(+SpaceBreak >> SwitchCase) >> | ||
195 | -(+SpaceBreak >> SwitchElse) >> | ||
196 | PopIndent; | ||
197 | |||
198 | rule Switch = key("switch") >> | ||
199 | DisableDo >> ensure(Exp, PopDo) >> | ||
200 | -key("do") >> -Space >> Break >> SwitchBlock; | ||
201 | |||
202 | rule IfCond = Exp >> -Assign; | ||
203 | rule IfElseIf = -(Break >> *EmptyLine >> CheckIndent) >> key("elseif") >> IfCond >> -key("then") >> Body; | ||
204 | rule IfElse = -(Break >> *EmptyLine >> CheckIndent) >> key("else") >> Body; | ||
205 | rule If = key("if") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; | ||
206 | rule Unless = key("unless") >> Seperator >> IfCond >> -key("then") >> Body >> *IfElseIf >> -IfElse; | ||
207 | |||
208 | rule While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; | ||
209 | |||
210 | rule for_step_value = sym(',') >> Exp; | ||
211 | rule for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; | ||
212 | |||
213 | rule For = key("for") >> DisableDo >> | ||
214 | ensure(for_args, PopDo) >> | ||
215 | -key("do") >> Body; | ||
216 | |||
217 | extern rule AssignableNameList; | ||
218 | 143 | ||
219 | extern rule star_exp; | 144 | PreventIndent = pl::user(true_(), [](const item_t& item) { |
220 | 145 | State* st = reinterpret_cast<State*>(item.user_data); | |
221 | rule for_in = star_exp | ExpList; | 146 | st->indents.push(-1); |
222 | 147 | return true; | |
223 | rule ForEach = key("for") >> AssignableNameList >> key("in") >> | 148 | }); |
224 | DisableDo >> ensure(for_in, PopDo) >> | ||
225 | -key("do") >> Body; | ||
226 | |||
227 | rule 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 | |||
233 | rule 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 | ||
240 | rule 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 | ||
247 | extern rule CompInner; | 156 | InBlock = Advance >> Block >> PopIndent; |
248 | 157 | ||
249 | rule Comprehension = sym('[') >> Exp >> CompInner >> sym(']'); | 158 | local_flag = expr('*') | expr('^'); |
250 | rule comp_value = sym(',') >> Exp; | 159 | Local = key("local") >> ((Space >> local_flag) | NameList); |
251 | rule TblComprehension = sym('{') >> (Exp >> -comp_value) >> CompInner >> sym('}'); | ||
252 | 160 | ||
253 | extern 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 | ||
255 | rule CompInner = Seperator >> (CompForEach | CompFor) >> *CompClause; | 165 | import_literal_inner = (range('a', 'z') | range('A', 'Z') | set("_-")) >> *(AlphaNum | '-'); |
256 | rule star_exp = sym('*') >> Exp; | 166 | import_literal_chain = Seperator >> import_literal_inner >> *(expr('.') >> import_literal_inner); |
257 | rule CompForEach = key("for") >> AssignableNameList >> key("in") >> (star_exp | Exp); | 167 | ImportLiteral = sym('\'') >> import_literal_chain >> symx('\'') | sym('"') >> import_literal_chain >> symx('"'); |
258 | rule CompFor = key("for") >> Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; | ||
259 | rule CompClause = CompFor | CompForEach | key("when") >> Exp; | ||
260 | 168 | ||
261 | extern rule TableBlock; | 169 | ImportFrom = ImportNameList >> *SpaceBreak >> key("from") >> Exp; |
170 | ImportAs = ImportLiteral >> -(key("as") >> (Space >> Variable | TableLit)); | ||
262 | 171 | ||
263 | rule 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 | ||
265 | rule 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 | ||
279 | rule 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 | ||
281 | rule 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 | |||
295 | rule BackcallOperator = expr("|>"); | ||
296 | |||
297 | extern rule AssignableChain; | ||
298 | |||
299 | rule Assignable = AssignableChain | Space >> Variable | SelfName; | ||
300 | |||
301 | extern rule Value; | ||
302 | |||
303 | rule exp_op_value = Space >> (BackcallOperator | BinaryOperator) >> *SpaceBreak >> Value; | ||
304 | rule Exp = Value >> *exp_op_value; | ||
305 | 188 | ||
306 | extern rule Chain, Callable, InvokeArgs, existential_op; | 189 | Switch = key("switch") >> |
190 | DisableDo >> ensure(Exp, PopDo) >> | ||
191 | -key("do") >> -Space >> Break >> SwitchBlock; | ||
307 | 192 | ||
308 | rule 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 | ||
310 | extern rule KeyValue, String, SimpleValue; | 199 | While = key("while") >> DisableDo >> ensure(Exp, PopDo) >> -key("do") >> Body; |
311 | |||
312 | rule simple_table = Seperator >> KeyValue >> *(sym(',') >> KeyValue); | ||
313 | rule Value = SimpleValue | simple_table | ChainValue | String; | ||
314 | |||
315 | extern rule LuaString; | ||
316 | 200 | ||
317 | rule single_string_inner = expr("\\'") | "\\\\" | not_(expr('\'')) >> Any; | 201 | for_step_value = sym(',') >> Exp; |
318 | rule SingleString = symx('\'') >> *single_string_inner >> symx('\''); | 202 | for_args = Space >> Variable >> sym('=') >> Exp >> sym(',') >> Exp >> -for_step_value; |
319 | rule interp = symx("#{") >> Exp >> sym('}'); | ||
320 | rule double_string_plain = expr("\\\"") | "\\\\" | not_(expr('"')) >> Any; | ||
321 | rule double_string_inner = +(not_(interp) >> double_string_plain); | ||
322 | rule double_string_content = double_string_inner | interp; | ||
323 | rule DoubleString = symx('"') >> Seperator >> *double_string_content >> symx('"'); | ||
324 | rule String = Space >> (DoubleString | SingleString | LuaString); | ||
325 | |||
326 | rule lua_string_open = '[' >> *expr('=') >> '['; | ||
327 | rule lua_string_close = ']' >> *expr('=') >> ']'; | ||
328 | |||
329 | rule 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 | |||
337 | rule 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 | ||
344 | rule LuaStringContent = *(not_(LuaStringClose) >> Any); | 204 | For = key("for") >> DisableDo >> |
205 | ensure(for_args, PopDo) >> | ||
206 | -key("do") >> Body; | ||
345 | 207 | ||
346 | rule 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 | |||
353 | rule Parens = sym('(') >> *SpaceBreak >> Exp >> *SpaceBreak >> sym(')'); | ||
354 | rule Callable = Space >> Variable | SelfName | VarArg | Parens; | ||
355 | rule FnArgsExpList = Exp >> *((Break | sym(',')) >> White >> Exp); | ||
356 | |||
357 | rule FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) | | ||
358 | (sym('!') >> not_(expr('='))); | ||
359 | |||
360 | extern rule ChainItems, DotChainItem, ColonChain; | ||
361 | |||
362 | rule existential_op = expr('?'); | ||
363 | rule chain_call = (Callable | String) >> -existential_op >> ChainItems; | ||
364 | rule chain_item = and_(set(".\\")) >> ChainItems; | ||
365 | rule chain_dot_chain = DotChainItem >> -existential_op >> -ChainItems; | ||
366 | |||
367 | rule Chain = chain_call | chain_item | | ||
368 | Space >> (chain_dot_chain | ColonChain); | ||
369 | |||
370 | rule AssignableChain = Seperator >> Chain; | ||
371 | 209 | ||
372 | extern rule ChainItem; | 210 | ForEach = key("for") >> AssignableNameList >> key("in") >> |
211 | DisableDo >> ensure(for_in, PopDo) >> | ||
212 | -key("do") >> Body; | ||
373 | 213 | ||
374 | rule chain_with_colon = +ChainItem >> -ColonChain; | 214 | Do = pl::user(key("do") >> Body, [](const item_t& item) |
375 | rule 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 | ||
377 | extern 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 | ||
379 | rule Index = symx('[') >> Exp >> sym(']'); | 227 | PopDo = pl::user(true_(), [](const item_t& item) |
380 | rule ChainItem = Invoke >> -existential_op | DotChainItem >> -existential_op | Slice | Index >> -existential_op; | 228 | { |
381 | rule DotChainItem = symx('.') >> Name; | 229 | State* st = reinterpret_cast<State*>(item.user_data); |
382 | rule ColonChainItem = symx('\\') >> (LuaKeyword | Name); | 230 | st->doStack.pop(); |
383 | rule invoke_chain = Invoke >> -existential_op >> -ChainItems; | 231 | return true; |
384 | rule 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 | ||
386 | rule default_value = true_(); | 307 | LuaStringClose = pl::user(lua_string_close, [](const item_t& item) { |
387 | rule 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 | ||
395 | rule Invoke = Seperator >> ( | 313 | LuaStringContent = *(not_(LuaStringClose) >> Any); |
396 | FnArgs | | ||
397 | SingleString | | ||
398 | DoubleString | | ||
399 | and_(expr('[')) >> LuaString); | ||
400 | 314 | ||
401 | extern 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 | ||
403 | rule 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 | ||
405 | rule table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(','); | 325 | FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) | |
326 | (sym('!') >> not_(expr('='))); | ||
406 | 327 | ||
407 | rule 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 | |||
414 | rule TableValueList = TableValue >> *(sym(',') >> TableValue); | ||
415 | |||
416 | rule TableLitLine = | ||
417 | ( | ||
418 | PushIndent >> (TableValueList >> PopIndent | PopIndent) | ||
419 | ) | ( | ||
420 | Space | ||
421 | ); | ||
422 | 332 | ||
423 | extern rule KeyValueLine; | 333 | Chain = chain_call | chain_item | |
334 | Space >> (chain_dot_chain | ColonChain); | ||
424 | 335 | ||
425 | rule TableBlockInner = Seperator >> KeyValueLine >> *(+(SpaceBreak) >> KeyValueLine); | 336 | AssignableChain = Seperator >> Chain; |
426 | rule TableBlock = +(SpaceBreak) >> Advance >> ensure(TableBlockInner, PopIndent); | ||
427 | 337 | ||
428 | extern rule Statement; | 338 | chain_with_colon = +ChainItem >> -ColonChain; |
429 | 339 | ChainItems = chain_with_colon | ColonChain; | |
430 | rule class_member_list = Seperator >> KeyValue >> *(sym(',') >> KeyValue); | ||
431 | rule ClassLine = CheckIndent >> (class_member_list | Statement) >> -sym(','); | ||
432 | rule ClassBlock = +(SpaceBreak) >> Advance >>Seperator >> ClassLine >> *(+(SpaceBreak) >> ClassLine) >> PopIndent; | ||
433 | 340 | ||
434 | rule 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 | ||
440 | rule export_values = NameList >> -(sym('=') >> ExpListLow); | 348 | default_value = true_(); |
441 | rule export_op = expr('*') | expr('^'); | 349 | Slice = |
442 | rule 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 | ||
444 | rule variable_pair = sym(':') >> not_(SomeSpace) >> Space >> Variable; | 357 | Invoke = Seperator >> ( |
358 | FnArgs | | ||
359 | SingleString | | ||
360 | DoubleString | | ||
361 | and_(expr('[')) >> LuaString); | ||
445 | 362 | ||
446 | rule normal_pair = | 363 | TableValue = KeyValue | Exp; |
447 | ( | ||
448 | KeyName | | ||
449 | sym('[') >> Exp >> sym(']') | | ||
450 | Space >> DoubleString | | ||
451 | Space >> SingleString | ||
452 | ) >> | ||
453 | symx(':') >> | ||
454 | (Exp | TableBlock | +(SpaceBreak) >> Exp); | ||
455 | 364 | ||
456 | rule KeyValue = variable_pair | normal_pair; | 365 | table_lit_lines = SpaceBreak >> TableLitLine >> *(-sym(',') >> SpaceBreak >> TableLitLine) >> -sym(','); |
457 | 366 | ||
458 | rule KeyValueList = KeyValue >> *(sym(',') >> KeyValue); | 367 | TableLit = |
459 | rule KeyValueLine = CheckIndent >> KeyValueList >> -sym(','); | 368 | sym('{') >> Seperator >> |
369 | -TableValueList >> | ||
370 | -sym(',') >> | ||
371 | -table_lit_lines >> | ||
372 | White >> sym('}'); | ||
460 | 373 | ||
461 | rule FnArgDef = (Space >> Variable | SelfName) >> -(sym('=') >> Exp); | 374 | TableValueList = TableValue >> *(sym(',') >> TableValue); |
462 | 375 | ||
463 | rule 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 | |||
474 | rule outer_var_shadow = key("using") >> (NameList | Space >> expr("nil")); | ||
475 | |||
476 | rule FnArgsDef = sym('(') >> White >> -FnArgDefList >> -outer_var_shadow >> White >> sym(')'); | ||
477 | rule fn_arrow = expr("->") | expr("=>"); | ||
478 | rule FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body; | ||
479 | |||
480 | rule NameList = Seperator >> Space >> Variable >> *(sym(',') >> Space >> Variable); | ||
481 | rule NameOrDestructure = Space >> Variable | TableLit; | ||
482 | rule AssignableNameList = Seperator >> NameOrDestructure >> *(sym(',') >> NameOrDestructure); | ||
483 | |||
484 | rule Backcall = -FnArgsDef >> Space >> symx("<-") >> Space >> ChainValue; | ||
485 | |||
486 | rule ExpList = Seperator >> Exp >> *(sym(',') >> Exp); | ||
487 | rule ExpListLow = Seperator >> Exp >> *((sym(',') | sym(';')) >> Exp); | ||
488 | |||
489 | rule ArgLine = CheckIndent >> Exp >> *(sym(',') >> Exp); | ||
490 | rule ArgBlock = ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent; | ||
491 | |||
492 | rule invoke_args_with_table = | ||
493 | sym(',') >> | ||
494 | ( | ||
495 | TableBlock | | ||
496 | SpaceBreak >> Advance >> ArgBlock >> -TableBlock | ||
497 | ); | 380 | ); |
498 | 381 | ||
499 | rule 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 | ||
506 | rule const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum); | 427 | outer_var_shadow = key("using") >> (NameList | Space >> expr("nil")); |
507 | rule minus_exp = expr('-') >> not_(SomeSpace) >> Exp; | 428 | |
508 | rule sharp_exp = expr('#') >> Exp; | 429 | FnArgsDef = sym('(') >> White >> -FnArgDefList >> -outer_var_shadow >> White >> sym(')'); |
509 | rule tilde_exp = expr('~') >> Exp; | 430 | fn_arrow = expr("->") | expr("=>"); |
510 | rule not_exp = expr("not") >> not_(AlphaNum) >> Exp; | 431 | FunLit = -FnArgsDef >> Space >> fn_arrow >> -Body; |
511 | rule unary_exp = minus_exp | sharp_exp | tilde_exp | not_exp; | 432 | |
512 | 433 | NameList = Seperator >> Space >> Variable >> *(sym(',') >> Space >> Variable); | |
513 | rule 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); | |
520 | rule ExpListAssign = ExpList >> -(Update | Assign); | 441 | |
521 | 442 | ArgLine = CheckIndent >> Exp >> *(sym(',') >> Exp); | |
522 | rule if_else_line = key("if") >> Exp >> -Assign >> (key("else") >> Exp | default_value); | 443 | ArgBlock = ArgLine >> *(sym(',') >> SpaceBreak >> ArgLine) >> PopIndent; |
523 | rule unless_line = key("unless") >> Exp; | 444 | |
524 | 445 | invoke_args_with_table = | |
525 | rule statement_appendix = (if_else_line | unless_line | CompInner) >> Space; | 446 | sym(',') >> |
526 | rule 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 | ( | |
534 | rule Body = -Space >> Break >> *EmptyLine >> InBlock | Statement; | 455 | Exp >> *(sym(',') >> Exp) >> -(invoke_args_with_table | TableBlock) | |
535 | 456 | TableBlock | |
536 | rule empty_line_stop = Space >> and_(Stop); | 457 | ); |
537 | rule Line = CheckIndent >> Statement | empty_line_stop; | 458 | |
538 | rule Block = Seperator >> Line >> *(+Break >> Line); | 459 | const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum); |
539 | 460 | minus_exp = expr('-') >> not_(SomeSpace) >> Exp; | |
540 | rule Shebang = expr("#!") >> *(not_(Stop) >> Any); | 461 | sharp_exp = expr('#') >> Exp; |
541 | rule 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 | |||
496 | ParseInfo 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 | |||
531 | std::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 | |||
535 | std::string MoonParser::toString(input::iterator begin, input::iterator end) { | ||
536 | return _converter.to_bytes(std::wstring(begin, end)); | ||
537 | } | ||
538 | |||
539 | input MoonParser::encode(std::string_view input) { | ||
540 | return _converter.from_bytes(std::string(input)); | ||
541 | } | ||
542 | |||
543 | std::string MoonParser::decode(const input& input) { | ||
544 | return _converter.to_bytes(input); | ||
545 | } | ||
546 | |||
547 | namespace 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 | |||
557 | std::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> | ||
18 | using namespace std::string_view_literals; | ||
17 | #include "MoonP/ast.hpp" | 19 | #include "MoonP/ast.hpp" |
18 | using namespace parserlib; | 20 | #include "MoonP/moon_ast.h" |
19 | 21 | ||
20 | namespace MoonP { | 22 | namespace MoonP { |
21 | 23 | ||
22 | struct State { | 24 | struct 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 | |||
36 | extern std::unordered_set<std::string> LuaKeywords; | ||
37 | extern std::unordered_set<std::string> Keywords; | ||
38 | |||
39 | class MoonParser { | ||
40 | public: | ||
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 | |||
65 | protected: | ||
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 | |||
79 | private: | ||
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 | |||
270 | namespace 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 | |||
21 | namespace parserlib { | 21 | namespace parserlib { |
22 | 22 | ||
23 | 23 | ||
24 | //internal map from rules to parse procs | ||
25 | typedef std::unordered_map<rule *, parse_proc> _parse_proc_map_t; | ||
26 | |||
27 | //on exit, it deletes the parse proc map | ||
28 | static _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 | ||
35 | static 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. |
44 | class _private { | 25 | class _private { |
45 | public: | 26 | public: |
@@ -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 | ||
1159 | rule::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 | */ |
1182 | rule::rule(char c) : | 1168 | rule::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 | */ |
1192 | rule::rule(const char *s) : | 1178 | rule::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 | */ |
1202 | rule::rule(const expr &e) : | 1188 | rule::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 | */ |
1212 | rule::rule(rule &r) : | 1198 | rule::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 | ||
1204 | rule& rule::operator = (rule & r) { | ||
1205 | m_expr = new _ref(r); | ||
1206 | return *this; | ||
1207 | } | ||
1208 | |||
1209 | rule &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 !() { | |||
1278 | void rule::set_parse_proc(parse_proc p) { | 1272 | void 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 | |||
28 | namespace parserlib { | 28 | namespace parserlib { |
29 | 29 | ||
30 | // const str hash helper functions | 30 | // const str hash helper functions |
31 | inline constexpr size_t hash(char const* input) | 31 | inline 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 | } |
35 | inline size_t hash(const char* input, int size, int index) | 34 | inline 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 | } |
39 | inline size_t constexpr operator"" _id(const char* s, size_t) | 37 | inline 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; | |||
52 | class rule; | 49 | class rule; |
53 | 50 | ||
54 | 51 | ||
55 | struct item_t | 52 | struct 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 | |||
281 | private: | 282 | private: |
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 | ||
16 | int main(int narg, const char** args) { | 16 | int 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 | |||