summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2021-06-26 14:56:24 +0800
committerLi Jin <dragon-fly@qq.com>2021-06-26 14:56:24 +0800
commit14ac9a31f84c7bd25b37c4ae6ad133572a5df3a7 (patch)
tree7510e116cef031cfd1a01e1f23813f24cfb4421b
parent175247c6d8317e0c5c4c675cfd9357b8f8e2bc17 (diff)
downloadyuescript-14ac9a31f84c7bd25b37c4ae6ad133572a5df3a7.tar.gz
yuescript-14ac9a31f84c7bd25b37c4ae6ad133572a5df3a7.tar.bz2
yuescript-14ac9a31f84c7bd25b37c4ae6ad133572a5df3a7.zip
fix issue #55.
-rw-r--r--src/yuescript/yue_ast.h3
-rw-r--r--src/yuescript/yue_compiler.cpp46
-rw-r--r--src/yuescript/yue_parser.cpp2
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
628AST_NODE(FnArgDef) 628AST_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)
632AST_END(FnArgDef) 633AST_END(FnArgDef)
633 634
634AST_NODE(FnArgDefList) 635AST_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
57typedef std::list<std::string> str_list; 57typedef std::list<std::string> str_list;
58 58
59const std::string_view version = "0.7.14"sv; 59const std::string_view version = "0.7.15"sv;
60const std::string_view extension = "yue"sv; 60const std::string_view extension = "yue"sv;
61 61
62class YueCompilerImpl { 62class 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 (