aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/yuescript/parser.cpp39
-rw-r--r--src/yuescript/parser.hpp2
-rw-r--r--src/yuescript/yue_ast.cpp4
-rw-r--r--src/yuescript/yue_ast.h21
-rw-r--r--src/yuescript/yue_compiler.cpp370
-rw-r--r--src/yuescript/yue_parser.cpp54
-rw-r--r--src/yuescript/yue_parser.h5
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.
345class _larger : public _expr {
346public:
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
362private:
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
345class _unary : public _expr { 380class _unary : public _expr {
346public: 381public:
@@ -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
1541expr 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*/
347expr range(int min, int max); 347expr range(int min, int max);
348 348
349expr 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}
72std::string UnicodeName_t::to_string(void* ud) const {
73 auto info = reinterpret_cast<YueFormat*>(ud);
74 return info->convert(this);
75}
72std::string Self_t::to_string(void*) const { 76std::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)
86AST_LEAF(Name) 86AST_LEAF(Name)
87AST_END(Name, "name"sv) 87AST_END(Name, "name"sv)
88 88
89AST_LEAF(UnicodeName)
90AST_END(UnicodeName, "unicode_name"sv)
91
89AST_NODE(Variable) 92AST_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)
92AST_END(Variable, "variable"sv) 95AST_END(Variable, "variable"sv)
93 96
94AST_NODE(LabelName) 97AST_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)
97AST_END(LabelName, "label_name"sv) 100AST_END(LabelName, "label_name"sv)
98 101
@@ -105,7 +108,7 @@ AST_LEAF(Self)
105AST_END(Self, "self"sv) 108AST_END(Self, "self"sv)
106 109
107AST_NODE(SelfName) 110AST_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)
110AST_END(SelfName, "self_name"sv) 113AST_END(SelfName, "self_name"sv)
111 114
@@ -113,7 +116,7 @@ AST_LEAF(SelfClass)
113AST_END(SelfClass, "self_class"sv) 116AST_END(SelfClass, "self_class"sv)
114 117
115AST_NODE(SelfClassName) 118AST_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)
118AST_END(SelfClassName, "self_class_name"sv) 121AST_END(SelfClassName, "self_class_name"sv)
119 122
@@ -123,7 +126,7 @@ AST_NODE(SelfItem)
123AST_END(SelfItem, "self_item"sv) 126AST_END(SelfItem, "self_item"sv)
124 127
125AST_NODE(KeyName) 128AST_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)
128AST_END(KeyName, "key_name"sv) 131AST_END(KeyName, "key_name"sv)
129 132
@@ -597,12 +600,12 @@ AST_NODE(Metamethod)
597AST_END(Metamethod, "metamethod"sv) 600AST_END(Metamethod, "metamethod"sv)
598 601
599AST_NODE(DotChainItem) 602AST_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)
602AST_END(DotChainItem, "dot_chain_item"sv) 605AST_END(DotChainItem, "dot_chain_item"sv)
603 606
604AST_NODE(ColonChainItem) 607AST_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)
608AST_END(ColonChainItem, "colon_chain_item"sv) 611AST_END(ColonChainItem, "colon_chain_item"sv)
@@ -761,7 +764,7 @@ AST_NODE(FunLit)
761AST_END(FunLit, "fun_lit"sv) 764AST_END(FunLit, "fun_lit"sv)
762 765
763AST_NODE(MacroName) 766AST_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)
766AST_END(MacroName, "macro_name"sv) 769AST_END(MacroName, "macro_name"sv)
767 770
@@ -777,7 +780,7 @@ AST_NODE(MacroInPlace)
777AST_END(MacroInPlace, "macro_in_place"sv) 780AST_END(MacroInPlace, "macro_in_place"sv)
778 781
779AST_NODE(Macro) 782AST_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, &macroLit) 785 AST_MEMBER(Macro, &name, &macroLit)
783AST_END(Macro, "macro"sv) 786AST_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
77const std::string_view version = "0.18.1"sv; 77const std::string_view version = "0.19.1"sv;
78const std::string_view extension = "yue"sv; 78const std::string_view extension = "yue"sv;
79 79
80class CompileError : public std::logic_error { 80class 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);