aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2023-06-29 10:58:56 +0800
committerLi Jin <dragon-fly@qq.com>2023-06-29 10:58:56 +0800
commitc98c6053635ddfca7aab15b268b0f2c1fcc0c6ef (patch)
treedcacf24e010346eb03e834d8081eb81e26f5c7ff
parent51faef5288a64a84b8f8e5cea8631c7518b94411 (diff)
downloadyuescript-c98c6053635ddfca7aab15b268b0f2c1fcc0c6ef.tar.gz
yuescript-c98c6053635ddfca7aab15b268b0f2c1fcc0c6ef.tar.bz2
yuescript-c98c6053635ddfca7aab15b268b0f2c1fcc0c6ef.zip
fix issue #139.
-rw-r--r--CMakeLists.txt6
-rw-r--r--makefile4
-rw-r--r--spec/inputs/goto.yue8
-rw-r--r--spec/inputs/import.yue2
-rw-r--r--spec/outputs/import.lua34
-rw-r--r--src/yuescript/ast.cpp10
-rw-r--r--src/yuescript/ast.hpp34
-rw-r--r--src/yuescript/yue_ast.cpp1239
-rw-r--r--src/yuescript/yue_ast.h28
-rw-r--r--src/yuescript/yue_compiler.cpp259
-rw-r--r--src/yuescript/yue_parser.h296
-rw-r--r--src/yuescript/yuescript.cpp6
12 files changed, 1585 insertions, 341 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3ecec9a..8d5908f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -61,6 +61,7 @@ endif ()
61add_library(libyue MODULE 61add_library(libyue MODULE
62 src/yuescript/ast.cpp 62 src/yuescript/ast.cpp
63 src/yuescript/parser.cpp 63 src/yuescript/parser.cpp
64 src/yuescript/yue_ast.cpp
64 src/yuescript/yue_parser.cpp 65 src/yuescript/yue_parser.cpp
65 src/yuescript/yue_compiler.cpp 66 src/yuescript/yue_compiler.cpp
66 src/yuescript/yuescript.cpp 67 src/yuescript/yuescript.cpp
@@ -71,10 +72,11 @@ target_link_libraries(libyue ${LUA_LIBRARIES})
71 72
72add_executable(yue 73add_executable(yue
73 src/yuescript/ast.cpp 74 src/yuescript/ast.cpp
74 src/yuescript/yue_compiler.cpp 75 src/yuescript/parser.cpp
76 src/yuescript/yue_ast.cpp
75 src/yuescript/yue_parser.cpp 77 src/yuescript/yue_parser.cpp
78 src/yuescript/yue_compiler.cpp
76 src/yuescript/yuescript.cpp 79 src/yuescript/yuescript.cpp
77 src/yuescript/parser.cpp
78 src/yue.cpp 80 src/yue.cpp
79) 81)
80 82
diff --git a/makefile b/makefile
index 6bd5f16..77b3eca 100644
--- a/makefile
+++ b/makefile
@@ -211,7 +211,7 @@ endif
211wasm: clean 211wasm: clean
212 @$(MAKE) generic CC='emcc' AR='emar rcu' RANLIB='emranlib' -C $(SRC_PATH)/3rdParty/lua 212 @$(MAKE) generic CC='emcc' AR='emar rcu' RANLIB='emranlib' -C $(SRC_PATH)/3rdParty/lua
213 @mkdir -p doc/docs/.vuepress/public/js 213 @mkdir -p doc/docs/.vuepress/public/js
214 @emcc $(SRC_PATH)/yue_wasm.cpp $(SRC_PATH)/yuescript/ast.cpp $(SRC_PATH)/yuescript/parser.cpp $(SRC_PATH)/yuescript/yue_compiler.cpp $(SRC_PATH)/yuescript/yue_parser.cpp $(SRC_PATH)/yuescript/yuescript.cpp $(SRC_PATH)/3rdParty/lua/liblua.a -O2 -o doc/docs/.vuepress/public/js/yuescript.js -I $(SRC_PATH) -I $(SRC_PATH)/3rdParty/lua -std=c++17 --bind -fexceptions -Wno-deprecated-declarations 214 @emcc $(SRC_PATH)/yue_wasm.cpp $(SRC_PATH)/yuescript/ast.cpp $(SRC_PATH)/yuescript/yue_ast.cpp $(SRC_PATH)/yuescript/parser.cpp $(SRC_PATH)/yuescript/yue_compiler.cpp $(SRC_PATH)/yuescript/yue_parser.cpp $(SRC_PATH)/yuescript/yuescript.cpp $(SRC_PATH)/3rdParty/lua/liblua.a -O2 -o doc/docs/.vuepress/public/js/yuescript.js -I $(SRC_PATH) -I $(SRC_PATH)/3rdParty/lua -std=c++17 --bind -fexceptions -Wno-deprecated-declarations
215 @${MAKE} clean 215 @${MAKE} clean
216 216
217# Debug build for gdb debugging 217# Debug build for gdb debugging
@@ -230,7 +230,7 @@ endif
230 @echo -n "Total build time: " 230 @echo -n "Total build time: "
231 @$(END_TIME) 231 @$(END_TIME)
232 232
233$(BUILD_PATH)/yue.so: $(SRC_PATH)/yuescript/ast.cpp $(SRC_PATH)/yuescript/yue_compiler.cpp $(SRC_PATH)/yuescript/yue_parser.cpp $(SRC_PATH)/yuescript/yuescript.cpp $(SRC_PATH)/yuescript/parser.cpp 233$(BUILD_PATH)/yue.so: $(SRC_PATH)/yuescript/ast.cpp $(SRC_PATH)/yuescript/yue_ast.cpp $(SRC_PATH)/yuescript/yue_compiler.cpp $(SRC_PATH)/yuescript/yue_parser.cpp $(SRC_PATH)/yuescript/yuescript.cpp $(SRC_PATH)/yuescript/parser.cpp
234 $(CMD_PREFIX)$(CXX) $(CXXFLAGS) -I $(SRC_PATH) -I $(SRC_PATH)/3rdParty -I $(LUAI) -L $(LUAL) -llua -o $@ -fPIC -shared $? 234 $(CMD_PREFIX)$(CXX) $(CXXFLAGS) -I $(SRC_PATH) -I $(SRC_PATH)/3rdParty -I $(LUAI) -L $(LUAL) -llua -o $@ -fPIC -shared $?
235 235
236# Standard, non-optimized release build 236# Standard, non-optimized release build
diff --git a/spec/inputs/goto.yue b/spec/inputs/goto.yue
index 61584ca..3f3ae89 100644
--- a/spec/inputs/goto.yue
+++ b/spec/inputs/goto.yue
@@ -16,10 +16,10 @@ do
16do 16do
17 for z = 1, 10 17 for z = 1, 10
18 for y = 1, 10 do for x = 1, 10 18 for y = 1, 10 do for x = 1, 10
19 if x^2 + y^2 == z^2 19 if x^2 + y^2 == z^2
20 print 'found a Pythagorean triple:', x, y, z 20 print 'found a Pythagorean triple:', x, y, z
21 print 'now trying next z...' 21 print 'now trying next z...'
22 goto zcontinue 22 goto zcontinue
23 ::zcontinue:: 23 ::zcontinue::
24 24
25do 25do
diff --git a/spec/inputs/import.yue b/spec/inputs/import.yue
index fe5caf5..73e05d2 100644
--- a/spec/inputs/import.yue
+++ b/spec/inputs/import.yue
@@ -7,7 +7,7 @@ import x, \y, z from items
7 7
8import master, \ghost from find "mytable" 8import master, \ghost from find "mytable"
9 9
10_table_0 = 232 10_obj_0 = 232
11 11
12import something from a table 12import something from a table
13 13
diff --git a/spec/outputs/import.lua b/spec/outputs/import.lua
index f8d6ef0..19d332a 100644
--- a/spec/outputs/import.lua
+++ b/spec/outputs/import.lua
@@ -22,18 +22,18 @@ do
22 end 22 end
23 end)() 23 end)()
24end 24end
25local _table_0 = 232 25local _obj_0 = 232
26local something 26local something
27do 27do
28 local _obj_0 = a(table) 28 local _obj_1 = a(table)
29 something = _obj_0.something 29 something = _obj_1.something
30end 30end
31if indent then 31if indent then
32 local okay, well 32 local okay, well
33 do 33 do
34 local _obj_0 = tables[100] 34 local _obj_1 = tables[100]
35 okay, well = _obj_0.okay, (function() 35 okay, well = _obj_1.okay, (function()
36 local _base_0 = _obj_0 36 local _base_0 = _obj_1
37 local _fn_0 = _base_0.well 37 local _fn_0 = _base_0.well
38 return _fn_0 and function(...) 38 return _fn_0 and function(...)
39 return _fn_0(_base_0, ...) 39 return _fn_0(_base_0, ...)
@@ -66,13 +66,13 @@ do
66 local Player = require("player") 66 local Player = require("player")
67 local C, Ct, Cmt 67 local C, Ct, Cmt
68 do 68 do
69 local _obj_0 = require("lpeg") 69 local _obj_1 = require("lpeg")
70 C, Ct, Cmt = _obj_0.C, _obj_0.Ct, _obj_0.Cmt 70 C, Ct, Cmt = _obj_1.C, _obj_1.Ct, _obj_1.Cmt
71 end 71 end
72 local one, two, ch 72 local one, two, ch
73 do 73 do
74 local _obj_0 = require("export") 74 local _obj_1 = require("export")
75 one, two, ch = _obj_0[1], _obj_0[2], _obj_0.Something.umm[1] 75 one, two, ch = _obj_1[1], _obj_1[2], _obj_1.Something.umm[1]
76 end 76 end
77 local Another = require("export").Another 77 local Another = require("export").Another
78end 78end
@@ -84,8 +84,8 @@ end
84do 84do
85 local func, ifVar 85 local func, ifVar
86 do 86 do
87 local _obj_0 = require("org.package.module") 87 local _obj_1 = require("org.package.module")
88 func, ifVar = _obj_0["function"], _obj_0["if"] 88 func, ifVar = _obj_1["function"], _obj_1["if"]
89 end 89 end
90end 90end
91do 91do
@@ -93,14 +93,14 @@ do
93 local index = getmetatable(require("m")).__index 93 local index = getmetatable(require("m")).__index
94 local f, c 94 local f, c
95 do 95 do
96 local _obj_0 = require("m") 96 local _obj_1 = require("m")
97 f = _obj_0.e 97 f = _obj_1.e
98 c = getmetatable(_obj_0).__pairs 98 c = getmetatable(_obj_1).__pairs
99 end 99 end
100 local d = require("m").c 100 local d = require("m").c
101 local g, i 101 local g, i
102 do 102 do
103 local _obj_0 = require("m") 103 local _obj_1 = require("m")
104 g, i = _obj_0[1], getmetatable(_obj_0[2]).__close 104 g, i = _obj_1[1], getmetatable(_obj_1[2]).__close
105 end 105 end
106end 106end
diff --git a/src/yuescript/ast.cpp b/src/yuescript/ast.cpp
index 6db2c21..34ff5d9 100644
--- a/src/yuescript/ast.cpp
+++ b/src/yuescript/ast.cpp
@@ -19,14 +19,14 @@ traversal ast_node::traverse(const std::function<traversal(ast_node*)>& func) {
19 return func(this); 19 return func(this);
20} 20}
21 21
22ast_node* ast_node::getByTypeIds(int* begin, int* end) { 22ast_node* ast_node::get_by_type_ids(int* begin, int* end) {
23 ast_node* current = this; 23 ast_node* current = this;
24 auto it = begin; 24 auto it = begin;
25 while (it != end) { 25 while (it != end) {
26 ast_node* findNode = nullptr; 26 ast_node* findNode = nullptr;
27 int i = *it; 27 int i = *it;
28 current->visitChild([&](ast_node* node) { 28 current->visit_child([&](ast_node* node) {
29 if (node->getId() == i) { 29 if (node->get_id() == i) {
30 findNode = node; 30 findNode = node;
31 return true; 31 return true;
32 } 32 }
@@ -43,7 +43,7 @@ ast_node* ast_node::getByTypeIds(int* begin, int* end) {
43 return current; 43 return current;
44} 44}
45 45
46bool ast_node::visitChild(const std::function<bool(ast_node*)>&) { 46bool ast_node::visit_child(const std::function<bool(ast_node*)>&) {
47 return false; 47 return false;
48} 48}
49 49
@@ -92,7 +92,7 @@ traversal ast_container::traverse(const std::function<traversal(ast_node*)>& fun
92 return traversal::Continue; 92 return traversal::Continue;
93} 93}
94 94
95bool ast_container::visitChild(const std::function<bool(ast_node*)>& func) { 95bool ast_container::visit_child(const std::function<bool(ast_node*)>& func) {
96 const auto& members = this->members(); 96 const auto& members = this->members();
97 for (auto member : members) { 97 for (auto member : members) {
98 switch (member->get_type()) { 98 switch (member->get_type()) {
diff --git a/src/yuescript/ast.hpp b/src/yuescript/ast.hpp
index f59b50f..c78d26c 100644
--- a/src/yuescript/ast.hpp
+++ b/src/yuescript/ast.hpp
@@ -98,16 +98,18 @@ public:
98 using select_last_t = typename select_last<Ts...>::type; 98 using select_last_t = typename select_last<Ts...>::type;
99 99
100 template <class... Args> 100 template <class... Args>
101 select_last_t<Args...>* getByPath() { 101 select_last_t<Args...>* get_by_path() {
102 int types[] = {id<Args>()...}; 102 int types[] = {id<Args>()...};
103 return static_cast<select_last_t<Args...>*>(getByTypeIds(std::begin(types), std::end(types))); 103 return static_cast<select_last_t<Args...>*>(get_by_type_ids(std::begin(types), std::end(types)));
104 } 104 }
105 105
106 virtual bool visitChild(const std::function<bool(ast_node*)>& func); 106 virtual bool visit_child(const std::function<bool(ast_node*)>& func);
107 107
108 virtual int getId() const = 0; 108 virtual int get_id() const = 0;
109 109
110 virtual const std::string_view getName() const = 0; 110 virtual const std::string_view get_name() const = 0;
111
112 virtual std::string to_string(void*) const { return {}; }
111 113
112 template <class T> 114 template <class T>
113 inline ast_ptr<false, T> new_ptr() const { 115 inline ast_ptr<false, T> new_ptr() const {
@@ -121,7 +123,7 @@ public:
121 123
122private: 124private:
123 int _ref; 125 int _ref;
124 ast_node* getByTypeIds(int* begin, int* end); 126 ast_node* get_by_type_ids(int* begin, int* end);
125}; 127};
126 128
127template <class T> 129template <class T>
@@ -130,12 +132,12 @@ id() { return 0; }
130 132
131template <class T> 133template <class T>
132T* ast_cast(ast_node* node) { 134T* ast_cast(ast_node* node) {
133 return node && id<T>() == node->getId() ? static_cast<T*>(node) : nullptr; 135 return node && id<T>() == node->get_id() ? static_cast<T*>(node) : nullptr;
134} 136}
135 137
136template <class T> 138template <class T>
137T* ast_to(ast_node* node) { 139T* ast_to(ast_node* node) {
138 assert(node->getId() == id<T>()); 140 assert(node->get_id() == id<T>());
139 return static_cast<T*>(node); 141 return static_cast<T*>(node);
140} 142}
141 143
@@ -143,7 +145,7 @@ template <class... Args>
143bool ast_is(ast_node* node) { 145bool ast_is(ast_node* node) {
144 if (!node) return false; 146 if (!node) return false;
145 bool result = false; 147 bool result = false;
146 int i = node->getId(); 148 int i = node->get_id();
147 using swallow = bool[]; 149 using swallow = bool[];
148 (void)swallow{result || (result = id<Args>() == i)...}; 150 (void)swallow{result || (result = id<Args>() == i)...};
149 return result; 151 return result;
@@ -181,7 +183,7 @@ public:
181 183
182 virtual traversal traverse(const std::function<traversal(ast_node*)>& func) override; 184 virtual traversal traverse(const std::function<traversal(ast_node*)>& func) override;
183 185
184 virtual bool visitChild(const std::function<bool(ast_node*)>& func) override; 186 virtual bool visit_child(const std::function<bool(ast_node*)>& func) override;
185 187
186private: 188private:
187 ast_member_vector m_members; 189 ast_member_vector m_members;
@@ -235,13 +237,13 @@ public:
235 237
236 template <class T> 238 template <class T>
237 T* to() const { 239 T* to() const {
238 assert(m_ptr && m_ptr->getId() == id<T>()); 240 assert(m_ptr && m_ptr->get_id() == id<T>());
239 return static_cast<T*>(m_ptr); 241 return static_cast<T*>(m_ptr);
240 } 242 }
241 243
242 template <class T> 244 template <class T>
243 bool is() const { 245 bool is() const {
244 return m_ptr && m_ptr->getId() == id<T>(); 246 return m_ptr && m_ptr->get_id() == id<T>();
245 } 247 }
246 248
247 void set(ast_node* node) { 249 void set(ast_node* node) {
@@ -333,7 +335,7 @@ public:
333 335
334private: 336private:
335 virtual bool accept(ast_node* node) override { 337 virtual bool accept(ast_node* node) override {
336 return node && (std::is_same<ast_node, T>() || id<T>() == node->getId()); 338 return node && (std::is_same<ast_node, T>() || id<T>() == node->get_id());
337 } 339 }
338}; 340};
339 341
@@ -380,7 +382,7 @@ private:
380 if (!node) return false; 382 if (!node) return false;
381 using swallow = bool[]; 383 using swallow = bool[];
382 bool result = false; 384 bool result = false;
383 (void)swallow{result || (result = id<Args>() == node->getId())...}; 385 (void)swallow{result || (result = id<Args>() == node->get_id())...};
384 return result; 386 return result;
385 } 387 }
386}; 388};
@@ -515,7 +517,7 @@ public:
515 517
516private: 518private:
517 virtual bool accept(ast_node* node) override { 519 virtual bool accept(ast_node* node) override {
518 return node && (std::is_same<ast_node, T>() || id<T>() == node->getId()); 520 return node && (std::is_same<ast_node, T>() || id<T>() == node->get_id());
519 } 521 }
520}; 522};
521 523
@@ -557,7 +559,7 @@ private:
557 if (!node) return false; 559 if (!node) return false;
558 using swallow = bool[]; 560 using swallow = bool[];
559 bool result = false; 561 bool result = false;
560 (void)swallow{result || (result = id<Args>() == node->getId())...}; 562 (void)swallow{result || (result = id<Args>() == node->get_id())...};
561 return result; 563 return result;
562 } 564 }
563}; 565};
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp
new file mode 100644
index 0000000..d9f8419
--- /dev/null
+++ b/src/yuescript/yue_ast.cpp
@@ -0,0 +1,1239 @@
1/* Copyright (c) 2023 Jin Li, dragon-fly@qq.com
2
3Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
5The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
7THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
8
9#include "yuescript/yue_ast.h"
10
11#include <sstream>
12
13namespace parserlib {
14using namespace std::string_view_literals;
15using namespace std::string_literals;
16
17void YueFormat::pushScope() {
18 indent++;
19}
20
21void YueFormat::popScope() {
22 indent--;
23}
24
25std::string YueFormat::ind() const {
26 if (spaceOverTab) {
27 return std::string(indent * tabSpaces, ' ');
28 }
29 return std::string(indent, '\t');
30}
31
32std::string YueFormat::convert(const ast_node* node) {
33 return converter.to_bytes(std::wstring(node->m_begin.m_it, node->m_end.m_it));
34}
35
36std::string YueFormat::toString(ast_node* node) {
37 return node->to_string(this);
38}
39
40typedef std::list<std::string> str_list;
41
42static std::string join(const str_list& items, std::string_view sep = {}) {
43 if (items.empty())
44 return {};
45 else if (items.size() == 1)
46 return items.front();
47 std::ostringstream joinBuf;
48 if (sep.empty()) {
49 for (const auto& item : items) {
50 joinBuf << item;
51 }
52 } else {
53 joinBuf << items.front();
54 auto begin = ++items.begin();
55 for (auto it = begin; it != items.end(); ++it) {
56 joinBuf << sep << *it;
57 }
58 }
59 return joinBuf.str();
60}
61
62namespace yue {
63
64std::string Num_t::to_string(void* ud) const {
65 auto info = reinterpret_cast<YueFormat*>(ud);
66 return info->convert(this);
67}
68std::string Name_t::to_string(void* ud) const {
69 auto info = reinterpret_cast<YueFormat*>(ud);
70 return info->convert(this);
71}
72std::string Self_t::to_string(void*) const {
73 return "@"s;
74}
75std::string SelfClass_t::to_string(void*) const {
76 return "@@"s;
77}
78std::string VarArg_t::to_string(void*) const {
79 return "..."s;
80}
81std::string Seperator_t::to_string(void*) const {
82 return {};
83}
84std::string LocalFlag_t::to_string(void* ud) const {
85 auto info = reinterpret_cast<YueFormat*>(ud);
86 return info->convert(this);
87}
88std::string ConstAttrib_t::to_string(void*) const {
89 return "const"s;
90}
91std::string CloseAttrib_t::to_string(void*) const {
92 return "close"s;
93}
94std::string ImportLiteralInner_t::to_string(void* ud) const {
95 auto info = reinterpret_cast<YueFormat*>(ud);
96 return info->convert(this);
97}
98std::string ImportAllMacro_t::to_string(void*) const {
99 return "$"s;
100}
101std::string FnArrowBack_t::to_string(void* ud) const {
102 auto info = reinterpret_cast<YueFormat*>(ud);
103 return info->convert(this);
104}
105std::string IfType_t::to_string(void* ud) const {
106 auto info = reinterpret_cast<YueFormat*>(ud);
107 return info->convert(this);
108}
109std::string WhileType_t::to_string(void* ud) const {
110 auto info = reinterpret_cast<YueFormat*>(ud);
111 return info->convert(this);
112}
113std::string UpdateOp_t::to_string(void* ud) const {
114 auto info = reinterpret_cast<YueFormat*>(ud);
115 return info->convert(this);
116}
117std::string BinaryOperator_t::to_string(void* ud) const {
118 auto info = reinterpret_cast<YueFormat*>(ud);
119 return info->convert(this);
120}
121std::string UnaryOperator_t::to_string(void* ud) const {
122 auto info = reinterpret_cast<YueFormat*>(ud);
123 auto op = info->convert(this);
124 if (op == "not"sv) {
125 return "not "s;
126 }
127 return op;
128}
129std::string LuaStringOpen_t::to_string(void* ud) const {
130 auto info = reinterpret_cast<YueFormat*>(ud);
131 return info->convert(this);
132}
133std::string LuaStringContent_t::to_string(void* ud) const {
134 auto info = reinterpret_cast<YueFormat*>(ud);
135 return info->convert(this);
136}
137std::string LuaStringClose_t::to_string(void* ud) const {
138 auto info = reinterpret_cast<YueFormat*>(ud);
139 return info->convert(this);
140}
141std::string SingleString_t::to_string(void* ud) const {
142 auto info = reinterpret_cast<YueFormat*>(ud);
143 return info->convert(this);
144}
145std::string DoubleStringInner_t::to_string(void* ud) const {
146 auto info = reinterpret_cast<YueFormat*>(ud);
147 return info->convert(this);
148}
149std::string Metatable_t::to_string(void* ud) const {
150 auto info = reinterpret_cast<YueFormat*>(ud);
151 return info->convert(this);
152}
153std::string DefaultValue_t::to_string(void*) const {
154 return {};
155}
156std::string ExistentialOp_t::to_string(void*) const {
157 return "?"s;
158}
159std::string TableAppendingOp_t::to_string(void*) const {
160 return "[]"s;
161}
162std::string GlobalOp_t::to_string(void* ud) const {
163 auto info = reinterpret_cast<YueFormat*>(ud);
164 return info->convert(this);
165}
166std::string ExportDefault_t::to_string(void*) const {
167 return "default"s;
168}
169std::string FnArrow_t::to_string(void* ud) const {
170 auto info = reinterpret_cast<YueFormat*>(ud);
171 return info->convert(this);
172}
173std::string ConstValue_t::to_string(void* ud) const {
174 auto info = reinterpret_cast<YueFormat*>(ud);
175 return info->convert(this);
176}
177std::string InRangeOpen_t::to_string(void*) const {
178 return {};
179}
180std::string InRangeClose_t::to_string(void*) const {
181 return {};
182}
183std::string NotIn_t::to_string(void*) const {
184 return {};
185}
186std::string BreakLoop_t::to_string(void* ud) const {
187 auto info = reinterpret_cast<YueFormat*>(ud);
188 return info->convert(this);
189}
190std::string YueLineComment_t::to_string(void* ud) const {
191 auto info = reinterpret_cast<YueFormat*>(ud);
192 return "--"s + info->convert(this);
193}
194std::string MultilineCommentInner_t::to_string(void* ud) const {
195 auto info = reinterpret_cast<YueFormat*>(ud);
196 return "--[["s + info->convert(this) + "]]"s;
197}
198std::string Variable_t::to_string(void* ud) const {
199 return name->to_string(ud);
200}
201std::string LabelName_t::to_string(void* ud) const {
202 return name->to_string(ud);
203}
204std::string LuaKeyword_t::to_string(void* ud) const {
205 return name->to_string(ud);
206}
207std::string SelfName_t::to_string(void* ud) const {
208 return "@"s + name->to_string(ud);
209}
210std::string SelfClassName_t::to_string(void* ud) const {
211 return "@@"s + name->to_string(ud);
212}
213std::string SelfItem_t::to_string(void* ud) const {
214 return name->to_string(ud);
215}
216std::string KeyName_t::to_string(void* ud) const {
217 return name->to_string(ud);
218}
219std::string NameList_t::to_string(void* ud) const {
220 str_list temp;
221 for (auto name : names.objects()) {
222 temp.emplace_back(name->to_string(ud));
223 }
224 return join(temp, ", "sv);
225}
226std::string LocalValues_t::to_string(void* ud) const {
227 str_list temp;
228 temp.emplace_back(nameList->to_string(ud));
229 if (valueList) {
230 if (valueList.is<TableBlock_t>()) {
231 temp.emplace_back("="s + valueList->to_string(ud));
232 } else {
233 temp.emplace_back("="s);
234 temp.emplace_back(valueList->to_string(ud));
235 }
236 }
237 return join(temp, " "sv);
238}
239std::string Local_t::to_string(void* ud) const {
240 return "local "s + item->to_string(ud);
241}
242std::string LocalAttrib_t::to_string(void* ud) const {
243 str_list temp;
244 for (auto item : leftList.objects()) {
245 temp.emplace_back(item->to_string(ud));
246 }
247 return attrib->to_string(ud) + ' ' + join(temp, ", "s) + ' ' + assign->to_string(ud);
248}
249std::string ColonImportName_t::to_string(void* ud) const {
250 return '\\' + name->to_string(ud);
251}
252std::string ImportLiteral_t::to_string(void* ud) const {
253 str_list temp;
254 for (auto inner : inners.objects()) {
255 temp.emplace_back(inner->to_string(ud));
256 }
257 return '"' + join(temp, "."sv) + '"';
258}
259std::string ImportFrom_t::to_string(void* ud) const {
260 str_list temp;
261 for (auto name : names.objects()) {
262 temp.emplace_back(name->to_string(ud));
263 }
264 return join(temp, ", "sv) + " from "s + exp->to_string(ud);
265}
266std::string MacroNamePair_t::to_string(void* ud) const {
267 return key->to_string(ud) + ": "s + value->to_string(ud);
268}
269std::string ImportTabLit_t::to_string(void* ud) const {
270 str_list temp;
271 for (auto item : items.objects()) {
272 if (ast_is<MacroName_t>(item)) {
273 temp.emplace_back(':' + item->to_string(ud));
274 } else {
275 temp.emplace_back(item->to_string(ud));
276 }
277 }
278 return '{' + join(temp, ", "sv) + '}';
279}
280std::string ImportAs_t::to_string(void* ud) const {
281 str_list temp{literal->to_string(ud)};
282 if (target) {
283 temp.emplace_back("as"s);
284 temp.emplace_back(target->to_string(ud));
285 }
286 return join(temp, " "s);
287}
288std::string Import_t::to_string(void* ud) const {
289 return "import "s + content->to_string(ud);
290}
291std::string Label_t::to_string(void* ud) const {
292 return "::"s + label->to_string(ud) + "::"s;
293}
294std::string Goto_t::to_string(void* ud) const {
295 return "goto "s + label->to_string(ud);
296}
297std::string ShortTabAppending_t::to_string(void* ud) const {
298 return "[] "s + assign->to_string(ud);
299}
300std::string Backcall_t::to_string(void* ud) const {
301 str_list temp;
302 if (argsDef) {
303 temp.emplace_back(argsDef->to_string(ud));
304 }
305 temp.emplace_back(arrow->to_string(ud));
306 temp.emplace_back(value->to_string(ud));
307 return join(temp, " "sv);
308}
309std::string PipeBody_t::to_string(void* ud) const {
310 auto info = reinterpret_cast<YueFormat*>(ud);
311 str_list temp;
312 for (auto value : values.objects()) {
313 temp.emplace_back(info->ind() + "|> "s + value->to_string(ud));
314 }
315 return join(temp, "\n"sv);
316}
317std::string ExpListLow_t::to_string(void* ud) const {
318 str_list temp;
319 for (auto exp : exprs.objects()) {
320 temp.emplace_back(exp->to_string(ud));
321 }
322 return join(temp, "; "sv);
323}
324std::string ExpList_t::to_string(void* ud) const {
325 str_list temp;
326 for (auto exp : exprs.objects()) {
327 temp.emplace_back(exp->to_string(ud));
328 }
329 return join(temp, ", "sv);
330}
331std::string Return_t::to_string(void* ud) const {
332 str_list temp{"return"s};
333 if (valueList) {
334 temp.emplace_back(valueList.is<TableBlock_t>() ? ""s : " "s);
335 temp.emplace_back(valueList->to_string(ud));
336 }
337 return join(temp);
338}
339std::string With_t::to_string(void* ud) const {
340 auto info = reinterpret_cast<YueFormat*>(ud);
341 str_list temp{
342 eop ? "with?"s : "with"s,
343 valueList->to_string(ud)};
344 if (assigns) {
345 temp.push_back(assigns->to_string(ud));
346 }
347 if (body.is<Statement_t>()) {
348 return join(temp, " "sv) + " do "s + body->to_string(ud);
349 } else {
350 auto line = join(temp, " "sv);
351 if (line.find('\n') != std::string::npos) {
352 line += " do"s;
353 }
354 info->pushScope();
355 auto code = body->to_string(ud);
356 info->popScope();
357 return line + '\n' + code;
358 }
359}
360std::string SwitchList_t::to_string(void* ud) const {
361 str_list temp;
362 for (auto exp : exprs.objects()) {
363 temp.emplace_back(exp->to_string(ud));
364 }
365 return join(temp, ", "sv);
366}
367std::string SwitchCase_t::to_string(void* ud) const {
368 auto info = reinterpret_cast<YueFormat*>(ud);
369 if (body.is<Statement_t>()) {
370 return "when "s + condition->to_string(ud) + " then "s + body->to_string(ud);
371 } else {
372 info->pushScope();
373 auto block = body->to_string(ud);
374 info->popScope();
375 auto line = "when "s + condition->to_string(ud);
376 if (line.find('\n') != std::string::npos) {
377 line += " then"s;
378 }
379 return line + '\n' + block;
380 }
381}
382std::string Switch_t::to_string(void* ud) const {
383 auto info = reinterpret_cast<YueFormat*>(ud);
384 str_list temp{"switch "s + target->to_string(ud)};
385 info->pushScope();
386 for (auto branch : branches.objects()) {
387 temp.emplace_back(info->ind() + branch->to_string(ud));
388 }
389 if (lastBranch) {
390 if (lastBranch.is<Statement_t>()) {
391 temp.emplace_back(info->ind() + "else "s + lastBranch->to_string(ud));
392 } else {
393 temp.emplace_back(info->ind() + "else"s);
394 info->pushScope();
395 temp.emplace_back(lastBranch->to_string(ud));
396 info->popScope();
397 }
398 }
399 info->popScope();
400 return join(temp, "\n"sv);
401}
402std::string Assignment_t::to_string(void* ud) const {
403 return expList->to_string(ud) + ' ' + assign->to_string(ud);
404}
405std::string IfCond_t::to_string(void* ud) const {
406 return condition->to_string(ud);
407}
408std::string If_t::to_string(void* ud) const {
409 auto info = reinterpret_cast<YueFormat*>(ud);
410 auto it = nodes.objects().begin();
411 str_list temp{
412 type->to_string(ud) + ' ' + (*it)->to_string(ud)};
413 if (temp.back().find('\n') != std::string::npos) {
414 temp.back() += " then"s;
415 }
416 ++it;
417 bool condition = true;
418 for (; it != nodes.objects().end(); ++it) {
419 auto node = *it;
420 switch (node->get_id()) {
421 case id<IfCond_t>():
422 temp.emplace_back(info->ind() + "elseif "s + node->to_string(ud));
423 condition = true;
424 break;
425 case id<Statement_t>(): {
426 if (condition) {
427 temp.back() += " then "s + node->to_string(ud);
428 } else {
429 temp.emplace_back(info->ind() + "else "s + node->to_string(ud));
430 }
431 condition = false;
432 break;
433 }
434 case id<Block_t>(): {
435 if (condition) {
436 info->pushScope();
437 temp.emplace_back(node->to_string(ud));
438 info->popScope();
439 } else {
440 temp.emplace_back(info->ind() + "else"s);
441 info->pushScope();
442 temp.emplace_back(node->to_string(ud));
443 info->popScope();
444 }
445 condition = false;
446 break;
447 }
448 }
449 }
450 return join(temp, "\n"sv);
451}
452std::string While_t::to_string(void* ud) const {
453 auto info = reinterpret_cast<YueFormat*>(ud);
454 str_list temp{
455 type->to_string(ud) + ' ' + condition->to_string(ud)};
456 if (body.is<Statement_t>()) {
457 temp.back() += " do "s + body->to_string(ud);
458 } else {
459 if (temp.back().find('\n') != std::string::npos) {
460 temp.back() += " do"s;
461 }
462 info->pushScope();
463 temp.emplace_back(body->to_string(ud));
464 info->popScope();
465 }
466 return join(temp, "\n"sv);
467}
468std::string Repeat_t::to_string(void* ud) const {
469 auto info = reinterpret_cast<YueFormat*>(ud);
470 str_list temp;
471 if (body->content.is<Statement_t>()) {
472 temp.emplace_back("repeat "s + body->to_string(ud));
473 } else {
474 temp.emplace_back("repeat"s);
475 info->pushScope();
476 temp.emplace_back(body->to_string(ud));
477 info->popScope();
478 }
479 temp.emplace_back(info->ind() + "until "s + condition->to_string(ud));
480 return join(temp, "\n"sv);
481}
482std::string ForStepValue_t::to_string(void* ud) const {
483 return value->to_string(ud);
484}
485std::string For_t::to_string(void* ud) const {
486 auto info = reinterpret_cast<YueFormat*>(ud);
487 auto line = "for "s + varName->to_string(ud) + " = "s + startValue->to_string(ud) + ", "s + stopValue->to_string(ud);
488 if (stepValue) {
489 line += ", "s + stepValue->to_string(ud);
490 }
491 if (body.is<Statement_t>()) {
492 return line + " do "s + body->to_string(ud);
493 } else {
494 if (line.find('\n') != std::string::npos) {
495 line += " do"s;
496 }
497 info->pushScope();
498 auto block = body->to_string(ud);
499 info->popScope();
500 return line + '\n' + block;
501 }
502}
503std::string ForEach_t::to_string(void* ud) const {
504 auto info = reinterpret_cast<YueFormat*>(ud);
505 auto line = "for "s + nameList->to_string(ud) + " in "s + loopValue->to_string(ud);
506 if (body.is<Statement_t>()) {
507 return line + " do "s + body->to_string(ud);
508 } else {
509 if (line.find('\n') != std::string::npos) {
510 line += " do"s;
511 }
512 info->pushScope();
513 auto block = body->to_string(ud);
514 info->popScope();
515 return line + '\n' + block;
516 }
517}
518std::string Do_t::to_string(void* ud) const {
519 auto info = reinterpret_cast<YueFormat*>(ud);
520 if (body->content.is<Statement_t>()) {
521 return "do "s + body->to_string(ud);
522 } else {
523 info->pushScope();
524 auto block = body->to_string(ud);
525 info->popScope();
526 return "do\n"s + block;
527 }
528}
529std::string CatchBlock_t::to_string(void* ud) const {
530 auto info = reinterpret_cast<YueFormat*>(ud);
531 auto line = "catch "s + err->to_string(ud);
532 info->pushScope();
533 auto block = body->to_string(ud);
534 info->popScope();
535 return line + '\n' + block;
536}
537std::string Try_t::to_string(void* ud) const {
538 auto info = reinterpret_cast<YueFormat*>(ud);
539 str_list temp;
540 if (func.is<Exp_t>()) {
541 temp.emplace_back("try "s + func->to_string(ud));
542 } else {
543 temp.emplace_back("try"s);
544 info->pushScope();
545 temp.emplace_back(func->to_string(ud));
546 info->popScope();
547 }
548 if (catchBlock) {
549 temp.emplace_back(info->ind() + catchBlock->to_string(ud));
550 }
551 return join(temp, "\n"sv);
552}
553std::string Comprehension_t::to_string(void* ud) const {
554 auto valueStr = value->to_string(ud);
555 return '[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + ' ' + forLoop->to_string(ud) + ']';
556}
557std::string CompValue_t::to_string(void* ud) const {
558 return value->to_string(ud);
559}
560std::string TblComprehension_t::to_string(void* ud) const {
561 auto line = '{' + key->to_string(ud);
562 if (value) {
563 line += ", "s + value->to_string(ud);
564 }
565 return line + ' ' + forLoop->to_string(ud) + '}';
566}
567std::string StarExp_t::to_string(void* ud) const {
568 return '*' + value->to_string(ud);
569}
570std::string CompForEach_t::to_string(void* ud) const {
571 return "for "s + nameList->to_string(ud) + " in "s + loopValue->to_string(ud);
572}
573std::string CompFor_t::to_string(void* ud) const {
574 auto line = "for "s + varName->to_string(ud) + " = "s + startValue->to_string(ud) + ", "s + stopValue->to_string(ud);
575 if (stepValue) {
576 line += stepValue->to_string(ud);
577 }
578 return line;
579}
580std::string CompInner_t::to_string(void* ud) const {
581 str_list temp;
582 for (auto item : items.objects()) {
583 if (ast_is<Exp_t>(item)) {
584 temp.emplace_back("when "s + item->to_string(ud));
585 } else {
586 temp.emplace_back(item->to_string(ud));
587 }
588 }
589 return join(temp, " "sv);
590}
591std::string Assign_t::to_string(void* ud) const {
592 str_list temp;
593 if (values.size() == 1 && ast_is<TableBlock_t>(values.front())) {
594 return '=' + values.front()->to_string(ud);
595 }
596 for (auto value : values.objects()) {
597 temp.emplace_back(value->to_string(ud));
598 }
599 return "= "s + join(temp, "; "sv);
600}
601std::string Update_t::to_string(void* ud) const {
602 return op->to_string(ud) + "= "s + value->to_string(ud);
603}
604std::string Assignable_t::to_string(void* ud) const {
605 return item->to_string(ud);
606}
607std::string AssignableChain_t::to_string(void* ud) const {
608 str_list temp;
609 for (auto item : items.objects()) {
610 if (ast_is<Exp_t, String_t>(item)) {
611 auto valueStr = item->to_string(ud);
612 temp.emplace_back('[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + ']');
613 } else {
614 temp.emplace_back(item->to_string(ud));
615 }
616 }
617 return join(temp);
618}
619std::string ExpOpValue_t::to_string(void* ud) const {
620 str_list pipes;
621 for (auto uexp : pipeExprs.objects()) {
622 pipes.emplace_back(uexp->to_string(ud));
623 }
624 return op->to_string(ud) + ' ' + join(pipes, " |> "sv);
625}
626std::string Exp_t::to_string(void* ud) const {
627 str_list pipes;
628 for (auto uexp : pipeExprs.objects()) {
629 pipes.emplace_back(uexp->to_string(ud));
630 }
631 str_list temp{join(pipes, " |> "sv)};
632 for (auto opValue : opValues.objects()) {
633 temp.emplace_back(opValue->to_string(ud));
634 }
635 if (nilCoalesed) {
636 temp.emplace_back("??"s);
637 temp.emplace_back(nilCoalesed->to_string(ud));
638 }
639 return join(temp, " "sv);
640}
641std::string Callable_t::to_string(void* ud) const {
642 return item->to_string(ud);
643}
644std::string ChainValue_t::to_string(void* ud) const {
645 str_list temp;
646 bool isMultilineChain = false;
647 for (auto item : items.objects()) {
648 if (item != items.back() && ast_is<InvokeArgs_t>(item)) {
649 isMultilineChain = true;
650 break;
651 }
652 }
653 if (isMultilineChain) {
654 auto it = items.objects().begin();
655 auto node = *it;
656 if (ast_is<Exp_t>(node)) {
657 auto valueStr = node->to_string(ud);
658 temp.emplace_back('[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + ']');
659 } else {
660 temp.emplace_back(node->to_string(ud));
661 }
662 ++it;
663 auto info = reinterpret_cast<YueFormat*>(ud);
664 info->pushScope();
665 for (; it != items.objects().end(); ++it) {
666 node = *it;
667 switch (node->get_id()) {
668 case id<Exp_t>(): {
669 auto valueStr = node->to_string(ud);
670 temp.emplace_back(info->ind() + '[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + ']');
671 break;
672 }
673 case id<Invoke_t>():
674 case id<InvokeArgs_t>():
675 temp.back() += node->to_string(ud);
676 break;
677 default:
678 temp.emplace_back(info->ind() + node->to_string(ud));
679 break;
680 }
681 }
682 info->popScope();
683 return join(temp, "\n"sv);
684 } else {
685 for (auto item : items.objects()) {
686 if (ast_is<Exp_t>(item)) {
687 auto valueStr = item->to_string(ud);
688 temp.emplace_back('[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + ']');
689 } else {
690 temp.emplace_back(item->to_string(ud));
691 }
692 }
693 return join(temp);
694 }
695}
696std::string SimpleTable_t::to_string(void* ud) const {
697 str_list temp;
698 for (auto pair : pairs.objects()) {
699 temp.emplace_back(pair->to_string(ud));
700 }
701 return join(temp, ", "sv);
702}
703std::string SimpleValue_t::to_string(void* ud) const {
704 return value->to_string(ud);
705}
706std::string Value_t::to_string(void* ud) const {
707 return item->to_string(ud);
708}
709std::string LuaString_t::to_string(void* ud) const {
710 auto str = content->to_string(ud);
711 auto newLine = str.find_first_of("\n"s) != std::string::npos ? "\n"s : ""s;
712 return open->to_string(ud) + newLine + str + close->to_string(ud);
713}
714std::string DoubleStringContent_t::to_string(void* ud) const {
715 if (content.is<Exp_t>()) {
716 return "#{"s + content->to_string(ud) + '}';
717 }
718 return content->to_string(ud);
719}
720std::string DoubleString_t::to_string(void* ud) const {
721 str_list temp;
722 for (auto seg : segments.objects()) {
723 temp.emplace_back(seg->to_string(ud));
724 }
725 return '"' + join(temp) + '"';
726}
727std::string String_t::to_string(void* ud) const {
728 return str->to_string(ud);
729}
730std::string Parens_t::to_string(void* ud) const {
731 return '(' + expr->to_string(ud) + ')';
732}
733std::string DotChainItem_t::to_string(void* ud) const {
734 return '.' + name->to_string(ud);
735}
736std::string ColonChainItem_t::to_string(void* ud) const {
737 return '\\' + name->to_string(ud);
738}
739std::string Metamethod_t::to_string(void* ud) const {
740 if (item.is<Exp_t>()) {
741 auto valueStr = item->to_string(ud);
742 return "<["s + (valueStr[0] == '[' ? " "s : ""s) + valueStr + "]>"s;
743 } else {
744 return '<' + item->to_string(ud) + '>';
745 }
746}
747std::string Slice_t::to_string(void* ud) const {
748 str_list temp;
749 if (startValue.is<Exp_t>()) {
750 temp.emplace_back(startValue->to_string(ud));
751 }
752 temp.emplace_back(", "s);
753 if (stopValue.is<Exp_t>()) {
754 temp.emplace_back(stopValue->to_string(ud));
755 }
756 if (stepValue.is<Exp_t>()) {
757 temp.emplace_back(", "s + stepValue->to_string(ud));
758 }
759 auto valueStr = join(temp);
760 return '[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + ']';
761}
762static bool isInBlockExp(ast_node* node) {
763 if (auto exp = ast_cast<Exp_t>(node)) {
764 auto unaryExp = static_cast<UnaryExp_t*>(exp->pipeExprs.front());
765 auto value = static_cast<Value_t*>(unaryExp->expos.front());
766 if (auto simpleValue = value->item.as<SimpleValue_t>()) {
767 if (!ast_is<TableLit_t, ConstValue_t, Num_t, VarArg_t,
768 TblComprehension_t, Comprehension_t>(simpleValue->value)) {
769 return true;
770 }
771 }
772 }
773 return false;
774}
775std::string Invoke_t::to_string(void* ud) const {
776 if (args.empty()) {
777 return "!"s;
778 } else if (args.size() == 1) {
779 auto arg = args.front();
780 if (ast_is<Exp_t>(arg)) {
781 return '(' + arg->to_string(ud) + ')';
782 } else {
783 return arg->to_string(ud);
784 }
785 } else {
786 auto info = reinterpret_cast<YueFormat*>(ud);
787 bool hasInBlockExp = false;
788 for (auto arg : args.objects()) {
789 if (arg != args.back() && isInBlockExp(arg)) {
790 hasInBlockExp = true;
791 break;
792 }
793 }
794 str_list temp;
795 if (hasInBlockExp) {
796 temp.push_back("("s);
797 info->pushScope();
798 for (auto arg : args.objects()) {
799 temp.emplace_back(info->ind() + arg->to_string(ud));
800 }
801 info->popScope();
802 temp.push_back(info->ind() + ')');
803 return join(temp, "\n"sv);
804 } else {
805 for (auto arg : args.objects()) {
806 temp.emplace_back(arg->to_string(ud));
807 }
808 return '(' + join(temp, ", "sv) + ')';
809 }
810 }
811}
812std::string SpreadExp_t::to_string(void* ud) const {
813 return "..."s + exp->to_string(ud);
814}
815std::string TableLit_t::to_string(void* ud) const {
816 auto info = reinterpret_cast<YueFormat*>(ud);
817 if (values.empty()) {
818 return "{ }"s;
819 }
820 str_list temp;
821 temp.emplace_back("{"s);
822 info->pushScope();
823 for (auto value : values.objects()) {
824 temp.emplace_back(info->ind() + value->to_string(ud));
825 }
826 info->popScope();
827 temp.emplace_back(info->ind() + '}');
828 return join(temp, "\n"sv);
829}
830std::string TableBlock_t::to_string(void* ud) const {
831 auto info = reinterpret_cast<YueFormat*>(ud);
832 str_list temp;
833 info->pushScope();
834 for (auto value : values.objects()) {
835 switch (value->get_id()) {
836 case id<Exp_t>():
837 case id<SpreadExp_t>():
838 temp.emplace_back(info->ind() + "* "s + value->to_string(ud));
839 break;
840 case id<TableBlock_t>():
841 temp.emplace_back(info->ind() + "*"s + value->to_string(ud));
842 break;
843 default:
844 temp.emplace_back(info->ind() + value->to_string(ud));
845 break;
846 }
847 }
848 info->popScope();
849 return '\n' + join(temp, "\n"sv);
850}
851std::string TableBlockIndent_t::to_string(void* ud) const {
852 auto info = reinterpret_cast<YueFormat*>(ud);
853 str_list temp;
854 info->pushScope();
855 for (auto value : values.objects()) {
856 if (value == values.front()) {
857 temp.emplace_back("* "s + value->to_string(ud));
858 } else {
859 temp.emplace_back(info->ind() + value->to_string(ud));
860 }
861 }
862 info->popScope();
863 return join(temp, "\n"sv);
864}
865std::string ClassMemberList_t::to_string(void* ud) const {
866 auto info = reinterpret_cast<YueFormat*>(ud);
867 str_list temp;
868 for (auto value : values.objects()) {
869 temp.emplace_back(info->ind() + value->to_string(ud));
870 }
871 return join(temp, "\n"sv);
872}
873std::string ClassBlock_t::to_string(void* ud) const {
874 auto info = reinterpret_cast<YueFormat*>(ud);
875 str_list temp;
876 info->pushScope();
877 for (auto content : contents.objects()) {
878 if (ast_is<Statement_t>(content)) {
879 temp.emplace_back(info->ind() + content->to_string(ud));
880 } else {
881 temp.emplace_back(content->to_string(ud));
882 }
883 }
884 info->popScope();
885 return '\n' + join(temp, "\n"sv);
886}
887std::string ClassDecl_t::to_string(void* ud) const {
888 auto line = "class"s;
889 if (name) {
890 line += ' ' + name->to_string(ud);
891 }
892 if (extend) {
893 line += " extends "s + extend->to_string(ud);
894 }
895 if (mixes) {
896 line += " using "s + mixes->to_string(ud);
897 }
898 if (body) {
899 line += body->to_string(ud);
900 }
901 return line;
902}
903std::string GlobalValues_t::to_string(void* ud) const {
904 auto line = nameList->to_string(ud);
905 if (valueList) {
906 if (valueList.is<TableBlock_t>()) {
907 line += " ="s + valueList->to_string(ud);
908 } else {
909 line += " = "s + valueList->to_string(ud);
910 }
911 }
912 return line;
913}
914std::string Global_t::to_string(void* ud) const {
915 return "global "s + item->to_string(ud);
916}
917std::string Export_t::to_string(void* ud) const {
918 auto line = "export"s;
919 if (def) {
920 line += " default "s;
921 }
922 switch (target->get_id()) {
923 case id<DotChainItem_t>():
924 line += target->to_string(ud);
925 break;
926 case id<Exp_t>(): {
927 auto valueStr = target->to_string(ud);
928 line += '[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + ']';
929 break;
930 }
931 default:
932 line += ' ' + target->to_string(ud);
933 break;
934 }
935 if (assign) {
936 line += ' ' + assign->to_string(ud);
937 }
938 return line;
939}
940std::string VariablePair_t::to_string(void* ud) const {
941 return ':' + name->to_string(ud);
942}
943std::string NormalPair_t::to_string(void* ud) const {
944 std::string line;
945 if (key.is<Exp_t>()) {
946 auto valueStr = key->to_string(ud);
947 line = '[' + (valueStr[0] == '[' ? " "s : ""s) + valueStr + "]:"s;
948 } else {
949 line = key->to_string(ud) + ":"s;
950 }
951 line += (value.is<TableBlock_t>() ? ""s : " "s) + value->to_string(ud);
952 return line;
953}
954std::string MetaVariablePair_t::to_string(void* ud) const {
955 return ":<"s + name->to_string(ud) + '>';
956}
957std::string MetaNormalPair_t::to_string(void* ud) const {
958 std::string line;
959 if (!key) {
960 line = "<>:"s;
961 } else if (key.is<Exp_t>()) {
962 auto valueStr = key->to_string(ud);
963 line = "<["s + (valueStr[0] == '[' ? " "s : ""s) + valueStr + "]>:"s;
964 } else {
965 line = '<' + key->to_string(ud) + ">:"s;
966 }
967 line += (value.is<TableBlock_t>() ? ""s : " "s) + value->to_string(ud);
968 return line;
969}
970std::string VariablePairDef_t::to_string(void* ud) const {
971 if (defVal) {
972 return pair->to_string(ud) + " = "s + defVal->to_string(ud);
973 } else {
974 return pair->to_string(ud);
975 }
976}
977std::string NormalPairDef_t::to_string(void* ud) const {
978 if (defVal) {
979 return pair->to_string(ud) + " = "s + defVal->to_string(ud);
980 } else {
981 return pair->to_string(ud);
982 }
983}
984std::string NormalDef_t::to_string(void* ud) const {
985 if (defVal) {
986 return item->to_string(ud) + " = "s + defVal->to_string(ud);
987 } else {
988 return item->to_string(ud);
989 }
990}
991std::string MetaVariablePairDef_t::to_string(void* ud) const {
992 if (defVal) {
993 return pair->to_string(ud) + " = "s + defVal->to_string(ud);
994 } else {
995 return pair->to_string(ud);
996 }
997}
998std::string MetaNormalPairDef_t::to_string(void* ud) const {
999 if (defVal) {
1000 return pair->to_string(ud) + " = "s + defVal->to_string(ud);
1001 } else {
1002 return pair->to_string(ud);
1003 }
1004}
1005std::string FnArgDef_t::to_string(void* ud) const {
1006 auto line = name->to_string(ud);
1007 if (op) {
1008 line += op->to_string(ud);
1009 }
1010 if (defaultValue) {
1011 if (isInBlockExp(defaultValue)) {
1012 line += " = ("s + defaultValue->to_string(ud) + ')';
1013 } else {
1014 line += " = "s + defaultValue->to_string(ud);
1015 }
1016 }
1017 return line;
1018}
1019std::string FnArgDefList_t::to_string(void* ud) const {
1020 str_list temp;
1021 for (auto def : definitions.objects()) {
1022 temp.emplace_back(def->to_string(ud));
1023 }
1024 if (varArg) {
1025 temp.emplace_back(varArg->to_string(ud));
1026 }
1027 return join(temp, ", "sv);
1028}
1029std::string OuterVarShadow_t::to_string(void* ud) const {
1030 if (varList) {
1031 return "using "s + varList->to_string(ud);
1032 } else {
1033 return "using nil"s;
1034 }
1035}
1036std::string FnArgsDef_t::to_string(void* ud) const {
1037 std::string line;
1038 if (defList) {
1039 line += defList->to_string(ud);
1040 }
1041 if (shadowOption) {
1042 line += (line.empty() ? ""s : " "s) + shadowOption->to_string(ud);
1043 }
1044 return '(' + line + ')';
1045}
1046std::string FunLit_t::to_string(void* ud) const {
1047 auto info = reinterpret_cast<YueFormat*>(ud);
1048 std::string line;
1049 if (argsDef) {
1050 line = argsDef->to_string(ud);
1051 }
1052 line += arrow->to_string(ud);
1053 if (body) {
1054 if (body->content.is<Statement_t>()) {
1055 line += ' ' + body->to_string(ud);
1056 } else {
1057 info->pushScope();
1058 line += '\n' + body->to_string(ud);
1059 info->popScope();
1060 }
1061 }
1062 return line;
1063}
1064std::string MacroName_t::to_string(void* ud) const {
1065 return '$' + name->to_string(ud);
1066}
1067std::string MacroLit_t::to_string(void* ud) const {
1068 auto info = reinterpret_cast<YueFormat*>(ud);
1069 std::string line;
1070 if (argsDef) {
1071 line = '(' + argsDef->to_string(ud) + ')';
1072 }
1073 line += "->"s;
1074 if (body) {
1075 if (body->content.is<Statement_t>()) {
1076 line += ' ' + body->to_string(ud);
1077 } else {
1078 info->pushScope();
1079 line += '\n' + body->to_string(ud);
1080 info->popScope();
1081 }
1082 }
1083 return line;
1084}
1085std::string Macro_t::to_string(void* ud) const {
1086 return "macro "s + name->to_string(ud) + " = "s + macroLit->to_string(ud);
1087}
1088std::string MacroInPlace_t::to_string(void* ud) const {
1089 auto info = reinterpret_cast<YueFormat*>(ud);
1090 auto line = "$->"s;
1091 if (body) {
1092 if (body->content.is<Statement_t>()) {
1093 line += ' ' + body->to_string(ud);
1094 } else {
1095 info->pushScope();
1096 line += '\n' + body->to_string(ud);
1097 info->popScope();
1098 }
1099 }
1100 return line;
1101}
1102std::string NameOrDestructure_t::to_string(void* ud) const {
1103 return item->to_string(ud);
1104}
1105std::string AssignableNameList_t::to_string(void* ud) const {
1106 str_list temp;
1107 for (auto item : items.objects()) {
1108 temp.emplace_back(item->to_string(ud));
1109 }
1110 return join(temp, ", "sv);
1111}
1112std::string InvokeArgs_t::to_string(void* ud) const {
1113 if (!args.empty() && ast_is<TableBlock_t>(args.back())) {
1114 str_list temp;
1115 for (auto arg : args.objects()) {
1116 if (arg != args.back()) {
1117 temp.emplace_back(arg->to_string(ud));
1118 }
1119 }
1120 auto list = join(temp, ", "sv);
1121 return ' ' + list + (list.empty() ? ""s : ","s) + args.back()->to_string(ud);
1122 } else {
1123 str_list temp;
1124 for (auto arg : args.objects()) {
1125 temp.emplace_back(arg->to_string(ud));
1126 }
1127 return ' ' + join(temp, ", "sv);
1128 }
1129}
1130std::string UnaryValue_t::to_string(void* ud) const {
1131 std::string line;
1132 for (auto op : ops.objects()) {
1133 line += op->to_string(ud);
1134 }
1135 line += value->to_string(ud);
1136 return line;
1137}
1138std::string UnaryExp_t::to_string(void* ud) const {
1139 std::string line;
1140 for (auto op : ops.objects()) {
1141 line += op->to_string(ud);
1142 }
1143 str_list temp;
1144 for (auto expo : expos.objects()) {
1145 temp.push_back(expo->to_string(ud));
1146 }
1147 line += join(temp, "^"sv);
1148 if (inExp) {
1149 line += ' ' + inExp->to_string(ud);
1150 }
1151 return line;
1152}
1153std::string InRange_t::to_string(void* ud) const {
1154 auto valueStr = openValue->to_string(ud);
1155 return "in "s + (open.is<InRangeOpen_t>() ? "("s : "["s + (valueStr[0] == '[' ? " "s : ""s)) + valueStr + ", "s + closeValue->to_string(ud) + (close.is<InRangeOpen_t>() ? ')' : ']');
1156}
1157std::string InDiscrete_t::to_string(void* ud) const {
1158 str_list temp;
1159 for (auto value : values.objects()) {
1160 temp.emplace_back(value->to_string(ud));
1161 }
1162 return "in "s + '{' + join(temp, ", "sv) + '}';
1163}
1164std::string In_t::to_string(void* ud) const {
1165 if (not_) {
1166 return "not "s + item->to_string(ud);
1167 } else {
1168 return item->to_string(ud);
1169 }
1170}
1171std::string ExpListAssign_t::to_string(void* ud) const {
1172 if (action) {
1173 return expList->to_string(ud) + ' ' + action->to_string(ud);
1174 } else {
1175 return expList->to_string(ud);
1176 }
1177}
1178std::string IfLine_t::to_string(void* ud) const {
1179 return type->to_string(ud) + ' ' + condition->to_string(ud);
1180}
1181std::string WhileLine_t::to_string(void* ud) const {
1182 return type->to_string(ud) + ' ' + condition->to_string(ud);
1183}
1184std::string StatementAppendix_t::to_string(void* ud) const {
1185 return item->to_string(ud);
1186}
1187std::string Statement_t::to_string(void* ud) const {
1188 std::string line;
1189 if (appendix) {
1190 return content->to_string(ud) + ' ' + appendix->to_string(ud);
1191 } else {
1192 return content->to_string(ud);
1193 }
1194}
1195std::string StatementSep_t::to_string(void*) const {
1196 return {};
1197}
1198std::string YueMultilineComment_t::to_string(void* ud) const {
1199 return "--[["s + inner->to_string(ud) + "]]"s;
1200}
1201std::string ChainAssign_t::to_string(void* ud) const {
1202 str_list temp;
1203 for (auto exp : exprs.objects()) {
1204 temp.emplace_back(exp->to_string(ud));
1205 }
1206 return join(temp, " = "sv) + ' ' + assign->to_string(ud);
1207}
1208std::string Body_t::to_string(void* ud) const {
1209 return content->to_string(ud);
1210}
1211std::string Block_t::to_string(void* ud) const {
1212 auto info = reinterpret_cast<YueFormat*>(ud);
1213 str_list temp;
1214 for (auto stmt_ : statements.objects()) {
1215 auto stmt = static_cast<Statement_t*>(stmt_);
1216 if (stmt->content.is<PipeBody_t>()) {
1217 info->pushScope();
1218 temp.emplace_back(stmt->to_string(ud));
1219 info->popScope();
1220 } else {
1221 temp.emplace_back(info->ind() + stmt->to_string(ud));
1222 }
1223 }
1224 return join(temp, "\n"sv);
1225}
1226std::string BlockEnd_t::to_string(void* ud) const {
1227 return block->to_string(ud);
1228}
1229std::string File_t::to_string(void* ud) const {
1230 if (block) {
1231 return block->to_string(ud);
1232 } else {
1233 return {};
1234 }
1235}
1236
1237} // namespace yue
1238
1239} // namespace parserlib
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index e95e35c..c47ba8a 100644
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -17,14 +17,16 @@ namespace parserlib {
17 namespace yue { \ 17 namespace yue { \
18 class type##_t : public ast_node { \ 18 class type##_t : public ast_node { \
19 public: \ 19 public: \
20 virtual int getId() const override { return COUNTER_READ; } 20 virtual int get_id() const override { return COUNTER_READ; } \
21 virtual std::string to_string(void*) const override;
21 22
22#define AST_NODE(type) \ 23#define AST_NODE(type) \
23 COUNTER_INC; \ 24 COUNTER_INC; \
24 namespace yue { \ 25 namespace yue { \
25 class type##_t : public ast_container { \ 26 class type##_t : public ast_container { \
26 public: \ 27 public: \
27 virtual int getId() const override { return COUNTER_READ; } 28 virtual int get_id() const override { return COUNTER_READ; } \
29 virtual std::string to_string(void*) const override;
28 30
29#define AST_MEMBER(type, ...) \ 31#define AST_MEMBER(type, ...) \
30 type##_t() { \ 32 type##_t() { \
@@ -32,7 +34,7 @@ namespace parserlib {
32 } 34 }
33 35
34#define AST_END(type, name) \ 36#define AST_END(type, name) \
35 virtual const std::string_view getName() const override { return name; } \ 37 virtual const std::string_view get_name() const override { return name; } \
36 } \ 38 } \
37 ; \ 39 ; \
38 } \ 40 } \
@@ -362,7 +364,7 @@ AST_NODE(Try)
362AST_END(Try, "try"sv) 364AST_END(Try, "try"sv)
363 365
364AST_NODE(Comprehension) 366AST_NODE(Comprehension)
365 ast_sel<true, Exp_t, Statement_t> value; 367 ast_sel<true, Exp_t, /*non-syntax-rule*/ Statement_t> value;
366 ast_ptr<true, CompInner_t> forLoop; 368 ast_ptr<true, CompInner_t> forLoop;
367 AST_MEMBER(Comprehension, &value, &forLoop) 369 AST_MEMBER(Comprehension, &value, &forLoop)
368AST_END(Comprehension, "comp"sv) 370AST_END(Comprehension, "comp"sv)
@@ -659,8 +661,9 @@ AST_NODE(TableLit)
659 ast_sel_list<false, 661 ast_sel_list<false,
660 VariablePairDef_t, NormalPairDef_t, SpreadExp_t, NormalDef_t, 662 VariablePairDef_t, NormalPairDef_t, SpreadExp_t, NormalDef_t,
661 MetaVariablePairDef_t, MetaNormalPairDef_t, 663 MetaVariablePairDef_t, MetaNormalPairDef_t,
662 VariablePair_t, NormalPair_t, Exp_t, TableBlockIndent_t, 664 VariablePair_t, NormalPair_t, Exp_t,
663 MetaVariablePair_t, MetaNormalPair_t> values; 665 MetaVariablePair_t, MetaNormalPair_t,
666 /*non-syntax-rule*/ TableBlockIndent_t> values;
664 AST_MEMBER(TableLit, &sep, &values) 667 AST_MEMBER(TableLit, &sep, &values)
665AST_END(TableLit, "table_lit"sv) 668AST_END(TableLit, "table_lit"sv)
666 669
@@ -901,4 +904,17 @@ AST_END(File, "file"sv)
901 904
902// clang-format on 905// clang-format on
903 906
907struct YueFormat {
908 int indent = 0;
909 bool spaceOverTab = false;
910 int tabSpaces = 4;
911 std::string toString(ast_node* node);
912
913 Converter converter;
914 void pushScope();
915 void popScope();
916 std::string convert(const ast_node* node);
917 std::string ind() const;
918};
919
904} // namespace parserlib 920} // namespace parserlib
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 477815d..c1426f9 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -72,7 +72,7 @@ static std::unordered_set<std::string> Metamethods = {
72 "close"s // Lua 5.4 72 "close"s // Lua 5.4
73}; 73};
74 74
75const std::string_view version = "0.17.1"sv; 75const std::string_view version = "0.17.2"sv;
76const std::string_view extension = "yue"sv; 76const std::string_view extension = "yue"sv;
77 77
78class CompileError : public std::logic_error { 78class CompileError : public std::logic_error {
@@ -176,7 +176,7 @@ public:
176 if (_info.exportMacro) { 176 if (_info.exportMacro) {
177 for (auto stmt_ : block->statements.objects()) { 177 for (auto stmt_ : block->statements.objects()) {
178 auto stmt = static_cast<Statement_t*>(stmt_); 178 auto stmt = static_cast<Statement_t*>(stmt_);
179 switch (stmt->content->getId()) { 179 switch (stmt->content->get_id()) {
180 case id<MacroInPlace_t>(): 180 case id<MacroInPlace_t>():
181 case id<Macro_t>(): 181 case id<Macro_t>():
182 break; 182 break;
@@ -702,30 +702,21 @@ private:
702 return str; 702 return str;
703 } 703 }
704 704
705 std::string join(const str_list& items) { 705 std::string join(const str_list& items, std::string_view sep = {}) {
706 if (items.empty()) 706 if (items.empty())
707 return Empty; 707 return Empty;
708 else if (items.size() == 1) 708 else if (items.size() == 1)
709 return items.front(); 709 return items.front();
710 for (const auto& item : items) { 710 if (sep.empty()) {
711 _joinBuf << item; 711 for (const auto& item : items) {
712 } 712 _joinBuf << item;
713 auto result = _joinBuf.str(); 713 }
714 _joinBuf.str(""); 714 } else {
715 _joinBuf.clear(); 715 auto begin = ++items.begin();
716 return result; 716 _joinBuf << items.front();
717 } 717 for (auto it = begin; it != items.end(); ++it) {
718 718 _joinBuf << sep << *it;
719 std::string join(const str_list& items, std::string_view sep) { 719 }
720 if (items.empty())
721 return Empty;
722 else if (items.size() == 1)
723 return items.front();
724 std::string sepStr = std::string(sep);
725 auto begin = ++items.begin();
726 _joinBuf << items.front();
727 for (auto it = begin; it != items.end(); ++it) {
728 _joinBuf << sepStr << *it;
729 } 720 }
730 auto result = _joinBuf.str(); 721 auto result = _joinBuf.str();
731 _joinBuf.str(""); 722 _joinBuf.str("");
@@ -735,7 +726,7 @@ private:
735 726
736 UnaryExp_t* singleUnaryExpFrom(ast_node* item) const { 727 UnaryExp_t* singleUnaryExpFrom(ast_node* item) const {
737 Exp_t* exp = nullptr; 728 Exp_t* exp = nullptr;
738 switch (item->getId()) { 729 switch (item->get_id()) {
739 case id<Exp_t>(): 730 case id<Exp_t>():
740 exp = static_cast<Exp_t*>(item); 731 exp = static_cast<Exp_t*>(item);
741 break; 732 break;
@@ -786,7 +777,7 @@ private:
786 if (unary->ops.empty()) { 777 if (unary->ops.empty()) {
787 Value_t* value = static_cast<Value_t*>(unary->expos.back()); 778 Value_t* value = static_cast<Value_t*>(unary->expos.back());
788 if (auto chain = ast_cast<ChainValue_t>(value->item); chain && chain->items.size() == 1) { 779 if (auto chain = ast_cast<ChainValue_t>(value->item); chain && chain->items.size() == 1) {
789 if (auto exp = chain->getByPath<Callable_t, Parens_t, Exp_t>()) { 780 if (auto exp = chain->get_by_path<Callable_t, Parens_t, Exp_t>()) {
790 if (auto insideValue = singleValueFrom(exp)) { 781 if (auto insideValue = singleValueFrom(exp)) {
791 return insideValue; 782 return insideValue;
792 } 783 }
@@ -855,7 +846,7 @@ private:
855 } 846 }
856 847
857 Statement_t* lastStatementFrom(ast_node* body) const { 848 Statement_t* lastStatementFrom(ast_node* body) const {
858 switch (body->getId()) { 849 switch (body->get_id()) {
859 case id<Block_t>(): 850 case id<Block_t>():
860 return lastStatementFrom(static_cast<Block_t*>(body)); 851 return lastStatementFrom(static_cast<Block_t*>(body));
861 case id<Statement_t>(): { 852 case id<Statement_t>(): {
@@ -893,7 +884,7 @@ private:
893 } 884 }
894 885
895 Exp_t* lastExpFromAssign(ast_node* action) { 886 Exp_t* lastExpFromAssign(ast_node* action) {
896 switch (action->getId()) { 887 switch (action->get_id()) {
897 case id<Update_t>(): { 888 case id<Update_t>(): {
898 auto update = static_cast<Update_t*>(action); 889 auto update = static_cast<Update_t*>(action);
899 return update->value; 890 return update->value;
@@ -908,7 +899,7 @@ private:
908 899
909 Exp_t* lastExpFromStatement(Statement_t* stmt) { 900 Exp_t* lastExpFromStatement(Statement_t* stmt) {
910 if (!stmt->content) return nullptr; 901 if (!stmt->content) return nullptr;
911 switch (stmt->content->getId()) { 902 switch (stmt->content->get_id()) {
912 case id<ExpListAssign_t>(): { 903 case id<ExpListAssign_t>(): {
913 auto expListAssign = static_cast<ExpListAssign_t*>(stmt->content.get()); 904 auto expListAssign = static_cast<ExpListAssign_t*>(stmt->content.get());
914 if (auto action = expListAssign->action.get()) { 905 if (auto action = expListAssign->action.get()) {
@@ -922,7 +913,7 @@ private:
922 if (auto action = exportNode->assign.get()) { 913 if (auto action = exportNode->assign.get()) {
923 return lastExpFromAssign(action); 914 return lastExpFromAssign(action);
924 } else { 915 } else {
925 switch (exportNode->target->getId()) { 916 switch (exportNode->target->get_id()) {
926 case id<Exp_t>(): return exportNode->target.to<Exp_t>(); 917 case id<Exp_t>(): return exportNode->target.to<Exp_t>();
927 case id<ExpList_t>(): return static_cast<Exp_t*>(exportNode->target.to<ExpList_t>()->exprs.back()); 918 case id<ExpList_t>(): return static_cast<Exp_t*>(exportNode->target.to<ExpList_t>()->exprs.back());
928 } 919 }
@@ -1040,7 +1031,7 @@ private:
1040 BREAK_IF(!chainValue); 1031 BREAK_IF(!chainValue);
1041 BREAK_IF(chainValue->items.size() != 1); 1032 BREAK_IF(chainValue->items.size() != 1);
1042 auto callable = ast_cast<Callable_t>(chainValue->items.front()); 1033 auto callable = ast_cast<Callable_t>(chainValue->items.front());
1043 BREAK_IF(!callable || !(callable->item.is<Variable_t>() || callable->getByPath<SelfItem_t, Self_t>())); 1034 BREAK_IF(!callable || !(callable->item.is<Variable_t>() || callable->get_by_path<SelfItem_t, Self_t>()));
1044 str_list tmp; 1035 str_list tmp;
1045 if (accessing) { 1036 if (accessing) {
1046 transformCallable(callable, tmp); 1037 transformCallable(callable, tmp);
@@ -1073,7 +1064,7 @@ private:
1073 if (chainItems.size() == 1) { 1064 if (chainItems.size() == 1) {
1074 auto firstItem = chainItems.back(); 1065 auto firstItem = chainItems.back();
1075 if (auto callable = ast_cast<Callable_t>(firstItem)) { 1066 if (auto callable = ast_cast<Callable_t>(firstItem)) {
1076 switch (callable->item->getId()) { 1067 switch (callable->item->get_id()) {
1077 case id<Variable_t>(): 1068 case id<Variable_t>():
1078 checkConst(_parser.toString(callable->item.get()), callable->item.get()); 1069 checkConst(_parser.toString(callable->item.get()), callable->item.get());
1079 return true; 1070 return true;
@@ -1081,7 +1072,7 @@ private:
1081 return true; 1072 return true;
1082 } 1073 }
1083 } else 1074 } else
1084 switch (firstItem->getId()) { 1075 switch (firstItem->get_id()) {
1085 case id<DotChainItem_t>(): 1076 case id<DotChainItem_t>():
1086 case id<Exp_t>(): 1077 case id<Exp_t>():
1087 return true; 1078 return true;
@@ -1094,7 +1085,7 @@ private:
1094 return false; 1085 return false;
1095 } 1086 }
1096 auto lastItem = chainItems.back(); 1087 auto lastItem = chainItems.back();
1097 switch (lastItem->getId()) { 1088 switch (lastItem->get_id()) {
1098 case id<DotChainItem_t>(): 1089 case id<DotChainItem_t>():
1099 case id<Exp_t>(): 1090 case id<Exp_t>():
1100 case id<TableAppendingOp_t>(): 1091 case id<TableAppendingOp_t>():
@@ -1107,7 +1098,7 @@ private:
1107 bool isAssignable(Exp_t* exp) { 1098 bool isAssignable(Exp_t* exp) {
1108 if (auto value = singleValueFrom(exp)) { 1099 if (auto value = singleValueFrom(exp)) {
1109 auto item = value->item.get(); 1100 auto item = value->item.get();
1110 switch (item->getId()) { 1101 switch (item->get_id()) {
1111 case id<SimpleTable_t>(): 1102 case id<SimpleTable_t>():
1112 return true; 1103 return true;
1113 case id<SimpleValue_t>(): { 1104 case id<SimpleValue_t>(): {
@@ -1265,7 +1256,7 @@ private:
1265 auto x = statement; 1256 auto x = statement;
1266 if (_config.reserveComment && !x->comments.empty()) { 1257 if (_config.reserveComment && !x->comments.empty()) {
1267 for (ast_node* node : x->comments.objects()) { 1258 for (ast_node* node : x->comments.objects()) {
1268 switch (node->getId()) { 1259 switch (node->get_id()) {
1269 case id<YueLineComment_t>(): { 1260 case id<YueLineComment_t>(): {
1270 auto comment = ast_cast<YueLineComment_t>(node); 1261 auto comment = ast_cast<YueLineComment_t>(node);
1271 out.push_back(indent() + "--"s + _parser.toString(comment) + '\n'); 1262 out.push_back(indent() + "--"s + _parser.toString(comment) + '\n');
@@ -1290,7 +1281,7 @@ private:
1290 } 1281 }
1291 } else if (auto attrib = statement->content.as<LocalAttrib_t>()) { 1282 } else if (auto attrib = statement->content.as<LocalAttrib_t>()) {
1292 auto appendix = statement->appendix.get(); 1283 auto appendix = statement->appendix.get();
1293 switch (appendix->item->getId()) { 1284 switch (appendix->item->get_id()) {
1294 case id<IfLine_t>(): { 1285 case id<IfLine_t>(): {
1295 auto if_line = static_cast<IfLine_t*>(appendix->item.get()); 1286 auto if_line = static_cast<IfLine_t*>(appendix->item.get());
1296 auto ifNode = x->new_ptr<If_t>(); 1287 auto ifNode = x->new_ptr<If_t>();
@@ -1299,7 +1290,7 @@ private:
1299 1290
1300 auto expList = x->new_ptr<ExpList_t>(); 1291 auto expList = x->new_ptr<ExpList_t>();
1301 for (auto val : attrib->assign->values.objects()) { 1292 for (auto val : attrib->assign->values.objects()) {
1302 switch (val->getId()) { 1293 switch (val->get_id()) {
1303 case id<If_t>(): 1294 case id<If_t>():
1304 case id<Switch_t>(): 1295 case id<Switch_t>():
1305 case id<With_t>(): { 1296 case id<With_t>(): {
@@ -1350,7 +1341,7 @@ private:
1350 } 1341 }
1351 } else if (!statement->appendix->item.is<IfLine_t>()) { 1342 } else if (!statement->appendix->item.is<IfLine_t>()) {
1352 auto appendix = statement->appendix->item.get(); 1343 auto appendix = statement->appendix->item.get();
1353 switch (statement->content->getId()) { 1344 switch (statement->content->get_id()) {
1354 case id<Return_t>(): 1345 case id<Return_t>():
1355 throw CompileError("loop line decorator can not be used in a return statement"sv, appendix); 1346 throw CompileError("loop line decorator can not be used in a return statement"sv, appendix);
1356 break; 1347 break;
@@ -1360,7 +1351,7 @@ private:
1360 } 1351 }
1361 } 1352 }
1362 auto appendix = statement->appendix.get(); 1353 auto appendix = statement->appendix.get();
1363 switch (appendix->item->getId()) { 1354 switch (appendix->item->get_id()) {
1364 case id<IfLine_t>(): { 1355 case id<IfLine_t>(): {
1365 auto if_line = static_cast<IfLine_t*>(appendix->item.get()); 1356 auto if_line = static_cast<IfLine_t*>(appendix->item.get());
1366 auto ifNode = x->new_ptr<If_t>(); 1357 auto ifNode = x->new_ptr<If_t>();
@@ -1429,7 +1420,7 @@ private:
1429 out.push_back(Empty); 1420 out.push_back(Empty);
1430 return; 1421 return;
1431 } 1422 }
1432 switch (content->getId()) { 1423 switch (content->get_id()) {
1433 case id<Import_t>(): transformImport(static_cast<Import_t*>(content), out); break; 1424 case id<Import_t>(): transformImport(static_cast<Import_t*>(content), out); break;
1434 case id<While_t>(): transformWhile(static_cast<While_t*>(content), out); break; 1425 case id<While_t>(): transformWhile(static_cast<While_t*>(content), out); break;
1435 case id<Repeat_t>(): transformRepeat(static_cast<Repeat_t*>(content), out); break; 1426 case id<Repeat_t>(): transformRepeat(static_cast<Repeat_t*>(content), out); break;
@@ -1461,7 +1452,7 @@ private:
1461 if (auto simpleValue = singleValue->item.as<SimpleValue_t>()) { 1452 if (auto simpleValue = singleValue->item.as<SimpleValue_t>()) {
1462 auto value = simpleValue->value.get(); 1453 auto value = simpleValue->value.get();
1463 bool specialSingleValue = true; 1454 bool specialSingleValue = true;
1464 switch (value->getId()) { 1455 switch (value->get_id()) {
1465 case id<If_t>(): transformIf(static_cast<If_t*>(value), out, ExpUsage::Common); break; 1456 case id<If_t>(): transformIf(static_cast<If_t*>(value), out, ExpUsage::Common); break;
1466 case id<ClassDecl_t>(): transformClassDecl(static_cast<ClassDecl_t*>(value), out, ExpUsage::Common); break; 1457 case id<ClassDecl_t>(): transformClassDecl(static_cast<ClassDecl_t*>(value), out, ExpUsage::Common); break;
1467 case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Common); break; 1458 case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Common); break;
@@ -1669,7 +1660,7 @@ private:
1669 bool checkValuesLater = false; 1660 bool checkValuesLater = false;
1670 if (exprs.size() > values.size()) { 1661 if (exprs.size() > values.size()) {
1671 BLOCK_START 1662 BLOCK_START
1672 switch (values.back()->getId()) { 1663 switch (values.back()->get_id()) {
1673 case id<If_t>(): 1664 case id<If_t>():
1674 case id<Switch_t>(): 1665 case id<Switch_t>():
1675 checkValuesLater = true; 1666 checkValuesLater = true;
@@ -1682,7 +1673,7 @@ private:
1682 throw CompileError(clearBuf(), values.front()); 1673 throw CompileError(clearBuf(), values.front());
1683 } 1674 }
1684 if (auto val = value->item.as<SimpleValue_t>()) { 1675 if (auto val = value->item.as<SimpleValue_t>()) {
1685 switch (val->value->getId()) { 1676 switch (val->value->get_id()) {
1686 case id<If_t>(): 1677 case id<If_t>():
1687 case id<Switch_t>(): 1678 case id<Switch_t>():
1688 case id<Do_t>(): 1679 case id<Do_t>():
@@ -1711,7 +1702,7 @@ private:
1711 BLOCK_START 1702 BLOCK_START
1712 auto value = singleValueFrom(*it); 1703 auto value = singleValueFrom(*it);
1713 BREAK_IF(!value); 1704 BREAK_IF(!value);
1714 if (value->item.is<SimpleTable_t>() || value->getByPath<SimpleValue_t, TableLit_t>()) { 1705 if (value->item.is<SimpleTable_t>() || value->get_by_path<SimpleValue_t, TableLit_t>()) {
1715 holdItem = true; 1706 holdItem = true;
1716 break; 1707 break;
1717 } 1708 }
@@ -1868,7 +1859,7 @@ private:
1868 value = val->value.get(); 1859 value = val->value.get();
1869 } 1860 }
1870 } 1861 }
1871 switch (value->getId()) { 1862 switch (value->get_id()) {
1872 case id<If_t>(): { 1863 case id<If_t>(): {
1873 auto ifNode = static_cast<If_t*>(value); 1864 auto ifNode = static_cast<If_t*>(value);
1874 auto assignList = assignment->expList.get(); 1865 auto assignList = assignment->expList.get();
@@ -2252,7 +2243,7 @@ private:
2252 } 2243 }
2253 2244
2254 void transformAssignItem(ast_node* value, str_list& out) { 2245 void transformAssignItem(ast_node* value, str_list& out) {
2255 switch (value->getId()) { 2246 switch (value->get_id()) {
2256 case id<With_t>(): transformWithClosure(static_cast<With_t*>(value), out); break; 2247 case id<With_t>(): transformWithClosure(static_cast<With_t*>(value), out); break;
2257 case id<If_t>(): transformIf(static_cast<If_t*>(value), out, ExpUsage::Closure); break; 2248 case id<If_t>(): transformIf(static_cast<If_t*>(value), out, ExpUsage::Closure); break;
2258 case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Closure); break; 2249 case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Closure); break;
@@ -2265,11 +2256,11 @@ private:
2265 std::list<DestructItem> destructFromExp(ast_node* node, bool optional) { 2256 std::list<DestructItem> destructFromExp(ast_node* node, bool optional) {
2266 const node_container* tableItems = nullptr; 2257 const node_container* tableItems = nullptr;
2267 ast_ptr<false, ExistentialOp_t> sep = optional ? node->new_ptr<ExistentialOp_t>() : nullptr; 2258 ast_ptr<false, ExistentialOp_t> sep = optional ? node->new_ptr<ExistentialOp_t>() : nullptr;
2268 switch (node->getId()) { 2259 switch (node->get_id()) {
2269 case id<Exp_t>(): { 2260 case id<Exp_t>(): {
2270 auto item = singleValueFrom(node)->item.get(); 2261 auto item = singleValueFrom(node)->item.get();
2271 if (!item) throw CompileError("invalid destructure value"sv, node); 2262 if (!item) throw CompileError("invalid destructure value"sv, node);
2272 auto tbA = item->getByPath<TableLit_t>(); 2263 auto tbA = item->get_by_path<TableLit_t>();
2273 if (tbA) { 2264 if (tbA) {
2274 tableItems = &tbA->values.objects(); 2265 tableItems = &tbA->values.objects();
2275 } else { 2266 } else {
@@ -2305,7 +2296,7 @@ private:
2305 int index = 0; 2296 int index = 0;
2306 auto subMetaDestruct = node->new_ptr<TableLit_t>(); 2297 auto subMetaDestruct = node->new_ptr<TableLit_t>();
2307 for (auto pair : *tableItems) { 2298 for (auto pair : *tableItems) {
2308 switch (pair->getId()) { 2299 switch (pair->get_id()) {
2309 case id<Exp_t>(): 2300 case id<Exp_t>():
2310 case id<NormalDef_t>(): { 2301 case id<NormalDef_t>(): {
2311 Exp_t* defVal = nullptr; 2302 Exp_t* defVal = nullptr;
@@ -2319,7 +2310,7 @@ private:
2319 } 2310 }
2320 auto value = singleValueFrom(pair); 2311 auto value = singleValueFrom(pair);
2321 auto item = value->item.get(); 2312 auto item = value->item.get();
2322 if (ast_is<SimpleTable_t>(item) || item->getByPath<TableLit_t>()) { 2313 if (ast_is<SimpleTable_t>(item) || item->get_by_path<TableLit_t>()) {
2323 auto subPairs = destructFromExp(pair, optional); 2314 auto subPairs = destructFromExp(pair, optional);
2324 if (!subPairs.empty()) { 2315 if (!subPairs.empty()) {
2325 if (defVal) { 2316 if (defVal) {
@@ -2372,14 +2363,14 @@ private:
2372 auto np = static_cast<NormalPair_t*>(pair); 2363 auto np = static_cast<NormalPair_t*>(pair);
2373 ast_ptr<true, ast_node> keyIndex; 2364 ast_ptr<true, ast_node> keyIndex;
2374 if (np->key) { 2365 if (np->key) {
2375 if (auto key = np->key->getByPath<Name_t>()) { 2366 if (auto key = np->key->get_by_path<Name_t>()) {
2376 auto keyNameStr = _parser.toString(key); 2367 auto keyNameStr = _parser.toString(key);
2377 if (LuaKeywords.find(keyNameStr) != LuaKeywords.end()) { 2368 if (LuaKeywords.find(keyNameStr) != LuaKeywords.end()) {
2378 keyIndex = toAst<Exp_t>('"' + keyNameStr + '"', key).get(); 2369 keyIndex = toAst<Exp_t>('"' + keyNameStr + '"', key).get();
2379 } else { 2370 } else {
2380 keyIndex = toAst<DotChainItem_t>('.' + keyNameStr, key).get(); 2371 keyIndex = toAst<DotChainItem_t>('.' + keyNameStr, key).get();
2381 } 2372 }
2382 } else if (auto key = np->key->getByPath<SelfItem_t>()) { 2373 } else if (auto key = np->key->get_by_path<SelfItem_t>()) {
2383 auto callable = np->new_ptr<Callable_t>(); 2374 auto callable = np->new_ptr<Callable_t>();
2384 callable->item.set(key); 2375 callable->item.set(key);
2385 auto chainValue = np->new_ptr<ChainValue_t>(); 2376 auto chainValue = np->new_ptr<ChainValue_t>();
@@ -2396,7 +2387,7 @@ private:
2396 if (auto exp = np->value.as<Exp_t>()) { 2387 if (auto exp = np->value.as<Exp_t>()) {
2397 if (!isAssignable(exp)) throw CompileError("can't do destructure value"sv, exp); 2388 if (!isAssignable(exp)) throw CompileError("can't do destructure value"sv, exp);
2398 auto item = singleValueFrom(exp)->item.get(); 2389 auto item = singleValueFrom(exp)->item.get();
2399 if (ast_is<SimpleTable_t>(item) || item->getByPath<TableLit_t>()) { 2390 if (ast_is<SimpleTable_t>(item) || item->get_by_path<TableLit_t>()) {
2400 auto subPairs = destructFromExp(exp, optional); 2391 auto subPairs = destructFromExp(exp, optional);
2401 if (!subPairs.empty()) { 2392 if (!subPairs.empty()) {
2402 if (defVal) { 2393 if (defVal) {
@@ -2476,7 +2467,7 @@ private:
2476 auto mp = static_cast<MetaNormalPair_t*>(pair); 2467 auto mp = static_cast<MetaNormalPair_t*>(pair);
2477 auto newPair = pair->new_ptr<NormalPair_t>(); 2468 auto newPair = pair->new_ptr<NormalPair_t>();
2478 if (mp->key) { 2469 if (mp->key) {
2479 switch (mp->key->getId()) { 2470 switch (mp->key->get_id()) {
2480 case id<Name_t>(): { 2471 case id<Name_t>(): {
2481 auto key = _parser.toString(mp->key); 2472 auto key = _parser.toString(mp->key);
2482 checkMetamethod(key, mp->key); 2473 checkMetamethod(key, mp->key);
@@ -2550,11 +2541,11 @@ private:
2550 if (!value) { 2541 if (!value) {
2551 throw CompileError("invalid destructure"sv, expr); 2542 throw CompileError("invalid destructure"sv, expr);
2552 } 2543 }
2553 ast_node* destructNode = value->getByPath<SimpleValue_t, TableLit_t>(); 2544 ast_node* destructNode = value->get_by_path<SimpleValue_t, TableLit_t>();
2554 if (destructNode || (destructNode = value->item.as<SimpleTable_t>())) { 2545 if (destructNode || (destructNode = value->item.as<SimpleTable_t>())) {
2555 if (*j != nil) { 2546 if (*j != nil) {
2556 if (auto ssVal = simpleSingleValueFrom(*j)) { 2547 if (auto ssVal = simpleSingleValueFrom(*j)) {
2557 switch (ssVal->value->getId()) { 2548 switch (ssVal->value->get_id()) {
2558 case id<ConstValue_t>(): 2549 case id<ConstValue_t>():
2559 throw CompileError("can not destructure a constant"sv, ssVal->value); 2550 throw CompileError("can not destructure a constant"sv, ssVal->value);
2560 break; 2551 break;
@@ -2571,7 +2562,7 @@ private:
2571 auto subDestruct = destructNode->new_ptr<TableLit_t>(); 2562 auto subDestruct = destructNode->new_ptr<TableLit_t>();
2572 auto subMetaDestruct = destructNode->new_ptr<TableLit_t>(); 2563 auto subMetaDestruct = destructNode->new_ptr<TableLit_t>();
2573 const node_container* dlist = nullptr; 2564 const node_container* dlist = nullptr;
2574 switch (destructNode->getId()) { 2565 switch (destructNode->get_id()) {
2575 case id<TableLit_t>(): 2566 case id<TableLit_t>():
2576 dlist = &static_cast<TableLit_t*>(destructNode)->values.objects(); 2567 dlist = &static_cast<TableLit_t*>(destructNode)->values.objects();
2577 break; 2568 break;
@@ -2581,7 +2572,7 @@ private:
2581 default: YUEE("AST node mismatch", destructNode); break; 2572 default: YUEE("AST node mismatch", destructNode); break;
2582 } 2573 }
2583 for (auto item : *dlist) { 2574 for (auto item : *dlist) {
2584 switch (item->getId()) { 2575 switch (item->get_id()) {
2585 case id<MetaVariablePairDef_t>(): { 2576 case id<MetaVariablePairDef_t>(): {
2586 auto mvp = static_cast<MetaVariablePairDef_t*>(item); 2577 auto mvp = static_cast<MetaVariablePairDef_t*>(item);
2587 auto mp = mvp->pair.get(); 2578 auto mp = mvp->pair.get();
@@ -2598,7 +2589,7 @@ private:
2598 auto mp = mnp->pair.get(); 2589 auto mp = mnp->pair.get();
2599 auto newPair = item->new_ptr<NormalPair_t>(); 2590 auto newPair = item->new_ptr<NormalPair_t>();
2600 if (mp->key) { 2591 if (mp->key) {
2601 switch (mp->key->getId()) { 2592 switch (mp->key->get_id()) {
2602 case id<Name_t>(): { 2593 case id<Name_t>(): {
2603 auto key = _parser.toString(mp->key); 2594 auto key = _parser.toString(mp->key);
2604 checkMetamethod(key, mp->key); 2595 checkMetamethod(key, mp->key);
@@ -2637,7 +2628,7 @@ private:
2637 auto mp = static_cast<MetaNormalPair_t*>(item); 2628 auto mp = static_cast<MetaNormalPair_t*>(item);
2638 auto newPair = item->new_ptr<NormalPair_t>(); 2629 auto newPair = item->new_ptr<NormalPair_t>();
2639 if (mp->key) { 2630 if (mp->key) {
2640 switch (mp->key->getId()) { 2631 switch (mp->key->get_id()) {
2641 case id<Name_t>(): { 2632 case id<Name_t>(): {
2642 auto key = _parser.toString(mp->key); 2633 auto key = _parser.toString(mp->key);
2643 checkMetamethod(key, mp->key); 2634 checkMetamethod(key, mp->key);
@@ -2808,7 +2799,7 @@ private:
2808 str_list temp; 2799 str_list temp;
2809 auto expList = assignment->expList.get(); 2800 auto expList = assignment->expList.get();
2810 auto action = assignment->action.get(); 2801 auto action = assignment->action.get();
2811 switch (action->getId()) { 2802 switch (action->get_id()) {
2812 case id<Update_t>(): { 2803 case id<Update_t>(): {
2813 if (expList->exprs.size() > 1) throw CompileError("can not apply update to multiple values"sv, expList); 2804 if (expList->exprs.size() > 1) throw CompileError("can not apply update to multiple values"sv, expList);
2814 auto update = static_cast<Update_t*>(action); 2805 auto update = static_cast<Update_t*>(action);
@@ -3002,7 +2993,7 @@ private:
3002 std::list<std::pair<IfCond_t*, ast_node*>> ifCondPairs; 2993 std::list<std::pair<IfCond_t*, ast_node*>> ifCondPairs;
3003 ifCondPairs.emplace_back(); 2994 ifCondPairs.emplace_back();
3004 for (auto node : nodes) { 2995 for (auto node : nodes) {
3005 switch (node->getId()) { 2996 switch (node->get_id()) {
3006 case id<IfCond_t>(): 2997 case id<IfCond_t>():
3007 ifCondPairs.back().first = static_cast<IfCond_t*>(node); 2998 ifCondPairs.back().first = static_cast<IfCond_t*>(node);
3008 break; 2999 break;
@@ -3375,7 +3366,7 @@ private:
3375 3366
3376 void transformValue(Value_t* value, str_list& out) { 3367 void transformValue(Value_t* value, str_list& out) {
3377 auto item = value->item.get(); 3368 auto item = value->item.get();
3378 switch (item->getId()) { 3369 switch (item->get_id()) {
3379 case id<SimpleValue_t>(): transformSimpleValue(static_cast<SimpleValue_t*>(item), out); break; 3370 case id<SimpleValue_t>(): transformSimpleValue(static_cast<SimpleValue_t*>(item), out); break;
3380 case id<SimpleTable_t>(): transform_simple_table(static_cast<SimpleTable_t*>(item), out); break; 3371 case id<SimpleTable_t>(): transform_simple_table(static_cast<SimpleTable_t*>(item), out); break;
3381 case id<ChainValue_t>(): transformChainValue(static_cast<ChainValue_t*>(item), out, ExpUsage::Closure); break; 3372 case id<ChainValue_t>(): transformChainValue(static_cast<ChainValue_t*>(item), out, ExpUsage::Closure); break;
@@ -3386,7 +3377,7 @@ private:
3386 3377
3387 void transformCallable(Callable_t* callable, str_list& out, const ast_sel<false, Invoke_t, InvokeArgs_t>& invoke = {}) { 3378 void transformCallable(Callable_t* callable, str_list& out, const ast_sel<false, Invoke_t, InvokeArgs_t>& invoke = {}) {
3388 auto item = callable->item.get(); 3379 auto item = callable->item.get();
3389 switch (item->getId()) { 3380 switch (item->get_id()) {
3390 case id<Variable_t>(): { 3381 case id<Variable_t>(): {
3391 transformVariable(static_cast<Variable_t*>(item), out); 3382 transformVariable(static_cast<Variable_t*>(item), out);
3392 if (_config.lintGlobalVariable && !isLocal(out.back())) { 3383 if (_config.lintGlobalVariable && !isLocal(out.back())) {
@@ -3414,7 +3405,7 @@ private:
3414 3405
3415 void transformSimpleValue(SimpleValue_t* simpleValue, str_list& out) { 3406 void transformSimpleValue(SimpleValue_t* simpleValue, str_list& out) {
3416 auto value = simpleValue->value.get(); 3407 auto value = simpleValue->value.get();
3417 switch (value->getId()) { 3408 switch (value->get_id()) {
3418 case id<ConstValue_t>(): transformConstValue(static_cast<ConstValue_t*>(value), out); break; 3409 case id<ConstValue_t>(): transformConstValue(static_cast<ConstValue_t*>(value), out); break;
3419 case id<If_t>(): transformIf(static_cast<If_t*>(value), out, ExpUsage::Closure); break; 3410 case id<If_t>(): transformIf(static_cast<If_t*>(value), out, ExpUsage::Closure); break;
3420 case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Closure); break; 3411 case id<Switch_t>(): transformSwitch(static_cast<Switch_t*>(value), out, ExpUsage::Closure); break;
@@ -3619,7 +3610,7 @@ private:
3619 if (auto local = stmt->content.as<Local_t>()) { 3610 if (auto local = stmt->content.as<Local_t>()) {
3620 if (!local->collected) { 3611 if (!local->collected) {
3621 local->collected = true; 3612 local->collected = true;
3622 switch (local->item->getId()) { 3613 switch (local->item->get_id()) {
3623 case id<LocalFlag_t>(): { 3614 case id<LocalFlag_t>(): {
3624 auto flag = static_cast<LocalFlag_t*>(local->item.get()); 3615 auto flag = static_cast<LocalFlag_t*>(local->item.get());
3625 LocalMode newMode = _parser.toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital; 3616 LocalMode newMode = _parser.toString(flag) == "*"sv ? LocalMode::Any : LocalMode::Capital;
@@ -3695,11 +3686,11 @@ private:
3695 BREAK_IF(!exp); 3686 BREAK_IF(!exp);
3696 auto value = singleValueFrom(exp); 3687 auto value = singleValueFrom(exp);
3697 BREAK_IF(!value); 3688 BREAK_IF(!value);
3698 classDecl = value->getByPath<SimpleValue_t, ClassDecl_t>(); 3689 classDecl = value->get_by_path<SimpleValue_t, ClassDecl_t>();
3699 BLOCK_END 3690 BLOCK_END
3700 } else if (auto expList = expListFrom(stmt)) { 3691 } else if (auto expList = expListFrom(stmt)) {
3701 auto value = singleValueFrom(expList); 3692 auto value = singleValueFrom(expList);
3702 classDecl = value->getByPath<SimpleValue_t, ClassDecl_t>(); 3693 classDecl = value->get_by_path<SimpleValue_t, ClassDecl_t>();
3703 } 3694 }
3704 if (classDecl) { 3695 if (classDecl) {
3705 if (auto variable = classDecl->name->item.as<Variable_t>()) { 3696 if (auto variable = classDecl->name->item.as<Variable_t>()) {
@@ -3743,7 +3734,7 @@ private:
3743 if (!last) throw CompileError("block is not assignable"sv, block); 3734 if (!last) throw CompileError("block is not assignable"sv, block);
3744 if (last->appendix) { 3735 if (last->appendix) {
3745 auto appendix = last->appendix->item.get(); 3736 auto appendix = last->appendix->item.get();
3746 switch (appendix->getId()) { 3737 switch (appendix->get_id()) {
3747 case id<WhileLine_t>(): 3738 case id<WhileLine_t>():
3748 throw CompileError("while-loop line decorator is not supported here"sv, appendix); 3739 throw CompileError("while-loop line decorator is not supported here"sv, appendix);
3749 break; 3740 break;
@@ -4068,7 +4059,7 @@ private:
4068 if (auto singleValue = singleValueFrom(valueList)) { 4059 if (auto singleValue = singleValueFrom(valueList)) {
4069 if (auto simpleValue = singleValue->item.as<SimpleValue_t>()) { 4060 if (auto simpleValue = singleValue->item.as<SimpleValue_t>()) {
4070 auto value = simpleValue->value.get(); 4061 auto value = simpleValue->value.get();
4071 switch (value->getId()) { 4062 switch (value->get_id()) {
4072 case id<Comprehension_t>(): 4063 case id<Comprehension_t>():
4073 transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Return); 4064 transformComprehension(static_cast<Comprehension_t*>(value), out, ExpUsage::Return);
4074 return; 4065 return;
@@ -4169,7 +4160,7 @@ private:
4169 for (auto _def : argDefList->definitions.objects()) { 4160 for (auto _def : argDefList->definitions.objects()) {
4170 auto def = static_cast<FnArgDef_t*>(_def); 4161 auto def = static_cast<FnArgDef_t*>(_def);
4171 auto& arg = argItems.emplace_back(); 4162 auto& arg = argItems.emplace_back();
4172 switch (def->name->getId()) { 4163 switch (def->name->get_id()) {
4173 case id<Variable_t>(): arg.name = _parser.toString(def->name); break; 4164 case id<Variable_t>(): arg.name = _parser.toString(def->name); break;
4174 case id<SelfItem_t>(): { 4165 case id<SelfItem_t>(): {
4175 assignSelf = true; 4166 assignSelf = true;
@@ -4180,7 +4171,7 @@ private:
4180 arg.checkExistence = true; 4171 arg.checkExistence = true;
4181 } 4172 }
4182 auto selfName = static_cast<SelfItem_t*>(def->name.get()); 4173 auto selfName = static_cast<SelfItem_t*>(def->name.get());
4183 switch (selfName->name->getId()) { 4174 switch (selfName->name->get_id()) {
4184 case id<SelfClassName_t>(): { 4175 case id<SelfClassName_t>(): {
4185 auto clsName = static_cast<SelfClassName_t*>(selfName->name.get()); 4176 auto clsName = static_cast<SelfClassName_t*>(selfName->name.get());
4186 arg.name = _parser.toString(clsName->name); 4177 arg.name = _parser.toString(clsName->name);
@@ -4254,7 +4245,7 @@ private:
4254 void transformSelfName(SelfItem_t* selfName, str_list& out, const ast_sel<false, Invoke_t, InvokeArgs_t>& invoke = {}) { 4245 void transformSelfName(SelfItem_t* selfName, str_list& out, const ast_sel<false, Invoke_t, InvokeArgs_t>& invoke = {}) {
4255 auto x = selfName; 4246 auto x = selfName;
4256 auto name = selfName->name.get(); 4247 auto name = selfName->name.get();
4257 switch (name->getId()) { 4248 switch (name->get_id()) {
4258 case id<SelfClassName_t>(): { 4249 case id<SelfClassName_t>(): {
4259 auto clsName = static_cast<SelfClassName_t*>(name); 4250 auto clsName = static_cast<SelfClassName_t*>(name);
4260 auto nameStr = _parser.toString(clsName->name); 4251 auto nameStr = _parser.toString(clsName->name);
@@ -4537,7 +4528,7 @@ private:
4537 break; 4528 break;
4538 } 4529 }
4539 auto baseChain = x->new_ptr<ChainValue_t>(); 4530 auto baseChain = x->new_ptr<ChainValue_t>();
4540 switch (chainList.front()->getId()) { 4531 switch (chainList.front()->get_id()) {
4541 case id<DotChainItem_t>(): 4532 case id<DotChainItem_t>():
4542 case id<ColonChainItem_t>(): 4533 case id<ColonChainItem_t>():
4543 case id<Exp_t>(): 4534 case id<Exp_t>():
@@ -4648,11 +4639,11 @@ private:
4648 chain = toAst<ChainValue_t>("getmetatable()"sv, x); 4639 chain = toAst<ChainValue_t>("getmetatable()"sv, x);
4649 ast_to<Invoke_t>(chain->items.back())->args.push_back(exp); 4640 ast_to<Invoke_t>(chain->items.back())->args.push_back(exp);
4650 } 4641 }
4651 switch ((*opIt)->getId()) { 4642 switch ((*opIt)->get_id()) {
4652 case id<ColonChainItem_t>(): { 4643 case id<ColonChainItem_t>(): {
4653 auto colon = static_cast<ColonChainItem_t*>(*opIt); 4644 auto colon = static_cast<ColonChainItem_t*>(*opIt);
4654 auto meta = colon->name.to<Metamethod_t>(); 4645 auto meta = colon->name.to<Metamethod_t>();
4655 switch (meta->item->getId()) { 4646 switch (meta->item->get_id()) {
4656 case id<Name_t>(): { 4647 case id<Name_t>(): {
4657 auto name = _parser.toString(meta->item); 4648 auto name = _parser.toString(meta->item);
4658 checkMetamethod(name, meta->item); 4649 checkMetamethod(name, meta->item);
@@ -4747,7 +4738,7 @@ private:
4747 auto dot = static_cast<DotChainItem_t*>(*opIt); 4738 auto dot = static_cast<DotChainItem_t*>(*opIt);
4748 if (dot->name.is<Metatable_t>()) break; 4739 if (dot->name.is<Metatable_t>()) break;
4749 auto meta = dot->name.to<Metamethod_t>(); 4740 auto meta = dot->name.to<Metamethod_t>();
4750 switch (meta->item->getId()) { 4741 switch (meta->item->get_id()) {
4751 case id<Name_t>(): { 4742 case id<Name_t>(): {
4752 auto name = _parser.toString(meta->item); 4743 auto name = _parser.toString(meta->item);
4753 checkMetamethod(name, meta->item); 4744 checkMetamethod(name, meta->item);
@@ -4778,7 +4769,7 @@ private:
4778 void transformChainList(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 4769 void transformChainList(const node_container& chainList, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
4779 auto x = chainList.front(); 4770 auto x = chainList.front();
4780 str_list temp; 4771 str_list temp;
4781 switch (x->getId()) { 4772 switch (x->get_id()) {
4782 case id<DotChainItem_t>(): 4773 case id<DotChainItem_t>():
4783 case id<ColonChainItem_t>(): 4774 case id<ColonChainItem_t>():
4784 case id<Exp_t>(): 4775 case id<Exp_t>():
@@ -4791,7 +4782,7 @@ private:
4791 } 4782 }
4792 for (auto it = chainList.begin(); it != chainList.end(); ++it) { 4783 for (auto it = chainList.begin(); it != chainList.end(); ++it) {
4793 auto item = *it; 4784 auto item = *it;
4794 switch (item->getId()) { 4785 switch (item->get_id()) {
4795 case id<Invoke_t>(): 4786 case id<Invoke_t>():
4796 transformInvoke(static_cast<Invoke_t*>(item), temp); 4787 transformInvoke(static_cast<Invoke_t*>(item), temp);
4797 break; 4788 break;
@@ -4823,7 +4814,7 @@ private:
4823 auto block = x->new_ptr<Block_t>(); 4814 auto block = x->new_ptr<Block_t>();
4824 { 4815 {
4825 auto chainValue = x->new_ptr<ChainValue_t>(); 4816 auto chainValue = x->new_ptr<ChainValue_t>();
4826 switch (chainList.front()->getId()) { 4817 switch (chainList.front()->get_id()) {
4827 case id<DotChainItem_t>(): 4818 case id<DotChainItem_t>():
4828 case id<ColonChainItem_t>(): 4819 case id<ColonChainItem_t>():
4829 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x)); 4820 chainValue->items.push_back(toAst<Callable_t>(_withVars.top(), x));
@@ -5058,7 +5049,7 @@ private:
5058 BREAK_IF(!exp); 5049 BREAK_IF(!exp);
5059 auto value = singleValueFrom(exp); 5050 auto value = singleValueFrom(exp);
5060 BREAK_IF(!value); 5051 BREAK_IF(!value);
5061 auto lstr = value->getByPath<String_t, LuaString_t>(); 5052 auto lstr = value->get_by_path<String_t, LuaString_t>();
5062 BREAK_IF(!lstr); 5053 BREAK_IF(!lstr);
5063 str = _parser.toString(lstr->content); 5054 str = _parser.toString(lstr->content);
5064 rawString = true; 5055 rawString = true;
@@ -5071,21 +5062,15 @@ private:
5071 auto exp = static_cast<Exp_t*>(arg); 5062 auto exp = static_cast<Exp_t*>(arg);
5072 BLOCK_START 5063 BLOCK_START
5073 BREAK_IF(!exp->opValues.empty()); 5064 BREAK_IF(!exp->opValues.empty());
5074 auto chainValue = exp->getByPath<UnaryExp_t, Value_t, ChainValue_t>(); 5065 auto chainValue = exp->get_by_path<UnaryExp_t, Value_t, ChainValue_t>();
5075 BREAK_IF(!chainValue); 5066 BREAK_IF(!chainValue);
5076 BREAK_IF(!isMacroChain(chainValue)); 5067 BREAK_IF(!isMacroChain(chainValue));
5077 str = std::get<1>(expandMacroStr(chainValue)); 5068 str = std::get<1>(expandMacroStr(chainValue));
5078 BLOCK_END 5069 BLOCK_END
5079 if (str.empty() && arg->m_begin.m_it == arg->m_end.m_it) {
5080 // exp is reassembled due to pipe expressions
5081 // in transform stage, toString(exp) won't be able
5082 // to convert its whole text content
5083 str = _parser.toString(exp->pipeExprs.front());
5084 }
5085 } 5070 }
5086 } 5071 }
5087 if (!rawString && str.empty()) { 5072 if (!rawString && str.empty()) {
5088 str = _parser.toString(arg); 5073 str = YueFormat{}.toString(arg);
5089 } 5074 }
5090 Utils::trim(str); 5075 Utils::trim(str);
5091 Utils::replace(str, "\r\n"sv, "\n"sv); 5076 Utils::replace(str, "\r\n"sv, "\n"sv);
@@ -5364,7 +5349,7 @@ private:
5364 void transformInvoke(Invoke_t* invoke, str_list& out) { 5349 void transformInvoke(Invoke_t* invoke, str_list& out) {
5365 str_list temp; 5350 str_list temp;
5366 for (auto arg : invoke->args.objects()) { 5351 for (auto arg : invoke->args.objects()) {
5367 switch (arg->getId()) { 5352 switch (arg->get_id()) {
5368 case id<Exp_t>(): transformExp(static_cast<Exp_t*>(arg), temp, ExpUsage::Closure); break; 5353 case id<Exp_t>(): transformExp(static_cast<Exp_t*>(arg), temp, ExpUsage::Closure); break;
5369 case id<SingleString_t>(): transformSingleString(static_cast<SingleString_t*>(arg), temp); break; 5354 case id<SingleString_t>(): transformSingleString(static_cast<SingleString_t*>(arg), temp); break;
5370 case id<DoubleString_t>(): transformDoubleString(static_cast<DoubleString_t*>(arg), temp); break; 5355 case id<DoubleString_t>(): transformDoubleString(static_cast<DoubleString_t*>(arg), temp); break;
@@ -5583,7 +5568,7 @@ private:
5583 } 5568 }
5584 for (; it != values.end(); ++it) { 5569 for (; it != values.end(); ++it) {
5585 auto item = *it; 5570 auto item = *it;
5586 switch (item->getId()) { 5571 switch (item->get_id()) {
5587 case id<SpreadExp_t>(): { 5572 case id<SpreadExp_t>(): {
5588 auto spread = static_cast<SpreadExp_t*>(item); 5573 auto spread = static_cast<SpreadExp_t*>(item);
5589 std::string indexVar = getUnusedName("_idx_"sv); 5574 std::string indexVar = getUnusedName("_idx_"sv);
@@ -5635,7 +5620,7 @@ private:
5635 auto assignment = toAst<ExpListAssign_t>(tableVar + "=nil"s, item); 5620 auto assignment = toAst<ExpListAssign_t>(tableVar + "=nil"s, item);
5636 auto chainValue = singleValueFrom(ast_to<Exp_t>(assignment->expList->exprs.front()))->item.to<ChainValue_t>(); 5621 auto chainValue = singleValueFrom(ast_to<Exp_t>(assignment->expList->exprs.front()))->item.to<ChainValue_t>();
5637 auto key = normalPair->key.get(); 5622 auto key = normalPair->key.get();
5638 switch (key->getId()) { 5623 switch (key->get_id()) {
5639 case id<KeyName_t>(): { 5624 case id<KeyName_t>(): {
5640 auto keyName = static_cast<KeyName_t*>(key); 5625 auto keyName = static_cast<KeyName_t*>(key);
5641 ast_ptr<false, ast_node> chainItem; 5626 ast_ptr<false, ast_node> chainItem;
@@ -5750,7 +5735,7 @@ private:
5750 auto assignment = toAst<ExpListAssign_t>(tableVar + "=nil"s, item); 5735 auto assignment = toAst<ExpListAssign_t>(tableVar + "=nil"s, item);
5751 auto chainValue = singleValueFrom(ast_to<Exp_t>(assignment->expList->exprs.front()))->item.to<ChainValue_t>(); 5736 auto chainValue = singleValueFrom(ast_to<Exp_t>(assignment->expList->exprs.front()))->item.to<ChainValue_t>();
5752 auto key = metaNormalPair->key.get(); 5737 auto key = metaNormalPair->key.get();
5753 switch (key->getId()) { 5738 switch (key->get_id()) {
5754 case id<Name_t>(): { 5739 case id<Name_t>(): {
5755 auto dotItem = x->new_ptr<DotChainItem_t>(); 5740 auto dotItem = x->new_ptr<DotChainItem_t>();
5756 dotItem->name.set(key); 5741 dotItem->name.set(key);
@@ -5825,7 +5810,7 @@ private:
5825 ast_sel<false, Exp_t, TableBlock_t> metatableItem; 5810 ast_sel<false, Exp_t, TableBlock_t> metatableItem;
5826 for (auto value : values) { 5811 for (auto value : values) {
5827 auto item = value; 5812 auto item = value;
5828 switch (item->getId()) { 5813 switch (item->get_id()) {
5829 case id<VariablePairDef_t>(): { 5814 case id<VariablePairDef_t>(): {
5830 auto pair = static_cast<VariablePairDef_t*>(item); 5815 auto pair = static_cast<VariablePairDef_t*>(item);
5831 if (pair->defVal) { 5816 if (pair->defVal) {
@@ -5868,7 +5853,7 @@ private:
5868 } 5853 }
5869 } 5854 }
5870 bool isMetamethod = false; 5855 bool isMetamethod = false;
5871 switch (item->getId()) { 5856 switch (item->get_id()) {
5872 case id<Exp_t>(): transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); break; 5857 case id<Exp_t>(): transformExp(static_cast<Exp_t*>(item), temp, ExpUsage::Closure); break;
5873 case id<VariablePair_t>(): transform_variable_pair(static_cast<VariablePair_t*>(item), temp); break; 5858 case id<VariablePair_t>(): transform_variable_pair(static_cast<VariablePair_t*>(item), temp); break;
5874 case id<NormalPair_t>(): transform_normal_pair(static_cast<NormalPair_t*>(item), temp, false); break; 5859 case id<NormalPair_t>(): transform_normal_pair(static_cast<NormalPair_t*>(item), temp, false); break;
@@ -5895,7 +5880,7 @@ private:
5895 if (metatableItem) { 5880 if (metatableItem) {
5896 throw CompileError("too many metatable declarations"sv, mp->key); 5881 throw CompileError("too many metatable declarations"sv, mp->key);
5897 } 5882 }
5898 switch (mp->key->getId()) { 5883 switch (mp->key->get_id()) {
5899 case id<Name_t>(): { 5884 case id<Name_t>(): {
5900 auto key = _parser.toString(mp->key); 5885 auto key = _parser.toString(mp->key);
5901 checkMetamethod(key, mp->key); 5886 checkMetamethod(key, mp->key);
@@ -5950,7 +5935,7 @@ private:
5950 if (!metatable->pairs.empty()) { 5935 if (!metatable->pairs.empty()) {
5951 transform_simple_table(metatable, tmp); 5936 transform_simple_table(metatable, tmp);
5952 } else 5937 } else
5953 switch (metatableItem->getId()) { 5938 switch (metatableItem->get_id()) {
5954 case id<Exp_t>(): 5939 case id<Exp_t>():
5955 transformExp(static_cast<Exp_t*>(metatableItem.get()), tmp, ExpUsage::Closure); 5940 transformExp(static_cast<Exp_t*>(metatableItem.get()), tmp, ExpUsage::Closure);
5956 break; 5941 break;
@@ -5978,7 +5963,7 @@ private:
5978 auto x = comp; 5963 auto x = comp;
5979 auto compInner = comp->forLoop.get(); 5964 auto compInner = comp->forLoop.get();
5980 for (auto item : compInner->items.objects()) { 5965 for (auto item : compInner->items.objects()) {
5981 switch (item->getId()) { 5966 switch (item->get_id()) {
5982 case id<CompForEach_t>(): 5967 case id<CompForEach_t>():
5983 transformCompForEach(static_cast<CompForEach_t*>(item), temp); 5968 transformCompForEach(static_cast<CompForEach_t*>(item), temp);
5984 break; 5969 break;
@@ -6035,7 +6020,7 @@ private:
6035 addToScope(lenVar); 6020 addToScope(lenVar);
6036 auto compInner = comp->forLoop.get(); 6021 auto compInner = comp->forLoop.get();
6037 for (auto item : compInner->items.objects()) { 6022 for (auto item : compInner->items.objects()) {
6038 switch (item->getId()) { 6023 switch (item->get_id()) {
6039 case id<CompForEach_t>(): 6024 case id<CompForEach_t>():
6040 transformCompForEach(static_cast<CompForEach_t*>(item), temp); 6025 transformCompForEach(static_cast<CompForEach_t*>(item), temp);
6041 break; 6026 break;
@@ -6115,7 +6100,7 @@ private:
6115 std::list<std::pair<ast_node*, ast_ptr<false, ast_node>>> destructPairs; 6100 std::list<std::pair<ast_node*, ast_ptr<false, ast_node>>> destructPairs;
6116 for (auto _item : nameList->items.objects()) { 6101 for (auto _item : nameList->items.objects()) {
6117 auto item = static_cast<NameOrDestructure_t*>(_item)->item.get(); 6102 auto item = static_cast<NameOrDestructure_t*>(_item)->item.get();
6118 switch (item->getId()) { 6103 switch (item->get_id()) {
6119 case id<Variable_t>(): 6104 case id<Variable_t>():
6120 transformVariable(static_cast<Variable_t*>(item), vars); 6105 transformVariable(static_cast<Variable_t*>(item), vars);
6121 varAfter.push_back(vars.back()); 6106 varAfter.push_back(vars.back());
@@ -6130,7 +6115,7 @@ private:
6130 default: YUEE("AST node mismatch", item); break; 6115 default: YUEE("AST node mismatch", item); break;
6131 } 6116 }
6132 } 6117 }
6133 switch (loopTarget->getId()) { 6118 switch (loopTarget->get_id()) {
6134 case id<StarExp_t>(): { 6119 case id<StarExp_t>(): {
6135 auto star_exp = static_cast<StarExp_t*>(loopTarget); 6120 auto star_exp = static_cast<StarExp_t*>(loopTarget);
6136 auto listVar = singleVariableFrom(star_exp->value, true); 6121 auto listVar = singleVariableFrom(star_exp->value, true);
@@ -6148,7 +6133,7 @@ private:
6148 BREAK_IF(!slice); 6133 BREAK_IF(!slice);
6149 endWithSlice = true; 6134 endWithSlice = true;
6150 if (listVar.empty() && chainList.size() == 2) { 6135 if (listVar.empty() && chainList.size() == 2) {
6151 if (auto var = chainList.front()->getByPath<Variable_t>()) { 6136 if (auto var = chainList.front()->get_by_path<Variable_t>()) {
6152 listVar = _parser.toString(var); 6137 listVar = _parser.toString(var);
6153 if (!isLocal(listVar)) listVar.clear(); 6138 if (!isLocal(listVar)) listVar.clear();
6154 } 6139 }
@@ -6303,7 +6288,7 @@ private:
6303 } 6288 }
6304 str_list temp; 6289 str_list temp;
6305 for (auto arg : invokeArgs->args.objects()) { 6290 for (auto arg : invokeArgs->args.objects()) {
6306 switch (arg->getId()) { 6291 switch (arg->get_id()) {
6307 case id<Exp_t>(): transformExp(static_cast<Exp_t*>(arg), temp, ExpUsage::Closure); break; 6292 case id<Exp_t>(): transformExp(static_cast<Exp_t*>(arg), temp, ExpUsage::Closure); break;
6308 case id<TableBlock_t>(): transformTableBlock(static_cast<TableBlock_t*>(arg), temp); break; 6293 case id<TableBlock_t>(): transformTableBlock(static_cast<TableBlock_t*>(arg), temp); break;
6309 default: YUEE("AST node mismatch", arg); break; 6294 default: YUEE("AST node mismatch", arg); break;
@@ -6337,7 +6322,7 @@ private:
6337 } 6322 }
6338 6323
6339 void transform_plain_body(ast_node* body, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 6324 void transform_plain_body(ast_node* body, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
6340 switch (body->getId()) { 6325 switch (body->get_id()) {
6341 case id<Block_t>(): 6326 case id<Block_t>():
6342 transformBlock(static_cast<Block_t*>(body), out, usage, assignList); 6327 transformBlock(static_cast<Block_t*>(body), out, usage, assignList);
6343 break; 6328 break;
@@ -6363,7 +6348,7 @@ private:
6363 auto simpleValue = value->item.as<SimpleValue_t>(); 6348 auto simpleValue = value->item.as<SimpleValue_t>();
6364 BREAK_IF(!simpleValue); 6349 BREAK_IF(!simpleValue);
6365 auto sVal = simpleValue->value.get(); 6350 auto sVal = simpleValue->value.get();
6366 switch (sVal->getId()) { 6351 switch (sVal->get_id()) {
6367 case id<With_t>(): { 6352 case id<With_t>(): {
6368 auto withNode = static_cast<With_t*>(sVal); 6353 auto withNode = static_cast<With_t*>(sVal);
6369 if (hasContinueStatement(withNode->body)) { 6354 if (hasContinueStatement(withNode->body)) {
@@ -6405,7 +6390,7 @@ private:
6405 BLOCK_END 6390 BLOCK_END
6406 } 6391 }
6407 } else { 6392 } else {
6408 switch (node->getId()) { 6393 switch (node->get_id()) {
6409 case id<Body_t>(): 6394 case id<Body_t>():
6410 case id<Block_t>(): 6395 case id<Block_t>():
6411 return traversal::Continue; 6396 return traversal::Continue;
@@ -6749,7 +6734,7 @@ private:
6749 void transform_normal_pair(NormalPair_t* pair, str_list& out, bool assignClass) { 6734 void transform_normal_pair(NormalPair_t* pair, str_list& out, bool assignClass) {
6750 auto key = pair->key.get(); 6735 auto key = pair->key.get();
6751 str_list temp; 6736 str_list temp;
6752 switch (key->getId()) { 6737 switch (key->get_id()) {
6753 case id<KeyName_t>(): { 6738 case id<KeyName_t>(): {
6754 auto keyName = static_cast<KeyName_t*>(key); 6739 auto keyName = static_cast<KeyName_t*>(key);
6755 transformKeyName(keyName, temp); 6740 transformKeyName(keyName, temp);
@@ -6765,7 +6750,7 @@ private:
6765 case id<String_t>(): { 6750 case id<String_t>(): {
6766 auto strNode = static_cast<String_t*>(key); 6751 auto strNode = static_cast<String_t*>(key);
6767 auto str = strNode->str.get(); 6752 auto str = strNode->str.get();
6768 switch (str->getId()) { 6753 switch (str->get_id()) {
6769 case id<DoubleString_t>(): 6754 case id<DoubleString_t>():
6770 transformDoubleString(static_cast<DoubleString_t*>(str), temp); 6755 transformDoubleString(static_cast<DoubleString_t*>(str), temp);
6771 temp.back() = '[' + temp.back() + ']'; 6756 temp.back() = '[' + temp.back() + ']';
@@ -6785,7 +6770,7 @@ private:
6785 default: YUEE("AST node mismatch", key); break; 6770 default: YUEE("AST node mismatch", key); break;
6786 } 6771 }
6787 auto value = pair->value.get(); 6772 auto value = pair->value.get();
6788 switch (value->getId()) { 6773 switch (value->get_id()) {
6789 case id<Exp_t>(): transformExp(static_cast<Exp_t*>(value), temp, ExpUsage::Closure); break; 6774 case id<Exp_t>(): transformExp(static_cast<Exp_t*>(value), temp, ExpUsage::Closure); break;
6790 case id<TableBlock_t>(): transformTableBlock(static_cast<TableBlock_t*>(value), temp); break; 6775 case id<TableBlock_t>(): transformTableBlock(static_cast<TableBlock_t*>(value), temp); break;
6791 default: YUEE("AST node mismatch", value); break; 6776 default: YUEE("AST node mismatch", value); break;
@@ -6795,7 +6780,7 @@ private:
6795 6780
6796 void transformKeyName(KeyName_t* keyName, str_list& out) { 6781 void transformKeyName(KeyName_t* keyName, str_list& out) {
6797 auto name = keyName->name.get(); 6782 auto name = keyName->name.get();
6798 switch (name->getId()) { 6783 switch (name->get_id()) {
6799 case id<SelfItem_t>(): 6784 case id<SelfItem_t>():
6800 transformSelfName(static_cast<SelfItem_t*>(name), out); 6785 transformSelfName(static_cast<SelfItem_t*>(name), out);
6801 break; 6786 break;
@@ -6830,7 +6815,7 @@ private:
6830 for (auto _seg : doubleString->segments.objects()) { 6815 for (auto _seg : doubleString->segments.objects()) {
6831 auto seg = static_cast<DoubleStringContent_t*>(_seg); 6816 auto seg = static_cast<DoubleStringContent_t*>(_seg);
6832 auto content = seg->content.get(); 6817 auto content = seg->content.get();
6833 switch (content->getId()) { 6818 switch (content->get_id()) {
6834 case id<DoubleStringInner_t>(): { 6819 case id<DoubleStringInner_t>(): {
6835 auto str = _parser.toString(content); 6820 auto str = _parser.toString(content);
6836 Utils::replace(str, "\r\n"sv, "\n"); 6821 Utils::replace(str, "\r\n"sv, "\n");
@@ -6851,7 +6836,7 @@ private:
6851 6836
6852 void transformString(String_t* string, str_list& out) { 6837 void transformString(String_t* string, str_list& out) {
6853 auto str = string->str.get(); 6838 auto str = string->str.get();
6854 switch (str->getId()) { 6839 switch (str->get_id()) {
6855 case id<SingleString_t>(): transformSingleString(static_cast<SingleString_t*>(str), out); break; 6840 case id<SingleString_t>(): transformSingleString(static_cast<SingleString_t*>(str), out); break;
6856 case id<DoubleString_t>(): transformDoubleString(static_cast<DoubleString_t*>(str), out); break; 6841 case id<DoubleString_t>(): transformDoubleString(static_cast<DoubleString_t*>(str), out); break;
6857 case id<LuaString_t>(): transformLuaString(static_cast<LuaString_t*>(str), out); break; 6842 case id<LuaString_t>(): transformLuaString(static_cast<LuaString_t*>(str), out); break;
@@ -6908,7 +6893,7 @@ private:
6908 if (auto dotChain = ast_cast<DotChainItem_t>(chain->items.back())) { 6893 if (auto dotChain = ast_cast<DotChainItem_t>(chain->items.back())) {
6909 className = '\"' + _parser.toString(dotChain->name) + '\"'; 6894 className = '\"' + _parser.toString(dotChain->name) + '\"';
6910 } else if (auto index = ast_cast<Exp_t>(chain->items.back())) { 6895 } else if (auto index = ast_cast<Exp_t>(chain->items.back())) {
6911 if (auto name = index->getByPath<UnaryExp_t, Value_t, String_t>()) { 6896 if (auto name = index->get_by_path<UnaryExp_t, Value_t, String_t>()) {
6912 transformString(name, temp); 6897 transformString(name, temp);
6913 className = std::move(temp.back()); 6898 className = std::move(temp.back());
6914 temp.pop_back(); 6899 temp.pop_back();
@@ -6957,11 +6942,11 @@ private:
6957 BREAK_IF(!exp); 6942 BREAK_IF(!exp);
6958 auto value = singleValueFrom(exp); 6943 auto value = singleValueFrom(exp);
6959 BREAK_IF(!value); 6944 BREAK_IF(!value);
6960 clsDecl = value->getByPath<SimpleValue_t, ClassDecl_t>(); 6945 clsDecl = value->get_by_path<SimpleValue_t, ClassDecl_t>();
6961 BLOCK_END 6946 BLOCK_END
6962 } else if (auto expList = expListFrom(statement)) { 6947 } else if (auto expList = expListFrom(statement)) {
6963 auto value = singleValueFrom(expList); 6948 auto value = singleValueFrom(expList);
6964 clsDecl = value->getByPath<SimpleValue_t, ClassDecl_t>(); 6949 clsDecl = value->get_by_path<SimpleValue_t, ClassDecl_t>();
6965 } 6950 }
6966 if (clsDecl) { 6951 if (clsDecl) {
6967 std::string clsName; 6952 std::string clsName;
@@ -6993,7 +6978,7 @@ private:
6993 if (body) { 6978 if (body) {
6994 std::list<ClassMember> members; 6979 std::list<ClassMember> members;
6995 for (auto content : classDecl->body->contents.objects()) { 6980 for (auto content : classDecl->body->contents.objects()) {
6996 switch (content->getId()) { 6981 switch (content->get_id()) {
6997 case id<ClassMemberList_t>(): { 6982 case id<ClassMemberList_t>(): {
6998 size_t inc = transform_class_member_list(static_cast<ClassMemberList_t*>(content), members, classVar); 6983 size_t inc = transform_class_member_list(static_cast<ClassMemberList_t*>(content), members, classVar);
6999 auto it = members.end(); 6984 auto it = members.end();
@@ -7153,7 +7138,7 @@ private:
7153 for (auto keyValue : class_member_list->values.objects()) { 7138 for (auto keyValue : class_member_list->values.objects()) {
7154 MemType type = MemType::Common; 7139 MemType type = MemType::Common;
7155 ast_ptr<false, ast_node> ref; 7140 ast_ptr<false, ast_node> ref;
7156 switch (keyValue->getId()) { 7141 switch (keyValue->get_id()) {
7157 case id<MetaVariablePair_t>(): { 7142 case id<MetaVariablePair_t>(): {
7158 auto mtPair = static_cast<MetaVariablePair_t*>(keyValue); 7143 auto mtPair = static_cast<MetaVariablePair_t*>(keyValue);
7159 auto nameStr = _parser.toString(mtPair->name); 7144 auto nameStr = _parser.toString(mtPair->name);
@@ -7206,14 +7191,14 @@ private:
7206 } 7191 }
7207 } 7192 }
7208 normal_pair->value->traverse([&](ast_node* node) { 7193 normal_pair->value->traverse([&](ast_node* node) {
7209 if (node->getId() == id<ClassDecl_t>()) return traversal::Return; 7194 if (node->get_id() == id<ClassDecl_t>()) return traversal::Return;
7210 if (auto chainValue = ast_cast<ChainValue_t>(node)) { 7195 if (auto chainValue = ast_cast<ChainValue_t>(node)) {
7211 if (auto callable = ast_cast<Callable_t>(chainValue->items.front())) { 7196 if (auto callable = ast_cast<Callable_t>(chainValue->items.front())) {
7212 auto var = callable->item.get(); 7197 auto var = callable->item.get();
7213 if (_parser.toString(var) == "super"sv) { 7198 if (_parser.toString(var) == "super"sv) {
7214 auto insertSelfToArguments = [&](ast_node* item) { 7199 auto insertSelfToArguments = [&](ast_node* item) {
7215 auto x = item; 7200 auto x = item;
7216 switch (item->getId()) { 7201 switch (item->get_id()) {
7217 case id<InvokeArgs_t>(): { 7202 case id<InvokeArgs_t>(): {
7218 auto invoke = static_cast<InvokeArgs_t*>(item); 7203 auto invoke = static_cast<InvokeArgs_t*>(item);
7219 invoke->args.push_front(toAst<Exp_t>("self"sv, x)); 7204 invoke->args.push_front(toAst<Exp_t>("self"sv, x));
@@ -7259,7 +7244,7 @@ private:
7259 if (type == MemType::Property) { 7244 if (type == MemType::Property) {
7260 decIndentOffset(); 7245 decIndentOffset();
7261 } 7246 }
7262 switch (keyValue->getId()) { 7247 switch (keyValue->get_id()) {
7263 case id<VariablePair_t>(): 7248 case id<VariablePair_t>():
7264 transform_variable_pair(static_cast<VariablePair_t*>(keyValue), temp); 7249 transform_variable_pair(static_cast<VariablePair_t*>(keyValue), temp);
7265 break; 7250 break;
@@ -7281,7 +7266,7 @@ private:
7281 7266
7282 void transformAssignable(Assignable_t* assignable, str_list& out) { 7267 void transformAssignable(Assignable_t* assignable, str_list& out) {
7283 auto item = assignable->item.get(); 7268 auto item = assignable->item.get();
7284 switch (item->getId()) { 7269 switch (item->get_id()) {
7285 case id<AssignableChain_t>(): transformAssignableChain(static_cast<AssignableChain_t*>(item), out); break; 7270 case id<AssignableChain_t>(): transformAssignableChain(static_cast<AssignableChain_t*>(item), out); break;
7286 case id<Variable_t>(): transformVariable(static_cast<Variable_t*>(item), out); break; 7271 case id<Variable_t>(): transformVariable(static_cast<Variable_t*>(item), out); break;
7287 case id<SelfItem_t>(): transformSelfName(static_cast<SelfItem_t*>(item), out); break; 7272 case id<SelfItem_t>(): transformSelfName(static_cast<SelfItem_t*>(item), out); break;
@@ -7399,12 +7384,12 @@ private:
7399 auto exp = ast_cast<Exp_t>(assign->values.objects().front()); 7384 auto exp = ast_cast<Exp_t>(assign->values.objects().front());
7400 BREAK_IF(!exp); 7385 BREAK_IF(!exp);
7401 if (auto value = singleValueFrom(exp)) { 7386 if (auto value = singleValueFrom(exp)) {
7402 clsDecl = value->getByPath<SimpleValue_t, ClassDecl_t>(); 7387 clsDecl = value->get_by_path<SimpleValue_t, ClassDecl_t>();
7403 } 7388 }
7404 BLOCK_END 7389 BLOCK_END
7405 } else if (auto expList = expListFrom(statement)) { 7390 } else if (auto expList = expListFrom(statement)) {
7406 auto value = singleValueFrom(expList); 7391 auto value = singleValueFrom(expList);
7407 clsDecl = value->getByPath<SimpleValue_t, ClassDecl_t>(); 7392 clsDecl = value->get_by_path<SimpleValue_t, ClassDecl_t>();
7408 } 7393 }
7409 if (clsDecl) { 7394 if (clsDecl) {
7410 auto variable = clsDecl->name.as<Variable_t>(); 7395 auto variable = clsDecl->name.as<Variable_t>();
@@ -7459,10 +7444,10 @@ private:
7459 void transformGlobal(Global_t* global, str_list& out) { 7444 void transformGlobal(Global_t* global, str_list& out) {
7460 auto x = global; 7445 auto x = global;
7461 auto item = global->item.get(); 7446 auto item = global->item.get();
7462 switch (item->getId()) { 7447 switch (item->get_id()) {
7463 case id<ClassDecl_t>(): { 7448 case id<ClassDecl_t>(): {
7464 auto classDecl = static_cast<ClassDecl_t*>(item); 7449 auto classDecl = static_cast<ClassDecl_t*>(item);
7465 if (classDecl->name && classDecl->name->item->getId() == id<Variable_t>()) { 7450 if (classDecl->name && classDecl->name->item->get_id() == id<Variable_t>()) {
7466 markVarsGlobal(GlobalMode::Any); 7451 markVarsGlobal(GlobalMode::Any);
7467 addGlobalVar(_parser.toString(classDecl->name->item), classDecl->name->item); 7452 addGlobalVar(_parser.toString(classDecl->name->item), classDecl->name->item);
7468 } 7453 }
@@ -7513,13 +7498,13 @@ private:
7513 } 7498 }
7514 7499
7515 std::optional<std::string> getExportKey(ast_node* node) { 7500 std::optional<std::string> getExportKey(ast_node* node) {
7516 switch (node->getId()) { 7501 switch (node->get_id()) {
7517 case id<Name_t>(): { 7502 case id<Name_t>(): {
7518 return _parser.toString(node); 7503 return _parser.toString(node);
7519 } 7504 }
7520 case id<String_t>(): { 7505 case id<String_t>(): {
7521 auto strNode = static_cast<String_t*>(node); 7506 auto strNode = static_cast<String_t*>(node);
7522 switch (strNode->str->getId()) { 7507 switch (strNode->str->get_id()) {
7523 case id<DoubleString_t>(): { 7508 case id<DoubleString_t>(): {
7524 auto str = static_cast<DoubleString_t*>(strNode->str.get()); 7509 auto str = static_cast<DoubleString_t*>(strNode->str.get());
7525 if (str->segments.size() == 1) { 7510 if (str->segments.size() == 1) {
@@ -7614,7 +7599,7 @@ private:
7614 } 7599 }
7615 for (auto _exp : expList->exprs.objects()) { 7600 for (auto _exp : expList->exprs.objects()) {
7616 auto exp = static_cast<Exp_t*>(_exp); 7601 auto exp = static_cast<Exp_t*>(_exp);
7617 if (!variableFrom(exp) && !exp->getByPath<UnaryExp_t, Value_t, SimpleValue_t, TableLit_t>() && !exp->getByPath<UnaryExp_t, Value_t, SimpleTable_t>()) { 7602 if (!variableFrom(exp) && !exp->get_by_path<UnaryExp_t, Value_t, SimpleValue_t, TableLit_t>() && !exp->get_by_path<UnaryExp_t, Value_t, SimpleTable_t>()) {
7618 throw CompileError("left hand expressions must be variables in export statement"sv, x); 7603 throw CompileError("left hand expressions must be variables in export statement"sv, x);
7619 } 7604 }
7620 } 7605 }
@@ -7664,8 +7649,8 @@ private:
7664 auto assignList = toAst<ExpList_t>(_info.moduleName + "[#"s + _info.moduleName + "+1]"s, x); 7649 auto assignList = toAst<ExpList_t>(_info.moduleName + "[#"s + _info.moduleName + "+1]"s, x);
7665 assignment->expList.set(assignList); 7650 assignment->expList.set(assignList);
7666 for (auto exp : expList->exprs.objects()) { 7651 for (auto exp : expList->exprs.objects()) {
7667 if (auto classDecl = exp->getByPath<UnaryExp_t, Value_t, SimpleValue_t, ClassDecl_t>()) { 7652 if (auto classDecl = exp->get_by_path<UnaryExp_t, Value_t, SimpleValue_t, ClassDecl_t>()) {
7668 if (classDecl->name && classDecl->name->item->getId() == id<Variable_t>()) { 7653 if (classDecl->name && classDecl->name->item->get_id() == id<Variable_t>()) {
7669 transformClassDecl(classDecl, temp, ExpUsage::Common); 7654 transformClassDecl(classDecl, temp, ExpUsage::Common);
7670 auto name = _parser.toString(classDecl->name->item); 7655 auto name = _parser.toString(classDecl->name->item);
7671 assignment->expList.set(toAst<ExpList_t>(_info.moduleName + "[\""s + name + "\"]"s, x)); 7656 assignment->expList.set(toAst<ExpList_t>(_info.moduleName + "[\""s + name + "\"]"s, x));
@@ -7711,7 +7696,7 @@ private:
7711 str_list temp; 7696 str_list temp;
7712 auto compInner = comp->forLoop.get(); 7697 auto compInner = comp->forLoop.get();
7713 for (auto item : compInner->items.objects()) { 7698 for (auto item : compInner->items.objects()) {
7714 switch (item->getId()) { 7699 switch (item->get_id()) {
7715 case id<CompForEach_t>(): 7700 case id<CompForEach_t>():
7716 transformCompForEach(static_cast<CompForEach_t*>(item), temp); 7701 transformCompForEach(static_cast<CompForEach_t*>(item), temp);
7717 break; 7702 break;
@@ -7926,7 +7911,7 @@ private:
7926 auto expList = x->new_ptr<ExpList_t>(); 7911 auto expList = x->new_ptr<ExpList_t>();
7927 auto assign = x->new_ptr<Assign_t>(); 7912 auto assign = x->new_ptr<Assign_t>();
7928 for (auto name : import->names.objects()) { 7913 for (auto name : import->names.objects()) {
7929 switch (name->getId()) { 7914 switch (name->get_id()) {
7930 case id<Variable_t>(): { 7915 case id<Variable_t>(): {
7931 auto var = static_cast<Variable_t*>(name); 7916 auto var = static_cast<Variable_t*>(name);
7932 { 7917 {
@@ -8015,7 +8000,7 @@ private:
8015 auto newTab = x->new_ptr<ImportTabLit_t>(); 8000 auto newTab = x->new_ptr<ImportTabLit_t>();
8016 if (auto tabLit = import->target.as<ImportTabLit_t>()) { 8001 if (auto tabLit = import->target.as<ImportTabLit_t>()) {
8017 for (auto item : tabLit->items.objects()) { 8002 for (auto item : tabLit->items.objects()) {
8018 switch (item->getId()) { 8003 switch (item->get_id()) {
8019#ifdef YUE_NO_MACRO 8004#ifdef YUE_NO_MACRO
8020 case id<MacroName_t>(): 8005 case id<MacroName_t>():
8021 case id<MacroNamePair_t>(): 8006 case id<MacroNamePair_t>():
@@ -8145,7 +8130,7 @@ private:
8145 auto simpleValue = x->new_ptr<SimpleValue_t>(); 8130 auto simpleValue = x->new_ptr<SimpleValue_t>();
8146 auto tableLit = x->new_ptr<TableLit_t>(); 8131 auto tableLit = x->new_ptr<TableLit_t>();
8147 for (auto pair : tabLit->items.objects()) { 8132 for (auto pair : tabLit->items.objects()) {
8148 switch (pair->getId()) { 8133 switch (pair->get_id()) {
8149 case id<VariablePair_t>(): { 8134 case id<VariablePair_t>(): {
8150 auto pairDef = pair->new_ptr<VariablePairDef_t>(); 8135 auto pairDef = pair->new_ptr<VariablePairDef_t>();
8151 pairDef->pair.set(pair); 8136 pairDef->pair.set(pair);
@@ -8203,7 +8188,7 @@ private:
8203 8188
8204 void transformImport(Import_t* import, str_list& out) { 8189 void transformImport(Import_t* import, str_list& out) {
8205 auto content = import->content.get(); 8190 auto content = import->content.get();
8206 switch (content->getId()) { 8191 switch (content->get_id()) {
8207 case id<ImportAs_t>(): 8192 case id<ImportAs_t>():
8208 transformImportAs(static_cast<ImportAs_t*>(content), out); 8193 transformImportAs(static_cast<ImportAs_t*>(content), out);
8209 break; 8194 break;
@@ -8360,7 +8345,7 @@ private:
8360 } 8345 }
8361 auto valueList = branch->condition.to<SwitchList_t>(); 8346 auto valueList = branch->condition.to<SwitchList_t>();
8362 if (auto value = singleValueFrom(valueList); 8347 if (auto value = singleValueFrom(valueList);
8363 value && (value->item.is<SimpleTable_t>() || value->getByPath<SimpleValue_t, TableLit_t>())) { 8348 value && (value->item.is<SimpleTable_t>() || value->get_by_path<SimpleValue_t, TableLit_t>())) {
8364 if (!firstBranch) { 8349 if (!firstBranch) {
8365 temp.push_back(indent() + "else"s + nll(branch)); 8350 temp.push_back(indent() + "else"s + nll(branch));
8366 pushScope(); 8351 pushScope();
@@ -8496,7 +8481,7 @@ private:
8496 local->defined = true; 8481 local->defined = true;
8497 transformLocalDef(local, temp); 8482 transformLocalDef(local, temp);
8498 } 8483 }
8499 switch (local->item->getId()) { 8484 switch (local->item->get_id()) {
8500 case id<LocalValues_t>(): { 8485 case id<LocalValues_t>(): {
8501 auto values = static_cast<LocalValues_t*>(local->item.get()); 8486 auto values = static_cast<LocalValues_t*>(local->item.get());
8502 if (values->valueList) { 8487 if (values->valueList) {
@@ -8556,7 +8541,7 @@ private:
8556 } else { 8541 } else {
8557 auto item = *i; 8542 auto item = *i;
8558 auto value = item->new_ptr<Value_t>(); 8543 auto value = item->new_ptr<Value_t>();
8559 switch (item->getId()) { 8544 switch (item->get_id()) {
8560 case id<SimpleTable_t>(): 8545 case id<SimpleTable_t>():
8561 value->item.set(item); 8546 value->item.set(item);
8562 break; 8547 break;
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index d7fbf90..9b4adae 100644
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -250,159 +250,159 @@ private:
250 NONE_AST_RULE(line); 250 NONE_AST_RULE(line);
251 NONE_AST_RULE(shebang); 251 NONE_AST_RULE(shebang);
252 252
253 AST_RULE(Num) 253 AST_RULE(Num);
254 AST_RULE(Name) 254 AST_RULE(Name);
255 AST_RULE(Variable) 255 AST_RULE(Variable);
256 AST_RULE(LabelName) 256 AST_RULE(LabelName);
257 AST_RULE(LuaKeyword) 257 AST_RULE(LuaKeyword);
258 AST_RULE(Self) 258 AST_RULE(Self);
259 AST_RULE(SelfName) 259 AST_RULE(SelfName);
260 AST_RULE(SelfClass) 260 AST_RULE(SelfClass);
261 AST_RULE(SelfClassName) 261 AST_RULE(SelfClassName);
262 AST_RULE(SelfItem) 262 AST_RULE(SelfItem);
263 AST_RULE(KeyName) 263 AST_RULE(KeyName);
264 AST_RULE(VarArg) 264 AST_RULE(VarArg);
265 AST_RULE(Seperator) 265 AST_RULE(Seperator);
266 AST_RULE(NameList) 266 AST_RULE(NameList);
267 AST_RULE(LocalFlag) 267 AST_RULE(LocalFlag);
268 AST_RULE(LocalValues) 268 AST_RULE(LocalValues);
269 AST_RULE(Local) 269 AST_RULE(Local);
270 AST_RULE(ConstAttrib) 270 AST_RULE(ConstAttrib);
271 AST_RULE(CloseAttrib) 271 AST_RULE(CloseAttrib);
272 AST_RULE(LocalAttrib); 272 AST_RULE(LocalAttrib);
273 AST_RULE(ColonImportName) 273 AST_RULE(ColonImportName);
274 AST_RULE(ImportLiteralInner) 274 AST_RULE(ImportLiteralInner);
275 AST_RULE(ImportLiteral) 275 AST_RULE(ImportLiteral);
276 AST_RULE(ImportFrom) 276 AST_RULE(ImportFrom);
277 AST_RULE(MacroNamePair) 277 AST_RULE(MacroNamePair);
278 AST_RULE(ImportAllMacro) 278 AST_RULE(ImportAllMacro);
279 AST_RULE(ImportTabLit) 279 AST_RULE(ImportTabLit);
280 AST_RULE(ImportAs) 280 AST_RULE(ImportAs);
281 AST_RULE(Import) 281 AST_RULE(Import);
282 AST_RULE(Label) 282 AST_RULE(Label);
283 AST_RULE(Goto) 283 AST_RULE(Goto);
284 AST_RULE(ShortTabAppending) 284 AST_RULE(ShortTabAppending);
285 AST_RULE(FnArrowBack) 285 AST_RULE(FnArrowBack);
286 AST_RULE(Backcall) 286 AST_RULE(Backcall);
287 AST_RULE(PipeBody) 287 AST_RULE(PipeBody);
288 AST_RULE(ExpListLow) 288 AST_RULE(ExpListLow);
289 AST_RULE(ExpList) 289 AST_RULE(ExpList);
290 AST_RULE(Return) 290 AST_RULE(Return);
291 AST_RULE(With) 291 AST_RULE(With);
292 AST_RULE(SwitchList) 292 AST_RULE(SwitchList);
293 AST_RULE(SwitchCase) 293 AST_RULE(SwitchCase);
294 AST_RULE(Switch) 294 AST_RULE(Switch);
295 AST_RULE(Assignment) 295 AST_RULE(Assignment);
296 AST_RULE(IfCond) 296 AST_RULE(IfCond);
297 AST_RULE(IfType) 297 AST_RULE(IfType);
298 AST_RULE(If) 298 AST_RULE(If);
299 AST_RULE(WhileType) 299 AST_RULE(WhileType);
300 AST_RULE(While) 300 AST_RULE(While);
301 AST_RULE(Repeat) 301 AST_RULE(Repeat);
302 AST_RULE(ForStepValue) 302 AST_RULE(ForStepValue);
303 AST_RULE(For) 303 AST_RULE(For);
304 AST_RULE(ForEach) 304 AST_RULE(ForEach);
305 AST_RULE(Do) 305 AST_RULE(Do);
306 AST_RULE(CatchBlock) 306 AST_RULE(CatchBlock);
307 AST_RULE(Try) 307 AST_RULE(Try);
308 AST_RULE(Comprehension) 308 AST_RULE(Comprehension);
309 AST_RULE(CompValue) 309 AST_RULE(CompValue);
310 AST_RULE(TblComprehension) 310 AST_RULE(TblComprehension);
311 AST_RULE(StarExp) 311 AST_RULE(StarExp);
312 AST_RULE(CompForEach) 312 AST_RULE(CompForEach);
313 AST_RULE(CompFor) 313 AST_RULE(CompFor);
314 AST_RULE(CompInner) 314 AST_RULE(CompInner);
315 AST_RULE(Assign) 315 AST_RULE(Assign);
316 AST_RULE(UpdateOp) 316 AST_RULE(UpdateOp);
317 AST_RULE(Update) 317 AST_RULE(Update);
318 AST_RULE(BinaryOperator) 318 AST_RULE(BinaryOperator);
319 AST_RULE(UnaryOperator) 319 AST_RULE(UnaryOperator);
320 AST_RULE(Assignable) 320 AST_RULE(Assignable);
321 AST_RULE(AssignableChain) 321 AST_RULE(AssignableChain);
322 AST_RULE(ExpOpValue) 322 AST_RULE(ExpOpValue);
323 AST_RULE(Exp) 323 AST_RULE(Exp);
324 AST_RULE(Callable) 324 AST_RULE(Callable);
325 AST_RULE(ChainValue) 325 AST_RULE(ChainValue);
326 AST_RULE(SimpleTable) 326 AST_RULE(SimpleTable);
327 AST_RULE(SimpleValue) 327 AST_RULE(SimpleValue);
328 AST_RULE(Value) 328 AST_RULE(Value);
329 AST_RULE(LuaStringOpen); 329 AST_RULE(LuaStringOpen);
330 AST_RULE(LuaStringContent); 330 AST_RULE(LuaStringContent);
331 AST_RULE(LuaStringClose); 331 AST_RULE(LuaStringClose);
332 AST_RULE(LuaString) 332 AST_RULE(LuaString);
333 AST_RULE(SingleString) 333 AST_RULE(SingleString);
334 AST_RULE(DoubleStringInner) 334 AST_RULE(DoubleStringInner);
335 AST_RULE(DoubleStringContent) 335 AST_RULE(DoubleStringContent);
336 AST_RULE(DoubleString) 336 AST_RULE(DoubleString);
337 AST_RULE(String) 337 AST_RULE(String);
338 AST_RULE(Parens) 338 AST_RULE(Parens);
339 AST_RULE(DotChainItem) 339 AST_RULE(DotChainItem);
340 AST_RULE(ColonChainItem) 340 AST_RULE(ColonChainItem);
341 AST_RULE(Metatable) 341 AST_RULE(Metatable);
342 AST_RULE(Metamethod) 342 AST_RULE(Metamethod);
343 AST_RULE(DefaultValue) 343 AST_RULE(DefaultValue);
344 AST_RULE(Slice) 344 AST_RULE(Slice);
345 AST_RULE(Invoke) 345 AST_RULE(Invoke);
346 AST_RULE(ExistentialOp) 346 AST_RULE(ExistentialOp);
347 AST_RULE(TableAppendingOp) 347 AST_RULE(TableAppendingOp);
348 AST_RULE(SpreadExp) 348 AST_RULE(SpreadExp);
349 AST_RULE(TableLit) 349 AST_RULE(TableLit);
350 AST_RULE(TableBlock) 350 AST_RULE(TableBlock);
351 AST_RULE(TableBlockIndent) 351 AST_RULE(TableBlockIndent);
352 AST_RULE(ClassMemberList) 352 AST_RULE(ClassMemberList);
353 AST_RULE(ClassBlock) 353 AST_RULE(ClassBlock);
354 AST_RULE(ClassDecl) 354 AST_RULE(ClassDecl);
355 AST_RULE(GlobalValues) 355 AST_RULE(GlobalValues);
356 AST_RULE(GlobalOp) 356 AST_RULE(GlobalOp);
357 AST_RULE(Global) 357 AST_RULE(Global);
358 AST_RULE(ExportDefault) 358 AST_RULE(ExportDefault);
359 AST_RULE(Export) 359 AST_RULE(Export);
360 AST_RULE(VariablePair) 360 AST_RULE(VariablePair);
361 AST_RULE(NormalPair) 361 AST_RULE(NormalPair);
362 AST_RULE(MetaVariablePair) 362 AST_RULE(MetaVariablePair);
363 AST_RULE(MetaNormalPair) 363 AST_RULE(MetaNormalPair);
364 AST_RULE(VariablePairDef) 364 AST_RULE(VariablePairDef);
365 AST_RULE(NormalPairDef) 365 AST_RULE(NormalPairDef);
366 AST_RULE(NormalDef) 366 AST_RULE(NormalDef);
367 AST_RULE(MetaVariablePairDef) 367 AST_RULE(MetaVariablePairDef);
368 AST_RULE(MetaNormalPairDef) 368 AST_RULE(MetaNormalPairDef);
369 AST_RULE(FnArgDef) 369 AST_RULE(FnArgDef);
370 AST_RULE(FnArgDefList) 370 AST_RULE(FnArgDefList);
371 AST_RULE(OuterVarShadow) 371 AST_RULE(OuterVarShadow);
372 AST_RULE(FnArgsDef) 372 AST_RULE(FnArgsDef);
373 AST_RULE(FnArrow) 373 AST_RULE(FnArrow);
374 AST_RULE(FunLit) 374 AST_RULE(FunLit);
375 AST_RULE(MacroName) 375 AST_RULE(MacroName);
376 AST_RULE(MacroLit) 376 AST_RULE(MacroLit);
377 AST_RULE(Macro) 377 AST_RULE(Macro);
378 AST_RULE(MacroInPlace) 378 AST_RULE(MacroInPlace);
379 AST_RULE(NameOrDestructure) 379 AST_RULE(NameOrDestructure);
380 AST_RULE(AssignableNameList) 380 AST_RULE(AssignableNameList);
381 AST_RULE(InvokeArgs) 381 AST_RULE(InvokeArgs);
382 AST_RULE(ConstValue) 382 AST_RULE(ConstValue);
383 AST_RULE(UnaryValue) 383 AST_RULE(UnaryValue);
384 AST_RULE(UnaryExp) 384 AST_RULE(UnaryExp);
385 AST_RULE(InRangeOpen) 385 AST_RULE(InRangeOpen);
386 AST_RULE(InRangeClose) 386 AST_RULE(InRangeClose);
387 AST_RULE(NotIn) 387 AST_RULE(NotIn);
388 AST_RULE(InRange) 388 AST_RULE(InRange);
389 AST_RULE(InDiscrete) 389 AST_RULE(InDiscrete);
390 AST_RULE(In) 390 AST_RULE(In);
391 AST_RULE(ExpListAssign) 391 AST_RULE(ExpListAssign);
392 AST_RULE(IfLine) 392 AST_RULE(IfLine);
393 AST_RULE(WhileLine) 393 AST_RULE(WhileLine);
394 AST_RULE(BreakLoop) 394 AST_RULE(BreakLoop);
395 AST_RULE(StatementAppendix) 395 AST_RULE(StatementAppendix);
396 AST_RULE(Statement) 396 AST_RULE(Statement);
397 AST_RULE(StatementSep); 397 AST_RULE(StatementSep);
398 AST_RULE(YueLineComment) 398 AST_RULE(YueLineComment);
399 AST_RULE(MultilineCommentInner) 399 AST_RULE(MultilineCommentInner);
400 AST_RULE(YueMultilineComment) 400 AST_RULE(YueMultilineComment);
401 AST_RULE(ChainAssign) 401 AST_RULE(ChainAssign);
402 AST_RULE(Body) 402 AST_RULE(Body);
403 AST_RULE(Block) 403 AST_RULE(Block);
404 AST_RULE(BlockEnd) 404 AST_RULE(BlockEnd);
405 AST_RULE(File) 405 AST_RULE(File);
406}; 406};
407 407
408namespace Utils { 408namespace Utils {
diff --git a/src/yuescript/yuescript.cpp b/src/yuescript/yuescript.cpp
index 22ba2a1..3954fb9 100644
--- a/src/yuescript/yuescript.cpp
+++ b/src/yuescript/yuescript.cpp
@@ -240,11 +240,11 @@ static int yuetoast(lua_State* L) {
240 lua_createtable(L, 0, 0); 240 lua_createtable(L, 0, 0);
241 int cacheIndex = lua_gettop(L); 241 int cacheIndex = lua_gettop(L);
242 auto getName = [&](yue::ast_node* node) { 242 auto getName = [&](yue::ast_node* node) {
243 int id = node->getId(); 243 int id = node->get_id();
244 lua_rawgeti(L, cacheIndex, id); 244 lua_rawgeti(L, cacheIndex, id);
245 if (lua_isnil(L, -1) != 0) { 245 if (lua_isnil(L, -1) != 0) {
246 lua_pop(L, 1); 246 lua_pop(L, 1);
247 auto name = node->getName(); 247 auto name = node->get_name();
248 lua_pushlstring(L, &name.front(), name.length()); 248 lua_pushlstring(L, &name.front(), name.length());
249 lua_pushvalue(L, -1); 249 lua_pushvalue(L, -1);
250 lua_rawseti(L, cacheIndex, id); 250 lua_rawseti(L, cacheIndex, id);
@@ -268,7 +268,7 @@ static int yuetoast(lua_State* L) {
268 switch (continuation) { 268 switch (continuation) {
269 case 0: { 269 case 0: {
270 if (!current.children) { 270 if (!current.children) {
271 node->visitChild([&](yue::ast_node* child) { 271 node->visit_child([&](yue::ast_node* child) {
272 if (yue::ast_is<yue::Seperator_t>(child)) { 272 if (yue::ast_is<yue::Seperator_t>(child)) {
273 current.hasSep = true; 273 current.hasSep = true;
274 return false; 274 return false;