diff options
author | Li Jin <dragon-fly@qq.com> | 2021-06-26 14:56:24 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2021-06-26 14:56:24 +0800 |
commit | 14ac9a31f84c7bd25b37c4ae6ad133572a5df3a7 (patch) | |
tree | 7510e116cef031cfd1a01e1f23813f24cfb4421b | |
parent | 175247c6d8317e0c5c4c675cfd9357b8f8e2bc17 (diff) | |
download | yuescript-14ac9a31f84c7bd25b37c4ae6ad133572a5df3a7.tar.gz yuescript-14ac9a31f84c7bd25b37c4ae6ad133572a5df3a7.tar.bz2 yuescript-14ac9a31f84c7bd25b37c4ae6ad133572a5df3a7.zip |
fix issue #55.
-rw-r--r-- | src/yuescript/yue_ast.h | 3 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 46 | ||||
-rw-r--r-- | src/yuescript/yue_parser.cpp | 2 |
3 files changed, 28 insertions, 23 deletions
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 695fbe1..7d79341 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
@@ -627,8 +627,9 @@ AST_END(Export) | |||
627 | 627 | ||
628 | AST_NODE(FnArgDef) | 628 | AST_NODE(FnArgDef) |
629 | ast_sel<true, Variable_t, SelfName_t> name; | 629 | ast_sel<true, Variable_t, SelfName_t> name; |
630 | ast_ptr<false, existential_op_t> op; | ||
630 | ast_ptr<false, Exp_t> defaultValue; | 631 | ast_ptr<false, Exp_t> defaultValue; |
631 | AST_MEMBER(FnArgDef, &name, &defaultValue) | 632 | AST_MEMBER(FnArgDef, &name, &op, &defaultValue) |
632 | AST_END(FnArgDef) | 633 | AST_END(FnArgDef) |
633 | 634 | ||
634 | AST_NODE(FnArgDefList) | 635 | AST_NODE(FnArgDefList) |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 4b3064e..90fc60f 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -56,7 +56,7 @@ using namespace parserlib; | |||
56 | 56 | ||
57 | typedef std::list<std::string> str_list; | 57 | typedef std::list<std::string> str_list; |
58 | 58 | ||
59 | const std::string_view version = "0.7.14"sv; | 59 | const std::string_view version = "0.7.15"sv; |
60 | const std::string_view extension = "yue"sv; | 60 | const std::string_view extension = "yue"sv; |
61 | 61 | ||
62 | class YueCompilerImpl { | 62 | class YueCompilerImpl { |
@@ -2801,6 +2801,7 @@ private: | |||
2801 | void transformFnArgDefList(FnArgDefList_t* argDefList, str_list& out) { | 2801 | void transformFnArgDefList(FnArgDefList_t* argDefList, str_list& out) { |
2802 | auto x = argDefList; | 2802 | auto x = argDefList; |
2803 | struct ArgItem { | 2803 | struct ArgItem { |
2804 | bool checkExistence = false; | ||
2804 | std::string name; | 2805 | std::string name; |
2805 | std::string assignSelf; | 2806 | std::string assignSelf; |
2806 | }; | 2807 | }; |
@@ -2815,27 +2816,33 @@ private: | |||
2815 | case id<Variable_t>(): arg.name = _parser.toString(def->name); break; | 2816 | case id<Variable_t>(): arg.name = _parser.toString(def->name); break; |
2816 | case id<SelfName_t>(): { | 2817 | case id<SelfName_t>(): { |
2817 | assignSelf = true; | 2818 | assignSelf = true; |
2819 | if (def->op) { | ||
2820 | if (def->defaultValue) { | ||
2821 | throw std::logic_error(_info.errorMessage("argument with default value should not check for existence"sv, def->op)); | ||
2822 | } | ||
2823 | arg.checkExistence = true; | ||
2824 | } | ||
2818 | auto selfName = static_cast<SelfName_t*>(def->name.get()); | 2825 | auto selfName = static_cast<SelfName_t*>(def->name.get()); |
2819 | switch (selfName->name->getId()) { | 2826 | switch (selfName->name->getId()) { |
2820 | case id<self_class_name_t>(): { | 2827 | case id<self_class_name_t>(): { |
2821 | auto clsName = static_cast<self_class_name_t*>(selfName->name.get()); | 2828 | auto clsName = static_cast<self_class_name_t*>(selfName->name.get()); |
2822 | arg.name = _parser.toString(clsName->name); | 2829 | arg.name = _parser.toString(clsName->name); |
2823 | arg.assignSelf = "self.__class."s + arg.name; | 2830 | arg.assignSelf = _parser.toString(clsName); |
2824 | break; | 2831 | break; |
2825 | } | 2832 | } |
2826 | case id<self_class_t>(): | ||
2827 | arg.name = "self.__class"sv; | ||
2828 | break; | ||
2829 | case id<self_name_t>(): { | 2833 | case id<self_name_t>(): { |
2830 | auto sfName = static_cast<self_name_t*>(selfName->name.get()); | 2834 | auto sfName = static_cast<self_name_t*>(selfName->name.get()); |
2831 | arg.name = _parser.toString(sfName->name); | 2835 | arg.name = _parser.toString(sfName->name); |
2832 | arg.assignSelf = "self."s + arg.name; | 2836 | arg.assignSelf = _parser.toString(sfName); |
2833 | break; | 2837 | break; |
2834 | } | 2838 | } |
2835 | case id<self_t>(): | 2839 | case id<self_t>(): |
2836 | arg.name = "self"sv; | 2840 | arg.name = "self"sv; |
2841 | if (def->op) throw std::logic_error(_info.errorMessage("can only check existence for assigning self field"sv, selfName->name)); | ||
2842 | break; | ||
2843 | default: | ||
2844 | throw std::logic_error(_info.errorMessage("invald self expression here"sv, selfName->name)); | ||
2837 | break; | 2845 | break; |
2838 | default: YUEE("AST node mismatch", selfName->name.get()); break; | ||
2839 | } | 2846 | } |
2840 | break; | 2847 | break; |
2841 | } | 2848 | } |
@@ -2867,23 +2874,20 @@ private: | |||
2867 | else varNames.append(", "s + arg.name); | 2874 | else varNames.append(", "s + arg.name); |
2868 | _varArgs.top() = true; | 2875 | _varArgs.top() = true; |
2869 | } | 2876 | } |
2870 | std::string initCodes = join(temp); | ||
2871 | if (assignSelf) { | 2877 | if (assignSelf) { |
2872 | auto sjoin = [](const decltype(argItems)& items, int index) { | 2878 | for (const auto& item : argItems) { |
2873 | std::string result; | 2879 | if (item.assignSelf.empty()) continue; |
2874 | for (auto it = items.begin(); it != items.end(); ++it) { | 2880 | if (item.checkExistence) { |
2875 | if (it->assignSelf.empty()) continue; | 2881 | auto stmt = toAst<Statement_t>(item.assignSelf + " = "s + item.name + " if "s + item.name + '?', x); |
2876 | if (result.empty()) result = (&it->name)[index]; | 2882 | transformStatement(stmt, temp); |
2877 | else result.append(", "s + (&it->name)[index]); | 2883 | } else { |
2878 | } | 2884 | auto assignment = toAst<ExpListAssign_t>(item.assignSelf + " = "s + item.name, x); |
2879 | return result; | 2885 | transformAssignment(assignment, temp); |
2880 | }; | 2886 | } |
2881 | std::string sleft = sjoin(argItems, 1); | 2887 | } |
2882 | std::string sright = sjoin(argItems, 0); | ||
2883 | initCodes.append(indent() + sleft + " = "s + sright + nll(argDefList)); | ||
2884 | } | 2888 | } |
2885 | out.push_back(varNames); | 2889 | out.push_back(varNames); |
2886 | out.push_back(initCodes); | 2890 | out.push_back(join(temp)); |
2887 | } | 2891 | } |
2888 | 2892 | ||
2889 | void transformSelfName(SelfName_t* selfName, str_list& out, const ast_sel<false,Invoke_t,InvokeArgs_t>& invoke = {}) { | 2893 | void transformSelfName(SelfName_t* selfName, str_list& out, const ast_sel<false,Invoke_t,InvokeArgs_t>& invoke = {}) { |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 255469d..c79d58e 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
@@ -548,7 +548,7 @@ YueParser::YueParser() { | |||
548 | KeyValueList = KeyValue >> *(sym(',') >> KeyValue); | 548 | KeyValueList = KeyValue >> *(sym(',') >> KeyValue); |
549 | KeyValueLine = CheckIndent >> (KeyValueList >> -sym(',') | TableBlockIndent | Space >> expr('*') >> (Exp | TableBlock)); | 549 | KeyValueLine = CheckIndent >> (KeyValueList >> -sym(',') | TableBlockIndent | Space >> expr('*') >> (Exp | TableBlock)); |
550 | 550 | ||
551 | FnArgDef = (Variable | SelfName) >> -(sym('=') >> Space >> Exp); | 551 | FnArgDef = (Variable | SelfName >> -existential_op) >> -(sym('=') >> Space >> Exp); |
552 | 552 | ||
553 | FnArgDefList = Space >> Seperator >> ( | 553 | FnArgDefList = Space >> Seperator >> ( |
554 | ( | 554 | ( |