diff options
author | Li Jin <dragon-fly@qq.com> | 2022-07-24 22:13:08 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2022-07-24 22:13:08 +0800 |
commit | 303834e1b1e6cd9cae64b66c2ae44dcd7185238f (patch) | |
tree | 519f6a1debcc5791d35e06dc5cbb1ce22f9cfd31 /src | |
parent | eb367126bf3a4f5b0e51ccef93b7c7136bea170e (diff) | |
download | yuescript-303834e1b1e6cd9cae64b66c2ae44dcd7185238f.tar.gz yuescript-303834e1b1e6cd9cae64b66c2ae44dcd7185238f.tar.bz2 yuescript-303834e1b1e6cd9cae64b66c2ae44dcd7185238f.zip |
add option --target=5.1 to generate Lua 5.1 compatible codes. add const destructure. make import item const by default.
Diffstat (limited to 'src')
-rw-r--r-- | src/yue.cpp | 39 | ||||
-rwxr-xr-x | src/yuescript/yue_ast.h | 24 | ||||
-rwxr-xr-x | src/yuescript/yue_compiler.cpp | 232 | ||||
-rwxr-xr-x | src/yuescript/yue_parser.cpp | 42 | ||||
-rwxr-xr-x | src/yuescript/yue_parser.h | 8 | ||||
-rw-r--r-- | src/yuescript/yuescript.cpp | 10 |
6 files changed, 256 insertions, 99 deletions
diff --git a/src/yue.cpp b/src/yue.cpp index 3e30c70..cb27db8 100644 --- a/src/yue.cpp +++ b/src/yue.cpp | |||
@@ -21,6 +21,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
21 | #include <string_view> | 21 | #include <string_view> |
22 | #include <memory> | 22 | #include <memory> |
23 | using namespace std::string_view_literals; | 23 | using namespace std::string_view_literals; |
24 | using namespace std::string_literals; | ||
24 | #include "ghc/fs_std.hpp" | 25 | #include "ghc/fs_std.hpp" |
25 | #include "linenoise.hpp" | 26 | #include "linenoise.hpp" |
26 | 27 | ||
@@ -91,10 +92,10 @@ static const char luaminifyCodes[] = | |||
91 | 92 | ||
92 | static void pushLuaminify(lua_State* L) { | 93 | static void pushLuaminify(lua_State* L) { |
93 | if (luaL_loadbuffer(L, luaminifyCodes, sizeof(luaminifyCodes) / sizeof(luaminifyCodes[0]) - 1, "=(luaminify)") != 0) { | 94 | if (luaL_loadbuffer(L, luaminifyCodes, sizeof(luaminifyCodes) / sizeof(luaminifyCodes[0]) - 1, "=(luaminify)") != 0) { |
94 | std::string err = std::string("failed to load luaminify module.\n") + lua_tostring(L, -1); | 95 | std::string err = "failed to load luaminify module.\n"s + lua_tostring(L, -1); |
95 | luaL_error(L, err.c_str()); | 96 | luaL_error(L, err.c_str()); |
96 | } else if (lua_pcall(L, 0, 1, 0) != 0) { | 97 | } else if (lua_pcall(L, 0, 1, 0) != 0) { |
97 | std::string err = std::string("failed to init luaminify module.\n") + lua_tostring(L, -1); | 98 | std::string err = "failed to init luaminify module.\n"s + lua_tostring(L, -1); |
98 | luaL_error(L, err.c_str()); | 99 | luaL_error(L, err.c_str()); |
99 | } | 100 | } |
100 | } | 101 | } |
@@ -209,7 +210,7 @@ int main(int narg, const char** args) { | |||
209 | DEFER(lua_settop(L, top)); | 210 | DEFER(lua_settop(L, top)); |
210 | pushYue(L, "loadstring"sv); | 211 | pushYue(L, "loadstring"sv); |
211 | lua_pushlstring(L, codes.c_str(), codes.size()); | 212 | lua_pushlstring(L, codes.c_str(), codes.size()); |
212 | lua_pushstring(L, (std::string("=(repl ") + std::to_string(count) + ')').c_str()); | 213 | lua_pushstring(L, ("=(repl "s + std::to_string(count) + ')').c_str()); |
213 | pushOptions(L, -1); | 214 | pushOptions(L, -1); |
214 | const std::string_view Err = "\033[35m"sv, Val = "\033[33m"sv, Stop = "\033[0m\n"sv; | 215 | const std::string_view Err = "\033[35m"sv, Val = "\033[33m"sv, Stop = "\033[0m\n"sv; |
215 | if (lua_pcall(L, 3, 2, 0) != 0) { | 216 | if (lua_pcall(L, 3, 2, 0) != 0) { |
@@ -218,7 +219,7 @@ int main(int narg, const char** args) { | |||
218 | } | 219 | } |
219 | if (lua_isnil(L, -2) != 0) { | 220 | if (lua_isnil(L, -2) != 0) { |
220 | std::string err = lua_tostring(L, -1); | 221 | std::string err = lua_tostring(L, -1); |
221 | auto modName = std::string("(repl "sv) + std::to_string(count) + "):"; | 222 | auto modName = "(repl "s + std::to_string(count) + "):"s; |
222 | if (err.substr(0, modName.size()) == modName) { | 223 | if (err.substr(0, modName.size()) == modName) { |
223 | err = err.substr(modName.size()); | 224 | err = err.substr(modName.size()); |
224 | } | 225 | } |
@@ -409,8 +410,8 @@ int main(int narg, const char** args) { | |||
409 | std::cout << help; | 410 | std::cout << help; |
410 | return 1; | 411 | return 1; |
411 | } | 412 | } |
412 | } else if (arg.size() > 1 && arg.substr(0, 1) == "-"sv && arg.substr(1, 1) != "-"sv) { | 413 | } else if (arg.size() > 2 && arg.substr(0, 2) == "--"sv && arg.substr(2, 1) != "-"sv) { |
413 | auto argStr = arg.substr(1); | 414 | auto argStr = arg.substr(2); |
414 | yue::Utils::trim(argStr); | 415 | yue::Utils::trim(argStr); |
415 | size_t idx = argStr.find('='); | 416 | size_t idx = argStr.find('='); |
416 | if (idx != std::string::npos) { | 417 | if (idx != std::string::npos) { |
@@ -420,7 +421,7 @@ int main(int narg, const char** args) { | |||
420 | yue::Utils::trim(value); | 421 | yue::Utils::trim(value); |
421 | config.options[key] = value; | 422 | config.options[key] = value; |
422 | } else { | 423 | } else { |
423 | config.options[argStr] = ""; | 424 | config.options[argStr] = std::string(); |
424 | } | 425 | } |
425 | } else { | 426 | } else { |
426 | if (fs::is_directory(arg)) { | 427 | if (fs::is_directory(arg)) { |
@@ -459,7 +460,13 @@ int main(int narg, const char** args) { | |||
459 | auto conf = config; | 460 | auto conf = config; |
460 | conf.module = file.first; | 461 | conf.module = file.first; |
461 | if (!workPath.empty()) { | 462 | if (!workPath.empty()) { |
462 | conf.options["path"] = (fs::path(workPath) / "?.lua").string(); | 463 | auto it = conf.options.find("path"); |
464 | if (it != conf.options.end()) { | ||
465 | it->second += ';'; | ||
466 | it->second += (fs::path(workPath) / "?.lua"sv).string(); | ||
467 | } else { | ||
468 | conf.options["path"] = (fs::path(workPath) / "?.lua"sv).string(); | ||
469 | } | ||
463 | } | 470 | } |
464 | if (dumpCompileTime) { | 471 | if (dumpCompileTime) { |
465 | auto start = std::chrono::high_resolution_clock::now(); | 472 | auto start = std::chrono::high_resolution_clock::now(); |
@@ -499,7 +506,7 @@ int main(int narg, const char** args) { | |||
499 | } else { | 506 | } else { |
500 | std::string targetExtension("lua"sv); | 507 | std::string targetExtension("lua"sv); |
501 | if (result.options) { | 508 | if (result.options) { |
502 | auto it = result.options->find("target_extension"); | 509 | auto it = result.options->find("target_extension"s); |
503 | if (it != result.options->end()) { | 510 | if (it != result.options->end()) { |
504 | targetExtension = it->second; | 511 | targetExtension = it->second; |
505 | } | 512 | } |
@@ -519,19 +526,19 @@ int main(int narg, const char** args) { | |||
519 | fs::create_directories(targetFile.parent_path()); | 526 | fs::create_directories(targetFile.parent_path()); |
520 | } | 527 | } |
521 | if (result.codes.empty()) { | 528 | if (result.codes.empty()) { |
522 | return std::tuple{0, targetFile.string(), std::string("Built "sv) + file.first + '\n'}; | 529 | return std::tuple{0, targetFile.string(), "Built "s + file.first + '\n'}; |
523 | } | 530 | } |
524 | std::ofstream output(targetFile, std::ios::trunc | std::ios::out); | 531 | std::ofstream output(targetFile, std::ios::trunc | std::ios::out); |
525 | if (output) { | 532 | if (output) { |
526 | const auto& codes = result.codes; | 533 | const auto& codes = result.codes; |
527 | if (config.reserveLineNumber) { | 534 | if (config.reserveLineNumber) { |
528 | auto head = std::string("-- [yue]: "sv) + file.first + '\n'; | 535 | auto head = "-- [yue]: "s + file.first + '\n'; |
529 | output.write(head.c_str(), head.size()); | 536 | output.write(head.c_str(), head.size()); |
530 | } | 537 | } |
531 | output.write(codes.c_str(), codes.size()); | 538 | output.write(codes.c_str(), codes.size()); |
532 | return std::tuple{0, targetFile.string(), std::string("Built "sv) + file.first + '\n'}; | 539 | return std::tuple{0, targetFile.string(), "Built "s + file.first + '\n'}; |
533 | } else { | 540 | } else { |
534 | return std::tuple{1, std::string(), std::string("Failed to write file: "sv) + targetFile.string() + '\n'}; | 541 | return std::tuple{1, std::string(), "Failed to write file: "s + targetFile.string() + '\n'}; |
535 | } | 542 | } |
536 | } | 543 | } |
537 | } else { | 544 | } else { |
@@ -541,7 +548,7 @@ int main(int narg, const char** args) { | |||
541 | return std::tuple{1, std::string(), buf.str()}; | 548 | return std::tuple{1, std::string(), buf.str()}; |
542 | } | 549 | } |
543 | } else { | 550 | } else { |
544 | return std::tuple{1, std::string(), std::string("Failed to read file: "sv) + file.first + ".\n"}; | 551 | return std::tuple{1, std::string(), "Failed to read file: "s + file.first + ".\n"}; |
545 | } | 552 | } |
546 | }); | 553 | }); |
547 | results.push_back(std::move(task)); | 554 | results.push_back(std::move(task)); |
@@ -588,7 +595,7 @@ int main(int narg, const char** args) { | |||
588 | if (lua_pcall(L, 1, 1, 0) != 0) { | 595 | if (lua_pcall(L, 1, 1, 0) != 0) { |
589 | ret = 2; | 596 | ret = 2; |
590 | std::string err = lua_tostring(L, -1); | 597 | std::string err = lua_tostring(L, -1); |
591 | errs.push_back(std::string("Failed to minify: "sv) + file + '\n' + err + '\n'); | 598 | errs.push_back("Failed to minify: "s + file + '\n' + err + '\n'); |
592 | } else { | 599 | } else { |
593 | size_t size = 0; | 600 | size_t size = 0; |
594 | const char* minifiedCodes = lua_tolstring(L, -1, &size); | 601 | const char* minifiedCodes = lua_tolstring(L, -1, &size); |
@@ -603,7 +610,7 @@ int main(int narg, const char** args) { | |||
603 | } | 610 | } |
604 | } else { | 611 | } else { |
605 | ret = 2; | 612 | ret = 2; |
606 | errs.push_back(std::string("Failed to minify: "sv) + file + '\n'); | 613 | errs.push_back("Failed to minify: "s + file + '\n'); |
607 | } | 614 | } |
608 | } else { | 615 | } else { |
609 | std::cout << msg; | 616 | std::cout << msg; |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 05ac5ef..620dfcc 100755 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
@@ -118,16 +118,22 @@ AST_NODE(Local) | |||
118 | AST_MEMBER(Local, &item) | 118 | AST_MEMBER(Local, &item) |
119 | AST_END(Local, "local"sv) | 119 | AST_END(Local, "local"sv) |
120 | 120 | ||
121 | class Assign_t; | 121 | AST_LEAF(const_attrib) |
122 | AST_END(const_attrib, "const"sv) | ||
123 | |||
124 | AST_LEAF(close_attrib) | ||
125 | AST_END(close_attrib, "close"sv) | ||
122 | 126 | ||
123 | AST_LEAF(Attrib) | 127 | class simple_table_t; |
124 | AST_END(Attrib, "attrib"sv) | 128 | class TableLit_t; |
129 | class Assign_t; | ||
125 | 130 | ||
126 | AST_NODE(LocalAttrib) | 131 | AST_NODE(LocalAttrib) |
127 | ast_ptr<true, Attrib_t> attrib; | 132 | ast_sel<true, const_attrib_t, close_attrib_t> attrib; |
128 | ast_ptr<true, NameList_t> nameList; | 133 | ast_ptr<true, Seperator_t> sep; |
134 | ast_sel_list<true, Variable_t, simple_table_t, TableLit_t> leftList; | ||
129 | ast_ptr<true, Assign_t> assign; | 135 | ast_ptr<true, Assign_t> assign; |
130 | AST_MEMBER(LocalAttrib, &attrib, &nameList, &assign) | 136 | AST_MEMBER(LocalAttrib, &attrib, &sep, &leftList, &assign) |
131 | AST_END(LocalAttrib, "local_attrib"sv) | 137 | AST_END(LocalAttrib, "local_attrib"sv) |
132 | 138 | ||
133 | AST_NODE(colon_import_name) | 139 | AST_NODE(colon_import_name) |
@@ -135,9 +141,6 @@ AST_NODE(colon_import_name) | |||
135 | AST_MEMBER(colon_import_name, &name) | 141 | AST_MEMBER(colon_import_name, &name) |
136 | AST_END(colon_import_name, "colon_import_name"sv) | 142 | AST_END(colon_import_name, "colon_import_name"sv) |
137 | 143 | ||
138 | class Exp_t; | ||
139 | class TableLit_t; | ||
140 | |||
141 | AST_LEAF(import_literal_inner) | 144 | AST_LEAF(import_literal_inner) |
142 | AST_END(import_literal_inner, "import_literal_inner"sv) | 145 | AST_END(import_literal_inner, "import_literal_inner"sv) |
143 | 146 | ||
@@ -147,6 +150,8 @@ AST_NODE(ImportLiteral) | |||
147 | AST_MEMBER(ImportLiteral, &sep, &inners) | 150 | AST_MEMBER(ImportLiteral, &sep, &inners) |
148 | AST_END(ImportLiteral, "import_literal"sv) | 151 | AST_END(ImportLiteral, "import_literal"sv) |
149 | 152 | ||
153 | class Exp_t; | ||
154 | |||
150 | AST_NODE(ImportFrom) | 155 | AST_NODE(ImportFrom) |
151 | ast_ptr<true, Seperator_t> sep; | 156 | ast_ptr<true, Seperator_t> sep; |
152 | ast_sel_list<true, colon_import_name_t, Variable_t> names; | 157 | ast_sel_list<true, colon_import_name_t, Variable_t> names; |
@@ -499,7 +504,6 @@ class String_t; | |||
499 | class const_value_t; | 504 | class const_value_t; |
500 | class ClassDecl_t; | 505 | class ClassDecl_t; |
501 | class unary_value_t; | 506 | class unary_value_t; |
502 | class TableLit_t; | ||
503 | class FunLit_t; | 507 | class FunLit_t; |
504 | 508 | ||
505 | AST_NODE(SimpleValue) | 509 | AST_NODE(SimpleValue) |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 7bbf5e9..0d027a0 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -13,6 +13,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
13 | #include <vector> | 13 | #include <vector> |
14 | #include <memory> | 14 | #include <memory> |
15 | #include <set> | 15 | #include <set> |
16 | #include <optional> | ||
16 | 17 | ||
17 | #include "yuescript/yue_parser.h" | 18 | #include "yuescript/yue_parser.h" |
18 | #include "yuescript/yue_compiler.h" | 19 | #include "yuescript/yue_compiler.h" |
@@ -37,9 +38,6 @@ extern "C" { | |||
37 | #endif // YUE_NO_MACRO | 38 | #endif // YUE_NO_MACRO |
38 | 39 | ||
39 | namespace yue { | 40 | namespace yue { |
40 | using namespace std::string_view_literals; | ||
41 | using namespace std::string_literals; | ||
42 | using namespace parserlib; | ||
43 | 41 | ||
44 | #define BLOCK_START do { | 42 | #define BLOCK_START do { |
45 | #define BLOCK_END } while (false); | 43 | #define BLOCK_END } while (false); |
@@ -56,7 +54,7 @@ using namespace parserlib; | |||
56 | 54 | ||
57 | typedef std::list<std::string> str_list; | 55 | typedef std::list<std::string> str_list; |
58 | 56 | ||
59 | const std::string_view version = "0.13.6"sv; | 57 | const std::string_view version = "0.14.0"sv; |
60 | const std::string_view extension = "yue"sv; | 58 | const std::string_view extension = "yue"sv; |
61 | 59 | ||
62 | class YueCompilerImpl { | 60 | class YueCompilerImpl { |
@@ -1266,8 +1264,8 @@ private: | |||
1266 | 1264 | ||
1267 | std::string getDestrucureDefine(ExpListAssign_t* assignment) { | 1265 | std::string getDestrucureDefine(ExpListAssign_t* assignment) { |
1268 | auto info = extractDestructureInfo(assignment, true, false); | 1266 | auto info = extractDestructureInfo(assignment, true, false); |
1269 | if (!info.first.empty()) { | 1267 | if (!info.destructures.empty()) { |
1270 | for (const auto& destruct : info.first) { | 1268 | for (const auto& destruct : info.destructures) { |
1271 | str_list defs; | 1269 | str_list defs; |
1272 | for (const auto& item : destruct.items) { | 1270 | for (const auto& item : destruct.items) { |
1273 | if (!item.targetVar.empty()) { | 1271 | if (!item.targetVar.empty()) { |
@@ -1319,11 +1317,30 @@ private: | |||
1319 | return assignment; | 1317 | return assignment; |
1320 | } | 1318 | } |
1321 | 1319 | ||
1320 | void markDestructureConst(ExpListAssign_t* assignment) { | ||
1321 | auto info = extractDestructureInfo(assignment, true, false); | ||
1322 | for (auto& destruct : info.destructures) { | ||
1323 | for (auto& item : destruct.items) { | ||
1324 | if (item.targetVar.empty()) { | ||
1325 | throw std::logic_error(_info.errorMessage("can only declare variable as const"sv, item.target)); | ||
1326 | } | ||
1327 | markVarConst(item.targetVar); | ||
1328 | } | ||
1329 | } | ||
1330 | } | ||
1331 | |||
1322 | void transformAssignment(ExpListAssign_t* assignment, str_list& out, bool optionalDestruct = false) { | 1332 | void transformAssignment(ExpListAssign_t* assignment, str_list& out, bool optionalDestruct = false) { |
1323 | checkAssignable(assignment->expList); | 1333 | checkAssignable(assignment->expList); |
1324 | BLOCK_START | 1334 | BLOCK_START |
1325 | auto assign = ast_cast<Assign_t>(assignment->action); | 1335 | auto assign = ast_cast<Assign_t>(assignment->action); |
1326 | BREAK_IF(!assign); | 1336 | BREAK_IF(!assign); |
1337 | if (assignment->expList->exprs.size() < assign->values.size()) { | ||
1338 | auto num = assignment->expList->exprs.size(); | ||
1339 | _buf << "no more than "sv << num << " right value"sv; | ||
1340 | if (num > 1) _buf << 's'; | ||
1341 | _buf << " required"sv; | ||
1342 | throw std::logic_error(_info.errorMessage(clearBuf(), assign->values.front())); | ||
1343 | } | ||
1327 | auto x = assignment; | 1344 | auto x = assignment; |
1328 | const auto& exprs = assignment->expList->exprs.objects(); | 1345 | const auto& exprs = assignment->expList->exprs.objects(); |
1329 | const auto& values = assign->values.objects(); | 1346 | const auto& values = assign->values.objects(); |
@@ -1554,15 +1571,15 @@ private: | |||
1554 | } | 1571 | } |
1555 | BLOCK_END | 1572 | BLOCK_END |
1556 | auto info = extractDestructureInfo(assignment, false, optionalDestruct); | 1573 | auto info = extractDestructureInfo(assignment, false, optionalDestruct); |
1557 | if (info.first.empty()) { | 1574 | if (info.destructures.empty()) { |
1558 | transformAssignmentCommon(assignment, out); | 1575 | transformAssignmentCommon(assignment, out); |
1559 | } else { | 1576 | } else { |
1560 | str_list temp; | 1577 | str_list temp; |
1561 | if (info.second) { | 1578 | if (info.assignment) { |
1562 | transformAssignmentCommon(info.second, temp); | 1579 | transformAssignmentCommon(info.assignment, temp); |
1563 | } | 1580 | } |
1564 | auto x = assignment; | 1581 | auto x = assignment; |
1565 | for (auto& destruct : info.first) { | 1582 | for (auto& destruct : info.destructures) { |
1566 | std::list<std::pair<ast_ptr<true, Exp_t>, ast_ptr<true, Exp_t>>> leftPairs; | 1583 | std::list<std::pair<ast_ptr<true, Exp_t>, ast_ptr<true, Exp_t>>> leftPairs; |
1567 | bool extraScope = false; | 1584 | bool extraScope = false; |
1568 | if (destruct.items.size() == 1) { | 1585 | if (destruct.items.size() == 1) { |
@@ -2030,24 +2047,22 @@ private: | |||
2030 | return pairs; | 2047 | return pairs; |
2031 | } | 2048 | } |
2032 | 2049 | ||
2033 | std::pair<std::list<Destructure>, ast_ptr<false, ExpListAssign_t>> | 2050 | struct DestructureInfo { |
2034 | extractDestructureInfo(ExpListAssign_t* assignment, bool varDefOnly, bool optional) { | 2051 | std::list<Destructure> destructures; |
2052 | ast_ptr<false, ExpListAssign_t> assignment; | ||
2053 | }; | ||
2054 | |||
2055 | DestructureInfo extractDestructureInfo(ExpListAssign_t* assignment, bool varDefOnly, bool optional) { | ||
2035 | auto x = assignment; | 2056 | auto x = assignment; |
2036 | std::list<Destructure> destructs; | 2057 | std::list<Destructure> destructs; |
2037 | if (!assignment->action.is<Assign_t>()) return {destructs, nullptr}; | 2058 | if (!assignment->action.is<Assign_t>()) return {destructs, nullptr}; |
2038 | auto exprs = assignment->expList->exprs.objects(); | 2059 | auto exprs = assignment->expList->exprs.objects(); |
2039 | auto values = assignment->action.to<Assign_t>()->values.objects(); | 2060 | auto values = assignment->action.to<Assign_t>()->values.objects(); |
2040 | size_t size = std::max(exprs.size(), values.size()); | 2061 | size_t size = std::max(exprs.size(), values.size()); |
2041 | ast_list<false, ast_node> cache; | 2062 | ast_ptr<false, Exp_t> nil; |
2042 | if (exprs.size() < size) { | ||
2043 | auto var = toAst<Exp_t>("_"sv, x); | ||
2044 | cache.push_back(var); | ||
2045 | while (exprs.size() < size) exprs.emplace_back(var); | ||
2046 | } | ||
2047 | ast_ptr<false, Exp_t> nullNode; | ||
2048 | if (values.size() < size) { | 2063 | if (values.size() < size) { |
2049 | nullNode = toAst<Exp_t>("nil"sv, x); | 2064 | nil = toAst<Exp_t>("nil"sv, x); |
2050 | while (values.size() < size) values.emplace_back(nullNode); | 2065 | while (values.size() < size) values.emplace_back(nil); |
2051 | } | 2066 | } |
2052 | using iter = node_container::iterator; | 2067 | using iter = node_container::iterator; |
2053 | std::vector<std::pair<iter, iter>> destructPairs; | 2068 | std::vector<std::pair<iter, iter>> destructPairs; |
@@ -2059,11 +2074,11 @@ private: | |||
2059 | auto value = singleValueFrom(expr); | 2074 | auto value = singleValueFrom(expr); |
2060 | ast_node* destructNode = value->getByPath<SimpleValue_t, TableLit_t>(); | 2075 | ast_node* destructNode = value->getByPath<SimpleValue_t, TableLit_t>(); |
2061 | if (destructNode || (destructNode = value->item.as<simple_table_t>())) { | 2076 | if (destructNode || (destructNode = value->item.as<simple_table_t>())) { |
2062 | if (*j != nullNode) { | 2077 | if (*j != nil) { |
2063 | if (auto ssVal = simpleSingleValueFrom(*j)) { | 2078 | if (auto ssVal = simpleSingleValueFrom(*j)) { |
2064 | switch (ssVal->value->getId()) { | 2079 | switch (ssVal->value->getId()) { |
2065 | case id<const_value_t>(): | 2080 | case id<const_value_t>(): |
2066 | throw std::logic_error(_info.errorMessage("can not destructure a const value"sv, ssVal->value)); | 2081 | throw std::logic_error(_info.errorMessage("can not destructure a constant"sv, ssVal->value)); |
2067 | break; | 2082 | break; |
2068 | case id<Num_t>(): | 2083 | case id<Num_t>(): |
2069 | throw std::logic_error(_info.errorMessage("can not destructure a number"sv, ssVal->value)); | 2084 | throw std::logic_error(_info.errorMessage("can not destructure a number"sv, ssVal->value)); |
@@ -2074,7 +2089,7 @@ private: | |||
2074 | } | 2089 | } |
2075 | } | 2090 | } |
2076 | } else { | 2091 | } else { |
2077 | throw std::logic_error(_info.errorMessage("can not destructure a nil value"sv, destructNode)); | 2092 | throw std::logic_error(_info.errorMessage("an explicit destructure target required"sv, destructNode)); |
2078 | } | 2093 | } |
2079 | destructPairs.push_back({i, j}); | 2094 | destructPairs.push_back({i, j}); |
2080 | auto subDestruct = destructNode->new_ptr<TableLit_t>(); | 2095 | auto subDestruct = destructNode->new_ptr<TableLit_t>(); |
@@ -2173,7 +2188,7 @@ private: | |||
2173 | } | 2188 | } |
2174 | destruct.items = std::move(pairs); | 2189 | destruct.items = std::move(pairs); |
2175 | if (!varDefOnly) { | 2190 | if (!varDefOnly) { |
2176 | if (*j == nullNode) { | 2191 | if (*j == nil) { |
2177 | for (auto& item : destruct.items) { | 2192 | for (auto& item : destruct.items) { |
2178 | item.structure.clear(); | 2193 | item.structure.clear(); |
2179 | } | 2194 | } |
@@ -3104,8 +3119,8 @@ private: | |||
3104 | } | 3119 | } |
3105 | } | 3120 | } |
3106 | auto info = extractDestructureInfo(assignment, true, false); | 3121 | auto info = extractDestructureInfo(assignment, true, false); |
3107 | if (!info.first.empty()) { | 3122 | if (!info.destructures.empty()) { |
3108 | for (const auto& destruct : info.first) | 3123 | for (const auto& destruct : info.destructures) |
3109 | for (const auto& item : destruct.items) | 3124 | for (const auto& item : destruct.items) |
3110 | if (!item.targetVar.empty()) { | 3125 | if (!item.targetVar.empty()) { |
3111 | if (std::isupper(item.targetVar[0]) && capital) { capital->decls.push_back(item.targetVar); | 3126 | if (std::isupper(item.targetVar[0]) && capital) { capital->decls.push_back(item.targetVar); |
@@ -3114,8 +3129,8 @@ private: | |||
3114 | } | 3129 | } |
3115 | } | 3130 | } |
3116 | } | 3131 | } |
3117 | if (info.second) { | 3132 | if (info.assignment) { |
3118 | auto defs = transformAssignDefs(info.second->expList, DefOp::Get); | 3133 | auto defs = transformAssignDefs(info.assignment->expList, DefOp::Get); |
3119 | for (const auto& def : defs) { | 3134 | for (const auto& def : defs) { |
3120 | if (std::isupper(def[0]) && capital) { capital->decls.push_back(def); | 3135 | if (std::isupper(def[0]) && capital) { capital->decls.push_back(def); |
3121 | } else if (any) { | 3136 | } else if (any) { |
@@ -3236,6 +3251,49 @@ private: | |||
3236 | } | 3251 | } |
3237 | } | 3252 | } |
3238 | 3253 | ||
3254 | std::optional<std::string> getOption(std::string_view key) { | ||
3255 | #ifndef YUE_NO_MACRO | ||
3256 | if (L) { | ||
3257 | int top = lua_gettop(L); | ||
3258 | DEFER(lua_settop(L, top)); | ||
3259 | pushYue("options"sv); // options | ||
3260 | lua_pushlstring(L, &key.front(), key.size()); | ||
3261 | lua_gettable(L, -2); | ||
3262 | if (lua_isstring(L, -1) != 0) { | ||
3263 | size_t size = 0; | ||
3264 | const char* str = lua_tolstring(L, -1, &size); | ||
3265 | return std::string(str, size); | ||
3266 | } | ||
3267 | } | ||
3268 | #endif // YUE_NO_MACRO | ||
3269 | auto it = _config.options.find(std::string(key)); | ||
3270 | if (it != _config.options.end()) { | ||
3271 | return it->second; | ||
3272 | } | ||
3273 | return std::nullopt; | ||
3274 | } | ||
3275 | |||
3276 | int getLuaTarget(ast_node* x) { | ||
3277 | if (auto target = getOption("target")) { | ||
3278 | if (target.value() == "5.1"sv) { | ||
3279 | return 501; | ||
3280 | } else if (target.value() == "5.2"sv) { | ||
3281 | return 502; | ||
3282 | } else if (target.value() == "5.3"sv) { | ||
3283 | return 503; | ||
3284 | } else if (target.value() == "5.4"sv) { | ||
3285 | return 504; | ||
3286 | } else { | ||
3287 | throw std::logic_error(_info.errorMessage("get invalid Lua target \""s + target.value() + "\", should be 5.1, 5.2, 5.3 or 5.4"s, x)); | ||
3288 | } | ||
3289 | } | ||
3290 | #ifndef YUE_NO_MACRO | ||
3291 | return LUA_VERSION_NUM; | ||
3292 | #else | ||
3293 | return 504; | ||
3294 | #endif // YUE_NO_MACRO | ||
3295 | } | ||
3296 | |||
3239 | #ifndef YUE_NO_MACRO | 3297 | #ifndef YUE_NO_MACRO |
3240 | void passOptions() { | 3298 | void passOptions() { |
3241 | if (!_config.options.empty()) { | 3299 | if (!_config.options.empty()) { |
@@ -5898,8 +5956,8 @@ private: | |||
5898 | auto names = transformAssignDefs(assignment->expList.get(), DefOp::Mark); | 5956 | auto names = transformAssignDefs(assignment->expList.get(), DefOp::Mark); |
5899 | varDefs.insert(varDefs.end(), names.begin(), names.end()); | 5957 | varDefs.insert(varDefs.end(), names.begin(), names.end()); |
5900 | auto info = extractDestructureInfo(assignment, true, false); | 5958 | auto info = extractDestructureInfo(assignment, true, false); |
5901 | if (!info.first.empty()) { | 5959 | if (!info.destructures.empty()) { |
5902 | for (const auto& destruct : info.first) | 5960 | for (const auto& destruct : info.destructures) |
5903 | for (const auto& item : destruct.items) | 5961 | for (const auto& item : destruct.items) |
5904 | if (!item.targetVar.empty() && addToScope(item.targetVar)) | 5962 | if (!item.targetVar.empty() && addToScope(item.targetVar)) |
5905 | varDefs.push_back(item.targetVar); | 5963 | varDefs.push_back(item.targetVar); |
@@ -6329,8 +6387,8 @@ private: | |||
6329 | return traversal::Stop; | 6387 | return traversal::Stop; |
6330 | } | 6388 | } |
6331 | auto info = extractDestructureInfo(assignment, true, false); | 6389 | auto info = extractDestructureInfo(assignment, true, false); |
6332 | if (!info.first.empty()) { | 6390 | if (!info.destructures.empty()) { |
6333 | for (const auto& destruct : info.first) | 6391 | for (const auto& destruct : info.destructures) |
6334 | for (const auto& item : destruct.items) | 6392 | for (const auto& item : destruct.items) |
6335 | if (!item.targetVar.empty() && !isDefined(item.targetVar)) | 6393 | if (!item.targetVar.empty() && !isDefined(item.targetVar)) |
6336 | return traversal::Stop; | 6394 | return traversal::Stop; |
@@ -6481,8 +6539,8 @@ private: | |||
6481 | transformAssignment(assignment, out); | 6539 | transformAssignment(assignment, out); |
6482 | str_list names = transformAssignDefs(expList, DefOp::Get); | 6540 | str_list names = transformAssignDefs(expList, DefOp::Get); |
6483 | auto info = extractDestructureInfo(assignment, true, false); | 6541 | auto info = extractDestructureInfo(assignment, true, false); |
6484 | if (!info.first.empty()) { | 6542 | if (!info.destructures.empty()) { |
6485 | for (const auto& destruct : info.first) | 6543 | for (const auto& destruct : info.destructures) |
6486 | for (const auto& item : destruct.items) | 6544 | for (const auto& item : destruct.items) |
6487 | if (!item.targetVar.empty()) | 6545 | if (!item.targetVar.empty()) |
6488 | names.push_back(item.targetVar); | 6546 | names.push_back(item.targetVar); |
@@ -6848,6 +6906,7 @@ private: | |||
6848 | temp.push_back(indent() + "end"s + nlr(import)); | 6906 | temp.push_back(indent() + "end"s + nlr(import)); |
6849 | } | 6907 | } |
6850 | out.push_back(join(temp)); | 6908 | out.push_back(join(temp)); |
6909 | markDestructureConst(assignment); | ||
6851 | } | 6910 | } |
6852 | 6911 | ||
6853 | std::string moduleNameFrom(ImportLiteral_t* literal) { | 6912 | std::string moduleNameFrom(ImportLiteral_t* literal) { |
@@ -7013,6 +7072,12 @@ private: | |||
7013 | assignment->expList.set(assignList); | 7072 | assignment->expList.set(assignList); |
7014 | assignment->action.set(assign); | 7073 | assignment->action.set(assign); |
7015 | transformAssignment(assignment, out); | 7074 | transformAssignment(assignment, out); |
7075 | if (auto var = ast_cast<Variable_t>(target)) { | ||
7076 | auto moduleName = _parser.toString(var); | ||
7077 | markVarConst(moduleName); | ||
7078 | } else { | ||
7079 | markDestructureConst(assignment); | ||
7080 | } | ||
7016 | } | 7081 | } |
7017 | 7082 | ||
7018 | void transformImport(Import_t* import, str_list& out) { | 7083 | void transformImport(Import_t* import, str_list& out) { |
@@ -7191,7 +7256,7 @@ private: | |||
7191 | auto info = extractDestructureInfo(assignment, true, false); | 7256 | auto info = extractDestructureInfo(assignment, true, false); |
7192 | transformAssignment(assignment, temp, true); | 7257 | transformAssignment(assignment, temp, true); |
7193 | str_list conds; | 7258 | str_list conds; |
7194 | for (const auto& destruct : info.first) { | 7259 | for (const auto& destruct : info.destructures) { |
7195 | for (const auto& item : destruct.items) { | 7260 | for (const auto& item : destruct.items) { |
7196 | if (!item.defVal) { | 7261 | if (!item.defVal) { |
7197 | transformExp(item.target, conds, ExpUsage::Closure); | 7262 | transformExp(item.target, conds, ExpUsage::Closure); |
@@ -7334,23 +7399,84 @@ private: | |||
7334 | 7399 | ||
7335 | void transformLocalAttrib(LocalAttrib_t* localAttrib, str_list& out) { | 7400 | void transformLocalAttrib(LocalAttrib_t* localAttrib, str_list& out) { |
7336 | auto x = localAttrib; | 7401 | auto x = localAttrib; |
7337 | auto attrib = _parser.toString(localAttrib->attrib); | 7402 | if (x->leftList.size() < x->assign->values.size()) { |
7338 | str_list vars; | 7403 | throw std::logic_error(_info.errorMessage("number of right values should not be greater than left values"sv, x->assign->values.front())); |
7339 | for (auto name : localAttrib->nameList->names.objects()) { | 7404 | } |
7340 | auto var = _parser.toString(name); | 7405 | auto listA = x->new_ptr<NameList_t>(); |
7341 | forceAddToScope(var); | 7406 | auto assignA = x->new_ptr<Assign_t>(); |
7342 | vars.push_back(var); | 7407 | auto listB = x->new_ptr<ExpList_t>(); |
7408 | auto assignB = x->new_ptr<Assign_t>(); | ||
7409 | auto i = x->leftList.objects().begin(); | ||
7410 | auto ie = x->leftList.objects().end(); | ||
7411 | auto j = x->assign->values.objects().begin(); | ||
7412 | auto je = x->assign->values.objects().end(); | ||
7413 | while (i != ie) { | ||
7414 | if (ast_is<Variable_t>(*i)) { | ||
7415 | listA->names.push_back(*i); | ||
7416 | if (j != je) assignA->values.push_back(*j); | ||
7417 | } else { | ||
7418 | auto item = *i; | ||
7419 | auto value = item->new_ptr<Value_t>(); | ||
7420 | switch (item->getId()) { | ||
7421 | case id<simple_table_t>(): | ||
7422 | value->item.set(item); | ||
7423 | break; | ||
7424 | case id<TableLit_t>(): { | ||
7425 | auto simpleValue = item->new_ptr<SimpleValue_t>(); | ||
7426 | simpleValue->value.set(item); | ||
7427 | value->item.set(simpleValue); | ||
7428 | break; | ||
7429 | } | ||
7430 | default: YUEE("AST node mismatch", item); break; | ||
7431 | } | ||
7432 | auto exp = newExp(value, item); | ||
7433 | listB->exprs.push_back(exp); | ||
7434 | if (j != je) assignB->values.push_back(*j); | ||
7435 | } | ||
7436 | ++i; | ||
7437 | if (j != je) ++j; | ||
7343 | } | 7438 | } |
7344 | attrib = " <"s + attrib + '>'; | 7439 | if (!listA->names.empty()) { |
7345 | for (auto& var : vars) { | 7440 | str_list vars; |
7346 | markVarConst(var); | 7441 | for (auto name : listA->names.objects()) { |
7347 | var.append(attrib); | 7442 | auto var = _parser.toString(name); |
7443 | forceAddToScope(var); | ||
7444 | vars.push_back(var); | ||
7445 | } | ||
7446 | if (getLuaTarget(x) >= 504) { | ||
7447 | std::string attrib; | ||
7448 | if (localAttrib->attrib.is<const_attrib_t>()) { | ||
7449 | attrib = " <const>"s; | ||
7450 | } else if (localAttrib->attrib.is<close_attrib_t>()) { | ||
7451 | attrib = " <close>"s; | ||
7452 | } else { | ||
7453 | YUEE("AST node mismatch", localAttrib->attrib); | ||
7454 | } | ||
7455 | for (auto& var : vars) { | ||
7456 | markVarConst(var); | ||
7457 | var.append(attrib); | ||
7458 | } | ||
7459 | } else { | ||
7460 | if (localAttrib->attrib.is<close_attrib_t>()) { | ||
7461 | throw std::logic_error(_info.errorMessage("close attribute is not available when not targeting Lua 5.4 or higher version"sv, x)); | ||
7462 | } | ||
7463 | for (auto& var : vars) { | ||
7464 | markVarConst(var); | ||
7465 | } | ||
7466 | } | ||
7467 | str_list temp; | ||
7468 | for (auto item : assignA->values.objects()) { | ||
7469 | transformAssignItem(item, temp); | ||
7470 | } | ||
7471 | out.push_back(indent() + "local "s + join(vars, ", "sv) + " = "s + join(temp, ", "sv) + nll(x)); | ||
7348 | } | 7472 | } |
7349 | str_list temp; | 7473 | if (!listB->exprs.empty()) { |
7350 | for (auto item : localAttrib->assign->values.objects()) { | 7474 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
7351 | transformAssignItem(item, temp); | 7475 | assignment->expList.set(listB); |
7476 | assignment->action.set(assignB); | ||
7477 | transformAssignment(assignment, out); | ||
7478 | markDestructureConst(assignment); | ||
7352 | } | 7479 | } |
7353 | out.push_back(indent() + "local "s + join(vars, ", "sv) + " = "s + join(temp, ", "sv) + nll(x)); | ||
7354 | } | 7480 | } |
7355 | 7481 | ||
7356 | void transformBreakLoop(BreakLoop_t* breakLoop, str_list& out) { | 7482 | void transformBreakLoop(BreakLoop_t* breakLoop, str_list& out) { |
@@ -7372,10 +7498,16 @@ private: | |||
7372 | } | 7498 | } |
7373 | 7499 | ||
7374 | void transformLabel(Label_t* label, str_list& out) { | 7500 | void transformLabel(Label_t* label, str_list& out) { |
7501 | if (getLuaTarget(label) < 502) { | ||
7502 | throw std::logic_error(_info.errorMessage("label statement is not available when not targeting Lua 5.2 or higher version"sv, label)); | ||
7503 | } | ||
7375 | out.push_back(indent() + "::"s + _parser.toString(label->label) + "::"s + nll(label)); | 7504 | out.push_back(indent() + "::"s + _parser.toString(label->label) + "::"s + nll(label)); |
7376 | } | 7505 | } |
7377 | 7506 | ||
7378 | void transformGoto(Goto_t* gotoNode, str_list& out) { | 7507 | void transformGoto(Goto_t* gotoNode, str_list& out) { |
7508 | if (getLuaTarget(gotoNode) < 502) { | ||
7509 | throw std::logic_error(_info.errorMessage("goto statement is not available when not targeting Lua 5.2 or higher version"sv, gotoNode)); | ||
7510 | } | ||
7379 | out.push_back(indent() + "goto "s + _parser.toString(gotoNode->label) + nll(gotoNode)); | 7511 | out.push_back(indent() + "goto "s + _parser.toString(gotoNode->label) + nll(gotoNode)); |
7380 | } | 7512 | } |
7381 | 7513 | ||
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 66043d3..94ce550 100755 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
@@ -11,25 +11,24 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
11 | namespace pl = parserlib; | 11 | namespace pl = parserlib; |
12 | 12 | ||
13 | namespace yue { | 13 | namespace yue { |
14 | using namespace std::string_view_literals; | ||
15 | 14 | ||
16 | std::unordered_set<std::string> LuaKeywords = { | 15 | std::unordered_set<std::string> LuaKeywords = { |
17 | "and", "break", "do", "else", "elseif", | 16 | "and"s, "break"s, "do"s, "else"s, "elseif"s, |
18 | "end", "false", "for", "function", "goto", | 17 | "end"s, "false"s, "for"s, "function"s, "goto"s, |
19 | "if", "in", "local", "nil", "not", | 18 | "if"s, "in"s, "local"s, "nil"s, "not"s, |
20 | "or", "repeat", "return", "then", "true", | 19 | "or"s, "repeat"s, "return"s, "then"s, "true"s, |
21 | "until", "while" | 20 | "until"s, "while"s |
22 | }; | 21 | }; |
23 | 22 | ||
24 | std::unordered_set<std::string> Keywords = { | 23 | std::unordered_set<std::string> Keywords = { |
25 | "and", "break", "do", "else", "elseif", | 24 | "and"s, "break"s, "do"s, "else"s, "elseif"s, |
26 | "end", "false", "for", "function", "goto", | 25 | "end"s, "false"s, "for"s, "function"s, "goto"s, |
27 | "if", "in", "local", "nil", "not", | 26 | "if"s, "in"s, "local"s, "nil"s, "not"s, |
28 | "or", "repeat", "return", "then", "true", | 27 | "or"s, "repeat"s, "return"s, "then"s, "true"s, |
29 | "until", "while", // Lua keywords | 28 | "until"s, "while"s, // Lua keywords |
30 | "as", "class", "continue", "export", "extends", | 29 | "as"s, "class"s, "continue"s, "export"s, "extends"s, |
31 | "from", "global", "import", "macro", "switch", | 30 | "from"s, "global"s, "import"s, "macro"s, "switch"s, |
32 | "try", "unless", "using", "when", "with" // Yue keywords | 31 | "try"s, "unless"s, "using"s, "when"s, "with"s // Yue keywords |
33 | }; | 32 | }; |
34 | 33 | ||
35 | YueParser::YueParser() { | 34 | YueParser::YueParser() { |
@@ -86,7 +85,7 @@ YueParser::YueParser() { | |||
86 | if (isValid) { | 85 | if (isValid) { |
87 | if (st->buffer == st->moduleName) { | 86 | if (st->buffer == st->moduleName) { |
88 | st->moduleFix++; | 87 | st->moduleFix++; |
89 | st->moduleName = std::string("_module_"sv) + std::to_string(st->moduleFix); | 88 | st->moduleName = "_module_"s + std::to_string(st->moduleFix); |
90 | } | 89 | } |
91 | } | 90 | } |
92 | st->buffer.clear(); | 91 | st->buffer.clear(); |
@@ -179,10 +178,15 @@ YueParser::YueParser() { | |||
179 | 178 | ||
180 | local_flag = expr('*') | expr('^'); | 179 | local_flag = expr('*') | expr('^'); |
181 | local_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); | 180 | local_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); |
182 | Attrib = (expr("const") | expr("close")) >> not_(AlphaNum); | ||
183 | Local = key("local") >> (Space >> local_flag | local_values); | 181 | Local = key("local") >> (Space >> local_flag | local_values); |
184 | 182 | ||
185 | LocalAttrib = Attrib >> NameList >> Assign; | 183 | const_attrib = key("const"); |
184 | close_attrib = key("close"); | ||
185 | local_const_item = (Space >> Variable | simple_table | TableLit); | ||
186 | LocalAttrib = ( | ||
187 | const_attrib >> Seperator >> local_const_item >> *(sym(',') >> local_const_item) | | ||
188 | close_attrib >> Seperator >> Space >> Variable >> *(sym(',') >> Space >> Variable) | ||
189 | ) >> Assign; | ||
186 | 190 | ||
187 | colon_import_name = sym('\\') >> Space >> Variable; | 191 | colon_import_name = sym('\\') >> Space >> Variable; |
188 | ImportName = colon_import_name | Space >> Variable; | 192 | ImportName = colon_import_name | Space >> Variable; |
@@ -754,6 +758,10 @@ std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc | |||
754 | ++it; | 758 | ++it; |
755 | } | 759 | } |
756 | auto line = Converter{}.to_bytes(std::wstring(begin, end)); | 760 | auto line = Converter{}.to_bytes(std::wstring(begin, end)); |
761 | while (col < static_cast<int>(line.size()) | ||
762 | && (line[col] == ' ' || line[col] == '\t')) { | ||
763 | col++; | ||
764 | } | ||
757 | Utils::replace(line, "\t"sv, " "sv); | 765 | Utils::replace(line, "\t"sv, " "sv); |
758 | std::ostringstream buf; | 766 | std::ostringstream buf; |
759 | buf << loc->m_begin.m_line << ": "sv << msg << | 767 | buf << loc->m_begin.m_line << ": "sv << msg << |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index b71a67c..b363ad7 100755 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
@@ -21,6 +21,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
21 | #include "yuescript/yue_ast.h" | 21 | #include "yuescript/yue_ast.h" |
22 | 22 | ||
23 | namespace yue { | 23 | namespace yue { |
24 | using namespace std::string_view_literals; | ||
25 | using namespace std::string_literals; | ||
24 | using namespace parserlib; | 26 | using namespace parserlib; |
25 | 27 | ||
26 | struct ParseInfo { | 28 | struct ParseInfo { |
@@ -77,7 +79,7 @@ protected: | |||
77 | int exportCount = 0; | 79 | int exportCount = 0; |
78 | int moduleFix = 0; | 80 | int moduleFix = 0; |
79 | size_t stringOpen = 0; | 81 | size_t stringOpen = 0; |
80 | std::string moduleName = "_module_0"; | 82 | std::string moduleName = "_module_0"s; |
81 | std::string buffer; | 83 | std::string buffer; |
82 | std::stack<int> indents; | 84 | std::stack<int> indents; |
83 | std::stack<bool> noDoStack; | 85 | std::stack<bool> noDoStack; |
@@ -189,6 +191,7 @@ private: | |||
189 | rule expo_value; | 191 | rule expo_value; |
190 | rule expo_exp; | 192 | rule expo_exp; |
191 | rule exp_not_tab; | 193 | rule exp_not_tab; |
194 | rule local_const_item; | ||
192 | rule empty_line_stop; | 195 | rule empty_line_stop; |
193 | rule Line; | 196 | rule Line; |
194 | rule Shebang; | 197 | rule Shebang; |
@@ -209,8 +212,9 @@ private: | |||
209 | AST_RULE(NameList) | 212 | AST_RULE(NameList) |
210 | AST_RULE(local_flag) | 213 | AST_RULE(local_flag) |
211 | AST_RULE(local_values) | 214 | AST_RULE(local_values) |
212 | AST_RULE(Attrib) | ||
213 | AST_RULE(Local) | 215 | AST_RULE(Local) |
216 | AST_RULE(const_attrib) | ||
217 | AST_RULE(close_attrib) | ||
214 | AST_RULE(LocalAttrib); | 218 | AST_RULE(LocalAttrib); |
215 | AST_RULE(colon_import_name) | 219 | AST_RULE(colon_import_name) |
216 | AST_RULE(import_literal_inner) | 220 | AST_RULE(import_literal_inner) |
diff --git a/src/yuescript/yuescript.cpp b/src/yuescript/yuescript.cpp index 2e96f16..98e214f 100644 --- a/src/yuescript/yuescript.cpp +++ b/src/yuescript/yuescript.cpp | |||
@@ -9,6 +9,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |||
9 | #include "yuescript/yue_compiler.h" | 9 | #include "yuescript/yue_compiler.h" |
10 | #include "yuescript/yue_parser.h" | 10 | #include "yuescript/yue_parser.h" |
11 | 11 | ||
12 | using namespace std::string_literals; | ||
13 | |||
12 | #if defined(YUE_BUILD_AS_DLL) | 14 | #if defined(YUE_BUILD_AS_DLL) |
13 | #define YUE_API __declspec(dllexport) | 15 | #define YUE_API __declspec(dllexport) |
14 | #else | 16 | #else |
@@ -25,12 +27,12 @@ static const char yuescriptCodes[] = | |||
25 | 27 | ||
26 | static void init_yuescript(lua_State* L) { | 28 | static void init_yuescript(lua_State* L) { |
27 | if (luaL_loadbuffer(L, yuescriptCodes, sizeof(yuescriptCodes) / sizeof(yuescriptCodes[0]) - 1, "=(yuescript)") != 0) { | 29 | if (luaL_loadbuffer(L, yuescriptCodes, sizeof(yuescriptCodes) / sizeof(yuescriptCodes[0]) - 1, "=(yuescript)") != 0) { |
28 | std::string err = std::string("failed to load yuescript module.\n") + lua_tostring(L, -1); | 30 | std::string err = "failed to load yuescript module.\n"s + lua_tostring(L, -1); |
29 | luaL_error(L, err.c_str()); | 31 | luaL_error(L, err.c_str()); |
30 | } else { | 32 | } else { |
31 | lua_insert(L, -2); | 33 | lua_insert(L, -2); |
32 | if (lua_pcall(L, 1, 0, 0) != 0) { | 34 | if (lua_pcall(L, 1, 0, 0) != 0) { |
33 | std::string err = std::string("failed to init yuescript module.\n") + lua_tostring(L, -1); | 35 | std::string err = "failed to init yuescript module.\n"s + lua_tostring(L, -1); |
34 | luaL_error(L, err.c_str()); | 36 | luaL_error(L, err.c_str()); |
35 | } | 37 | } |
36 | } | 38 | } |
@@ -41,10 +43,10 @@ static const char stpCodes[] = | |||
41 | 43 | ||
42 | static int init_stacktraceplus(lua_State* L) { | 44 | static int init_stacktraceplus(lua_State* L) { |
43 | if (luaL_loadbuffer(L, stpCodes, sizeof(stpCodes) / sizeof(stpCodes[0]) - 1, "=(stacktraceplus)") != 0) { | 45 | if (luaL_loadbuffer(L, stpCodes, sizeof(stpCodes) / sizeof(stpCodes[0]) - 1, "=(stacktraceplus)") != 0) { |
44 | std::string err = std::string("failed to load stacktraceplus module.\n") + lua_tostring(L, -1); | 46 | std::string err = "failed to load stacktraceplus module.\n"s + lua_tostring(L, -1); |
45 | luaL_error(L, err.c_str()); | 47 | luaL_error(L, err.c_str()); |
46 | } else if (lua_pcall(L, 0, 1, 0) != 0) { | 48 | } else if (lua_pcall(L, 0, 1, 0) != 0) { |
47 | std::string err = std::string("failed to init stacktraceplus module.\n") + lua_tostring(L, -1); | 49 | std::string err = "failed to init stacktraceplus module.\n"s + lua_tostring(L, -1); |
48 | luaL_error(L, err.c_str()); | 50 | luaL_error(L, err.c_str()); |
49 | } | 51 | } |
50 | return 1; | 52 | return 1; |