aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2025-05-21 15:42:03 +0800
committerLi Jin <dragon-fly@qq.com>2025-05-21 15:42:03 +0800
commitd4b7efe3f48b40d108754d2e8359fee1cd9dded8 (patch)
tree2ec4133a47b947ec78d12076f981aa38d3b569c6 /src
parent0603800a4114ed8b4c9572a7d7852995c9b9f334 (diff)
downloadyuescript-d4b7efe3f48b40d108754d2e8359fee1cd9dded8.tar.gz
yuescript-d4b7efe3f48b40d108754d2e8359fee1cd9dded8.tar.bz2
yuescript-d4b7efe3f48b40d108754d2e8359fee1cd9dded8.zip
Added global const declaration.
Diffstat (limited to 'src')
-rw-r--r--src/yuescript/yue_ast.cpp9
-rw-r--r--src/yuescript/yue_ast.h3
-rw-r--r--src/yuescript/yue_compiler.cpp58
-rw-r--r--src/yuescript/yue_parser.cpp2
4 files changed, 46 insertions, 26 deletions
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp
index 612bdcd..56e3447 100644
--- a/src/yuescript/yue_ast.cpp
+++ b/src/yuescript/yue_ast.cpp
@@ -170,9 +170,8 @@ std::string TableAppendingOp_t::to_string(void*) const {
170std::string PlainItem_t::to_string(void *) const { 170std::string PlainItem_t::to_string(void *) const {
171 return {}; 171 return {};
172} 172}
173std::string GlobalOp_t::to_string(void* ud) const { 173std::string GlobalOp_t::to_string(void*) const {
174 auto info = reinterpret_cast<YueFormat*>(ud); 174 return "*"s;
175 return info->convert(this);
176} 175}
177std::string ExportDefault_t::to_string(void*) const { 176std::string ExportDefault_t::to_string(void*) const {
178 return "default"s; 177 return "default"s;
@@ -1133,7 +1132,7 @@ std::string ClassDecl_t::to_string(void* ud) const {
1133 return line; 1132 return line;
1134} 1133}
1135std::string GlobalValues_t::to_string(void* ud) const { 1134std::string GlobalValues_t::to_string(void* ud) const {
1136 auto line = nameList->to_string(ud); 1135 std::string line = nameList->to_string(ud);
1137 if (valueList) { 1136 if (valueList) {
1138 if (valueList.is<TableBlock_t>()) { 1137 if (valueList.is<TableBlock_t>()) {
1139 line += " =\n"s + valueList->to_string(ud); 1138 line += " =\n"s + valueList->to_string(ud);
@@ -1144,7 +1143,7 @@ std::string GlobalValues_t::to_string(void* ud) const {
1144 return line; 1143 return line;
1145} 1144}
1146std::string Global_t::to_string(void* ud) const { 1145std::string Global_t::to_string(void* ud) const {
1147 return "global "s + item->to_string(ud); 1146 return "global "s + (constAttrib ? "const "s : ""s) + item->to_string(ud);
1148} 1147}
1149std::string Export_t::to_string(void* ud) const { 1148std::string Export_t::to_string(void* ud) const {
1150 auto line = "export"s; 1149 auto line = "export"s;
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h
index 782db5a..8501a19 100644
--- a/src/yuescript/yue_ast.h
+++ b/src/yuescript/yue_ast.h
@@ -727,8 +727,9 @@ AST_LEAF(GlobalOp)
727AST_END(GlobalOp) 727AST_END(GlobalOp)
728 728
729AST_NODE(Global) 729AST_NODE(Global)
730 ast_ptr<false, ConstAttrib_t> constAttrib;
730 ast_sel<true, ClassDecl_t, GlobalOp_t, GlobalValues_t> item; 731 ast_sel<true, ClassDecl_t, GlobalOp_t, GlobalValues_t> item;
731 AST_MEMBER(Global, &item) 732 AST_MEMBER(Global, &constAttrib, &item)
732AST_END(Global) 733AST_END(Global)
733 734
734AST_LEAF(ExportDefault) 735AST_LEAF(ExportDefault)
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index 1a9387b..452ffbd 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -429,8 +429,9 @@ private:
429 }; 429 };
430 enum class VarType { 430 enum class VarType {
431 Local = 0, 431 Local = 0,
432 Const = 1, 432 LocalConst = 1,
433 Global = 2 433 Global = 2,
434 GlobalConst = 3
434 }; 435 };
435 struct Scope { 436 struct Scope {
436 GlobalMode mode = GlobalMode::None; 437 GlobalMode mode = GlobalMode::None;
@@ -558,7 +559,7 @@ private:
558 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { 559 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
559 auto vars = it->vars.get(); 560 auto vars = it->vars.get();
560 auto vit = vars->find(name); 561 auto vit = vars->find(name);
561 if (vit != vars->end() && vit->second != VarType::Global) { 562 if (vit != vars->end() && (vit->second == VarType::Local || vit->second == VarType::LocalConst)) {
562 local = true; 563 local = true;
563 break; 564 break;
564 } 565 }
@@ -571,7 +572,7 @@ private:
571 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) { 572 for (auto it = _scopes.rbegin(); it != _scopes.rend(); ++it) {
572 auto vars = it->vars.get(); 573 auto vars = it->vars.get();
573 auto vit = vars->find(name); 574 auto vit = vars->find(name);
574 if (vit != vars->end() && vit->second == VarType::Global) { 575 if (vit != vars->end() && (vit->second == VarType::Global || vit->second == VarType::GlobalConst)) {
575 global = true; 576 global = true;
576 break; 577 break;
577 } 578 }
@@ -593,7 +594,7 @@ private:
593 auto vars = it->vars.get(); 594 auto vars = it->vars.get();
594 auto vit = vars->find(name); 595 auto vit = vars->find(name);
595 if (vit != vars->end()) { 596 if (vit != vars->end()) {
596 isConst = (vit->second == VarType::Const); 597 isConst = (vit->second == VarType::LocalConst || vit->second == VarType::GlobalConst);
597 break; 598 break;
598 } 599 }
599 if (checkShadowScopeOnly && it->allows) break; 600 if (checkShadowScopeOnly && it->allows) break;
@@ -874,9 +875,9 @@ private:
874 return false; 875 return false;
875 } 876 }
876 877
877 void markVarConst(const std::string& name) { 878 void markVarLocalConst(const std::string& name) {
878 auto& scope = _scopes.back(); 879 auto& scope = _scopes.back();
879 scope.vars->insert_or_assign(name, VarType::Const); 880 scope.vars->insert_or_assign(name, VarType::LocalConst);
880 } 881 }
881 882
882 void markVarShadowed() { 883 void markVarShadowed() {
@@ -895,6 +896,11 @@ private:
895 scope.vars->insert_or_assign(name, VarType::Global); 896 scope.vars->insert_or_assign(name, VarType::Global);
896 } 897 }
897 898
899 void markVarGlobalConst(const std::string& name) {
900 auto& scope = _scopes.back();
901 scope.vars->insert_or_assign(name, VarType::GlobalConst);
902 }
903
898 void addToAllowList(const std::string& name) { 904 void addToAllowList(const std::string& name) {
899 auto& scope = _scopes.back(); 905 auto& scope = _scopes.back();
900 scope.allows->insert(name); 906 scope.allows->insert(name);
@@ -2051,7 +2057,7 @@ private:
2051 if (item.targetVar.empty()) { 2057 if (item.targetVar.empty()) {
2052 throw CompileError("can only declare variable as const"sv, item.target); 2058 throw CompileError("can only declare variable as const"sv, item.target);
2053 } 2059 }
2054 markVarConst(item.targetVar); 2060 markVarLocalConst(item.targetVar);
2055 } 2061 }
2056 } 2062 }
2057 } 2063 }
@@ -8064,7 +8070,7 @@ private:
8064 pushScope(); 8070 pushScope();
8065 for (const auto& var : vars) forceAddToScope(var); 8071 for (const auto& var : vars) forceAddToScope(var);
8066 for (const auto& var : varAfter) addToScope(var); 8072 for (const auto& var : varAfter) addToScope(var);
8067 if (!varConstAfter.empty()) markVarConst(varConstAfter); 8073 if (!varConstAfter.empty()) markVarLocalConst(varConstAfter);
8068 if (!destructPairs.empty()) { 8074 if (!destructPairs.empty()) {
8069 temp.clear(); 8075 temp.clear();
8070 for (auto& pair : destructPairs) { 8076 for (auto& pair : destructPairs) {
@@ -8149,7 +8155,7 @@ private:
8149 _buf << indent() << "for "sv << varName << " = "sv << start << ", "sv << stop << (step.empty() ? Empty : ", "s + step) << " do"sv << nll(var); 8155 _buf << indent() << "for "sv << varName << " = "sv << start << ", "sv << stop << (step.empty() ? Empty : ", "s + step) << " do"sv << nll(var);
8150 pushScope(); 8156 pushScope();
8151 forceAddToScope(varName); 8157 forceAddToScope(varName);
8152 markVarConst(varName); 8158 markVarLocalConst(varName);
8153 out.push_back(clearBuf()); 8159 out.push_back(clearBuf());
8154 } 8160 }
8155 8161
@@ -8923,7 +8929,7 @@ private:
8923 auto names = transformAssignDefs(assignment->expList.get(), DefOp::Get); 8929 auto names = transformAssignDefs(assignment->expList.get(), DefOp::Get);
8924 for (const auto& name : names) { 8930 for (const auto& name : names) {
8925 forceAddToScope(name.first); 8931 forceAddToScope(name.first);
8926 markVarConst(name.first); 8932 markVarLocalConst(name.first);
8927 varDefs.push_back(name.first); 8933 varDefs.push_back(name.first);
8928 classConstVars.push_back(name.first); 8934 classConstVars.push_back(name.first);
8929 } 8935 }
@@ -8937,7 +8943,7 @@ private:
8937 for (const auto& item : destruct.items) { 8943 for (const auto& item : destruct.items) {
8938 if (!item.targetVar.empty()) { 8944 if (!item.targetVar.empty()) {
8939 forceAddToScope(item.targetVar); 8945 forceAddToScope(item.targetVar);
8940 markVarConst(item.targetVar); 8946 markVarLocalConst(item.targetVar);
8941 varDefs.push_back(item.targetVar); 8947 varDefs.push_back(item.targetVar);
8942 classConstVars.push_back(item.targetVar); 8948 classConstVars.push_back(item.targetVar);
8943 } 8949 }
@@ -9511,12 +9517,18 @@ private:
9511 switch (item->get_id()) { 9517 switch (item->get_id()) {
9512 case id<ClassDecl_t>(): { 9518 case id<ClassDecl_t>(): {
9513 auto classDecl = static_cast<ClassDecl_t*>(item); 9519 auto classDecl = static_cast<ClassDecl_t*>(item);
9520 std::string varName;
9514 if (classDecl->name) { 9521 if (classDecl->name) {
9515 if (auto var = classDecl->name->item.as<Variable_t>()) { 9522 if (auto var = classDecl->name->item.as<Variable_t>()) {
9516 addGlobalVar(variableToString(var), classDecl->name->item); 9523 varName = variableToString(var);
9524 addGlobalVar(varName, var);
9517 } 9525 }
9518 } 9526 }
9527 if (varName.empty()) {
9528 throw CompileError("missing name for class", classDecl);
9529 }
9519 transformClassDecl(classDecl, out, ExpUsage::Common); 9530 transformClassDecl(classDecl, out, ExpUsage::Common);
9531 markVarGlobalConst(varName);
9520 break; 9532 break;
9521 } 9533 }
9522 case id<GlobalOp_t>(): 9534 case id<GlobalOp_t>():
@@ -9530,9 +9542,11 @@ private:
9530 auto values = global->item.to<GlobalValues_t>(); 9542 auto values = global->item.to<GlobalValues_t>();
9531 if (values->valueList) { 9543 if (values->valueList) {
9532 auto expList = x->new_ptr<ExpList_t>(); 9544 auto expList = x->new_ptr<ExpList_t>();
9545 str_list varNames;
9533 for (auto name : values->nameList->names.objects()) { 9546 for (auto name : values->nameList->names.objects()) {
9534 auto var = static_cast<Variable_t*>(name); 9547 auto var = static_cast<Variable_t*>(name);
9535 addGlobalVar(variableToString(var), var); 9548 varNames.emplace_back(variableToString(var));
9549 addGlobalVar(varNames.back(), var);
9536 auto callable = x->new_ptr<Callable_t>(); 9550 auto callable = x->new_ptr<Callable_t>();
9537 callable->item.set(name); 9551 callable->item.set(name);
9538 auto chainValue = x->new_ptr<ChainValue_t>(); 9552 auto chainValue = x->new_ptr<ChainValue_t>();
@@ -9551,7 +9565,13 @@ private:
9551 } 9565 }
9552 assignment->action.set(assign); 9566 assignment->action.set(assign);
9553 transformAssignment(assignment, out); 9567 transformAssignment(assignment, out);
9568 for (const auto& name : varNames) {
9569 markVarGlobalConst(name);
9570 }
9554 } else { 9571 } else {
9572 if (global->constAttrib) {
9573 throw CompileError("missing initial value for global const", global->constAttrib);
9574 }
9555 for (auto name : values->nameList->names.objects()) { 9575 for (auto name : values->nameList->names.objects()) {
9556 auto var = static_cast<Variable_t*>(name); 9576 auto var = static_cast<Variable_t*>(name);
9557 addGlobalVar(variableToString(var), var); 9577 addGlobalVar(variableToString(var), var);
@@ -10216,7 +10236,7 @@ private:
10216 out.push_back(join(temp)); 10236 out.push_back(join(temp));
10217 auto vars = getAssignVars(assignment); 10237 auto vars = getAssignVars(assignment);
10218 for (const auto& var : vars) { 10238 for (const auto& var : vars) {
10219 markVarConst(var); 10239 markVarLocalConst(var);
10220 } 10240 }
10221 } 10241 }
10222 10242
@@ -10444,7 +10464,7 @@ private:
10444 transformAssignment(assignment, out); 10464 transformAssignment(assignment, out);
10445 if (auto var = ast_cast<Variable_t>(target)) { 10465 if (auto var = ast_cast<Variable_t>(target)) {
10446 auto moduleName = variableToString(var); 10466 auto moduleName = variableToString(var);
10447 markVarConst(moduleName); 10467 markVarLocalConst(moduleName);
10448 } else { 10468 } else {
10449 markDestructureConst(assignment); 10469 markDestructureConst(assignment);
10450 } 10470 }
@@ -11028,7 +11048,7 @@ private:
11028 } 11048 }
11029 transformAssignment(assignment, temp); 11049 transformAssignment(assignment, temp);
11030 for (const auto& name : vars) { 11050 for (const auto& name : vars) {
11031 markVarConst(name); 11051 markVarLocalConst(name);
11032 } 11052 }
11033 if (localAttrib->attrib.is<CloseAttrib_t>()) { 11053 if (localAttrib->attrib.is<CloseAttrib_t>()) {
11034 str_list leftVars, rightVars; 11054 str_list leftVars, rightVars;
@@ -11100,7 +11120,7 @@ private:
11100 temp.push_back(indent() + "local "s + join(leftVars, ", "sv) + " = "s + join(items, ", "sv) + nll(x)); 11120 temp.push_back(indent() + "local "s + join(leftVars, ", "sv) + " = "s + join(items, ", "sv) + nll(x));
11101 } 11121 }
11102 for (const auto& var : vars) { 11122 for (const auto& var : vars) {
11103 markVarConst(var); 11123 markVarLocalConst(var);
11104 } 11124 }
11105 } 11125 }
11106 if (!listB->exprs.empty()) { 11126 if (!listB->exprs.empty()) {
@@ -11125,7 +11145,7 @@ private:
11125 temp.push_back(indent() + "local "s + join(vars, ", "sv) + nll(x)); 11145 temp.push_back(indent() + "local "s + join(vars, ", "sv) + nll(x));
11126 transformAssignment(assignment, temp); 11146 transformAssignment(assignment, temp);
11127 for (const auto& name : vars) { 11147 for (const auto& name : vars) {
11128 markVarConst(name); 11148 markVarLocalConst(name);
11129 } 11149 }
11130 } 11150 }
11131 out.push_back(join(temp)); 11151 out.push_back(join(temp));
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index eaabf0d..045e2c7 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -761,7 +761,7 @@ YueParser::YueParser() {
761 761
762 GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow)); 762 GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow));
763 GlobalOp = expr('*') | '^'; 763 GlobalOp = expr('*') | '^';
764 Global = key("global") >> space >> (ClassDecl | GlobalOp | GlobalValues); 764 Global = key("global") >> space >> (-(ConstAttrib >> space) >> ClassDecl | GlobalOp | -(ConstAttrib >> space) >> GlobalValues);
765 765
766 ExportDefault = key("default"); 766 ExportDefault = key("default");
767 767