diff options
author | Li Jin <dragon-fly@qq.com> | 2019-10-03 01:36:12 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2019-10-03 01:36:12 +0800 |
commit | b98904d49cdb836f9dd4b3962abd2a35c4da89d5 (patch) | |
tree | c26e8d19d1d7dee9358b1fa3bf09c20974031546 | |
parent | 0a4164b929e9532236df5645464e68188b3dd4c3 (diff) | |
download | yuescript-b98904d49cdb836f9dd4b3962abd2a35c4da89d5.tar.gz yuescript-b98904d49cdb836f9dd4b3962abd2a35c4da89d5.tar.bz2 yuescript-b98904d49cdb836f9dd4b3962abd2a35c4da89d5.zip |
updating
-rw-r--r-- | MoonParser/moon_ast.cpp | 206 | ||||
-rw-r--r-- | MoonParser/moon_parser.cpp | 28 |
2 files changed, 113 insertions, 121 deletions
diff --git a/MoonParser/moon_ast.cpp b/MoonParser/moon_ast.cpp index c2e940c..2dfab8e 100644 --- a/MoonParser/moon_ast.cpp +++ b/MoonParser/moon_ast.cpp | |||
@@ -591,7 +591,7 @@ private: | |||
591 | case "With"_id: transformWith(static_cast<With_t*>(content), out); break; | 591 | case "With"_id: transformWith(static_cast<With_t*>(content), out); break; |
592 | case "For"_id: transformFor(static_cast<For_t*>(content), out); break; | 592 | case "For"_id: transformFor(static_cast<For_t*>(content), out); break; |
593 | case "ForEach"_id: transformForEach(static_cast<ForEach_t*>(content), out); break; | 593 | case "ForEach"_id: transformForEach(static_cast<ForEach_t*>(content), out); break; |
594 | case "Switch"_id: transformSwitch(content, out); break; | 594 | case "Switch"_id: transformSwitch(static_cast<Switch_t*>(content), out); break; |
595 | case "Return"_id: transformReturn(static_cast<Return_t*>(content), out); break; | 595 | case "Return"_id: transformReturn(static_cast<Return_t*>(content), out); break; |
596 | case "Local"_id: transformLocal(content, out); break; | 596 | case "Local"_id: transformLocal(content, out); break; |
597 | case "Export"_id: transformExport(static_cast<Export_t*>(content), out); break; | 597 | case "Export"_id: transformExport(static_cast<Export_t*>(content), out); break; |
@@ -899,7 +899,7 @@ private: | |||
899 | switch (value->getId()) { | 899 | switch (value->getId()) { |
900 | case "With"_id: transformWith(static_cast<With_t*>(value), out); break; | 900 | case "With"_id: transformWith(static_cast<With_t*>(value), out); break; |
901 | case "If"_id: transformIf(static_cast<If_t*>(value), out, IfUsage::Closure); break; | 901 | case "If"_id: transformIf(static_cast<If_t*>(value), out, IfUsage::Closure); break; |
902 | case "Switch"_id: transformSwitch(value, out); break; | 902 | case "Switch"_id: transformSwitchClosure(static_cast<>(value), out); break; |
903 | case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), out); break; | 903 | case "TableBlock"_id: transformTableBlock(static_cast<TableBlock_t*>(value), out); break; |
904 | case "Exp"_id: transformExp(static_cast<Exp_t*>(value), out); break; | 904 | case "Exp"_id: transformExp(static_cast<Exp_t*>(value), out); break; |
905 | default: break; | 905 | default: break; |
@@ -941,7 +941,7 @@ private: | |||
941 | std::vector<std::string> temp; | 941 | std::vector<std::string> temp; |
942 | transformExp(static_cast<Exp_t*>(pair), temp); | 942 | transformExp(static_cast<Exp_t*>(pair), temp); |
943 | pairs.push_back({ | 943 | pairs.push_back({ |
944 | item->getByPath<Callable_t, Variable_t>(), | 944 | item->getByPath<Callable_t, Variable_t>() != nullptr, |
945 | temp.back(), | 945 | temp.back(), |
946 | s("["sv) + std::to_string(index) + s("]"sv) | 946 | s("["sv) + std::to_string(index) + s("]"sv) |
947 | }); | 947 | }); |
@@ -972,7 +972,7 @@ private: | |||
972 | std::vector<std::string> temp; | 972 | std::vector<std::string> temp; |
973 | transformExp(exp, temp); | 973 | transformExp(exp, temp); |
974 | pairs.push_back({ | 974 | pairs.push_back({ |
975 | item->getByPath<Callable_t, Variable_t>(), | 975 | item->getByPath<Callable_t, Variable_t>() != nullptr, |
976 | temp.back(), s("."sv) + toString(key) | 976 | temp.back(), s("."sv) + toString(key) |
977 | }); | 977 | }); |
978 | } | 978 | } |
@@ -995,6 +995,7 @@ private: | |||
995 | std::pair<std::list<Destructure>, ast_ptr<Assignment_t, false, false>> | 995 | std::pair<std::list<Destructure>, ast_ptr<Assignment_t, false, false>> |
996 | extractDestructureInfo(Assignment_t* assignment) { | 996 | extractDestructureInfo(Assignment_t* assignment) { |
997 | std::list<Destructure> destructs; | 997 | std::list<Destructure> destructs; |
998 | if (!assignment->target.is<Assign_t>()) return { destructs, nullptr }; | ||
998 | auto exprs = assignment->assignable->exprs.objects(); | 999 | auto exprs = assignment->assignable->exprs.objects(); |
999 | auto values = assignment->target.to<Assign_t>()->values.objects(); | 1000 | auto values = assignment->target.to<Assign_t>()->values.objects(); |
1000 | size_t size = std::max(exprs.size(),values.size()); | 1001 | size_t size = std::max(exprs.size(),values.size()); |
@@ -1048,40 +1049,49 @@ private: | |||
1048 | std::vector<std::string> temp; | 1049 | std::vector<std::string> temp; |
1049 | auto expList = assignment->assignable.get(); | 1050 | auto expList = assignment->assignable.get(); |
1050 | auto action = assignment->target.get(); | 1051 | auto action = assignment->target.get(); |
1051 | auto defs = transformAssignDefs(expList); | 1052 | switch (action->getId()) { |
1052 | std::string preDefine = getPredefine(defs); | 1053 | case "Update"_id: { |
1053 | bool oneLined = defs.size() == expList->exprs.objects().size() && | 1054 | auto update = static_cast<Update_t*>(action); |
1054 | traversal::Stop != action->traverse([&](ast_node* n) { | 1055 | transformExpList(expList, temp); |
1055 | if (n->getId() == "Callable"_id) { | 1056 | transformExp(update->value, temp); |
1056 | if (auto name = n->getByPath<Variable_t>()) { | 1057 | _buf << indent() << temp.front() << " = "sv << temp.front() << |
1057 | for (const auto& def : defs) { | 1058 | " "sv << toString(update->op) << " "sv << temp.back() << nll(assignment); |
1058 | if (def ==toString(name)) { | 1059 | out.push_back(clearBuf()); |
1059 | return traversal::Stop; | 1060 | break; |
1061 | } | ||
1062 | case "Assign"_id: { | ||
1063 | auto defs = transformAssignDefs(expList); | ||
1064 | std::string preDefine = getPredefine(defs); | ||
1065 | bool oneLined = defs.size() == expList->exprs.objects().size() && | ||
1066 | traversal::Stop != action->traverse([&](ast_node* n) { | ||
1067 | if (n->getId() == "Callable"_id) { | ||
1068 | if (auto name = n->getByPath<Variable_t>()) { | ||
1069 | for (const auto& def : defs) { | ||
1070 | if (def == toString(name)) { | ||
1071 | return traversal::Stop; | ||
1072 | } | ||
1060 | } | 1073 | } |
1061 | } | 1074 | } |
1062 | } | 1075 | } |
1063 | } | 1076 | return traversal::Continue; |
1064 | return traversal::Continue; | 1077 | }); |
1065 | }); | 1078 | transformExpList(expList, temp); |
1066 | transformExpList(expList, temp); | 1079 | std::string left = temp.back(); |
1067 | std::string left = temp.back(); | 1080 | temp.pop_back(); |
1068 | temp.clear(); | ||
1069 | switch (action->getId()) { | ||
1070 | case "Update"_id: transformUpdate(action, temp); break; | ||
1071 | case "Assign"_id: { | ||
1072 | auto assign = static_cast<Assign_t*>(action); | 1081 | auto assign = static_cast<Assign_t*>(action); |
1073 | for (auto value : assign->values.objects()) { | 1082 | for (auto value : assign->values.objects()) { |
1074 | transformAssignItem(value, temp); | 1083 | transformAssignItem(value, temp); |
1075 | } | 1084 | } |
1085 | if (oneLined) { | ||
1086 | out.push_back((preDefine.empty() ? indent() + left : preDefine) + s(" = "sv) + join(temp, ", "sv) + nll(assignment)); | ||
1087 | } | ||
1088 | else { | ||
1089 | out.push_back((preDefine.empty() ? Empty : preDefine + nll(assignment)) + indent() + left + s(" = "sv) + join(temp, ", "sv) + nll(assignment)); | ||
1090 | } | ||
1076 | break; | 1091 | break; |
1077 | } | 1092 | } |
1078 | default: break; | 1093 | default: break; |
1079 | } | 1094 | } |
1080 | if (oneLined) { | ||
1081 | out.push_back((preDefine.empty() ? indent() + left : preDefine) + s(" = "sv) + join(temp, ", "sv) + nll(assignment)); | ||
1082 | } else { | ||
1083 | out.push_back((preDefine.empty() ? Empty : preDefine + nll(assignment)) + indent() + left + s(" = "sv) + join(temp, ", "sv) + nll(assignment)); | ||
1084 | } | ||
1085 | } | 1095 | } |
1086 | 1096 | ||
1087 | void transformCond(const std::list<ast_node*>& nodes, std::vector<std::string>& out, IfUsage usage = IfUsage::Common, bool unless = false) { | 1097 | void transformCond(const std::list<ast_node*>& nodes, std::vector<std::string>& out, IfUsage usage = IfUsage::Common, bool unless = false) { |
@@ -1870,11 +1880,6 @@ private: | |||
1870 | auto star_exp = static_cast<star_exp_t*>(loopTarget); | 1880 | auto star_exp = static_cast<star_exp_t*>(loopTarget); |
1871 | bool newListVal = false; | 1881 | bool newListVal = false; |
1872 | auto listVar = variableFrom(star_exp->value); | 1882 | auto listVar = variableFrom(star_exp->value); |
1873 | if (listVar.empty()) { | ||
1874 | newListVal = true; | ||
1875 | listVar = getUnusedName("_list_"); | ||
1876 | varBefore.push_back(listVar); | ||
1877 | } | ||
1878 | auto indexVar = getUnusedName("_index_"); | 1883 | auto indexVar = getUnusedName("_index_"); |
1879 | varAfter.push_back(indexVar); | 1884 | varAfter.push_back(indexVar); |
1880 | auto value = singleValueFrom(star_exp->value); | 1885 | auto value = singleValueFrom(star_exp->value); |
@@ -1887,6 +1892,10 @@ private: | |||
1887 | auto slice = ast_cast<Slice_t>(chainList.back()); | 1892 | auto slice = ast_cast<Slice_t>(chainList.back()); |
1888 | if (!slice) break; | 1893 | if (!slice) break; |
1889 | endWithSlice = true; | 1894 | endWithSlice = true; |
1895 | if (listVar.empty() && chainList.size() == 2 && | ||
1896 | ast_is<Callable_t>(chainList.front())) { | ||
1897 | listVar = toString(ast_to<Callable_t>(chainList.front())->item); | ||
1898 | } | ||
1890 | chainList.pop_back(); | 1899 | chainList.pop_back(); |
1891 | auto chain = new_ptr<Chain_t>(); | 1900 | auto chain = new_ptr<Chain_t>(); |
1892 | for (auto item : chainList) { | 1901 | for (auto item : chainList) { |
@@ -1934,6 +1943,11 @@ private: | |||
1934 | _buf << indent(1) << "local "sv << join(vars, ", "sv) << " = "sv << listVar << "["sv << indexVar << "]"sv << nll(nameList); | 1943 | _buf << indent(1) << "local "sv << join(vars, ", "sv) << " = "sv << listVar << "["sv << indexVar << "]"sv << nll(nameList); |
1935 | out.push_back(clearBuf()); | 1944 | out.push_back(clearBuf()); |
1936 | } while (false); | 1945 | } while (false); |
1946 | if (listVar.empty()) { | ||
1947 | newListVal = true; | ||
1948 | listVar = getUnusedName("_list_"); | ||
1949 | varBefore.push_back(listVar); | ||
1950 | } | ||
1937 | if (!endWithSlice) { | 1951 | if (!endWithSlice) { |
1938 | transformExp(star_exp->value, temp); | 1952 | transformExp(star_exp->value, temp); |
1939 | if (newListVal) _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); | 1953 | if (newListVal) _buf << indent() << "local "sv << listVar << " = "sv << temp.back() << nll(nameList); |
@@ -3070,11 +3084,45 @@ private: | |||
3070 | out.push_back(clearBuf()); | 3084 | out.push_back(clearBuf()); |
3071 | } | 3085 | } |
3072 | 3086 | ||
3073 | void transformUpdate(ast_node* node, std::vector<std::string>& out) {noop(node, out);} | 3087 | void transformSwitch(Switch_t* switchNode, std::vector<std::string>& out, bool implicitReturn = false) { |
3074 | void transformSwitch(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} | 3088 | std::vector<std::string> temp; |
3089 | auto objVar = variableFrom(switchNode->target); | ||
3090 | if (objVar.empty()) { | ||
3091 | objVar = getUnusedName("_obj_"sv); | ||
3092 | addToScope(objVar); | ||
3093 | transformExp(switchNode->target, temp); | ||
3094 | _buf << indent() << "local "sv << objVar << " = "sv << temp.back() << nll(switchNode); | ||
3095 | temp.back() = clearBuf(); | ||
3096 | } | ||
3097 | const auto& branches = switchNode->branches.objects(); | ||
3098 | for (auto branch_ : branches) { | ||
3099 | auto branch = static_cast<SwitchCase_t*>(branch_); | ||
3100 | temp.push_back(indent() + s(branches.front() == branch ? "if"sv : "elseif"sv)); | ||
3101 | std::vector<std::string> tmp; | ||
3102 | const auto& exprs = branch->valueList->exprs.objects(); | ||
3103 | for (auto exp_ : exprs) { | ||
3104 | auto exp = static_cast<Exp_t*>(exp_); | ||
3105 | transformExp(exp, tmp); | ||
3106 | temp.back().append(s(" "sv) + objVar + s(" == "sv) + tmp.back + | ||
3107 | (exp == exprs.back() ? ""sv : " or"sv)); | ||
3108 | } | ||
3109 | temp.back().append(s(" then"sv) + nll(branch)); | ||
3110 | pushScope(); | ||
3111 | transformBody(branch->body, temp, implicitReturn); | ||
3112 | popScope(); | ||
3113 | } | ||
3114 | if (switchNode->lastBranch) { | ||
3115 | temp.push_back(indent() + s("else"sv) + nll(switchNode->lastBranch)); | ||
3116 | pushScope(); | ||
3117 | transformBody(switchNode->lastBranch, temp, implicitReturn); | ||
3118 | popScope(); | ||
3119 | } | ||
3120 | temp.push_back(indent() + s("end"sv) + nlr(switchNode)); | ||
3121 | out.push_back(join(temp)); | ||
3122 | } | ||
3123 | |||
3075 | void transformLocal(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} | 3124 | void transformLocal(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} |
3076 | void transformBreakLoop(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} | 3125 | void transformBreakLoop(ast_node* node, std::vector<std::string>& out) {noopnl(node, out);} |
3077 | void transform_unless_line(ast_node* node, std::vector<std::string>& out) {noop(node, out);} | ||
3078 | }; | 3126 | }; |
3079 | 3127 | ||
3080 | const std::string MoonCompliler::Empty; | 3128 | const std::string MoonCompliler::Empty; |
@@ -3082,78 +3130,22 @@ const std::string MoonCompliler::Empty; | |||
3082 | int main() | 3130 | int main() |
3083 | { | 3131 | { |
3084 | std::string s = R"TestCodesHere( | 3132 | std::string s = R"TestCodesHere( |
3085 | 3133 | switch abc.x | |
3086 | hi = [x*2 for _, x in ipairs{1,2,3,4}] | 3134 | when "a","b" then 1 |
3087 | 3135 | when "c" then 2 | |
3088 | items = {1,2,3,4,5,6} | 3136 | else 3 |
3089 | 3137 | a = switch abc.x | |
3090 | [z for z in ipairs items when z > 4] | 3138 | when "a","b" then 1 |
3091 | 3139 | when "c" then 2 | |
3092 | rad = [{a} for a in ipairs { | 3140 | else 3 |
3093 | 1,2,3,4,5,6, | 3141 | f switch abc.x |
3094 | } when good_number a] | 3142 | when "a","b" then 1 |
3095 | 3143 | when "c" then 2 | |
3096 | 3144 | else 3 | |
3097 | [z for z in items for j in list when z > 4] | 3145 | switch abc.x |
3098 | 3146 | when "a","b" then 1 | |
3099 | require "util" | 3147 | when "c" then 2 |
3100 | 3148 | else 3 | |
3101 | dump = (x) -> print util.dump x | ||
3102 | |||
3103 | range = (count) -> | ||
3104 | i = 0 | ||
3105 | return coroutine.wrap -> | ||
3106 | while i < count | ||
3107 | coroutine.yield i | ||
3108 | i = i + 1 | ||
3109 | |||
3110 | dump [x for x in range 10] | ||
3111 | dump [{x, y} for x in range 5 when x > 2 for y in range 5] | ||
3112 | |||
3113 | things = [x + y for x in range 10 when x > 5 for y in range 10 when y > 7] | ||
3114 | |||
3115 | print x,y for x in ipairs{1,2,4} for y in ipairs{1,2,3} when x != 2 | ||
3116 | |||
3117 | print "hello", x for x in items | ||
3118 | |||
3119 | [x for x in x] | ||
3120 | x = [x for x in x] | ||
3121 | |||
3122 | print x,y for x in ipairs{1,2,4} for y in ipairs{1,2,3} when x != 2 | ||
3123 | |||
3124 | double = [x*2 for x in *items] | ||
3125 | |||
3126 | print x for x in *double | ||
3127 | |||
3128 | cut = [x for x in *items when x > 3] | ||
3129 | |||
3130 | hello = [x + y for x in *items for y in *items] | ||
3131 | |||
3132 | print z for z in *hello | ||
3133 | |||
3134 | |||
3135 | -- slice | ||
3136 | x = {1, 2, 3, 4, 5, 6, 7} | ||
3137 | print y for y in *x[2,-5,2] | ||
3138 | print y for y in *x[,3] | ||
3139 | print y for y in *x[2,] | ||
3140 | print y for y in *x[,,2] | ||
3141 | print y for y in *x[2,,2] | ||
3142 | |||
3143 | a, b, c = 1, 5, 2 | ||
3144 | print y for y in *x[a,b,c] | ||
3145 | |||
3146 | |||
3147 | normal = (hello) -> | ||
3148 | [x for x in yeah] | ||
3149 | |||
3150 | |||
3151 | test = x 1,2,3,4,5 | ||
3152 | print thing for thing in *test | ||
3153 | |||
3154 | -> a = b for row in *rows | ||
3155 | |||
3156 | |||
3157 | )TestCodesHere"; | 3149 | )TestCodesHere"; |
3158 | MoonCompliler{}.complile(s); | 3150 | MoonCompliler{}.complile(s); |
3159 | return 0; | 3151 | return 0; |
diff --git a/MoonParser/moon_parser.cpp b/MoonParser/moon_parser.cpp index 3c3078a..7fab4f5 100644 --- a/MoonParser/moon_parser.cpp +++ b/MoonParser/moon_parser.cpp | |||
@@ -223,20 +223,20 @@ extern rule TableBlock; | |||
223 | rule Assign = sym('=') >> Seperator >> (With | If | Switch | TableBlock | Exp >> *((sym(',') | sym(';')) >> Exp)); | 223 | rule Assign = sym('=') >> Seperator >> (With | If | Switch | TableBlock | Exp >> *((sym(',') | sym(';')) >> Exp)); |
224 | 224 | ||
225 | rule update_op = | 225 | rule update_op = |
226 | expr("..=") | | 226 | expr("..") | |
227 | expr("+=") | | 227 | expr("+") | |
228 | expr("-=") | | 228 | expr("-") | |
229 | expr("*=") | | 229 | expr("*") | |
230 | expr("/=") | | 230 | expr("/") | |
231 | expr("%=") | | 231 | expr("%") | |
232 | expr("or=") | | 232 | expr("or") | |
233 | expr("and=") | | 233 | expr("and") | |
234 | expr("&=") | | 234 | expr("&") | |
235 | expr("|=") | | 235 | expr("|") | |
236 | expr(">>=") | | 236 | expr(">>") | |
237 | expr("<<="); | 237 | expr("<<"); |
238 | 238 | ||
239 | rule Update = Space >> update_op >> Exp; | 239 | rule Update = Space >> update_op >> expr("=") >> Exp; |
240 | 240 | ||
241 | rule BinaryOperator = | 241 | rule BinaryOperator = |
242 | (expr("or") >> not_(AlphaNum)) | | 242 | (expr("or") >> not_(AlphaNum)) | |