From a19b242cbaf53721b20a3163dd06f43e9ef2b487 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Mon, 11 Oct 2021 10:59:55 +0800 Subject: fix issue #68. --- src/yuescript/yue_ast.h | 3 ++- src/yuescript/yue_compiler.cpp | 16 +++++++++++++--- src/yuescript/yue_parser.cpp | 3 ++- 3 files changed, 17 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 6c9953c..38da1fa 100755 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h @@ -623,8 +623,9 @@ AST_END(ClassBlock) AST_NODE(ClassDecl) ast_ptr name; ast_ptr extend; + ast_ptr mixes; ast_ptr body; - AST_MEMBER(ClassDecl, &name, &extend, &body) + AST_MEMBER(ClassDecl, &name, &extend, &mixes, &body) AST_END(ClassDecl) AST_NODE(global_values) diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 71efa3c..3ff032c 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -60,7 +60,7 @@ using namespace parserlib; typedef std::list str_list; -const std::string_view version = "0.8.3"sv; +const std::string_view version = "0.8.4"sv; const std::string_view extension = "yue"sv; class YueCompilerImpl { @@ -5039,6 +5039,16 @@ private: } else { temp.back() += "{ }"s + nll(classDecl); } + if (classDecl->mixes) { + auto mixin = getUnusedName("_mixin_"); + auto key = getUnusedName("_key_"); + auto val = getUnusedName("_val_"); + auto mixins = _parser.toString(classDecl->mixes); + _buf << "for "sv << mixin << " in *{"sv << mixins << "}\n"sv; + _buf << "\tfor "sv << key << ',' << val << " in pairs "sv << mixin << ".__base\n"sv; + _buf << "\t\t"sv << baseVar << '[' << key << "]="sv << val << " if not "sv << key << "\\match\"^__\""sv; + transformBlock(toAst(clearBuf(), x), temp, ExpUsage::Common); + } temp.push_back(indent() + baseVar + ".__index = "s + baseVar + nll(classDecl)); str_list tmp; if (usage == ExpUsage::Assignment) { @@ -5052,9 +5062,9 @@ private: if (extend) { _buf << indent() << "setmetatable("sv << baseVar << ", "sv << parentVar << ".__base)"sv << nll(classDecl); } - _buf << indent() << classVar << " = " << globalVar("setmetatable"sv, classDecl) << "({"sv << nll(classDecl); + _buf << indent() << classVar << " = "sv << globalVar("setmetatable"sv, classDecl) << "({"sv << nll(classDecl); if (!builtins.empty()) { - _buf << join(builtins) << ","sv << nll(classDecl); + _buf << join(builtins) << ',' << nll(classDecl); } else { if (extend) { _buf << indent(1) << "__init = function(self, ...)"sv << nll(classDecl); diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 0b7f79e..6ecd369 100755 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp @@ -492,7 +492,8 @@ YueParser::YueParser() { ClassDecl = key("class") >> not_(expr(':')) >> -Assignable >> - -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >> + -(key("extends") >> PreventIndent >> ensure(Exp, PopIndent)) >> + -(key("using") >> PreventIndent >> ensure(ExpList, PopIndent)) >> -ClassBlock; global_values = NameList >> -(sym('=') >> (TableBlock | ExpListLow)); -- cgit v1.2.3-55-g6feb