diff options
author | Li Jin <dragon-fly@qq.com> | 2023-09-25 11:50:46 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2023-09-25 11:50:46 +0800 |
commit | 066aaa11b58365ffa39cfb0b63e6d1b03a7274b1 (patch) | |
tree | c162048859aae47577953dcee390dd4af3de8796 | |
parent | cf2e784581df4d24b03b85f0ac02514a166150b6 (diff) | |
download | yuescript-066aaa11b58365ffa39cfb0b63e6d1b03a7274b1.tar.gz yuescript-066aaa11b58365ffa39cfb0b63e6d1b03a7274b1.tar.bz2 yuescript-066aaa11b58365ffa39cfb0b63e6d1b03a7274b1.zip |
added `from import` for issue #149.
-rw-r--r-- | spec/inputs/import.yue | 29 | ||||
-rw-r--r-- | spec/outputs/import.lua | 33 | ||||
-rw-r--r-- | src/yuescript/yue_ast.cpp | 10 | ||||
-rw-r--r-- | src/yuescript/yue_ast.h | 9 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 32 | ||||
-rw-r--r-- | src/yuescript/yue_parser.cpp | 3 | ||||
-rw-r--r-- | src/yuescript/yue_parser.h | 1 |
7 files changed, 104 insertions, 13 deletions
diff --git a/spec/inputs/import.yue b/spec/inputs/import.yue index eb2a487..7a21995 100644 --- a/spec/inputs/import.yue +++ b/spec/inputs/import.yue | |||
@@ -47,6 +47,35 @@ do | |||
47 | import x1, y1, \z1 from "mymodule" | 47 | import x1, y1, \z1 from "mymodule" |
48 | 48 | ||
49 | do | 49 | do |
50 | from 'yue' import p | ||
51 | from 'mymodule' import x1, y1, \z1 | ||
52 | |||
53 | do | ||
54 | from z import a, b, c | ||
55 | |||
56 | do | ||
57 | from z import a, | ||
58 | b, c | ||
59 | |||
60 | do | ||
61 | from z import a | ||
62 | b | ||
63 | c | ||
64 | |||
65 | do | ||
66 | from z import | ||
67 | a | ||
68 | b | ||
69 | c | ||
70 | |||
71 | do | ||
72 | from z | ||
73 | import | ||
74 | a | ||
75 | b | ||
76 | c | ||
77 | |||
78 | do | ||
50 | import 'module' | 79 | import 'module' |
51 | import 'module_x' | 80 | import 'module_x' |
52 | import "d-a-s-h-e-s" | 81 | import "d-a-s-h-e-s" |
diff --git a/spec/outputs/import.lua b/spec/outputs/import.lua index b384d9d..ef83f2d 100644 --- a/spec/outputs/import.lua +++ b/spec/outputs/import.lua | |||
@@ -80,6 +80,39 @@ do | |||
80 | end | 80 | end |
81 | end | 81 | end |
82 | do | 82 | do |
83 | local p | ||
84 | do | ||
85 | local _obj_1 = require('yue') | ||
86 | p = _obj_1.p | ||
87 | end | ||
88 | local x1, y1, z1 | ||
89 | do | ||
90 | local _obj_1 = require('mymodule') | ||
91 | x1, y1, z1 = _obj_1.x1, _obj_1.y1, (function() | ||
92 | local _base_0 = _obj_1 | ||
93 | local _fn_0 = _base_0.z1 | ||
94 | return _fn_0 and function(...) | ||
95 | return _fn_0(_base_0, ...) | ||
96 | end | ||
97 | end)() | ||
98 | end | ||
99 | end | ||
100 | do | ||
101 | local a, b, c = z.a, z.b, z.c | ||
102 | end | ||
103 | do | ||
104 | local a, b, c = z.a, z.b, z.c | ||
105 | end | ||
106 | do | ||
107 | local a, b, c = z.a, z.b, z.c | ||
108 | end | ||
109 | do | ||
110 | local a, b, c = z.a, z.b, z.c | ||
111 | end | ||
112 | do | ||
113 | local a, b, c = z.a, z.b, z.c | ||
114 | end | ||
115 | do | ||
83 | local module = require('module') | 116 | local module = require('module') |
84 | local module_x = require('module_x') | 117 | local module_x = require('module_x') |
85 | local d_a_s_h_e_s = require("d-a-s-h-e-s") | 118 | local d_a_s_h_e_s = require("d-a-s-h-e-s") |
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 { | |||
271 | } | 271 | } |
272 | return join(temp, ", "sv) + " from "s + item->to_string(ud); | 272 | return join(temp, ", "sv) + " from "s + item->to_string(ud); |
273 | } | 273 | } |
274 | std::string FromImport_t::to_string(void* ud) const { | ||
275 | str_list temp; | ||
276 | for (auto name : names.objects()) { | ||
277 | temp.emplace_back(name->to_string(ud)); | ||
278 | } | ||
279 | return "from "s + item->to_string(ud) + " import "s + join(temp, ", "sv); | ||
280 | } | ||
274 | std::string MacroNamePair_t::to_string(void* ud) const { | 281 | std::string MacroNamePair_t::to_string(void* ud) const { |
275 | return key->to_string(ud) + ": "s + value->to_string(ud); | 282 | return key->to_string(ud) + ": "s + value->to_string(ud); |
276 | } | 283 | } |
@@ -294,6 +301,9 @@ std::string ImportAs_t::to_string(void* ud) const { | |||
294 | return join(temp, " "s); | 301 | return join(temp, " "s); |
295 | } | 302 | } |
296 | std::string Import_t::to_string(void* ud) const { | 303 | std::string Import_t::to_string(void* ud) const { |
304 | if (ast_is<FromImport_t>(content)) { | ||
305 | return content->to_string(ud); | ||
306 | } | ||
297 | return "import "s + content->to_string(ud); | 307 | return "import "s + content->to_string(ud); |
298 | } | 308 | } |
299 | std::string Label_t::to_string(void* ud) const { | 309 | 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) | |||
195 | AST_MEMBER(ImportFrom, &sep, &names, &item) | 195 | AST_MEMBER(ImportFrom, &sep, &names, &item) |
196 | AST_END(ImportFrom, "import_from"sv) | 196 | AST_END(ImportFrom, "import_from"sv) |
197 | 197 | ||
198 | AST_NODE(FromImport) | ||
199 | ast_sel<true, ImportLiteral_t, Exp_t> item; | ||
200 | ast_ptr<true, Seperator_t> sep; | ||
201 | ast_sel_list<true, ColonImportName_t, Variable_t> names; | ||
202 | AST_MEMBER(FromImport, &item, &sep, &names) | ||
203 | AST_END(FromImport, "from_import"sv) | ||
204 | |||
198 | AST_NODE(MacroNamePair) | 205 | AST_NODE(MacroNamePair) |
199 | ast_ptr<true, MacroName_t> key; | 206 | ast_ptr<true, MacroName_t> key; |
200 | ast_ptr<true, MacroName_t> value; | 207 | ast_ptr<true, MacroName_t> value; |
@@ -217,7 +224,7 @@ AST_NODE(ImportAs) | |||
217 | AST_END(ImportAs, "import_as"sv) | 224 | AST_END(ImportAs, "import_as"sv) |
218 | 225 | ||
219 | AST_NODE(Import) | 226 | AST_NODE(Import) |
220 | ast_sel<true, ImportAs_t, ImportFrom_t> content; | 227 | ast_sel<true, ImportAs_t, ImportFrom_t, FromImport_t> content; |
221 | AST_MEMBER(Import, &content) | 228 | AST_MEMBER(Import, &content) |
222 | AST_END(Import, "import"sv) | 229 | AST_END(Import, "import"sv) |
223 | 230 | ||
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<std::string> Metamethods = { | |||
74 | "close"s // Lua 5.4 | 74 | "close"s // Lua 5.4 |
75 | }; | 75 | }; |
76 | 76 | ||
77 | const std::string_view version = "0.19.3"sv; | 77 | const std::string_view version = "0.19.4"sv; |
78 | const std::string_view extension = "yue"sv; | 78 | const std::string_view extension = "yue"sv; |
79 | 79 | ||
80 | class CompileError : public std::logic_error { | 80 | class CompileError : public std::logic_error { |
@@ -8372,19 +8372,19 @@ private: | |||
8372 | } | 8372 | } |
8373 | } | 8373 | } |
8374 | 8374 | ||
8375 | void transformImportFrom(ImportFrom_t* import, str_list& out) { | 8375 | void transformImportFrom(ImportFrom_t* importNode, str_list& out) { |
8376 | str_list temp; | 8376 | str_list temp; |
8377 | auto x = import; | 8377 | auto x = importNode; |
8378 | auto objVar = singleVariableFrom(import->item, true); | 8378 | auto objVar = singleVariableFrom(importNode->item, true); |
8379 | ast_ptr<false, ExpListAssign_t> objAssign; | 8379 | ast_ptr<false, ExpListAssign_t> objAssign; |
8380 | if (objVar.empty()) { | 8380 | if (objVar.empty()) { |
8381 | objVar = getUnusedName("_obj_"sv); | 8381 | objVar = getUnusedName("_obj_"sv); |
8382 | auto expList = toAst<ExpList_t>(objVar, x); | 8382 | auto expList = toAst<ExpList_t>(objVar, x); |
8383 | auto assign = x->new_ptr<Assign_t>(); | 8383 | auto assign = x->new_ptr<Assign_t>(); |
8384 | if (import->item.is<Exp_t>()) { | 8384 | if (importNode->item.is<Exp_t>()) { |
8385 | assign->values.push_back(import->item); | 8385 | assign->values.push_back(importNode->item); |
8386 | } else { | 8386 | } else { |
8387 | auto exp = toAst<Exp_t>("require "s + _parser.toString(import->item.to<ImportLiteral_t>()), import->item); | 8387 | auto exp = toAst<Exp_t>("require "s + _parser.toString(importNode->item.to<ImportLiteral_t>()), importNode->item); |
8388 | assign->values.push_back(exp); | 8388 | assign->values.push_back(exp); |
8389 | } | 8389 | } |
8390 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 8390 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
@@ -8394,7 +8394,7 @@ private: | |||
8394 | } | 8394 | } |
8395 | auto expList = x->new_ptr<ExpList_t>(); | 8395 | auto expList = x->new_ptr<ExpList_t>(); |
8396 | auto assign = x->new_ptr<Assign_t>(); | 8396 | auto assign = x->new_ptr<Assign_t>(); |
8397 | for (auto name : import->names.objects()) { | 8397 | for (auto name : importNode->names.objects()) { |
8398 | switch (name->get_id()) { | 8398 | switch (name->get_id()) { |
8399 | case id<Variable_t>(): { | 8399 | case id<Variable_t>(): { |
8400 | auto var = static_cast<Variable_t*>(name); | 8400 | auto var = static_cast<Variable_t*>(name); |
@@ -8443,9 +8443,9 @@ private: | |||
8443 | if (objAssign) { | 8443 | if (objAssign) { |
8444 | auto preDef = toLocalDecl(transformAssignDefs(expList, DefOp::Mark)); | 8444 | auto preDef = toLocalDecl(transformAssignDefs(expList, DefOp::Mark)); |
8445 | if (!preDef.empty()) { | 8445 | if (!preDef.empty()) { |
8446 | temp.push_back(preDef + nll(import)); | 8446 | temp.push_back(preDef + nll(importNode)); |
8447 | } | 8447 | } |
8448 | temp.push_back(indent() + "do"s + nll(import)); | 8448 | temp.push_back(indent() + "do"s + nll(importNode)); |
8449 | pushScope(); | 8449 | pushScope(); |
8450 | transformAssignment(objAssign, temp); | 8450 | transformAssignment(objAssign, temp); |
8451 | } | 8451 | } |
@@ -8455,7 +8455,7 @@ private: | |||
8455 | transformAssignment(assignment, temp); | 8455 | transformAssignment(assignment, temp); |
8456 | if (objAssign) { | 8456 | if (objAssign) { |
8457 | popScope(); | 8457 | popScope(); |
8458 | temp.push_back(indent() + "end"s + nlr(import)); | 8458 | temp.push_back(indent() + "end"s + nlr(importNode)); |
8459 | } | 8459 | } |
8460 | out.push_back(join(temp)); | 8460 | out.push_back(join(temp)); |
8461 | auto vars = getAssignVars(assignment); | 8461 | auto vars = getAssignVars(assignment); |
@@ -8464,6 +8464,13 @@ private: | |||
8464 | } | 8464 | } |
8465 | } | 8465 | } |
8466 | 8466 | ||
8467 | void transformFromImport(FromImport_t* importNode, str_list& out) { | ||
8468 | auto importFrom = importNode->new_ptr<ImportFrom_t>(); | ||
8469 | importFrom->names.dup(importNode->names); | ||
8470 | importFrom->item.set(importNode->item); | ||
8471 | transformImportFrom(importFrom, out); | ||
8472 | } | ||
8473 | |||
8467 | std::string moduleNameFrom(ImportLiteral_t* literal) { | 8474 | std::string moduleNameFrom(ImportLiteral_t* literal) { |
8468 | auto name = _parser.toString(literal->inners.back()); | 8475 | auto name = _parser.toString(literal->inners.back()); |
8469 | Utils::replace(name, "-"sv, "_"sv); | 8476 | Utils::replace(name, "-"sv, "_"sv); |
@@ -8679,6 +8686,9 @@ private: | |||
8679 | case id<ImportFrom_t>(): | 8686 | case id<ImportFrom_t>(): |
8680 | transformImportFrom(static_cast<ImportFrom_t*>(content), out); | 8687 | transformImportFrom(static_cast<ImportFrom_t*>(content), out); |
8681 | break; | 8688 | break; |
8689 | case id<FromImport_t>(): | ||
8690 | transformFromImport(static_cast<FromImport_t*>(content), out); | ||
8691 | break; | ||
8682 | default: YUEE("AST node mismatch", content); break; | 8692 | default: YUEE("AST node mismatch", content); break; |
8683 | } | 8693 | } |
8684 | } | 8694 | } |
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() { | |||
286 | import_name = ColonImportName | Variable; | 286 | import_name = ColonImportName | Variable; |
287 | import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name); | 287 | import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name); |
288 | ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> (ImportLiteral | not_(String) >> Exp); | 288 | ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> (ImportLiteral | not_(String) >> Exp); |
289 | FromImport = key("from") >> space >> (ImportLiteral | not_(String) >> Exp) >> *space_break >> space >> key("import") >> space >> import_name_list; | ||
289 | 290 | ||
290 | ImportLiteralInner = (range('a', 'z') | range('A', 'Z') | set("_-") | larger(255)) >> *(alpha_num | '-' | larger(255)); | 291 | ImportLiteralInner = (range('a', 'z') | range('A', 'Z') | set("_-") | larger(255)) >> *(alpha_num | '-' | larger(255)); |
291 | import_literal_chain = Seperator >> ImportLiteralInner >> *('.' >> ImportLiteralInner); | 292 | import_literal_chain = Seperator >> ImportLiteralInner >> *('.' >> ImportLiteralInner); |
@@ -324,7 +325,7 @@ YueParser::YueParser() { | |||
324 | 325 | ||
325 | ImportAs = ImportLiteral >> -(space >> key("as") >> space >> (ImportTabLit | Variable | ImportAllMacro)); | 326 | ImportAs = ImportLiteral >> -(space >> key("as") >> space >> (ImportTabLit | Variable | ImportAllMacro)); |
326 | 327 | ||
327 | Import = key("import") >> space >> (ImportAs | ImportFrom); | 328 | Import = key("import") >> space >> (ImportAs | ImportFrom) | FromImport; |
328 | 329 | ||
329 | Label = "::" >> LabelName >> "::"; | 330 | Label = "::" >> LabelName >> "::"; |
330 | 331 | ||
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: | |||
277 | AST_RULE(ImportLiteralInner); | 277 | AST_RULE(ImportLiteralInner); |
278 | AST_RULE(ImportLiteral); | 278 | AST_RULE(ImportLiteral); |
279 | AST_RULE(ImportFrom); | 279 | AST_RULE(ImportFrom); |
280 | AST_RULE(FromImport); | ||
280 | AST_RULE(MacroNamePair); | 281 | AST_RULE(MacroNamePair); |
281 | AST_RULE(ImportAllMacro); | 282 | AST_RULE(ImportAllMacro); |
282 | AST_RULE(ImportTabLit); | 283 | AST_RULE(ImportTabLit); |