diff options
author | Li Jin <dragon-fly@qq.com> | 2025-05-21 15:42:03 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2025-05-21 15:42:03 +0800 |
commit | d4b7efe3f48b40d108754d2e8359fee1cd9dded8 (patch) | |
tree | 2ec4133a47b947ec78d12076f981aa38d3b569c6 /src | |
parent | 0603800a4114ed8b4c9572a7d7852995c9b9f334 (diff) | |
download | yuescript-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.cpp | 9 | ||||
-rw-r--r-- | src/yuescript/yue_ast.h | 3 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 58 | ||||
-rw-r--r-- | src/yuescript/yue_parser.cpp | 2 |
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 { | |||
170 | std::string PlainItem_t::to_string(void *) const { | 170 | std::string PlainItem_t::to_string(void *) const { |
171 | return {}; | 171 | return {}; |
172 | } | 172 | } |
173 | std::string GlobalOp_t::to_string(void* ud) const { | 173 | std::string GlobalOp_t::to_string(void*) const { |
174 | auto info = reinterpret_cast<YueFormat*>(ud); | 174 | return "*"s; |
175 | return info->convert(this); | ||
176 | } | 175 | } |
177 | std::string ExportDefault_t::to_string(void*) const { | 176 | std::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 | } |
1135 | std::string GlobalValues_t::to_string(void* ud) const { | 1134 | std::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 | } |
1146 | std::string Global_t::to_string(void* ud) const { | 1145 | std::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 | } |
1149 | std::string Export_t::to_string(void* ud) const { | 1148 | std::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) | |||
727 | AST_END(GlobalOp) | 727 | AST_END(GlobalOp) |
728 | 728 | ||
729 | AST_NODE(Global) | 729 | AST_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) |
732 | AST_END(Global) | 733 | AST_END(Global) |
733 | 734 | ||
734 | AST_LEAF(ExportDefault) | 735 | AST_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 | ||