diff options
| -rwxr-xr-x | doc/docs/doc/README.md | 11 | ||||
| -rwxr-xr-x | doc/docs/zh/doc/README.md | 11 | ||||
| -rw-r--r-- | spec/inputs/global.yue | 5 | ||||
| -rw-r--r-- | spec/outputs/global.lua | 25 | ||||
| -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 |
8 files changed, 98 insertions, 26 deletions
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/README.md index dac96ee..1142fc3 100755 --- a/doc/docs/doc/README.md +++ b/doc/docs/doc/README.md | |||
| @@ -1513,6 +1513,17 @@ const {:a, :b, c, d} = tb | |||
| 1513 | </pre> | 1513 | </pre> |
| 1514 | </YueDisplay> | 1514 | </YueDisplay> |
| 1515 | 1515 | ||
| 1516 | You can also declare a global variable to be `const`. | ||
| 1517 | |||
| 1518 | ```moonscript | ||
| 1519 | global const Constant = 123 | ||
| 1520 | ``` | ||
| 1521 | <YueDisplay> | ||
| 1522 | <pre> | ||
| 1523 | global const Constant = 123 | ||
| 1524 | </pre> | ||
| 1525 | </YueDisplay> | ||
| 1526 | |||
| 1516 | ## Literals | 1527 | ## Literals |
| 1517 | 1528 | ||
| 1518 | All of the primitive literals in Lua can be used. This applies to numbers, strings, booleans, and **nil**. | 1529 | All of the primitive literals in Lua can be used. This applies to numbers, strings, booleans, and **nil**. |
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md index 850afed..a4e76bb 100755 --- a/doc/docs/zh/doc/README.md +++ b/doc/docs/zh/doc/README.md | |||
| @@ -1512,6 +1512,17 @@ const {:a, :b, c, d} = tb | |||
| 1512 | </pre> | 1512 | </pre> |
| 1513 | </YueDisplay> | 1513 | </YueDisplay> |
| 1514 | 1514 | ||
| 1515 | 你也可以声明全局变量为常量。 | ||
| 1516 | |||
| 1517 | ```moonscript | ||
| 1518 | global const Constant = 123 | ||
| 1519 | ``` | ||
| 1520 | <YueDisplay> | ||
| 1521 | <pre> | ||
| 1522 | global const Constant = 123 | ||
| 1523 | </pre> | ||
| 1524 | </YueDisplay> | ||
| 1525 | |||
| 1515 | ## 字面量 | 1526 | ## 字面量 |
| 1516 | 1527 | ||
| 1517 | Lua中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和**nil**。 | 1528 | Lua中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和**nil**。 |
diff --git a/spec/inputs/global.yue b/spec/inputs/global.yue index ce1cc15..8316d16 100644 --- a/spec/inputs/global.yue +++ b/spec/inputs/global.yue | |||
| @@ -82,3 +82,8 @@ do | |||
| 82 | FooBar = "pascal case" | 82 | FooBar = "pascal case" |
| 83 | FOOBAR = "all uppercase" | 83 | FOOBAR = "all uppercase" |
| 84 | 84 | ||
| 85 | do | ||
| 86 | global const class A | ||
| 87 | global const Flag = 1 | ||
| 88 | global const const, x, y = "const", 1, 2 | ||
| 89 | |||
diff --git a/spec/outputs/global.lua b/spec/outputs/global.lua index 54a21a9..3918f85 100644 --- a/spec/outputs/global.lua +++ b/spec/outputs/global.lua | |||
| @@ -93,3 +93,28 @@ do | |||
| 93 | FooBar = "pascal case" | 93 | FooBar = "pascal case" |
| 94 | FOOBAR = "all uppercase" | 94 | FOOBAR = "all uppercase" |
| 95 | end | 95 | end |
| 96 | do | ||
| 97 | do | ||
| 98 | local _class_0 | ||
| 99 | local _base_0 = { } | ||
| 100 | if _base_0.__index == nil then | ||
| 101 | _base_0.__index = _base_0 | ||
| 102 | end | ||
| 103 | _class_0 = setmetatable({ | ||
| 104 | __init = function() end, | ||
| 105 | __base = _base_0, | ||
| 106 | __name = "A" | ||
| 107 | }, { | ||
| 108 | __index = _base_0, | ||
| 109 | __call = function(cls, ...) | ||
| 110 | local _self_0 = setmetatable({ }, _base_0) | ||
| 111 | cls.__init(_self_0, ...) | ||
| 112 | return _self_0 | ||
| 113 | end | ||
| 114 | }) | ||
| 115 | _base_0.__class = _class_0 | ||
| 116 | A = _class_0 | ||
| 117 | end | ||
| 118 | Flag = 1 | ||
| 119 | const, x, y = "const", 1, 2 | ||
| 120 | end | ||
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 | ||
