aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2025-11-21 12:21:04 +0800
committerLi Jin <dragon-fly@qq.com>2025-11-21 12:21:04 +0800
commit43dde2fff316051d03968e8efd313f19b53112fc (patch)
treeae3f99ce6edcd397b75002003048518ee33bae5b /src
parentb462de9d09d4708490161c7c16858bce2c9cb9b6 (diff)
downloadyuescript-main.tar.gz
yuescript-main.tar.bz2
yuescript-main.zip
Updated syntax.HEADv0.29.9main
* Added error check for mixed use of tabs and spaces. * Supported SimpleTable destructuring for ForEach syntax.
Diffstat (limited to 'src')
-rw-r--r--src/yuescript/yue_ast.h2
-rw-r--r--src/yuescript/yue_compiler.cpp26
-rw-r--r--src/yuescript/yue_parser.cpp46
-rw-r--r--src/yuescript/yue_parser.h1
4 files changed, 47 insertions, 28 deletions
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index 0008fd6..5f04fa0 100644
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -848,7 +848,7 @@ AST_NODE(Macro)
848AST_END(Macro) 848AST_END(Macro)
849 849
850AST_NODE(NameOrDestructure) 850AST_NODE(NameOrDestructure)
851 ast_sel<true, Variable_t, TableLit_t, Comprehension_t> item; 851 ast_sel<true, Variable_t, SimpleTable_t, TableLit_t, Comprehension_t> item;
852 AST_MEMBER(NameOrDestructure, &item) 852 AST_MEMBER(NameOrDestructure, &item)
853AST_END(NameOrDestructure) 853AST_END(NameOrDestructure)
854 854
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index d6db3fc..55ab4ec 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -78,7 +78,7 @@ static std::unordered_set<std::string> Metamethods = {
78 "close"s // Lua 5.4 78 "close"s // Lua 5.4
79}; 79};
80 80
81const std::string_view version = "0.29.8"sv; 81const std::string_view version = "0.29.9"sv;
82const std::string_view extension = "yue"sv; 82const std::string_view extension = "yue"sv;
83 83
84class CompileError : public std::logic_error { 84class CompileError : public std::logic_error {
@@ -8427,13 +8427,8 @@ private:
8427 varConstAfter = vars.back(); 8427 varConstAfter = vars.back();
8428 } 8428 }
8429 break; 8429 break;
8430 case id<TableLit_t>(): { 8430 case id<SimpleTable_t>():
8431 auto desVar = getUnusedName("_des_"sv); 8431 case id<TableLit_t>():
8432 destructPairs.emplace_back(item, toAst<Exp_t>(desVar, x));
8433 vars.push_back(desVar);
8434 varAfter.push_back(desVar);
8435 break;
8436 }
8437 case id<Comprehension_t>(): { 8432 case id<Comprehension_t>(): {
8438 auto desVar = getUnusedName("_des_"sv); 8433 auto desVar = getUnusedName("_des_"sv);
8439 destructPairs.emplace_back(item, toAst<Exp_t>(desVar, x)); 8434 destructPairs.emplace_back(item, toAst<Exp_t>(desVar, x));
@@ -8642,11 +8637,18 @@ private:
8642 if (!destructPairs.empty()) { 8637 if (!destructPairs.empty()) {
8643 temp.clear(); 8638 temp.clear();
8644 for (auto& pair : destructPairs) { 8639 for (auto& pair : destructPairs) {
8645 auto sValue = x->new_ptr<SimpleValue_t>();
8646 sValue->value.set(pair.first);
8647 auto exp = newExp(sValue, x);
8648 auto expList = x->new_ptr<ExpList_t>(); 8640 auto expList = x->new_ptr<ExpList_t>();
8649 expList->exprs.push_back(exp); 8641 if (ast_is<SimpleTable_t>(pair.first)) {
8642 auto value = x->new_ptr<Value_t>();
8643 value->item.set(pair.first);
8644 auto exp = newExp(value, x);
8645 expList->exprs.push_back(exp);
8646 } else {
8647 auto sValue = x->new_ptr<SimpleValue_t>();
8648 sValue->value.set(pair.first);
8649 auto exp = newExp(sValue, x);
8650 expList->exprs.push_back(exp);
8651 }
8650 auto assign = x->new_ptr<Assign_t>(); 8652 auto assign = x->new_ptr<Assign_t>();
8651 assign->values.push_back(pair.second); 8653 assign->values.push_back(pair.second);
8652 auto assignment = x->new_ptr<ExpListAssign_t>(); 8654 auto assignment = x->new_ptr<ExpListAssign_t>();
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index fccb6fb..cbba115 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -232,27 +232,43 @@ YueParser::YueParser() {
232 KeyName = SelfItem | Name | UnicodeName; 232 KeyName = SelfItem | Name | UnicodeName;
233 VarArg = "..."; 233 VarArg = "...";
234 234
235 check_indent = pl::user(plain_space, [](const item_t& item) { 235 auto getIndent = [](const item_t& item) -> int {
236 if (item.begin->m_it == item.end->m_it) return 0;
237 State* st = reinterpret_cast<State*>(item.user_data);
238 bool useTab = false;
239 if (st->useTab) {
240 useTab = st->useTab.value();
241 } else {
242 useTab = *item.begin->m_it == '\t';
243 st->useTab = useTab;
244 }
236 int indent = 0; 245 int indent = 0;
237 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { 246 if (useTab) {
238 switch (*i) { 247 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
239 case ' ': indent++; break; 248 switch (*i) {
240 case '\t': indent += 4; break; 249 case '\t': indent += 4; break;
250 default: throw ParserError("can not mix the use of tabs and spaces as indents"sv, item.begin); break;
251 }
252 }
253 } else {
254 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
255 switch (*i) {
256 case ' ': indent++; break;
257 default: throw ParserError("can not mix the use of tabs and spaces as indents"sv, item.begin); break;
258 }
241 } 259 }
242 } 260 }
261 return indent;
262 };
263
264 check_indent = pl::user(plain_space, [getIndent](const item_t& item) {
243 State* st = reinterpret_cast<State*>(item.user_data); 265 State* st = reinterpret_cast<State*>(item.user_data);
244 return st->indents.top() == indent; 266 return st->indents.top() == getIndent(item);
245 }); 267 });
246 check_indent_match = and_(check_indent); 268 check_indent_match = and_(check_indent);
247 269
248 advance = pl::user(plain_space, [](const item_t& item) { 270 advance = pl::user(plain_space, [getIndent](const item_t& item) {
249 int indent = 0; 271 int indent = getIndent(item);
250 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
251 switch (*i) {
252 case ' ': indent++; break;
253 case '\t': indent += 4; break;
254 }
255 }
256 State* st = reinterpret_cast<State*>(item.user_data); 272 State* st = reinterpret_cast<State*>(item.user_data);
257 int top = st->indents.top(); 273 int top = st->indents.top();
258 if (top != -1 && indent > top) { 274 if (top != -1 && indent > top) {
@@ -921,7 +937,7 @@ YueParser::YueParser() {
921 MacroInPlace = '$' >> space >> "->" >> space >> Body; 937 MacroInPlace = '$' >> space >> "->" >> space >> Body;
922 938
923 NameList = Seperator >> Variable >> *(space >> ',' >> space >> Variable); 939 NameList = Seperator >> Variable >> *(space >> ',' >> space >> Variable);
924 NameOrDestructure = Variable | TableLit | Comprehension; 940 NameOrDestructure = Variable | TableLit | Comprehension | SimpleTable;
925 AssignableNameList = Seperator >> NameOrDestructure >> *(space >> ',' >> space >> NameOrDestructure); 941 AssignableNameList = Seperator >> NameOrDestructure >> *(space >> ',' >> space >> NameOrDestructure);
926 942
927 FnArrowBack = '<' >> set("-="); 943 FnArrowBack = '<' >> set("-=");
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index 4c546b1..d5c37e2 100644
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -119,6 +119,7 @@ protected:
119 int expLevel = 0; 119 int expLevel = 0;
120 size_t stringOpen = 0; 120 size_t stringOpen = 0;
121 std::string buffer; 121 std::string buffer;
122 std::optional<bool> useTab;
122 std::stack<int> indents; 123 std::stack<int> indents;
123 std::vector<bool> noDoStack; 124 std::vector<bool> noDoStack;
124 std::vector<bool> noChainBlockStack; 125 std::vector<bool> noChainBlockStack;