From 066aaa11b58365ffa39cfb0b63e6d1b03a7274b1 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Mon, 25 Sep 2023 11:50:46 +0800 Subject: added `from import` for issue #149. --- src/yuescript/yue_ast.cpp | 10 ++++++++++ src/yuescript/yue_ast.h | 9 ++++++++- src/yuescript/yue_compiler.cpp | 32 +++++++++++++++++++++----------- src/yuescript/yue_parser.cpp | 3 ++- src/yuescript/yue_parser.h | 1 + 5 files changed, 42 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index 39f19ea..ed34274 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp @@ -271,6 +271,13 @@ std::string ImportFrom_t::to_string(void* ud) const { } return join(temp, ", "sv) + " from "s + item->to_string(ud); } +std::string FromImport_t::to_string(void* ud) const { + str_list temp; + for (auto name : names.objects()) { + temp.emplace_back(name->to_string(ud)); + } + return "from "s + item->to_string(ud) + " import "s + join(temp, ", "sv); +} std::string MacroNamePair_t::to_string(void* ud) const { return key->to_string(ud) + ": "s + value->to_string(ud); } @@ -294,6 +301,9 @@ std::string ImportAs_t::to_string(void* ud) const { return join(temp, " "s); } std::string Import_t::to_string(void* ud) const { + if (ast_is(content)) { + return content->to_string(ud); + } return "import "s + content->to_string(ud); } std::string Label_t::to_string(void* ud) const { diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 78f6c9f..a02f548 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h @@ -195,6 +195,13 @@ AST_NODE(ImportFrom) AST_MEMBER(ImportFrom, &sep, &names, &item) AST_END(ImportFrom, "import_from"sv) +AST_NODE(FromImport) + ast_sel item; + ast_ptr sep; + ast_sel_list names; + AST_MEMBER(FromImport, &item, &sep, &names) +AST_END(FromImport, "from_import"sv) + AST_NODE(MacroNamePair) ast_ptr key; ast_ptr value; @@ -217,7 +224,7 @@ AST_NODE(ImportAs) AST_END(ImportAs, "import_as"sv) AST_NODE(Import) - ast_sel content; + ast_sel content; AST_MEMBER(Import, &content) AST_END(Import, "import"sv) diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 3c11429..b81764f 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -74,7 +74,7 @@ static std::unordered_set Metamethods = { "close"s // Lua 5.4 }; -const std::string_view version = "0.19.3"sv; +const std::string_view version = "0.19.4"sv; const std::string_view extension = "yue"sv; class CompileError : public std::logic_error { @@ -8372,19 +8372,19 @@ private: } } - void transformImportFrom(ImportFrom_t* import, str_list& out) { + void transformImportFrom(ImportFrom_t* importNode, str_list& out) { str_list temp; - auto x = import; - auto objVar = singleVariableFrom(import->item, true); + auto x = importNode; + auto objVar = singleVariableFrom(importNode->item, true); ast_ptr objAssign; if (objVar.empty()) { objVar = getUnusedName("_obj_"sv); auto expList = toAst(objVar, x); auto assign = x->new_ptr(); - if (import->item.is()) { - assign->values.push_back(import->item); + if (importNode->item.is()) { + assign->values.push_back(importNode->item); } else { - auto exp = toAst("require "s + _parser.toString(import->item.to()), import->item); + auto exp = toAst("require "s + _parser.toString(importNode->item.to()), importNode->item); assign->values.push_back(exp); } auto assignment = x->new_ptr(); @@ -8394,7 +8394,7 @@ private: } auto expList = x->new_ptr(); auto assign = x->new_ptr(); - for (auto name : import->names.objects()) { + for (auto name : importNode->names.objects()) { switch (name->get_id()) { case id(): { auto var = static_cast(name); @@ -8443,9 +8443,9 @@ private: if (objAssign) { auto preDef = toLocalDecl(transformAssignDefs(expList, DefOp::Mark)); if (!preDef.empty()) { - temp.push_back(preDef + nll(import)); + temp.push_back(preDef + nll(importNode)); } - temp.push_back(indent() + "do"s + nll(import)); + temp.push_back(indent() + "do"s + nll(importNode)); pushScope(); transformAssignment(objAssign, temp); } @@ -8455,7 +8455,7 @@ private: transformAssignment(assignment, temp); if (objAssign) { popScope(); - temp.push_back(indent() + "end"s + nlr(import)); + temp.push_back(indent() + "end"s + nlr(importNode)); } out.push_back(join(temp)); auto vars = getAssignVars(assignment); @@ -8464,6 +8464,13 @@ private: } } + void transformFromImport(FromImport_t* importNode, str_list& out) { + auto importFrom = importNode->new_ptr(); + importFrom->names.dup(importNode->names); + importFrom->item.set(importNode->item); + transformImportFrom(importFrom, out); + } + std::string moduleNameFrom(ImportLiteral_t* literal) { auto name = _parser.toString(literal->inners.back()); Utils::replace(name, "-"sv, "_"sv); @@ -8679,6 +8686,9 @@ private: case id(): transformImportFrom(static_cast(content), out); break; + case id(): + transformFromImport(static_cast(content), out); + break; default: YUEE("AST node mismatch", content); break; } } diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 6ba9b13..5d2b4c9 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp @@ -286,6 +286,7 @@ YueParser::YueParser() { import_name = ColonImportName | Variable; import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name); ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> (ImportLiteral | not_(String) >> Exp); + FromImport = key("from") >> space >> (ImportLiteral | not_(String) >> Exp) >> *space_break >> space >> key("import") >> space >> import_name_list; ImportLiteralInner = (range('a', 'z') | range('A', 'Z') | set("_-") | larger(255)) >> *(alpha_num | '-' | larger(255)); import_literal_chain = Seperator >> ImportLiteralInner >> *('.' >> ImportLiteralInner); @@ -324,7 +325,7 @@ YueParser::YueParser() { ImportAs = ImportLiteral >> -(space >> key("as") >> space >> (ImportTabLit | Variable | ImportAllMacro)); - Import = key("import") >> space >> (ImportAs | ImportFrom); + Import = key("import") >> space >> (ImportAs | ImportFrom) | FromImport; Label = "::" >> LabelName >> "::"; diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 72d966d..874bbc8 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h @@ -277,6 +277,7 @@ private: AST_RULE(ImportLiteralInner); AST_RULE(ImportLiteral); AST_RULE(ImportFrom); + AST_RULE(FromImport); AST_RULE(MacroNamePair); AST_RULE(ImportAllMacro); AST_RULE(ImportTabLit); -- cgit v1.2.3-55-g6feb