diff options
Diffstat (limited to 'src')
-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); |