diff options
Diffstat (limited to '')
| -rw-r--r-- | src/yuescript/ast.hpp | 2 | ||||
| -rwxr-xr-x | src/yuescript/yue_ast.h | 14 | ||||
| -rwxr-xr-x | src/yuescript/yue_compiler.cpp | 87 | ||||
| -rwxr-xr-x | src/yuescript/yue_parser.cpp | 12 | ||||
| -rwxr-xr-x | src/yuescript/yue_parser.h | 2 |
5 files changed, 108 insertions, 9 deletions
diff --git a/src/yuescript/ast.hpp b/src/yuescript/ast.hpp index 0636a74..6f89b52 100644 --- a/src/yuescript/ast.hpp +++ b/src/yuescript/ast.hpp | |||
| @@ -364,7 +364,7 @@ private: | |||
| 364 | 364 | ||
| 365 | class _ast_list : public ast_member { | 365 | class _ast_list : public ast_member { |
| 366 | public: | 366 | public: |
| 367 | ~_ast_list() { | 367 | ~_ast_list() { |
| 368 | clear(); | 368 | clear(); |
| 369 | } | 369 | } |
| 370 | 370 | ||
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 79e35a5..d2a6557 100755 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
| @@ -316,6 +316,18 @@ AST_NODE(Do) | |||
| 316 | AST_MEMBER(Do, &body) | 316 | AST_MEMBER(Do, &body) |
| 317 | AST_END(Do) | 317 | AST_END(Do) |
| 318 | 318 | ||
| 319 | AST_NODE(catch_block) | ||
| 320 | ast_ptr<true, Variable_t> err; | ||
| 321 | ast_ptr<true, Block_t> body; | ||
| 322 | AST_MEMBER(catch_block, &err, &body) | ||
| 323 | AST_END(catch_block) | ||
| 324 | |||
| 325 | AST_NODE(Try) | ||
| 326 | ast_sel<true, Block_t, Exp_t> func; | ||
| 327 | ast_ptr<false, catch_block_t> catchBlock; | ||
| 328 | AST_MEMBER(Try, &func, &catchBlock) | ||
| 329 | AST_END(Try) | ||
| 330 | |||
| 319 | class CompInner_t; | 331 | class CompInner_t; |
| 320 | class Statement_t; | 332 | class Statement_t; |
| 321 | 333 | ||
| @@ -474,7 +486,7 @@ class FunLit_t; | |||
| 474 | AST_NODE(SimpleValue) | 486 | AST_NODE(SimpleValue) |
| 475 | ast_sel<true, const_value_t, | 487 | ast_sel<true, const_value_t, |
| 476 | If_t, Switch_t, With_t, ClassDecl_t, | 488 | If_t, Switch_t, With_t, ClassDecl_t, |
| 477 | ForEach_t, For_t, While_t, Do_t, | 489 | ForEach_t, For_t, While_t, Do_t, Try_t, |
| 478 | unary_value_t, | 490 | unary_value_t, |
| 479 | TblComprehension_t, TableLit_t, Comprehension_t, | 491 | TblComprehension_t, TableLit_t, Comprehension_t, |
| 480 | FunLit_t, Num_t> value; | 492 | FunLit_t, Num_t> value; |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index fbb3fb5..2b9ebc9 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -60,7 +60,7 @@ using namespace parserlib; | |||
| 60 | 60 | ||
| 61 | typedef std::list<std::string> str_list; | 61 | typedef std::list<std::string> str_list; |
| 62 | 62 | ||
| 63 | const std::string_view version = "0.9.11"sv; | 63 | const std::string_view version = "0.10.0"sv; |
| 64 | const std::string_view extension = "yue"sv; | 64 | const std::string_view extension = "yue"sv; |
| 65 | 65 | ||
| 66 | class YueCompilerImpl { | 66 | class YueCompilerImpl { |
| @@ -576,8 +576,8 @@ private: | |||
| 576 | return exp; | 576 | return exp; |
| 577 | } | 577 | } |
| 578 | 578 | ||
| 579 | SimpleValue_t* simpleSingleValueFrom(ast_node* expList) const { | 579 | SimpleValue_t* simpleSingleValueFrom(ast_node* node) const { |
| 580 | auto value = singleValueFrom(expList); | 580 | auto value = singleValueFrom(node); |
| 581 | if (value && value->item.is<SimpleValue_t>()) { | 581 | if (value && value->item.is<SimpleValue_t>()) { |
| 582 | return static_cast<SimpleValue_t*>(value->item.get()); | 582 | return static_cast<SimpleValue_t*>(value->item.get()); |
| 583 | } | 583 | } |
| @@ -1042,6 +1042,7 @@ private: | |||
| 1042 | case id<For_t>(): transformFor(static_cast<For_t*>(value), out); break; | 1042 | case id<For_t>(): transformFor(static_cast<For_t*>(value), out); break; |
| 1043 | case id<While_t>(): transformWhile(static_cast<While_t*>(value), out); break; | 1043 | case id<While_t>(): transformWhile(static_cast<While_t*>(value), out); break; |
| 1044 | case id<Do_t>(): transformDo(static_cast<Do_t*>(value), out, ExpUsage::Common); break; | 1044 | case id<Do_t>(): transformDo(static_cast<Do_t*>(value), out, ExpUsage::Common); break; |
| 1045 | case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Common); break; | ||
| 1045 | case id<Comprehension_t>(): transformCompCommon(static_cast<Comprehension_t*>(value), out); break; | 1046 | case id<Comprehension_t>(): transformCompCommon(static_cast<Comprehension_t*>(value), out); break; |
| 1046 | default: specialSingleValue = false; break; | 1047 | default: specialSingleValue = false; break; |
| 1047 | } | 1048 | } |
| @@ -2660,6 +2661,7 @@ private: | |||
| 2660 | case id<For_t>(): transformForClosure(static_cast<For_t*>(value), out); break; | 2661 | case id<For_t>(): transformForClosure(static_cast<For_t*>(value), out); break; |
| 2661 | case id<While_t>(): transformWhileClosure(static_cast<While_t*>(value), out); break; | 2662 | case id<While_t>(): transformWhileClosure(static_cast<While_t*>(value), out); break; |
| 2662 | case id<Do_t>(): transformDo(static_cast<Do_t*>(value), out, ExpUsage::Closure); break; | 2663 | case id<Do_t>(): transformDo(static_cast<Do_t*>(value), out, ExpUsage::Closure); break; |
| 2664 | case id<Try_t>(): transformTry(static_cast<Try_t*>(value), out, ExpUsage::Closure); break; | ||
| 2663 | case id<unary_value_t>(): transform_unary_value(static_cast<unary_value_t*>(value), out); break; | 2665 | case id<unary_value_t>(): transform_unary_value(static_cast<unary_value_t*>(value), out); break; |
| 2664 | case id<TblComprehension_t>(): transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Closure); break; | 2666 | case id<TblComprehension_t>(): transformTblComprehension(static_cast<TblComprehension_t*>(value), out, ExpUsage::Closure); break; |
| 2665 | case id<TableLit_t>(): transformTableLit(static_cast<TableLit_t*>(value), out); break; | 2667 | case id<TableLit_t>(): transformTableLit(static_cast<TableLit_t*>(value), out); break; |
| @@ -6087,6 +6089,85 @@ private: | |||
| 6087 | out.push_back(join(temp)); | 6089 | out.push_back(join(temp)); |
| 6088 | } | 6090 | } |
| 6089 | 6091 | ||
| 6092 | void transformTry(Try_t* tryNode, str_list& out, ExpUsage usage) { | ||
| 6093 | auto x = tryNode; | ||
| 6094 | ast_ptr<true, Exp_t> errHandler; | ||
| 6095 | if (tryNode->catchBlock) { | ||
| 6096 | auto errHandleStr = "("s + _parser.toString(tryNode->catchBlock->err) + ")->\n"s + _parser.toString(tryNode->catchBlock->body); | ||
| 6097 | errHandler.set(toAst<Exp_t>(errHandleStr, x)); | ||
| 6098 | } | ||
| 6099 | if (auto tryBlock = tryNode->func.as<Block_t>()) { | ||
| 6100 | auto tryExp = toAst<Exp_t>("->\n"s + _parser.toString(tryBlock), x); | ||
| 6101 | if (errHandler) { | ||
| 6102 | auto xpcall = toAst<ChainValue_t>("xpcall()", x); | ||
| 6103 | auto invoke = ast_to<Invoke_t>(xpcall->items.back()); | ||
| 6104 | invoke->args.push_back(tryExp); | ||
| 6105 | invoke->args.push_back(errHandler); | ||
| 6106 | transformChainValue(xpcall, out, ExpUsage::Closure); | ||
| 6107 | } else { | ||
| 6108 | auto pcall = toAst<ChainValue_t>("pcall()", x); | ||
| 6109 | auto invoke = ast_to<Invoke_t>(pcall->items.back()); | ||
| 6110 | invoke->args.push_back(tryExp); | ||
| 6111 | transformChainValue(pcall, out, ExpUsage::Closure); | ||
| 6112 | } | ||
| 6113 | if (usage == ExpUsage::Common) { | ||
| 6114 | out.back().append(nlr(x)); | ||
| 6115 | } | ||
| 6116 | return; | ||
| 6117 | } else if (auto value = singleValueFrom(tryNode->func)) { | ||
| 6118 | BLOCK_START | ||
| 6119 | auto chainValue = value->item.as<ChainValue_t>(); | ||
| 6120 | BREAK_IF(!chainValue); | ||
| 6121 | BREAK_IF(!isChainValueCall(chainValue)); | ||
| 6122 | ast_ptr<true, ast_node> last = chainValue->items.back(); | ||
| 6123 | chainValue->items.pop_back(); | ||
| 6124 | _ast_list* args = nullptr; | ||
| 6125 | if (auto invoke = ast_cast<InvokeArgs_t>(last)) { | ||
| 6126 | args = &invoke->args; | ||
| 6127 | } else { | ||
| 6128 | args = &(ast_to<Invoke_t>(last)->args); | ||
| 6129 | } | ||
| 6130 | if (errHandler) { | ||
| 6131 | auto xpcall = toAst<ChainValue_t>("xpcall()", x); | ||
| 6132 | auto invoke = ast_to<Invoke_t>(xpcall->items.back()); | ||
| 6133 | invoke->args.push_back(tryNode->func); | ||
| 6134 | invoke->args.push_back(errHandler); | ||
| 6135 | for (auto arg : args->objects()) { | ||
| 6136 | invoke->args.push_back(arg); | ||
| 6137 | } | ||
| 6138 | transformChainValue(xpcall, out, ExpUsage::Closure); | ||
| 6139 | } else { | ||
| 6140 | auto pcall = toAst<ChainValue_t>("pcall()", x); | ||
| 6141 | auto invoke = ast_to<Invoke_t>(pcall->items.back()); | ||
| 6142 | invoke->args.push_back(tryNode->func); | ||
| 6143 | for (auto arg : args->objects()) { | ||
| 6144 | invoke->args.push_back(arg); | ||
| 6145 | } | ||
| 6146 | transformChainValue(pcall, out, ExpUsage::Closure); | ||
| 6147 | } | ||
| 6148 | if (usage == ExpUsage::Common) { | ||
| 6149 | out.back().append(nlr(x)); | ||
| 6150 | } | ||
| 6151 | return; | ||
| 6152 | BLOCK_END | ||
| 6153 | } | ||
| 6154 | if (errHandler) { | ||
| 6155 | auto xpcall = toAst<ChainValue_t>("xpcall()", x); | ||
| 6156 | auto invoke = ast_to<Invoke_t>(xpcall->items.back()); | ||
| 6157 | invoke->args.push_back(tryNode->func); | ||
| 6158 | invoke->args.push_back(errHandler); | ||
| 6159 | transformChainValue(xpcall, out, ExpUsage::Closure); | ||
| 6160 | } else { | ||
| 6161 | auto pcall = toAst<ChainValue_t>("pcall()", x); | ||
| 6162 | auto invoke = ast_to<Invoke_t>(pcall->items.back()); | ||
| 6163 | invoke->args.push_back(tryNode->func); | ||
| 6164 | transformChainValue(pcall, out, ExpUsage::Closure); | ||
| 6165 | } | ||
| 6166 | if (usage == ExpUsage::Common) { | ||
| 6167 | out.back().append(nlr(x)); | ||
| 6168 | } | ||
| 6169 | } | ||
| 6170 | |||
| 6090 | void transformImportFrom(ImportFrom_t* import, str_list& out) { | 6171 | void transformImportFrom(ImportFrom_t* import, str_list& out) { |
| 6091 | str_list temp; | 6172 | str_list temp; |
| 6092 | auto x = import; | 6173 | auto x = import; |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 3d12190..8325366 100755 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -29,7 +29,8 @@ std::unordered_set<std::string> Keywords = { | |||
| 29 | "until", "while", // Lua keywords | 29 | "until", "while", // Lua keywords |
| 30 | "as", "class", "continue", "export", "extends", | 30 | "as", "class", "continue", "export", "extends", |
| 31 | "from", "global", "import", "is", "macro", | 31 | "from", "global", "import", "is", "macro", |
| 32 | "switch", "unless", "using", "when", "with" // Yue keywords | 32 | "switch", "try", "unless", "using", "when", |
| 33 | "with" // Yue keywords | ||
| 33 | }; | 34 | }; |
| 34 | 35 | ||
| 35 | YueParser::YueParser() { | 36 | YueParser::YueParser() { |
| @@ -229,8 +230,8 @@ YueParser::YueParser() { | |||
| 229 | SwitchBlock = *EmptyLine >> | 230 | SwitchBlock = *EmptyLine >> |
| 230 | Advance >> Seperator >> | 231 | Advance >> Seperator >> |
| 231 | SwitchCase >> | 232 | SwitchCase >> |
| 232 | *(+SpaceBreak >> SwitchCase) >> | 233 | *(Break >> *EmptyLine >> CheckIndent >> SwitchCase) >> |
| 233 | -(+SpaceBreak >> SwitchElse) >> | 234 | -(Break >> *EmptyLine >> CheckIndent >> SwitchElse) >> |
| 234 | PopIndent; | 235 | PopIndent; |
| 235 | 236 | ||
| 236 | Switch = Space >> key("switch") >> disable_do(Exp) >> -(Space >> key("do")) | 237 | Switch = Space >> key("switch") >> disable_do(Exp) >> -(Space >> key("do")) |
| @@ -299,6 +300,9 @@ YueParser::YueParser() { | |||
| 299 | return true; | 300 | return true; |
| 300 | }); | 301 | }); |
| 301 | 302 | ||
| 303 | catch_block = Break >> *EmptyLine >> CheckIndent >> Space >> key("catch") >> Space >> Variable >> InBlock; | ||
| 304 | Try = Space >> key("try") >> (InBlock | Exp) >> -catch_block; | ||
| 305 | |||
| 302 | Comprehension = sym('[') >> Exp >> Space >> CompInner >> sym(']'); | 306 | Comprehension = sym('[') >> Exp >> Space >> CompInner >> sym(']'); |
| 303 | comp_value = sym(',') >> Exp; | 307 | comp_value = sym(',') >> Exp; |
| 304 | TblComprehension = sym('{') >> Exp >> -comp_value >> Space >> CompInner >> sym('}'); | 308 | TblComprehension = sym('{') >> Exp >> -comp_value >> Space >> CompInner >> sym('}'); |
| @@ -609,7 +613,7 @@ YueParser::YueParser() { | |||
| 609 | const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum); | 613 | const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum); |
| 610 | 614 | ||
| 611 | SimpleValue = Space >> (const_value | | 615 | SimpleValue = Space >> (const_value | |
| 612 | If | Switch | With | ClassDecl | ForEach | For | While | Do | | 616 | If | Switch | Try | With | ClassDecl | ForEach | For | While | Do | |
| 613 | unary_value | TblComprehension | TableLit | Comprehension | | 617 | unary_value | TblComprehension | TableLit | Comprehension | |
| 614 | FunLit | Num); | 618 | FunLit | Num); |
| 615 | 619 | ||
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 7dea126..bd86f50 100755 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
| @@ -238,6 +238,8 @@ private: | |||
| 238 | AST_RULE(For) | 238 | AST_RULE(For) |
| 239 | AST_RULE(ForEach) | 239 | AST_RULE(ForEach) |
| 240 | AST_RULE(Do) | 240 | AST_RULE(Do) |
| 241 | AST_RULE(catch_block) | ||
| 242 | AST_RULE(Try) | ||
| 241 | AST_RULE(Comprehension) | 243 | AST_RULE(Comprehension) |
| 242 | AST_RULE(comp_value) | 244 | AST_RULE(comp_value) |
| 243 | AST_RULE(TblComprehension) | 245 | AST_RULE(TblComprehension) |
