diff options
Diffstat (limited to '')
| -rw-r--r-- | src/yuescript/parser.cpp | 39 | ||||
| -rw-r--r-- | src/yuescript/parser.hpp | 2 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.cpp | 4 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.h | 21 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 370 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 54 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.h | 5 |
7 files changed, 320 insertions, 175 deletions
diff --git a/src/yuescript/parser.cpp b/src/yuescript/parser.cpp index 04b7ffd..a7d695e 100644 --- a/src/yuescript/parser.cpp +++ b/src/yuescript/parser.cpp | |||
| @@ -341,6 +341,41 @@ private: | |||
| 341 | } | 341 | } |
| 342 | }; | 342 | }; |
| 343 | 343 | ||
| 344 | // right interval expression. | ||
| 345 | class _larger : public _expr { | ||
| 346 | public: | ||
| 347 | // constructor from ansi string. | ||
| 348 | _larger(size_t value) | ||
| 349 | : m_value(value) { | ||
| 350 | } | ||
| 351 | |||
| 352 | // parse with whitespace | ||
| 353 | virtual bool parse_non_term(_context& con) const override { | ||
| 354 | return _parse(con); | ||
| 355 | } | ||
| 356 | |||
| 357 | // parse terminal | ||
| 358 | virtual bool parse_term(_context& con) const override { | ||
| 359 | return _parse(con); | ||
| 360 | } | ||
| 361 | |||
| 362 | private: | ||
| 363 | size_t m_value; | ||
| 364 | |||
| 365 | // internal parse | ||
| 366 | bool _parse(_context& con) const { | ||
| 367 | if (!con.end()) { | ||
| 368 | size_t ch = con.symbol(); | ||
| 369 | if (ch > m_value) { | ||
| 370 | con.next_col(); | ||
| 371 | return true; | ||
| 372 | } | ||
| 373 | } | ||
| 374 | con.set_error_pos(); | ||
| 375 | return false; | ||
| 376 | } | ||
| 377 | }; | ||
| 378 | |||
| 344 | // base class for unary expressions | 379 | // base class for unary expressions |
| 345 | class _unary : public _expr { | 380 | class _unary : public _expr { |
| 346 | public: | 381 | public: |
| @@ -1503,6 +1538,10 @@ expr range(int min, int max) { | |||
| 1503 | return _private::construct_expr(new _set(min, max)); | 1538 | return _private::construct_expr(new _set(min, max)); |
| 1504 | } | 1539 | } |
| 1505 | 1540 | ||
| 1541 | expr larger(size_t value) { | ||
| 1542 | return _private::construct_expr(new _larger(value)); | ||
| 1543 | } | ||
| 1544 | |||
| 1506 | /** creates an expression which increments the line counter | 1545 | /** creates an expression which increments the line counter |
| 1507 | and resets the column counter when the given expression | 1546 | and resets the column counter when the given expression |
| 1508 | is parsed successfully; used for newline characters. | 1547 | is parsed successfully; used for newline characters. |
diff --git a/src/yuescript/parser.hpp b/src/yuescript/parser.hpp index d2612cd..a0ec396 100644 --- a/src/yuescript/parser.hpp +++ b/src/yuescript/parser.hpp | |||
| @@ -346,6 +346,8 @@ expr set(const char* s); | |||
| 346 | */ | 346 | */ |
| 347 | expr range(int min, int max); | 347 | expr range(int min, int max); |
| 348 | 348 | ||
| 349 | expr larger(size_t value); | ||
| 350 | |||
| 349 | /** creates an expression which increments the line counter | 351 | /** creates an expression which increments the line counter |
| 350 | and resets the column counter when the given expression | 352 | and resets the column counter when the given expression |
| 351 | is parsed successfully; used for newline characters. | 353 | is parsed successfully; used for newline characters. |
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index fee15af..105bd74 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp | |||
| @@ -69,6 +69,10 @@ std::string Name_t::to_string(void* ud) const { | |||
| 69 | auto info = reinterpret_cast<YueFormat*>(ud); | 69 | auto info = reinterpret_cast<YueFormat*>(ud); |
| 70 | return info->convert(this); | 70 | return info->convert(this); |
| 71 | } | 71 | } |
| 72 | std::string UnicodeName_t::to_string(void* ud) const { | ||
| 73 | auto info = reinterpret_cast<YueFormat*>(ud); | ||
| 74 | return info->convert(this); | ||
| 75 | } | ||
| 72 | std::string Self_t::to_string(void*) const { | 76 | std::string Self_t::to_string(void*) const { |
| 73 | return "@"s; | 77 | return "@"s; |
| 74 | } | 78 | } |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 807d01b..a7f897c 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
| @@ -86,13 +86,16 @@ AST_END(Num, "num"sv) | |||
| 86 | AST_LEAF(Name) | 86 | AST_LEAF(Name) |
| 87 | AST_END(Name, "name"sv) | 87 | AST_END(Name, "name"sv) |
| 88 | 88 | ||
| 89 | AST_LEAF(UnicodeName) | ||
| 90 | AST_END(UnicodeName, "unicode_name"sv) | ||
| 91 | |||
| 89 | AST_NODE(Variable) | 92 | AST_NODE(Variable) |
| 90 | ast_ptr<true, Name_t> name; | 93 | ast_sel<true, Name_t, UnicodeName_t> name; |
| 91 | AST_MEMBER(Variable, &name) | 94 | AST_MEMBER(Variable, &name) |
| 92 | AST_END(Variable, "variable"sv) | 95 | AST_END(Variable, "variable"sv) |
| 93 | 96 | ||
| 94 | AST_NODE(LabelName) | 97 | AST_NODE(LabelName) |
| 95 | ast_ptr<true, Name_t> name; | 98 | ast_ptr<true, UnicodeName_t> name; |
| 96 | AST_MEMBER(LabelName, &name) | 99 | AST_MEMBER(LabelName, &name) |
| 97 | AST_END(LabelName, "label_name"sv) | 100 | AST_END(LabelName, "label_name"sv) |
| 98 | 101 | ||
| @@ -105,7 +108,7 @@ AST_LEAF(Self) | |||
| 105 | AST_END(Self, "self"sv) | 108 | AST_END(Self, "self"sv) |
| 106 | 109 | ||
| 107 | AST_NODE(SelfName) | 110 | AST_NODE(SelfName) |
| 108 | ast_ptr<true, Name_t> name; | 111 | ast_sel<true, Name_t, UnicodeName_t> name; |
| 109 | AST_MEMBER(SelfName, &name) | 112 | AST_MEMBER(SelfName, &name) |
| 110 | AST_END(SelfName, "self_name"sv) | 113 | AST_END(SelfName, "self_name"sv) |
| 111 | 114 | ||
| @@ -113,7 +116,7 @@ AST_LEAF(SelfClass) | |||
| 113 | AST_END(SelfClass, "self_class"sv) | 116 | AST_END(SelfClass, "self_class"sv) |
| 114 | 117 | ||
| 115 | AST_NODE(SelfClassName) | 118 | AST_NODE(SelfClassName) |
| 116 | ast_ptr<true, Name_t> name; | 119 | ast_sel<true, Name_t, UnicodeName_t> name; |
| 117 | AST_MEMBER(SelfClassName, &name) | 120 | AST_MEMBER(SelfClassName, &name) |
| 118 | AST_END(SelfClassName, "self_class_name"sv) | 121 | AST_END(SelfClassName, "self_class_name"sv) |
| 119 | 122 | ||
| @@ -123,7 +126,7 @@ AST_NODE(SelfItem) | |||
| 123 | AST_END(SelfItem, "self_item"sv) | 126 | AST_END(SelfItem, "self_item"sv) |
| 124 | 127 | ||
| 125 | AST_NODE(KeyName) | 128 | AST_NODE(KeyName) |
| 126 | ast_sel<true, SelfItem_t, Name_t> name; | 129 | ast_sel<true, SelfItem_t, Name_t, UnicodeName_t> name; |
| 127 | AST_MEMBER(KeyName, &name) | 130 | AST_MEMBER(KeyName, &name) |
| 128 | AST_END(KeyName, "key_name"sv) | 131 | AST_END(KeyName, "key_name"sv) |
| 129 | 132 | ||
| @@ -597,12 +600,12 @@ AST_NODE(Metamethod) | |||
| 597 | AST_END(Metamethod, "metamethod"sv) | 600 | AST_END(Metamethod, "metamethod"sv) |
| 598 | 601 | ||
| 599 | AST_NODE(DotChainItem) | 602 | AST_NODE(DotChainItem) |
| 600 | ast_sel<true, Name_t, Metatable_t, Metamethod_t> name; | 603 | ast_sel<true, Name_t, Metatable_t, Metamethod_t, UnicodeName_t> name; |
| 601 | AST_MEMBER(DotChainItem, &name) | 604 | AST_MEMBER(DotChainItem, &name) |
| 602 | AST_END(DotChainItem, "dot_chain_item"sv) | 605 | AST_END(DotChainItem, "dot_chain_item"sv) |
| 603 | 606 | ||
| 604 | AST_NODE(ColonChainItem) | 607 | AST_NODE(ColonChainItem) |
| 605 | ast_sel<true, LuaKeyword_t, Name_t, Metamethod_t> name; | 608 | ast_sel<true, Name_t, LuaKeyword_t, Metamethod_t, UnicodeName_t> name; |
| 606 | bool switchToDot = false; | 609 | bool switchToDot = false; |
| 607 | AST_MEMBER(ColonChainItem, &name) | 610 | AST_MEMBER(ColonChainItem, &name) |
| 608 | AST_END(ColonChainItem, "colon_chain_item"sv) | 611 | AST_END(ColonChainItem, "colon_chain_item"sv) |
| @@ -761,7 +764,7 @@ AST_NODE(FunLit) | |||
| 761 | AST_END(FunLit, "fun_lit"sv) | 764 | AST_END(FunLit, "fun_lit"sv) |
| 762 | 765 | ||
| 763 | AST_NODE(MacroName) | 766 | AST_NODE(MacroName) |
| 764 | ast_ptr<true, Name_t> name; | 767 | ast_ptr<true, UnicodeName_t> name; |
| 765 | AST_MEMBER(MacroName, &name) | 768 | AST_MEMBER(MacroName, &name) |
| 766 | AST_END(MacroName, "macro_name"sv) | 769 | AST_END(MacroName, "macro_name"sv) |
| 767 | 770 | ||
| @@ -777,7 +780,7 @@ AST_NODE(MacroInPlace) | |||
| 777 | AST_END(MacroInPlace, "macro_in_place"sv) | 780 | AST_END(MacroInPlace, "macro_in_place"sv) |
| 778 | 781 | ||
| 779 | AST_NODE(Macro) | 782 | AST_NODE(Macro) |
| 780 | ast_ptr<true, Name_t> name; | 783 | ast_ptr<true, UnicodeName_t> name; |
| 781 | ast_ptr<true, MacroLit_t> macroLit; | 784 | ast_ptr<true, MacroLit_t> macroLit; |
| 782 | AST_MEMBER(Macro, &name, ¯oLit) | 785 | AST_MEMBER(Macro, &name, ¯oLit) |
| 783 | AST_END(Macro, "macro"sv) | 786 | AST_END(Macro, "macro"sv) |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index ab35364..40f12af 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -74,7 +74,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
| 74 | "close"s // Lua 5.4 | 74 | "close"s // Lua 5.4 |
| 75 | }; | 75 | }; |
| 76 | 76 | ||
| 77 | const std::string_view version = "0.18.1"sv; | 77 | const std::string_view version = "0.19.1"sv; |
| 78 | const std::string_view extension = "yue"sv; | 78 | const std::string_view extension = "yue"sv; |
| 79 | 79 | ||
| 80 | class CompileError : public std::logic_error { | 80 | class CompileError : public std::logic_error { |
| @@ -621,7 +621,7 @@ private: | |||
| 621 | do { | 621 | do { |
| 622 | newName = nameStr + std::to_string(index); | 622 | newName = nameStr + std::to_string(index); |
| 623 | index++; | 623 | index++; |
| 624 | } while (isSolidDefined(newName)); | 624 | } while (isSolidDefined(newName) || _info.usedNames.find(newName) != _info.usedNames.end()); |
| 625 | return newName; | 625 | return newName; |
| 626 | } | 626 | } |
| 627 | 627 | ||
| @@ -966,6 +966,7 @@ private: | |||
| 966 | EndWithEOP, | 966 | EndWithEOP, |
| 967 | HasEOP, | 967 | HasEOP, |
| 968 | HasKeyword, | 968 | HasKeyword, |
| 969 | HasUnicode, | ||
| 969 | Macro, | 970 | Macro, |
| 970 | Metatable, | 971 | Metatable, |
| 971 | MetaFieldInvocation | 972 | MetaFieldInvocation |
| @@ -989,10 +990,20 @@ private: | |||
| 989 | ChainType type = ChainType::Common; | 990 | ChainType type = ChainType::Common; |
| 990 | for (auto item : chainValue->items.objects()) { | 991 | for (auto item : chainValue->items.objects()) { |
| 991 | if (auto colonChain = ast_cast<ColonChainItem_t>(item)) { | 992 | if (auto colonChain = ast_cast<ColonChainItem_t>(item)) { |
| 992 | if (ast_is<LuaKeyword_t>(colonChain->name)) { | 993 | switch (colonChain->name->get_id()) { |
| 993 | type = ChainType::HasKeyword; | 994 | case id<LuaKeyword_t>(): |
| 994 | } else if (auto meta = colonChain->name.as<Metamethod_t>(); meta && !meta->item.is<Name_t>()) { | 995 | type = ChainType::HasKeyword; |
| 995 | return ChainType::MetaFieldInvocation; | 996 | break; |
| 997 | case id<UnicodeName_t>(): | ||
| 998 | type = ChainType::HasUnicode; | ||
| 999 | break; | ||
| 1000 | case id<Metamethod_t>(): { | ||
| 1001 | auto meta = static_cast<Metamethod_t*>(colonChain->name.get()); | ||
| 1002 | if (!meta->item.is<Name_t>()) { | ||
| 1003 | return ChainType::MetaFieldInvocation; | ||
| 1004 | } | ||
| 1005 | break; | ||
| 1006 | } | ||
| 996 | } | 1007 | } |
| 997 | } else if (ast_is<ExistentialOp_t>(item)) { | 1008 | } else if (ast_is<ExistentialOp_t>(item)) { |
| 998 | return ChainType::HasEOP; | 1009 | return ChainType::HasEOP; |
| @@ -1021,6 +1032,30 @@ private: | |||
| 1021 | return Empty; | 1032 | return Empty; |
| 1022 | } | 1033 | } |
| 1023 | 1034 | ||
| 1035 | std::string unicodeVariableFrom(UnicodeName_t* uname) { | ||
| 1036 | std::ostringstream buf; | ||
| 1037 | for (auto it = uname->m_begin.m_it; it != uname->m_end.m_it; ++it) { | ||
| 1038 | auto ch = *it; | ||
| 1039 | if (ch > 255) { | ||
| 1040 | buf << "_u"sv << std::hex << ch; | ||
| 1041 | } else { | ||
| 1042 | buf << static_cast<char>(ch); | ||
| 1043 | } | ||
| 1044 | } | ||
| 1045 | return buf.str(); | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | std::string variableToString(Variable_t* var) { | ||
| 1049 | switch (var->name->get_id()) { | ||
| 1050 | case id<Name_t>(): | ||
| 1051 | return _parser.toString(var->name); | ||
| 1052 | case id<UnicodeName_t>(): { | ||
| 1053 | return unicodeVariableFrom(static_cast<UnicodeName_t*>(var->name.get())); | ||
| 1054 | } | ||
| 1055 | default: YUEE("AST node mismatch", var->name); return std::string(); | ||
| 1056 | } | ||
| 1057 | } | ||
| 1058 | |||
| 1024 | std::string singleVariableFrom(ast_node* expList, bool accessing) { | 1059 | std::string singleVariableFrom(ast_node* expList, bool accessing) { |
| 1025 | if (!ast_is<Exp_t, ExpList_t, Value_t>(expList)) return Empty; | 1060 | if (!ast_is<Exp_t, ExpList_t, Value_t>(expList)) return Empty; |
| 1026 | BLOCK_START | 1061 | BLOCK_START |
| @@ -1067,9 +1102,11 @@ private: | |||
| 1067 | auto firstItem = chainItems.back(); | 1102 | auto firstItem = chainItems.back(); |
| 1068 | if (auto callable = ast_cast<Callable_t>(firstItem)) { | 1103 | if (auto callable = ast_cast<Callable_t>(firstItem)) { |
| 1069 | switch (callable->item->get_id()) { | 1104 | switch (callable->item->get_id()) { |
| 1070 | case id<Variable_t>(): | 1105 | case id<Variable_t>(): { |
| 1071 | checkConst(_parser.toString(callable->item.get()), callable->item.get()); | 1106 | auto var = static_cast<Variable_t*>(callable->item.get()); |
| 1107 | checkConst(variableToString(var), callable->item.get()); | ||
| 1072 | return true; | 1108 | return true; |
| 1109 | } | ||
| 1073 | case id<SelfItem_t>(): | 1110 | case id<SelfItem_t>(): |
| 1074 | return true; | 1111 | return true; |
| 1075 | } | 1112 | } |
| @@ -1123,7 +1160,7 @@ private: | |||
| 1123 | if (auto assignableChain = ast_cast<AssignableChain_t>(assignable->item)) { | 1160 | if (auto assignableChain = ast_cast<AssignableChain_t>(assignable->item)) { |
| 1124 | return isAssignable(assignableChain->items.objects()); | 1161 | return isAssignable(assignableChain->items.objects()); |
| 1125 | } else if (auto variable = assignable->item.as<Variable_t>()) { | 1162 | } else if (auto variable = assignable->item.as<Variable_t>()) { |
| 1126 | checkConst(_parser.toString(variable), variable); | 1163 | checkConst(variableToString(variable), variable); |
| 1127 | } | 1164 | } |
| 1128 | return true; | 1165 | return true; |
| 1129 | } | 1166 | } |
| @@ -1524,8 +1561,9 @@ private: | |||
| 1524 | Mark | 1561 | Mark |
| 1525 | }; | 1562 | }; |
| 1526 | 1563 | ||
| 1527 | str_list transformAssignDefs(ExpList_t* expList, DefOp op) { | 1564 | using DefList = std::list<std::pair<std::string, std::string>>; |
| 1528 | str_list defs; | 1565 | DefList transformAssignDefs(ExpList_t* expList, DefOp op) { |
| 1566 | DefList defs; | ||
| 1529 | for (auto exp_ : expList->exprs.objects()) { | 1567 | for (auto exp_ : expList->exprs.objects()) { |
| 1530 | auto exp = static_cast<Exp_t*>(exp_); | 1568 | auto exp = static_cast<Exp_t*>(exp_); |
| 1531 | if (auto value = singleValueFrom(exp)) { | 1569 | if (auto value = singleValueFrom(exp)) { |
| @@ -1535,21 +1573,27 @@ private: | |||
| 1535 | auto callable = ast_cast<Callable_t>(chain->items.front()); | 1573 | auto callable = ast_cast<Callable_t>(chain->items.front()); |
| 1536 | BREAK_IF(!callable); | 1574 | BREAK_IF(!callable); |
| 1537 | std::string name; | 1575 | std::string name; |
| 1576 | std::string unicodeName; | ||
| 1538 | if (auto var = callable->item.as<Variable_t>()) { | 1577 | if (auto var = callable->item.as<Variable_t>()) { |
| 1539 | name = _parser.toString(var); | 1578 | name = variableToString(var); |
| 1579 | if (var->name.is<UnicodeName_t>()) { | ||
| 1580 | unicodeName = _parser.toString(var->name); | ||
| 1581 | } | ||
| 1540 | } else if (auto self = callable->item.as<SelfItem_t>()) { | 1582 | } else if (auto self = callable->item.as<SelfItem_t>()) { |
| 1541 | if (self->name.is<Self_t>()) name = "self"sv; | 1583 | if (self->name.is<Self_t>()) { |
| 1584 | name = "self"sv; | ||
| 1585 | } | ||
| 1542 | } | 1586 | } |
| 1543 | BREAK_IF(name.empty()); | 1587 | BREAK_IF(name.empty()); |
| 1544 | switch (op) { | 1588 | switch (op) { |
| 1545 | case DefOp::Mark: | 1589 | case DefOp::Mark: |
| 1546 | if (addToScope(name)) defs.push_back(name); | 1590 | if (addToScope(name)) defs.emplace_back(name, unicodeName); |
| 1547 | break; | 1591 | break; |
| 1548 | case DefOp::Check: | 1592 | case DefOp::Check: |
| 1549 | if (!isDefined(name)) defs.push_back(name); | 1593 | if (!isDefined(name)) defs.emplace_back(name, unicodeName); |
| 1550 | break; | 1594 | break; |
| 1551 | case DefOp::Get: | 1595 | case DefOp::Get: |
| 1552 | defs.push_back(name); | 1596 | defs.emplace_back(name, unicodeName); |
| 1553 | break; | 1597 | break; |
| 1554 | } | 1598 | } |
| 1555 | BLOCK_END | 1599 | BLOCK_END |
| @@ -1561,6 +1605,15 @@ private: | |||
| 1561 | return defs; | 1605 | return defs; |
| 1562 | } | 1606 | } |
| 1563 | 1607 | ||
| 1608 | std::string toLocalDecl(const DefList& defs) { | ||
| 1609 | if (defs.empty()) return Empty; | ||
| 1610 | str_list items; | ||
| 1611 | for (const auto& def : defs) { | ||
| 1612 | items.emplace_back(def.first); | ||
| 1613 | } | ||
| 1614 | return indent() + "local "s + join(items, ", "sv); | ||
| 1615 | } | ||
| 1616 | |||
| 1564 | std::string toLocalDecl(const str_list& defs) { | 1617 | std::string toLocalDecl(const str_list& defs) { |
| 1565 | if (defs.empty()) return Empty; | 1618 | if (defs.empty()) return Empty; |
| 1566 | return indent() + "local "s + join(defs, ", "sv); | 1619 | return indent() + "local "s + join(defs, ", "sv); |
| @@ -1991,6 +2044,7 @@ private: | |||
| 1991 | return; | 2044 | return; |
| 1992 | } | 2045 | } |
| 1993 | case ChainType::HasKeyword: | 2046 | case ChainType::HasKeyword: |
| 2047 | case ChainType::HasUnicode: | ||
| 1994 | case ChainType::Macro: | 2048 | case ChainType::Macro: |
| 1995 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); | 2049 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); |
| 1996 | return; | 2050 | return; |
| @@ -2348,9 +2402,10 @@ private: | |||
| 2348 | } | 2402 | } |
| 2349 | auto vp = static_cast<VariablePair_t*>(pair); | 2403 | auto vp = static_cast<VariablePair_t*>(pair); |
| 2350 | auto name = _parser.toString(vp->name); | 2404 | auto name = _parser.toString(vp->name); |
| 2405 | auto uname = vp->name->name.as<UnicodeName_t>(); | ||
| 2351 | auto chain = toAst<ChainValue_t>('.' + name, vp->name); | 2406 | auto chain = toAst<ChainValue_t>('.' + name, vp->name); |
| 2352 | pairs.push_back({toAst<Exp_t>(name, vp).get(), | 2407 | pairs.push_back({toAst<Exp_t>(name, vp).get(), |
| 2353 | name, | 2408 | uname ? variableToString(vp->name) : name, |
| 2354 | chain, | 2409 | chain, |
| 2355 | defVal}); | 2410 | defVal}); |
| 2356 | break; | 2411 | break; |
| @@ -2365,12 +2420,12 @@ private: | |||
| 2365 | auto np = static_cast<NormalPair_t*>(pair); | 2420 | auto np = static_cast<NormalPair_t*>(pair); |
| 2366 | ast_ptr<true, ast_node> keyIndex; | 2421 | ast_ptr<true, ast_node> keyIndex; |
| 2367 | if (np->key) { | 2422 | if (np->key) { |
| 2368 | if (auto key = np->key->get_by_path<Name_t>()) { | 2423 | if (auto keyName = np->key.as<KeyName_t>(); keyName && ast_is<Name_t, UnicodeName_t>(keyName->name)) { |
| 2369 | auto keyNameStr = _parser.toString(key); | 2424 | auto keyNameStr = _parser.toString(keyName->name); |
| 2370 | if (LuaKeywords.find(keyNameStr) != LuaKeywords.end()) { | 2425 | if (keyName->name.is<UnicodeName_t>() || LuaKeywords.find(keyNameStr) != LuaKeywords.end()) { |
| 2371 | keyIndex = toAst<Exp_t>('"' + keyNameStr + '"', key).get(); | 2426 | keyIndex = toAst<Exp_t>('"' + keyNameStr + '"', keyName->name).get(); |
| 2372 | } else { | 2427 | } else { |
| 2373 | keyIndex = toAst<DotChainItem_t>('.' + keyNameStr, key).get(); | 2428 | keyIndex = toAst<DotChainItem_t>('.' + keyNameStr, keyName->name).get(); |
| 2374 | } | 2429 | } |
| 2375 | } else if (auto key = np->key->get_by_path<SelfItem_t>()) { | 2430 | } else if (auto key = np->key->get_by_path<SelfItem_t>()) { |
| 2376 | auto callable = np->new_ptr<Callable_t>(); | 2431 | auto callable = np->new_ptr<Callable_t>(); |
| @@ -2719,7 +2774,17 @@ private: | |||
| 2719 | } else if (destruct.items.size() == 1 && !singleValueFrom(*j)) { | 2774 | } else if (destruct.items.size() == 1 && !singleValueFrom(*j)) { |
| 2720 | auto p = destruct.value.get(); | 2775 | auto p = destruct.value.get(); |
| 2721 | auto parens = p->new_ptr<Parens_t>(); | 2776 | auto parens = p->new_ptr<Parens_t>(); |
| 2722 | parens->expr.set(p); | 2777 | if (auto tableBlock = ast_cast<TableBlock_t>(p)) { |
| 2778 | auto tableLit = p->new_ptr<TableLit_t>(); | ||
| 2779 | tableLit->values.dup(tableBlock->values); | ||
| 2780 | auto simpleValue = p->new_ptr<SimpleValue_t>(); | ||
| 2781 | simpleValue->value.set(tableLit); | ||
| 2782 | parens->expr.set(newExp(simpleValue, p)); | ||
| 2783 | } else if (ast_is<Exp_t>(p)) { | ||
| 2784 | parens->expr.set(p); | ||
| 2785 | } else { | ||
| 2786 | YUEE("AST node mismatch", p); | ||
| 2787 | } | ||
| 2723 | auto callable = p->new_ptr<Callable_t>(); | 2788 | auto callable = p->new_ptr<Callable_t>(); |
| 2724 | callable->item.set(parens); | 2789 | callable->item.set(parens); |
| 2725 | auto chainValue = p->new_ptr<ChainValue_t>(); | 2790 | auto chainValue = p->new_ptr<ChainValue_t>(); |
| @@ -2818,11 +2883,13 @@ private: | |||
| 2818 | BREAK_IF(chain->items.size() < 2); | 2883 | BREAK_IF(chain->items.size() < 2); |
| 2819 | if (chain->items.size() == 2) { | 2884 | if (chain->items.size() == 2) { |
| 2820 | if (auto callable = ast_cast<Callable_t>(chain->items.front())) { | 2885 | if (auto callable = ast_cast<Callable_t>(chain->items.front())) { |
| 2821 | ast_node* var = callable->item.as<Variable_t>(); | 2886 | if (auto var = callable->item.as<Variable_t>()) { |
| 2822 | if (auto self = callable->item.as<SelfItem_t>()) { | 2887 | BREAK_IF(isLocal(variableToString(var))); |
| 2823 | var = self->name.as<Self_t>(); | 2888 | } else if (auto self = callable->item.as<SelfItem_t>()) { |
| 2889 | if (auto var = self->name.as<Self_t>()) { | ||
| 2890 | BREAK_IF(isLocal(_parser.toString(var))); | ||
| 2891 | } | ||
| 2824 | } | 2892 | } |
| 2825 | BREAK_IF(var && isLocal(_parser.toString(var))); | ||
| 2826 | } | 2893 | } |
| 2827 | } | 2894 | } |
| 2828 | auto tmpChain = x->new_ptr<ChainValue_t>(); | 2895 | auto tmpChain = x->new_ptr<ChainValue_t>(); |
| @@ -2919,7 +2986,7 @@ private: | |||
| 2919 | } | 2986 | } |
| 2920 | std::string preDefine = toLocalDecl(defs); | 2987 | std::string preDefine = toLocalDecl(defs); |
| 2921 | for (const auto& def : defs) { | 2988 | for (const auto& def : defs) { |
| 2922 | addToScope(def); | 2989 | addToScope(def.first); |
| 2923 | } | 2990 | } |
| 2924 | if (preDefine.empty()) { | 2991 | if (preDefine.empty()) { |
| 2925 | transformExpList(expList, temp); | 2992 | transformExpList(expList, temp); |
| @@ -2932,7 +2999,7 @@ private: | |||
| 2932 | } else { | 2999 | } else { |
| 2933 | std::string preDefine = toLocalDecl(defs); | 3000 | std::string preDefine = toLocalDecl(defs); |
| 2934 | for (const auto& def : defs) { | 3001 | for (const auto& def : defs) { |
| 2935 | addToScope(def); | 3002 | addToScope(def.first); |
| 2936 | } | 3003 | } |
| 2937 | transformExpList(expList, temp); | 3004 | transformExpList(expList, temp); |
| 2938 | std::string left = std::move(temp.back()); | 3005 | std::string left = std::move(temp.back()); |
| @@ -3623,47 +3690,7 @@ private: | |||
| 3623 | if (auto appendix = stmt->appendix.get()) { | 3690 | if (auto appendix = stmt->appendix.get()) { |
| 3624 | switch (appendix->item->get_id()) { | 3691 | switch (appendix->item->get_id()) { |
| 3625 | case id<IfLine_t>(): { | 3692 | case id<IfLine_t>(): { |
| 3626 | auto if_line = static_cast<IfLine_t*>(appendix->item.get()); | 3693 | throw CompileError("if line decorator is not supported here"sv, appendix->item.get()); |
| 3627 | auto ifNode = appendix->new_ptr<If_t>(); | ||
| 3628 | ifNode->type.set(if_line->type); | ||
| 3629 | ifNode->nodes.push_back(if_line->condition); | ||
| 3630 | auto expList = appendix->new_ptr<ExpList_t>(); | ||
| 3631 | for (auto val : assignAction->values.objects()) { | ||
| 3632 | switch (val->get_id()) { | ||
| 3633 | case id<If_t>(): | ||
| 3634 | case id<Switch_t>(): | ||
| 3635 | case id<With_t>(): { | ||
| 3636 | auto simpleValue = val->new_ptr<SimpleValue_t>(); | ||
| 3637 | simpleValue->value.set(val); | ||
| 3638 | auto exp = newExp(simpleValue, val); | ||
| 3639 | expList->exprs.push_back(exp); | ||
| 3640 | break; | ||
| 3641 | } | ||
| 3642 | case id<TableBlock_t>(): { | ||
| 3643 | auto tableBlock = static_cast<TableBlock_t*>(val); | ||
| 3644 | auto tabLit = val->new_ptr<TableLit_t>(); | ||
| 3645 | tabLit->values.dup(tableBlock->values); | ||
| 3646 | auto simpleValue = val->new_ptr<SimpleValue_t>(); | ||
| 3647 | simpleValue->value.set(tabLit); | ||
| 3648 | auto exp = newExp(simpleValue, val); | ||
| 3649 | expList->exprs.push_back(exp); | ||
| 3650 | break; | ||
| 3651 | } | ||
| 3652 | case id<Exp_t>(): { | ||
| 3653 | expList->exprs.push_back(val); | ||
| 3654 | break; | ||
| 3655 | } | ||
| 3656 | default: YUEE("AST node mismatch", val); break; | ||
| 3657 | } | ||
| 3658 | } | ||
| 3659 | auto newExpListAssign = assignAction->new_ptr<ExpListAssign_t>(); | ||
| 3660 | newExpListAssign->expList.set(expList); | ||
| 3661 | auto newStmt = assignAction->new_ptr<Statement_t>(); | ||
| 3662 | newStmt->content.set(newExpListAssign); | ||
| 3663 | ifNode->nodes.push_back(newStmt); | ||
| 3664 | auto newSVal = ifNode->new_ptr<SimpleValue_t>(); | ||
| 3665 | newSVal->value.set(ifNode); | ||
| 3666 | newInvoke->args.push_back(newExp(newSVal, newSVal)); | ||
| 3667 | break; | 3694 | break; |
| 3668 | } | 3695 | } |
| 3669 | case id<WhileLine_t>(): { | 3696 | case id<WhileLine_t>(): { |
| @@ -3790,7 +3817,7 @@ private: | |||
| 3790 | str_list doCloses; | 3817 | str_list doCloses; |
| 3791 | pushScope(); | 3818 | pushScope(); |
| 3792 | for (auto var : localAttrib->leftList.objects()) { | 3819 | for (auto var : localAttrib->leftList.objects()) { |
| 3793 | auto varName = _parser.toString(ast_to<Variable_t>(var)); | 3820 | auto varName = variableToString(ast_to<Variable_t>(var)); |
| 3794 | auto closeVar = getUnusedName("_close_"sv); | 3821 | auto closeVar = getUnusedName("_close_"sv); |
| 3795 | addToScope(closeVar); | 3822 | addToScope(closeVar); |
| 3796 | getCloses.push_back(closeVar + "=assert "s + varName + ".<close>"s); | 3823 | getCloses.push_back(closeVar + "=assert "s + varName + ".<close>"s); |
| @@ -3845,7 +3872,7 @@ private: | |||
| 3845 | case id<LocalValues_t>(): { | 3872 | case id<LocalValues_t>(): { |
| 3846 | auto values = local->item.to<LocalValues_t>(); | 3873 | auto values = local->item.to<LocalValues_t>(); |
| 3847 | for (auto name : values->nameList->names.objects()) { | 3874 | for (auto name : values->nameList->names.objects()) { |
| 3848 | local->forceDecls.push_back(_parser.toString(name)); | 3875 | local->forceDecls.push_back(variableToString(static_cast<Variable_t*>(name))); |
| 3849 | } | 3876 | } |
| 3850 | break; | 3877 | break; |
| 3851 | } | 3878 | } |
| @@ -3888,10 +3915,10 @@ private: | |||
| 3888 | if (info.assignment) { | 3915 | if (info.assignment) { |
| 3889 | auto defs = transformAssignDefs(info.assignment->expList, DefOp::Get); | 3916 | auto defs = transformAssignDefs(info.assignment->expList, DefOp::Get); |
| 3890 | for (const auto& def : defs) { | 3917 | for (const auto& def : defs) { |
| 3891 | if (std::isupper(def[0]) && capital) { | 3918 | if (std::isupper(def.first[0]) && capital) { |
| 3892 | capital->decls.push_back(def); | 3919 | capital->decls.push_back(def.first); |
| 3893 | } else if (any) { | 3920 | } else if (any) { |
| 3894 | any->decls.push_back(def); | 3921 | any->decls.push_back(def.first); |
| 3895 | } | 3922 | } |
| 3896 | } | 3923 | } |
| 3897 | } | 3924 | } |
| @@ -3911,7 +3938,7 @@ private: | |||
| 3911 | } | 3938 | } |
| 3912 | if (classDecl) { | 3939 | if (classDecl) { |
| 3913 | if (auto variable = classDecl->name->item.as<Variable_t>()) { | 3940 | if (auto variable = classDecl->name->item.as<Variable_t>()) { |
| 3914 | auto className = _parser.toString(variable); | 3941 | auto className = variableToString(variable); |
| 3915 | if (!className.empty()) { | 3942 | if (!className.empty()) { |
| 3916 | if (std::isupper(className[0]) && capital) { | 3943 | if (std::isupper(className[0]) && capital) { |
| 3917 | capital->decls.push_back(className); | 3944 | capital->decls.push_back(className); |
| @@ -4378,7 +4405,7 @@ private: | |||
| 4378 | auto def = static_cast<FnArgDef_t*>(_def); | 4405 | auto def = static_cast<FnArgDef_t*>(_def); |
| 4379 | auto& arg = argItems.emplace_back(); | 4406 | auto& arg = argItems.emplace_back(); |
| 4380 | switch (def->name->get_id()) { | 4407 | switch (def->name->get_id()) { |
| 4381 | case id<Variable_t>(): arg.name = _parser.toString(def->name); break; | 4408 | case id<Variable_t>(): arg.name = variableToString(static_cast<Variable_t*>(def->name.get())); break; |
| 4382 | case id<SelfItem_t>(): { | 4409 | case id<SelfItem_t>(): { |
| 4383 | assignSelf = true; | 4410 | assignSelf = true; |
| 4384 | if (def->op) { | 4411 | if (def->op) { |
| @@ -4391,13 +4418,21 @@ private: | |||
| 4391 | switch (selfName->name->get_id()) { | 4418 | switch (selfName->name->get_id()) { |
| 4392 | case id<SelfClassName_t>(): { | 4419 | case id<SelfClassName_t>(): { |
| 4393 | auto clsName = static_cast<SelfClassName_t*>(selfName->name.get()); | 4420 | auto clsName = static_cast<SelfClassName_t*>(selfName->name.get()); |
| 4394 | arg.name = _parser.toString(clsName->name); | 4421 | if (clsName->name.is<UnicodeName_t>()) { |
| 4422 | arg.name = unicodeVariableFrom(static_cast<UnicodeName_t*>(clsName->name.get())); | ||
| 4423 | } else { | ||
| 4424 | arg.name = _parser.toString(clsName->name); | ||
| 4425 | } | ||
| 4395 | arg.assignSelf = _parser.toString(clsName); | 4426 | arg.assignSelf = _parser.toString(clsName); |
| 4396 | break; | 4427 | break; |
| 4397 | } | 4428 | } |
| 4398 | case id<SelfName_t>(): { | 4429 | case id<SelfName_t>(): { |
| 4399 | auto sfName = static_cast<SelfName_t*>(selfName->name.get()); | 4430 | auto sfName = static_cast<SelfName_t*>(selfName->name.get()); |
| 4400 | arg.name = _parser.toString(sfName->name); | 4431 | if (sfName->name.is<UnicodeName_t>()) { |
| 4432 | arg.name = unicodeVariableFrom(static_cast<UnicodeName_t*>(sfName->name.get())); | ||
| 4433 | } else { | ||
| 4434 | arg.name = _parser.toString(sfName->name); | ||
| 4435 | } | ||
| 4401 | arg.assignSelf = _parser.toString(sfName); | 4436 | arg.assignSelf = _parser.toString(sfName); |
| 4402 | break; | 4437 | break; |
| 4403 | } | 4438 | } |
| @@ -4466,7 +4501,7 @@ private: | |||
| 4466 | case id<SelfClassName_t>(): { | 4501 | case id<SelfClassName_t>(): { |
| 4467 | auto clsName = static_cast<SelfClassName_t*>(name); | 4502 | auto clsName = static_cast<SelfClassName_t*>(name); |
| 4468 | auto nameStr = _parser.toString(clsName->name); | 4503 | auto nameStr = _parser.toString(clsName->name); |
| 4469 | if (LuaKeywords.find(nameStr) != LuaKeywords.end()) { | 4504 | if (clsName->name.is<UnicodeName_t>() || LuaKeywords.find(nameStr) != LuaKeywords.end()) { |
| 4470 | out.push_back("self.__class[\""s + nameStr + "\"]"s); | 4505 | out.push_back("self.__class[\""s + nameStr + "\"]"s); |
| 4471 | if (invoke) { | 4506 | if (invoke) { |
| 4472 | if (auto invokePtr = invoke.as<Invoke_t>()) { | 4507 | if (auto invokePtr = invoke.as<Invoke_t>()) { |
| @@ -4487,7 +4522,7 @@ private: | |||
| 4487 | case id<SelfName_t>(): { | 4522 | case id<SelfName_t>(): { |
| 4488 | auto sfName = static_cast<SelfClassName_t*>(name); | 4523 | auto sfName = static_cast<SelfClassName_t*>(name); |
| 4489 | auto nameStr = _parser.toString(sfName->name); | 4524 | auto nameStr = _parser.toString(sfName->name); |
| 4490 | if (LuaKeywords.find(nameStr) != LuaKeywords.end()) { | 4525 | if (sfName->name.is<UnicodeName_t>() || LuaKeywords.find(nameStr) != LuaKeywords.end()) { |
| 4491 | out.push_back("self[\""s + nameStr + "\"]"s); | 4526 | out.push_back("self[\""s + nameStr + "\"]"s); |
| 4492 | if (invoke) { | 4527 | if (invoke) { |
| 4493 | if (auto invokePtr = invoke.as<Invoke_t>()) { | 4528 | if (auto invokePtr = invoke.as<Invoke_t>()) { |
| @@ -5028,7 +5063,7 @@ private: | |||
| 5028 | if (!ast_is<Invoke_t, InvokeArgs_t>(followItem)) { | 5063 | if (!ast_is<Invoke_t, InvokeArgs_t>(followItem)) { |
| 5029 | throw CompileError("colon chain item must be followed by invoke arguments"sv, colonItem); | 5064 | throw CompileError("colon chain item must be followed by invoke arguments"sv, colonItem); |
| 5030 | } | 5065 | } |
| 5031 | if (colonItem->name.is<LuaKeyword_t>()) { | 5066 | if (ast_is<LuaKeyword_t, UnicodeName_t>(colonItem->name)) { |
| 5032 | std::string callVar; | 5067 | std::string callVar; |
| 5033 | auto block = x->new_ptr<Block_t>(); | 5068 | auto block = x->new_ptr<Block_t>(); |
| 5034 | { | 5069 | { |
| @@ -5044,7 +5079,7 @@ private: | |||
| 5044 | } | 5079 | } |
| 5045 | auto exp = newExp(chainValue, x); | 5080 | auto exp = newExp(chainValue, x); |
| 5046 | callVar = singleVariableFrom(exp, true); | 5081 | callVar = singleVariableFrom(exp, true); |
| 5047 | if (callVar.empty()) { | 5082 | if (callVar.empty() || !isLocal(callVar)) { |
| 5048 | callVar = getUnusedName("_call_"s); | 5083 | callVar = getUnusedName("_call_"s); |
| 5049 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 5084 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| 5050 | assignment->expList.set(toAst<ExpList_t>(callVar, x)); | 5085 | assignment->expList.set(toAst<ExpList_t>(callVar, x)); |
| @@ -5337,8 +5372,8 @@ private: | |||
| 5337 | throw CompileError("macro table field \"locals\" must be a table of strings"sv, x); | 5372 | throw CompileError("macro table field \"locals\" must be a table of strings"sv, x); |
| 5338 | } | 5373 | } |
| 5339 | auto name = lua_tolstring(L, -1, &len); | 5374 | auto name = lua_tolstring(L, -1, &len); |
| 5340 | if (_parser.match<Variable_t>({name, len})) { | 5375 | if (auto varNode = toAst<Variable_t>({name, len}, x)) { |
| 5341 | localVars.push_back(std::string(name, len)); | 5376 | localVars.push_back(variableToString(varNode)); |
| 5342 | } else { | 5377 | } else { |
| 5343 | throw CompileError("macro table field \"locals\" must contain names for local variables, got \""s + std::string(name, len) + '"', x); | 5378 | throw CompileError("macro table field \"locals\" must contain names for local variables, got \""s + std::string(name, len) + '"', x); |
| 5344 | } | 5379 | } |
| @@ -5562,6 +5597,10 @@ private: | |||
| 5562 | } | 5597 | } |
| 5563 | 5598 | ||
| 5564 | void transformDotChainItem(DotChainItem_t* dotChainItem, str_list& out) { | 5599 | void transformDotChainItem(DotChainItem_t* dotChainItem, str_list& out) { |
| 5600 | if (auto uname = dotChainItem->name.as<UnicodeName_t>()) { | ||
| 5601 | out.push_back("[\""s + _parser.toString(uname) + "\"]"s); | ||
| 5602 | return; | ||
| 5603 | } | ||
| 5565 | auto name = _parser.toString(dotChainItem->name); | 5604 | auto name = _parser.toString(dotChainItem->name); |
| 5566 | if (LuaKeywords.find(name) != LuaKeywords.end()) { | 5605 | if (LuaKeywords.find(name) != LuaKeywords.end()) { |
| 5567 | out.push_back("[\""s + name + "\"]"s); | 5606 | out.push_back("[\""s + name + "\"]"s); |
| @@ -5882,7 +5921,7 @@ private: | |||
| 5882 | } | 5921 | } |
| 5883 | 5922 | ||
| 5884 | void transformVariable(Variable_t* name, str_list& out) { | 5923 | void transformVariable(Variable_t* name, str_list& out) { |
| 5885 | out.push_back(_parser.toString(name)); | 5924 | out.push_back(variableToString(name)); |
| 5886 | } | 5925 | } |
| 5887 | 5926 | ||
| 5888 | void transformNum(Num_t* num, str_list& out) { | 5927 | void transformNum(Num_t* num, str_list& out) { |
| @@ -5993,9 +6032,9 @@ private: | |||
| 5993 | case id<KeyName_t>(): { | 6032 | case id<KeyName_t>(): { |
| 5994 | auto keyName = static_cast<KeyName_t*>(key); | 6033 | auto keyName = static_cast<KeyName_t*>(key); |
| 5995 | ast_ptr<false, ast_node> chainItem; | 6034 | ast_ptr<false, ast_node> chainItem; |
| 5996 | if (auto name = keyName->name.as<Name_t>()) { | 6035 | if (ast_is<Name_t, UnicodeName_t>(keyName->name)) { |
| 5997 | auto dotItem = x->new_ptr<DotChainItem_t>(); | 6036 | auto dotItem = x->new_ptr<DotChainItem_t>(); |
| 5998 | dotItem->name.set(name); | 6037 | dotItem->name.set(keyName->name); |
| 5999 | chainItem = dotItem.get(); | 6038 | chainItem = dotItem.get(); |
| 6000 | } else { | 6039 | } else { |
| 6001 | auto selfName = keyName->name.to<SelfItem_t>(); | 6040 | auto selfName = keyName->name.to<SelfItem_t>(); |
| @@ -6503,7 +6542,7 @@ private: | |||
| 6503 | endWithSlice = true; | 6542 | endWithSlice = true; |
| 6504 | if (listVar.empty() && chainList.size() == 2) { | 6543 | if (listVar.empty() && chainList.size() == 2) { |
| 6505 | if (auto var = chainList.front()->get_by_path<Variable_t>()) { | 6544 | if (auto var = chainList.front()->get_by_path<Variable_t>()) { |
| 6506 | listVar = _parser.toString(var); | 6545 | listVar = variableToString(var); |
| 6507 | if (!isLocal(listVar)) listVar.clear(); | 6546 | if (!isLocal(listVar)) listVar.clear(); |
| 6508 | } | 6547 | } |
| 6509 | } | 6548 | } |
| @@ -6668,7 +6707,7 @@ private: | |||
| 6668 | 6707 | ||
| 6669 | void transformForHead(Variable_t* var, Exp_t* startVal, Exp_t* stopVal, ForStepValue_t* stepVal, str_list& out) { | 6708 | void transformForHead(Variable_t* var, Exp_t* startVal, Exp_t* stopVal, ForStepValue_t* stepVal, str_list& out) { |
| 6670 | str_list temp; | 6709 | str_list temp; |
| 6671 | std::string varName = _parser.toString(var); | 6710 | std::string varName = variableToString(var); |
| 6672 | transformExp(startVal, temp, ExpUsage::Closure); | 6711 | transformExp(startVal, temp, ExpUsage::Closure); |
| 6673 | transformExp(stopVal, temp, ExpUsage::Closure); | 6712 | transformExp(stopVal, temp, ExpUsage::Closure); |
| 6674 | if (stepVal) { | 6713 | if (stepVal) { |
| @@ -7092,12 +7131,18 @@ private: | |||
| 7092 | 7131 | ||
| 7093 | void transform_variable_pair(VariablePair_t* pair, str_list& out) { | 7132 | void transform_variable_pair(VariablePair_t* pair, str_list& out) { |
| 7094 | auto name = _parser.toString(pair->name); | 7133 | auto name = _parser.toString(pair->name); |
| 7134 | if (pair->name->name.is<UnicodeName_t>()) { | ||
| 7135 | std::string varName = variableToString(pair->name); | ||
| 7136 | out.push_back("[\""s + name + "\"] = "s + varName); | ||
| 7137 | name = varName; | ||
| 7138 | } else { | ||
| 7139 | out.push_back(name + " = "s + name); | ||
| 7140 | } | ||
| 7095 | if (_config.lintGlobalVariable && !isLocal(name)) { | 7141 | if (_config.lintGlobalVariable && !isLocal(name)) { |
| 7096 | if (_globals.find(name) == _globals.end()) { | 7142 | if (_globals.find(name) == _globals.end()) { |
| 7097 | _globals[name] = {pair->name->m_begin.m_line, pair->name->m_begin.m_col}; | 7143 | _globals[name] = {pair->name->m_begin.m_line, pair->name->m_begin.m_col}; |
| 7098 | } | 7144 | } |
| 7099 | } | 7145 | } |
| 7100 | out.push_back(name + " = "s + name); | ||
| 7101 | } | 7146 | } |
| 7102 | 7147 | ||
| 7103 | void transform_normal_pair(NormalPair_t* pair, str_list& out, bool assignClass) { | 7148 | void transform_normal_pair(NormalPair_t* pair, str_list& out, bool assignClass) { |
| @@ -7162,6 +7207,11 @@ private: | |||
| 7162 | } | 7207 | } |
| 7163 | break; | 7208 | break; |
| 7164 | } | 7209 | } |
| 7210 | case id<UnicodeName_t>(): { | ||
| 7211 | auto nameStr = _parser.toString(name); | ||
| 7212 | out.push_back("[\""s + nameStr + "\"]"s); | ||
| 7213 | break; | ||
| 7214 | } | ||
| 7165 | default: YUEE("AST node mismatch", name); break; | 7215 | default: YUEE("AST node mismatch", name); break; |
| 7166 | } | 7216 | } |
| 7167 | } | 7217 | } |
| @@ -7214,16 +7264,17 @@ private: | |||
| 7214 | } | 7264 | } |
| 7215 | } | 7265 | } |
| 7216 | 7266 | ||
| 7217 | std::pair<std::string, bool> defineClassVariable(Assignable_t* assignable) { | 7267 | std::tuple<std::string, bool, std::string> defineClassVariable(Assignable_t* assignable) { |
| 7218 | if (auto variable = assignable->item.as<Variable_t>()) { | 7268 | if (auto variable = assignable->item.as<Variable_t>()) { |
| 7219 | auto name = _parser.toString(variable); | 7269 | auto name = variableToString(variable); |
| 7270 | auto realName = variable->name.is<UnicodeName_t>() ? _parser.toString(variable->name) : name; | ||
| 7220 | if (addToScope(name)) { | 7271 | if (addToScope(name)) { |
| 7221 | return {name, true}; | 7272 | return {name, true, realName}; |
| 7222 | } else { | 7273 | } else { |
| 7223 | return {name, false}; | 7274 | return {name, false, realName}; |
| 7224 | } | 7275 | } |
| 7225 | } | 7276 | } |
| 7226 | return {Empty, false}; | 7277 | return {Empty, false, Empty}; |
| 7227 | } | 7278 | } |
| 7228 | 7279 | ||
| 7229 | void transformClassDeclClosure(ClassDecl_t* classDecl, str_list& out) { | 7280 | void transformClassDeclClosure(ClassDecl_t* classDecl, str_list& out) { |
| @@ -7249,29 +7300,30 @@ private: | |||
| 7249 | auto extend = classDecl->extend.get(); | 7300 | auto extend = classDecl->extend.get(); |
| 7250 | std::string className; | 7301 | std::string className; |
| 7251 | std::string assignItem; | 7302 | std::string assignItem; |
| 7303 | std::string classTextName; | ||
| 7252 | if (assignable) { | 7304 | if (assignable) { |
| 7253 | if (!isAssignable(assignable)) { | 7305 | if (!isAssignable(assignable)) { |
| 7254 | throw CompileError("left hand expression is not assignable"sv, assignable); | 7306 | throw CompileError("left hand expression is not assignable"sv, assignable); |
| 7255 | } | 7307 | } |
| 7256 | bool newDefined = false; | 7308 | bool newDefined = false; |
| 7257 | std::tie(className, newDefined) = defineClassVariable(assignable); | 7309 | std::tie(className, newDefined, classTextName) = defineClassVariable(assignable); |
| 7258 | if (newDefined) { | 7310 | if (newDefined) { |
| 7259 | temp.push_back(indent() + "local "s + className + nll(classDecl)); | 7311 | temp.push_back(indent() + "local "s + className + nll(classDecl)); |
| 7260 | } | 7312 | } |
| 7261 | if (className.empty()) { | 7313 | if (classTextName.empty()) { |
| 7262 | if (auto chain = ast_cast<AssignableChain_t>(assignable->item)) { | 7314 | if (auto chain = ast_cast<AssignableChain_t>(assignable->item)) { |
| 7263 | if (auto dotChain = ast_cast<DotChainItem_t>(chain->items.back())) { | 7315 | if (auto dotChain = ast_cast<DotChainItem_t>(chain->items.back())) { |
| 7264 | className = '\"' + _parser.toString(dotChain->name) + '\"'; | 7316 | classTextName = '\"' + _parser.toString(dotChain->name) + '\"'; |
| 7265 | } else if (auto index = ast_cast<Exp_t>(chain->items.back())) { | 7317 | } else if (auto index = ast_cast<Exp_t>(chain->items.back())) { |
| 7266 | if (auto name = index->get_by_path<UnaryExp_t, Value_t, String_t>()) { | 7318 | if (auto name = index->get_by_path<UnaryExp_t, Value_t, String_t>()) { |
| 7267 | transformString(name, temp); | 7319 | transformString(name, temp); |
| 7268 | className = std::move(temp.back()); | 7320 | classTextName = std::move(temp.back()); |
| 7269 | temp.pop_back(); | 7321 | temp.pop_back(); |
| 7270 | } | 7322 | } |
| 7271 | } | 7323 | } |
| 7272 | } | 7324 | } |
| 7273 | } else { | 7325 | } else { |
| 7274 | className = '\"' + className + '\"'; | 7326 | classTextName = '\"' + classTextName + '\"'; |
| 7275 | } | 7327 | } |
| 7276 | pushScope(); | 7328 | pushScope(); |
| 7277 | transformAssignable(assignable, temp); | 7329 | transformAssignable(assignable, temp); |
| @@ -7279,9 +7331,17 @@ private: | |||
| 7279 | assignItem = std::move(temp.back()); | 7331 | assignItem = std::move(temp.back()); |
| 7280 | temp.pop_back(); | 7332 | temp.pop_back(); |
| 7281 | } else if (expList) { | 7333 | } else if (expList) { |
| 7282 | auto name = singleVariableFrom(expList, true); | 7334 | if (auto value = singleValueFrom(expList); value->item.is<ChainValue_t>()) { |
| 7283 | if (!name.empty()) { | 7335 | auto chainValue = static_cast<ChainValue_t*>(value->item.get()); |
| 7284 | className = '\"' + name + '\"'; | 7336 | if (auto callable = ast_cast<Callable_t>(chainValue->items.front()); callable && chainValue->items.size() == 1) { |
| 7337 | if (auto self = callable->item.as<SelfItem_t>()) { | ||
| 7338 | if (auto selfVar = self->name.as<Self_t>()) { | ||
| 7339 | classTextName = "\"self\""; | ||
| 7340 | } | ||
| 7341 | } else if (auto var = callable->item.as<Variable_t>()) { | ||
| 7342 | classTextName = '\"' + _parser.toString(var) + '\"'; | ||
| 7343 | } | ||
| 7344 | } | ||
| 7285 | } | 7345 | } |
| 7286 | } | 7346 | } |
| 7287 | temp.push_back(indent() + "do"s + nll(classDecl)); | 7347 | temp.push_back(indent() + "do"s + nll(classDecl)); |
| @@ -7296,7 +7356,9 @@ private: | |||
| 7296 | ClassDecl_t* clsDecl = nullptr; | 7356 | ClassDecl_t* clsDecl = nullptr; |
| 7297 | if (auto assignment = assignmentFrom(statement)) { | 7357 | if (auto assignment = assignmentFrom(statement)) { |
| 7298 | auto names = transformAssignDefs(assignment->expList.get(), DefOp::Mark); | 7358 | auto names = transformAssignDefs(assignment->expList.get(), DefOp::Mark); |
| 7299 | varDefs.insert(varDefs.end(), names.begin(), names.end()); | 7359 | for (const auto& name : names) { |
| 7360 | varDefs.push_back(name.first); | ||
| 7361 | } | ||
| 7300 | auto info = extractDestructureInfo(assignment, true, false); | 7362 | auto info = extractDestructureInfo(assignment, true, false); |
| 7301 | if (!info.destructures.empty()) { | 7363 | if (!info.destructures.empty()) { |
| 7302 | for (const auto& destruct : info.destructures) | 7364 | for (const auto& destruct : info.destructures) |
| @@ -7320,8 +7382,9 @@ private: | |||
| 7320 | } | 7382 | } |
| 7321 | if (clsDecl) { | 7383 | if (clsDecl) { |
| 7322 | std::string clsName; | 7384 | std::string clsName; |
| 7385 | std::string clsTextName; | ||
| 7323 | bool newDefined = false; | 7386 | bool newDefined = false; |
| 7324 | std::tie(clsName, newDefined) = defineClassVariable(clsDecl->name); | 7387 | std::tie(clsName, newDefined, clsTextName) = defineClassVariable(clsDecl->name); |
| 7325 | if (newDefined) varDefs.push_back(clsName); | 7388 | if (newDefined) varDefs.push_back(clsName); |
| 7326 | } | 7389 | } |
| 7327 | } | 7390 | } |
| @@ -7437,9 +7500,9 @@ private: | |||
| 7437 | } | 7500 | } |
| 7438 | } | 7501 | } |
| 7439 | _buf << indent(1) << "__base = "sv << baseVar; | 7502 | _buf << indent(1) << "__base = "sv << baseVar; |
| 7440 | if (!className.empty()) { | 7503 | if (!classTextName.empty()) { |
| 7441 | _buf << ","sv << nll(classDecl); | 7504 | _buf << ","sv << nll(classDecl); |
| 7442 | _buf << indent(1) << "__name = "sv << className; | 7505 | _buf << indent(1) << "__name = "sv << classTextName; |
| 7443 | } | 7506 | } |
| 7444 | if (extend) { | 7507 | if (extend) { |
| 7445 | _buf << ","sv << nll(classDecl); | 7508 | _buf << ","sv << nll(classDecl); |
| @@ -7546,12 +7609,15 @@ private: | |||
| 7546 | type = MemType::Property; | 7609 | type = MemType::Property; |
| 7547 | auto name = ast_cast<SelfName_t>(selfItem->name); | 7610 | auto name = ast_cast<SelfName_t>(selfItem->name); |
| 7548 | if (!name) throw CompileError("invalid class poperty name"sv, selfItem->name); | 7611 | if (!name) throw CompileError("invalid class poperty name"sv, selfItem->name); |
| 7549 | newSuperCall = classVar + ".__parent."s + _parser.toString(name->name); | 7612 | if (name->name.is<UnicodeName_t>()) { |
| 7613 | newSuperCall = classVar + ".__parent[\""s + _parser.toString(name->name) + "\"]"s; | ||
| 7614 | } else { | ||
| 7615 | newSuperCall = classVar + ".__parent."s + _parser.toString(name->name); | ||
| 7616 | } | ||
| 7550 | } else { | 7617 | } else { |
| 7551 | auto x = keyName; | 7618 | auto x = keyName; |
| 7552 | auto nameNode = keyName->name.as<Name_t>(); | 7619 | if (!ast_is<Name_t, UnicodeName_t>(keyName->name)) break; |
| 7553 | if (!nameNode) break; | 7620 | auto name = _parser.toString(keyName->name); |
| 7554 | auto name = _parser.toString(nameNode); | ||
| 7555 | if (name == "new"sv) { | 7621 | if (name == "new"sv) { |
| 7556 | type = MemType::Builtin; | 7622 | type = MemType::Builtin; |
| 7557 | keyName->name.set(toAst<Name_t>("__init"sv, x)); | 7623 | keyName->name.set(toAst<Name_t>("__init"sv, x)); |
| @@ -7563,7 +7629,7 @@ private: | |||
| 7563 | normal_pair->value->traverse([&](ast_node* node) { | 7629 | normal_pair->value->traverse([&](ast_node* node) { |
| 7564 | if (node->get_id() == id<ClassDecl_t>()) return traversal::Return; | 7630 | if (node->get_id() == id<ClassDecl_t>()) return traversal::Return; |
| 7565 | if (auto chainValue = ast_cast<ChainValue_t>(node)) { | 7631 | if (auto chainValue = ast_cast<ChainValue_t>(node)) { |
| 7566 | if (auto callable = ast_cast<Callable_t>(chainValue->items.front())) { | 7632 | if (auto callable = ast_cast<Callable_t>(chainValue->items.front()); callable && callable->item.is<Variable_t>()) { |
| 7567 | auto var = callable->item.get(); | 7633 | auto var = callable->item.get(); |
| 7568 | if (_parser.toString(var) == "super"sv) { | 7634 | if (_parser.toString(var) == "super"sv) { |
| 7569 | auto insertSelfToArguments = [&](ast_node* item) { | 7635 | auto insertSelfToArguments = [&](ast_node* item) { |
| @@ -7763,7 +7829,7 @@ private: | |||
| 7763 | } | 7829 | } |
| 7764 | if (clsDecl) { | 7830 | if (clsDecl) { |
| 7765 | auto variable = clsDecl->name.as<Variable_t>(); | 7831 | auto variable = clsDecl->name.as<Variable_t>(); |
| 7766 | if (!isDefined(_parser.toString(variable))) return traversal::Stop; | 7832 | if (!isDefined(variableToString(variable))) return traversal::Stop; |
| 7767 | } | 7833 | } |
| 7768 | return traversal::Return; | 7834 | return traversal::Return; |
| 7769 | } | 7835 | } |
| @@ -7817,9 +7883,11 @@ private: | |||
| 7817 | switch (item->get_id()) { | 7883 | switch (item->get_id()) { |
| 7818 | case id<ClassDecl_t>(): { | 7884 | case id<ClassDecl_t>(): { |
| 7819 | auto classDecl = static_cast<ClassDecl_t*>(item); | 7885 | auto classDecl = static_cast<ClassDecl_t*>(item); |
| 7820 | if (classDecl->name && classDecl->name->item->get_id() == id<Variable_t>()) { | 7886 | if (classDecl->name) { |
| 7821 | markVarsGlobal(GlobalMode::Any); | 7887 | if (auto var = classDecl->name->item.as<Variable_t>()) { |
| 7822 | addGlobalVar(_parser.toString(classDecl->name->item), classDecl->name->item); | 7888 | markVarsGlobal(GlobalMode::Any); |
| 7889 | addGlobalVar(variableToString(var), classDecl->name->item); | ||
| 7890 | } | ||
| 7823 | } | 7891 | } |
| 7824 | transformClassDecl(classDecl, out, ExpUsage::Common); | 7892 | transformClassDecl(classDecl, out, ExpUsage::Common); |
| 7825 | break; | 7893 | break; |
| @@ -7837,7 +7905,8 @@ private: | |||
| 7837 | if (values->valueList) { | 7905 | if (values->valueList) { |
| 7838 | auto expList = x->new_ptr<ExpList_t>(); | 7906 | auto expList = x->new_ptr<ExpList_t>(); |
| 7839 | for (auto name : values->nameList->names.objects()) { | 7907 | for (auto name : values->nameList->names.objects()) { |
| 7840 | addGlobalVar(_parser.toString(name), name); | 7908 | auto var = static_cast<Variable_t*>(name); |
| 7909 | addGlobalVar(variableToString(var), var); | ||
| 7841 | auto callable = x->new_ptr<Callable_t>(); | 7910 | auto callable = x->new_ptr<Callable_t>(); |
| 7842 | callable->item.set(name); | 7911 | callable->item.set(name); |
| 7843 | auto chainValue = x->new_ptr<ChainValue_t>(); | 7912 | auto chainValue = x->new_ptr<ChainValue_t>(); |
| @@ -7858,7 +7927,8 @@ private: | |||
| 7858 | transformAssignment(assignment, out); | 7927 | transformAssignment(assignment, out); |
| 7859 | } else { | 7928 | } else { |
| 7860 | for (auto name : values->nameList->names.objects()) { | 7929 | for (auto name : values->nameList->names.objects()) { |
| 7861 | addGlobalVar(_parser.toString(name), name); | 7930 | auto var = static_cast<Variable_t*>(name); |
| 7931 | addGlobalVar(variableToString(var), var); | ||
| 7862 | } | 7932 | } |
| 7863 | } | 7933 | } |
| 7864 | break; | 7934 | break; |
| @@ -7938,14 +8008,14 @@ private: | |||
| 7938 | dotChain && dotChain->name.is<Metamethod_t>()) { | 8008 | dotChain && dotChain->name.is<Metamethod_t>()) { |
| 7939 | auto nameStr = name.value(); | 8009 | auto nameStr = name.value(); |
| 7940 | if (_exportedMetaKeys.find(nameStr) != _exportedMetaKeys.end()) { | 8010 | if (_exportedMetaKeys.find(nameStr) != _exportedMetaKeys.end()) { |
| 7941 | throw CompileError("export module metamethod key \"" + nameStr + "\" duplicated"s, dotChain->name); | 8011 | throw CompileError("export module metamethod key \""s + nameStr + "\" duplicated"s, dotChain->name); |
| 7942 | } else { | 8012 | } else { |
| 7943 | _exportedMetaKeys.insert(nameStr); | 8013 | _exportedMetaKeys.insert(nameStr); |
| 7944 | } | 8014 | } |
| 7945 | } else { | 8015 | } else { |
| 7946 | auto nameStr = name.value(); | 8016 | auto nameStr = name.value(); |
| 7947 | if (_exportedKeys.find(nameStr) != _exportedKeys.end()) { | 8017 | if (_exportedKeys.find(nameStr) != _exportedKeys.end()) { |
| 7948 | throw CompileError("export module key \"" + nameStr + "\" duplicated"s, exportNode->target); | 8018 | throw CompileError("export module key \""s + nameStr + "\" duplicated"s, exportNode->target); |
| 7949 | } else { | 8019 | } else { |
| 7950 | _exportedKeys.insert(nameStr); | 8020 | _exportedKeys.insert(nameStr); |
| 7951 | } | 8021 | } |
| @@ -7977,26 +8047,30 @@ private: | |||
| 7977 | assignment->expList.set(expList); | 8047 | assignment->expList.set(expList); |
| 7978 | assignment->action.set(exportNode->assign); | 8048 | assignment->action.set(exportNode->assign); |
| 7979 | transformAssignment(assignment, out); | 8049 | transformAssignment(assignment, out); |
| 7980 | str_list names = transformAssignDefs(expList, DefOp::Get); | 8050 | auto names = transformAssignDefs(expList, DefOp::Get); |
| 7981 | auto info = extractDestructureInfo(assignment, true, false); | 8051 | auto info = extractDestructureInfo(assignment, true, false); |
| 7982 | if (!info.destructures.empty()) { | 8052 | if (!info.destructures.empty()) { |
| 7983 | for (const auto& destruct : info.destructures) | 8053 | for (const auto& destruct : info.destructures) |
| 7984 | for (const auto& item : destruct.items) | 8054 | for (const auto& item : destruct.items) |
| 7985 | if (!item.targetVar.empty()) | 8055 | if (!item.targetVar.empty()) { |
| 7986 | names.push_back(item.targetVar); | 8056 | auto dot = ast_cast<DotChainItem_t>(item.structure->items.back()); |
| 8057 | auto uname = dot->name.as<UnicodeName_t>(); | ||
| 8058 | names.emplace_back(item.targetVar, uname ? _parser.toString(uname) : Empty); | ||
| 8059 | } | ||
| 7987 | } | 8060 | } |
| 7988 | if (_info.exportDefault) { | 8061 | if (_info.exportDefault) { |
| 7989 | out.back().append(indent() + _info.moduleName + " = "s + names.back() + nlr(exportNode)); | 8062 | out.back().append(indent() + _info.moduleName + " = "s + names.back().first + nlr(exportNode)); |
| 7990 | } else { | 8063 | } else { |
| 7991 | str_list lefts, rights; | 8064 | str_list lefts, rights; |
| 7992 | for (const auto& name : names) { | 8065 | for (const auto& name : names) { |
| 7993 | if (_exportedKeys.find(name) != _exportedKeys.end()) { | 8066 | auto realName = name.second.empty() ? name.first : name.second; |
| 7994 | throw CompileError("export module key \"" + name + "\" duplicated"s, x); | 8067 | if (_exportedKeys.find(realName) != _exportedKeys.end()) { |
| 8068 | throw CompileError("export module key \""s + realName + "\" duplicated"s, x); | ||
| 7995 | } else { | 8069 | } else { |
| 7996 | _exportedKeys.insert(name); | 8070 | _exportedKeys.insert(realName); |
| 7997 | } | 8071 | } |
| 7998 | lefts.push_back(_info.moduleName + "[\""s + name + "\"]"s); | 8072 | lefts.push_back(_info.moduleName + "[\""s + realName + "\"]"s); |
| 7999 | rights.push_back(name); | 8073 | rights.push_back(name.first); |
| 8000 | } | 8074 | } |
| 8001 | out.back().append(indent() + join(lefts, ", "sv) + " = "s + join(rights, ", "sv) + nlr(exportNode)); | 8075 | out.back().append(indent() + join(lefts, ", "sv) + " = "s + join(rights, ", "sv) + nlr(exportNode)); |
| 8002 | } | 8076 | } |
| @@ -8020,16 +8094,18 @@ private: | |||
| 8020 | assignment->expList.set(assignList); | 8094 | assignment->expList.set(assignList); |
| 8021 | for (auto exp : expList->exprs.objects()) { | 8095 | for (auto exp : expList->exprs.objects()) { |
| 8022 | if (auto classDecl = exp->get_by_path<UnaryExp_t, Value_t, SimpleValue_t, ClassDecl_t>()) { | 8096 | if (auto classDecl = exp->get_by_path<UnaryExp_t, Value_t, SimpleValue_t, ClassDecl_t>()) { |
| 8023 | if (classDecl->name && classDecl->name->item->get_id() == id<Variable_t>()) { | 8097 | if (classDecl->name) { |
| 8024 | transformClassDecl(classDecl, temp, ExpUsage::Common); | 8098 | if (auto var = classDecl->name->item.as<Variable_t>()) { |
| 8025 | auto name = _parser.toString(classDecl->name->item); | 8099 | transformClassDecl(classDecl, temp, ExpUsage::Common); |
| 8026 | assignment->expList.set(toAst<ExpList_t>(_info.moduleName + "[\""s + name + "\"]"s, x)); | 8100 | auto name = variableToString(var); |
| 8027 | auto assign = x->new_ptr<Assign_t>(); | 8101 | assignment->expList.set(toAst<ExpList_t>(_info.moduleName + "[\""s + name + "\"]"s, x)); |
| 8028 | assign->values.push_back(toAst<Exp_t>(name, x)); | 8102 | auto assign = x->new_ptr<Assign_t>(); |
| 8029 | assignment->action.set(assign); | 8103 | assign->values.push_back(toAst<Exp_t>(name, x)); |
| 8030 | transformAssignment(assignment, temp); | 8104 | assignment->action.set(assign); |
| 8031 | assignment->expList.set(assignList); | 8105 | transformAssignment(assignment, temp); |
| 8032 | continue; | 8106 | assignment->expList.set(assignList); |
| 8107 | continue; | ||
| 8108 | } | ||
| 8033 | } | 8109 | } |
| 8034 | } | 8110 | } |
| 8035 | auto assign = x->new_ptr<Assign_t>(); | 8111 | auto assign = x->new_ptr<Assign_t>(); |
| @@ -8180,7 +8256,7 @@ private: | |||
| 8180 | auto x = tryNode; | 8256 | auto x = tryNode; |
| 8181 | ast_ptr<true, Exp_t> errHandler; | 8257 | ast_ptr<true, Exp_t> errHandler; |
| 8182 | if (tryNode->catchBlock) { | 8258 | if (tryNode->catchBlock) { |
| 8183 | auto errHandleStr = "("s + _parser.toString(tryNode->catchBlock->err) + ")->"s; | 8259 | auto errHandleStr = "("s + variableToString(tryNode->catchBlock->err) + ")->"s; |
| 8184 | errHandler.set(toAst<Exp_t>(errHandleStr, x->func)); | 8260 | errHandler.set(toAst<Exp_t>(errHandleStr, x->func)); |
| 8185 | auto funLit = simpleSingleValueFrom(errHandler)->value.to<FunLit_t>(); | 8261 | auto funLit = simpleSingleValueFrom(errHandler)->value.to<FunLit_t>(); |
| 8186 | auto body = x->new_ptr<Body_t>(); | 8262 | auto body = x->new_ptr<Body_t>(); |
| @@ -8582,7 +8658,7 @@ private: | |||
| 8582 | assignment->action.set(assign); | 8658 | assignment->action.set(assign); |
| 8583 | transformAssignment(assignment, out); | 8659 | transformAssignment(assignment, out); |
| 8584 | if (auto var = ast_cast<Variable_t>(target)) { | 8660 | if (auto var = ast_cast<Variable_t>(target)) { |
| 8585 | auto moduleName = _parser.toString(var); | 8661 | auto moduleName = variableToString(var); |
| 8586 | markVarConst(moduleName); | 8662 | markVarConst(moduleName); |
| 8587 | } else { | 8663 | } else { |
| 8588 | markDestructureConst(assignment); | 8664 | markDestructureConst(assignment); |
| @@ -9001,7 +9077,7 @@ private: | |||
| 9001 | auto assign = x->new_ptr<Assign_t>(); | 9077 | auto assign = x->new_ptr<Assign_t>(); |
| 9002 | str_list vars; | 9078 | str_list vars; |
| 9003 | for (auto varNode : listA->names.objects()) { | 9079 | for (auto varNode : listA->names.objects()) { |
| 9004 | auto var = _parser.toString(varNode); | 9080 | auto var = variableToString(static_cast<Variable_t*>(varNode)); |
| 9005 | forceAddToScope(var); | 9081 | forceAddToScope(var); |
| 9006 | vars.push_back(var); | 9082 | vars.push_back(var); |
| 9007 | auto callable = x->new_ptr<Callable_t>(); | 9083 | auto callable = x->new_ptr<Callable_t>(); |
| @@ -9038,7 +9114,7 @@ private: | |||
| 9038 | for (auto name : listA->names.objects()) { | 9114 | for (auto name : listA->names.objects()) { |
| 9039 | auto closeName = getUnusedName("_close_"sv); | 9115 | auto closeName = getUnusedName("_close_"sv); |
| 9040 | leftVars.push_back(closeName); | 9116 | leftVars.push_back(closeName); |
| 9041 | rightVars.push_back(_parser.toString(name)); | 9117 | rightVars.push_back(variableToString(static_cast<Variable_t*>(name))); |
| 9042 | addToScope(closeName); | 9118 | addToScope(closeName); |
| 9043 | } | 9119 | } |
| 9044 | popScope(); | 9120 | popScope(); |
| @@ -9052,7 +9128,7 @@ private: | |||
| 9052 | if (!listA->names.empty()) { | 9128 | if (!listA->names.empty()) { |
| 9053 | str_list vars; | 9129 | str_list vars; |
| 9054 | for (auto name : listA->names.objects()) { | 9130 | for (auto name : listA->names.objects()) { |
| 9055 | auto var = _parser.toString(name); | 9131 | auto var = variableToString(static_cast<Variable_t*>(name)); |
| 9056 | forceAddToScope(var); | 9132 | forceAddToScope(var); |
| 9057 | vars.push_back(var); | 9133 | vars.push_back(var); |
| 9058 | } | 9134 | } |
| @@ -9161,7 +9237,7 @@ private: | |||
| 9161 | if (getLuaTarget(label) < 502) { | 9237 | if (getLuaTarget(label) < 502) { |
| 9162 | throw CompileError("label statement is not available when not targeting Lua version 5.2 or higher"sv, label); | 9238 | throw CompileError("label statement is not available when not targeting Lua version 5.2 or higher"sv, label); |
| 9163 | } | 9239 | } |
| 9164 | auto labelStr = _parser.toString(label->label); | 9240 | auto labelStr = unicodeVariableFrom(label->label->name); |
| 9165 | int currentScope = _gotoScopes.top(); | 9241 | int currentScope = _gotoScopes.top(); |
| 9166 | if (static_cast<int>(_labels.size()) <= currentScope) { | 9242 | if (static_cast<int>(_labels.size()) <= currentScope) { |
| 9167 | _labels.resize(currentScope + 1, std::nullopt); | 9243 | _labels.resize(currentScope + 1, std::nullopt); |
| @@ -9182,7 +9258,7 @@ private: | |||
| 9182 | if (getLuaTarget(gotoNode) < 502) { | 9258 | if (getLuaTarget(gotoNode) < 502) { |
| 9183 | throw CompileError("goto statement is not available when not targeting Lua version 5.2 or higher"sv, gotoNode); | 9259 | throw CompileError("goto statement is not available when not targeting Lua version 5.2 or higher"sv, gotoNode); |
| 9184 | } | 9260 | } |
| 9185 | auto labelStr = _parser.toString(gotoNode->label); | 9261 | auto labelStr = unicodeVariableFrom(gotoNode->label->name); |
| 9186 | gotos.push_back({gotoNode, labelStr, _gotoScopes.top(), static_cast<int>(_scopes.size())}); | 9262 | gotos.push_back({gotoNode, labelStr, _gotoScopes.top(), static_cast<int>(_scopes.size())}); |
| 9187 | out.push_back(indent() + "goto "s + labelStr + nll(gotoNode)); | 9263 | out.push_back(indent() + "goto "s + labelStr + nll(gotoNode)); |
| 9188 | } | 9264 | } |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 693a3bc..ea45e85 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -59,7 +59,8 @@ YueParser::YueParser() { | |||
| 59 | white = space >> *(line_break >> space); | 59 | white = space >> *(line_break >> space); |
| 60 | alpha_num = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_'; | 60 | alpha_num = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_'; |
| 61 | not_alpha_num = not_(alpha_num); | 61 | not_alpha_num = not_(alpha_num); |
| 62 | Name = (range('a', 'z') | range('A', 'Z') | '_') >> *alpha_num; | 62 | Name = (range('a', 'z') | range('A', 'Z') | '_') >> *alpha_num >> not_(larger(255)); |
| 63 | UnicodeName = (range('a', 'z') | range('A', 'Z') | '_' | larger(255)) >> *(larger(255) | alpha_num); | ||
| 63 | num_expo = set("eE") >> -set("+-") >> num_char; | 64 | num_expo = set("eE") >> -set("+-") >> num_char; |
| 64 | num_expo_hex = set("pP") >> -set("+-") >> num_char; | 65 | num_expo_hex = set("pP") >> -set("+-") >> num_char; |
| 65 | lj_num = -set("uU") >> set("lL") >> set("lL"); | 66 | lj_num = -set("uU") >> set("lL") >> set("lL"); |
| @@ -160,23 +161,34 @@ YueParser::YueParser() { | |||
| 160 | 161 | ||
| 161 | #define body (in_block | Statement | empty_block_error) | 162 | #define body (in_block | Statement | empty_block_error) |
| 162 | 163 | ||
| 163 | Variable = pl::user(Name, [](const item_t& item) { | 164 | Variable = pl::user(Name | UnicodeName, [](const item_t& item) { |
| 164 | State* st = reinterpret_cast<State*>(item.user_data); | 165 | State* st = reinterpret_cast<State*>(item.user_data); |
| 165 | for (auto it = item.begin->m_it; it != item.end->m_it; ++it) st->buffer += static_cast<char>(*it); | 166 | for (auto it = item.begin->m_it; it != item.end->m_it; ++it) { |
| 167 | if (*it > 255) { | ||
| 168 | st->buffer.clear(); | ||
| 169 | return true; | ||
| 170 | } | ||
| 171 | st->buffer += static_cast<char>(*it); | ||
| 172 | } | ||
| 166 | auto isValid = Keywords.find(st->buffer) == Keywords.end(); | 173 | auto isValid = Keywords.find(st->buffer) == Keywords.end(); |
| 167 | if (isValid) { | 174 | if (isValid) { |
| 168 | if (st->buffer == st->moduleName) { | 175 | if (st->buffer[0] == '_') { |
| 169 | st->moduleFix++; | 176 | st->usedNames.insert(st->buffer); |
| 170 | st->moduleName = "_module_"s + std::to_string(st->moduleFix); | ||
| 171 | } | 177 | } |
| 172 | } | 178 | } |
| 173 | st->buffer.clear(); | 179 | st->buffer.clear(); |
| 174 | return isValid; | 180 | return isValid; |
| 175 | }); | 181 | }); |
| 176 | 182 | ||
| 177 | LabelName = pl::user(Name, [](const item_t& item) { | 183 | LabelName = pl::user(UnicodeName, [](const item_t& item) { |
| 178 | State* st = reinterpret_cast<State*>(item.user_data); | 184 | State* st = reinterpret_cast<State*>(item.user_data); |
| 179 | for (auto it = item.begin->m_it; it != item.end->m_it; ++it) st->buffer += static_cast<char>(*it); | 185 | for (auto it = item.begin->m_it; it != item.end->m_it; ++it) { |
| 186 | if (*it > 255) { | ||
| 187 | st->buffer.clear(); | ||
| 188 | return true; | ||
| 189 | } | ||
| 190 | st->buffer += static_cast<char>(*it); | ||
| 191 | } | ||
| 180 | auto isValid = LuaKeywords.find(st->buffer) == LuaKeywords.end(); | 192 | auto isValid = LuaKeywords.find(st->buffer) == LuaKeywords.end(); |
| 181 | st->buffer.clear(); | 193 | st->buffer.clear(); |
| 182 | return isValid; | 194 | return isValid; |
| @@ -191,12 +203,12 @@ YueParser::YueParser() { | |||
| 191 | }); | 203 | }); |
| 192 | 204 | ||
| 193 | Self = '@'; | 205 | Self = '@'; |
| 194 | SelfName = '@' >> Name; | 206 | SelfName = '@' >> (Name | UnicodeName); |
| 195 | SelfClass = "@@"; | 207 | SelfClass = "@@"; |
| 196 | SelfClassName = "@@" >> Name; | 208 | SelfClassName = "@@" >> (Name | UnicodeName); |
| 197 | 209 | ||
| 198 | SelfItem = SelfClassName | SelfClass | SelfName | Self; | 210 | SelfItem = SelfClassName | SelfClass | SelfName | Self; |
| 199 | KeyName = SelfItem | Name; | 211 | KeyName = SelfItem | Name | UnicodeName; |
| 200 | VarArg = "..."; | 212 | VarArg = "..."; |
| 201 | 213 | ||
| 202 | check_indent = pl::user(plain_space, [](const item_t& item) { | 214 | check_indent = pl::user(plain_space, [](const item_t& item) { |
| @@ -275,7 +287,7 @@ YueParser::YueParser() { | |||
| 275 | import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name); | 287 | import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name); |
| 276 | ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> Exp; | 288 | ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> Exp; |
| 277 | 289 | ||
| 278 | ImportLiteralInner = (range('a', 'z') | range('A', 'Z') | set("_-")) >> *(alpha_num | '-'); | 290 | ImportLiteralInner = (range('a', 'z') | range('A', 'Z') | set("_-") | larger(255)) >> *(alpha_num | '-' | larger(255)); |
| 279 | import_literal_chain = Seperator >> ImportLiteralInner >> *('.' >> ImportLiteralInner); | 291 | import_literal_chain = Seperator >> ImportLiteralInner >> *('.' >> ImportLiteralInner); |
| 280 | ImportLiteral = ( | 292 | ImportLiteral = ( |
| 281 | '\'' >> import_literal_chain >> '\'' | 293 | '\'' >> import_literal_chain >> '\'' |
| @@ -608,8 +620,8 @@ YueParser::YueParser() { | |||
| 608 | DotChainItem >> -ExistentialOp | | 620 | DotChainItem >> -ExistentialOp | |
| 609 | Slice | | 621 | Slice | |
| 610 | index >> -ExistentialOp; | 622 | index >> -ExistentialOp; |
| 611 | DotChainItem = '.' >> (Name | Metatable | Metamethod); | 623 | DotChainItem = '.' >> (Name | Metatable | Metamethod | UnicodeName); |
| 612 | ColonChainItem = (expr('\\') | "::") >> (LuaKeyword | Name | Metamethod); | 624 | ColonChainItem = (expr('\\') | "::") >> (LuaKeyword | Name | Metamethod | UnicodeName); |
| 613 | invoke_chain = Invoke >> -ExistentialOp >> -chain_items; | 625 | invoke_chain = Invoke >> -ExistentialOp >> -chain_items; |
| 614 | colon_chain = ColonChainItem >> -ExistentialOp >> -invoke_chain; | 626 | colon_chain = ColonChainItem >> -ExistentialOp >> -invoke_chain; |
| 615 | 627 | ||
| @@ -779,10 +791,10 @@ YueParser::YueParser() { | |||
| 779 | FnArrow = expr("->") | "=>"; | 791 | FnArrow = expr("->") | "=>"; |
| 780 | FunLit = -FnArgsDef >> space >> FnArrow >> -(space >> Body); | 792 | FunLit = -FnArgsDef >> space >> FnArrow >> -(space >> Body); |
| 781 | 793 | ||
| 782 | MacroName = '$' >> Name; | 794 | MacroName = '$' >> UnicodeName; |
| 783 | macro_args_def = '(' >> white >> -FnArgDefList >> white >> ')'; | 795 | macro_args_def = '(' >> white >> -FnArgDefList >> white >> ')'; |
| 784 | MacroLit = -(macro_args_def >> space) >> "->" >> space >> Body; | 796 | MacroLit = -(macro_args_def >> space) >> "->" >> space >> Body; |
| 785 | Macro = key("macro") >> space >> Name >> space >> '=' >> space >> MacroLit; | 797 | Macro = key("macro") >> space >> UnicodeName >> space >> '=' >> space >> MacroLit; |
| 786 | MacroInPlace = '$' >> space >> "->" >> space >> Body; | 798 | MacroInPlace = '$' >> space >> "->" >> space >> Body; |
| 787 | 799 | ||
| 788 | NameList = Seperator >> Variable >> *(space >> ',' >> space >> Variable); | 800 | NameList = Seperator >> Variable >> *(space >> ',' >> space >> Variable); |
| @@ -955,7 +967,15 @@ ParseInfo YueParser::parse(std::string_view codes, rule& r) { | |||
| 955 | State state; | 967 | State state; |
| 956 | res.node.set(::yue::parse(*(res.codes), r, errors, &state)); | 968 | res.node.set(::yue::parse(*(res.codes), r, errors, &state)); |
| 957 | if (state.exportCount > 0) { | 969 | if (state.exportCount > 0) { |
| 958 | res.moduleName = std::move(state.moduleName); | 970 | int index = 0; |
| 971 | std::string moduleName; | ||
| 972 | auto moduleStr = "_module_"s; | ||
| 973 | do { | ||
| 974 | moduleName = moduleStr + std::to_string(index); | ||
| 975 | index++; | ||
| 976 | } while (state.usedNames.find(moduleName) != state.usedNames.end()); | ||
| 977 | res.moduleName = moduleName; | ||
| 978 | res.usedNames = std::move(state.usedNames); | ||
| 959 | res.exportDefault = state.exportDefault; | 979 | res.exportDefault = state.exportDefault; |
| 960 | res.exportMacro = state.exportMacro; | 980 | res.exportMacro = state.exportMacro; |
| 961 | res.exportMetatable = !state.exportMetatable && state.exportMetamethod; | 981 | res.exportMetatable = !state.exportMetatable && state.exportMetamethod; |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index dd5e253..72d966d 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
| @@ -40,6 +40,7 @@ struct ParseInfo { | |||
| 40 | bool exportMacro = false; | 40 | bool exportMacro = false; |
| 41 | bool exportMetatable = false; | 41 | bool exportMetatable = false; |
| 42 | std::string moduleName; | 42 | std::string moduleName; |
| 43 | std::unordered_set<std::string> usedNames; | ||
| 43 | std::string errorMessage(std::string_view msg, int errLine, int errCol, int lineOffset = 0) const; | 44 | std::string errorMessage(std::string_view msg, int errLine, int errCol, int lineOffset = 0) const; |
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| @@ -105,16 +106,15 @@ protected: | |||
| 105 | bool exportMetatable = false; | 106 | bool exportMetatable = false; |
| 106 | bool exportMetamethod = false; | 107 | bool exportMetamethod = false; |
| 107 | int exportCount = 0; | 108 | int exportCount = 0; |
| 108 | int moduleFix = 0; | ||
| 109 | int expLevel = 0; | 109 | int expLevel = 0; |
| 110 | size_t stringOpen = 0; | 110 | size_t stringOpen = 0; |
| 111 | std::string moduleName = "_module_0"s; | ||
| 112 | std::string buffer; | 111 | std::string buffer; |
| 113 | std::stack<int> indents; | 112 | std::stack<int> indents; |
| 114 | std::stack<bool> noDoStack; | 113 | std::stack<bool> noDoStack; |
| 115 | std::stack<bool> noChainBlockStack; | 114 | std::stack<bool> noChainBlockStack; |
| 116 | std::stack<bool> noTableBlockStack; | 115 | std::stack<bool> noTableBlockStack; |
| 117 | std::stack<bool> noForStack; | 116 | std::stack<bool> noForStack; |
| 117 | std::unordered_set<std::string> usedNames; | ||
| 118 | }; | 118 | }; |
| 119 | 119 | ||
| 120 | template <class T> | 120 | template <class T> |
| @@ -254,6 +254,7 @@ private: | |||
| 254 | 254 | ||
| 255 | AST_RULE(Num); | 255 | AST_RULE(Num); |
| 256 | AST_RULE(Name); | 256 | AST_RULE(Name); |
| 257 | AST_RULE(UnicodeName); | ||
| 257 | AST_RULE(Variable); | 258 | AST_RULE(Variable); |
| 258 | AST_RULE(LabelName); | 259 | AST_RULE(LabelName); |
| 259 | AST_RULE(LuaKeyword); | 260 | AST_RULE(LuaKeyword); |
