diff options
| author | Li Jin <dragon-fly@qq.com> | 2025-05-28 18:20:16 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2025-05-28 18:20:16 +0800 |
| commit | 5604bbbb80bfcedb4a9085b90864e221f8104b33 (patch) | |
| tree | 8828cddb1b0fe0ca734d6209507bdbda3133f48d | |
| parent | 87267ca9e93606b70bdc0397349b176b8d142514 (diff) | |
| download | yuescript-5604bbbb80bfcedb4a9085b90864e221f8104b33.tar.gz yuescript-5604bbbb80bfcedb4a9085b90864e221f8104b33.tar.bz2 yuescript-5604bbbb80bfcedb4a9085b90864e221f8104b33.zip | |
Added `try!` syntax.
| -rwxr-xr-x | doc/docs/doc/README.md | 65 | ||||
| -rwxr-xr-x | doc/docs/zh/doc/README.md | 41 | ||||
| -rw-r--r-- | spec/inputs/try_catch.yue | 122 | ||||
| -rw-r--r-- | spec/outputs/5.1/try_catch.lua | 265 | ||||
| -rw-r--r-- | spec/outputs/assign.lua | 6 | ||||
| -rw-r--r-- | spec/outputs/codes_from_doc.lua | 100 | ||||
| -rw-r--r-- | spec/outputs/codes_from_doc_zh.lua | 100 | ||||
| -rw-r--r-- | spec/outputs/try_catch.lua | 266 | ||||
| -rw-r--r-- | spec/outputs/unicode/assign.lua | 6 | ||||
| -rw-r--r-- | spec/outputs/unicode/macro.lua | 46 | ||||
| -rw-r--r-- | spec/outputs/unicode/multiline_chain.lua | 6 | ||||
| -rw-r--r-- | spec/outputs/unicode/syntax.lua | 6 | ||||
| -rw-r--r-- | spec/outputs/unicode/vararg.lua | 28 | ||||
| -rw-r--r-- | spec/outputs/upvalue_func.lua | 48 | ||||
| -rw-r--r-- | spec/outputs/vararg.lua | 28 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.cpp | 10 | ||||
| -rw-r--r-- | src/yuescript/yue_ast.h | 6 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 155 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.h | 1 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 25 | ||||
| -rw-r--r-- | src/yuescript/yue_parser.h | 13 | ||||
| -rw-r--r-- | src/yuescript/yuescript.cpp | 15 |
22 files changed, 1169 insertions, 189 deletions
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/README.md index a970baa..1d9c8ad 100755 --- a/doc/docs/doc/README.md +++ b/doc/docs/doc/README.md | |||
| @@ -1243,7 +1243,7 @@ If the destructuring statement is complicated, feel free to spread it out over a | |||
| 1243 | </pre> | 1243 | </pre> |
| 1244 | </YueDisplay> | 1244 | </YueDisplay> |
| 1245 | 1245 | ||
| 1246 | It’s common to extract values from at table and assign them the local variables that have the same name as the key. In order to avoid repetition we can use the **:** prefix operator: | 1246 | It's common to extract values from at table and assign them the local variables that have the same name as the key. In order to avoid repetition we can use the **:** prefix operator: |
| 1247 | 1247 | ||
| 1248 | ```moonscript | 1248 | ```moonscript |
| 1249 | {:concat, :insert} = table | 1249 | {:concat, :insert} = table |
| @@ -1516,6 +1516,47 @@ catch err | |||
| 1516 | </pre> | 1516 | </pre> |
| 1517 | </YueDisplay> | 1517 | </YueDisplay> |
| 1518 | 1518 | ||
| 1519 | ### Try! | ||
| 1520 | |||
| 1521 | `try!` is a more concise error handling syntax that omit the boolean status from the `try` statement, and it will return the result from the try block when success, otherwise return nil instead of error object. | ||
| 1522 | |||
| 1523 | ```moonscript | ||
| 1524 | a, b, c = try! func! | ||
| 1525 | |||
| 1526 | -- with nil coalescing operator | ||
| 1527 | a = (try! func!) ?? "default" | ||
| 1528 | |||
| 1529 | -- as function argument | ||
| 1530 | f try! func! | ||
| 1531 | |||
| 1532 | -- with catch block | ||
| 1533 | f try! | ||
| 1534 | print 123 | ||
| 1535 | func! | ||
| 1536 | catch e | ||
| 1537 | print e | ||
| 1538 | e | ||
| 1539 | ``` | ||
| 1540 | <YueDisplay> | ||
| 1541 | <pre> | ||
| 1542 | a, b, c = try! func! | ||
| 1543 | |||
| 1544 | -- with nil coalescing operator | ||
| 1545 | a = (try! func!) ?? "default" | ||
| 1546 | |||
| 1547 | -- as function argument | ||
| 1548 | f try! func! | ||
| 1549 | |||
| 1550 | -- with catch block | ||
| 1551 | f try! | ||
| 1552 | print 123 | ||
| 1553 | func! | ||
| 1554 | catch e | ||
| 1555 | print e | ||
| 1556 | e | ||
| 1557 | </pre> | ||
| 1558 | </YueDisplay> | ||
| 1559 | |||
| 1519 | ## Attributes | 1560 | ## Attributes |
| 1520 | 1561 | ||
| 1521 | Syntax support for Lua 5.4 attributes. And you can still use both the `const` and `close` declaration and get constant check and scoped callback working when targeting Lua versions below 5.4. | 1562 | Syntax support for Lua 5.4 attributes. And you can still use both the `const` and `close` declaration and get constant check and scoped callback working when targeting Lua versions below 5.4. |
| @@ -2417,7 +2458,7 @@ print func_b! -- prints table object | |||
| 2417 | </pre> | 2458 | </pre> |
| 2418 | </YueDisplay> | 2459 | </YueDisplay> |
| 2419 | 2460 | ||
| 2420 | This is done to avoid the needless creation of tables for functions that don’t need to return the results of the loop. | 2461 | This is done to avoid the needless creation of tables for functions that don't need to return the results of the loop. |
| 2421 | 2462 | ||
| 2422 | ## Repeat Loop | 2463 | ## Repeat Loop |
| 2423 | 2464 | ||
| @@ -2746,7 +2787,7 @@ next_number = switch b | |||
| 2746 | </pre> | 2787 | </pre> |
| 2747 | </YueDisplay> | 2788 | </YueDisplay> |
| 2748 | 2789 | ||
| 2749 | We can use the then keyword to write a switch’s when block on a single line. No extra keyword is needed to write the else block on a single line. | 2790 | We can use the then keyword to write a switch's when block on a single line. No extra keyword is needed to write the else block on a single line. |
| 2750 | 2791 | ||
| 2751 | ```moonscript | 2792 | ```moonscript |
| 2752 | msg = switch math.random(1, 5) | 2793 | msg = switch math.random(1, 5) |
| @@ -2792,7 +2833,7 @@ else | |||
| 2792 | </pre> | 2833 | </pre> |
| 2793 | </YueDisplay> | 2834 | </YueDisplay> |
| 2794 | 2835 | ||
| 2795 | It is worth noting the order of the case comparison expression. The case’s expression is on the left hand side. This can be useful if the case’s expression wants to overwrite how the comparison is done by defining an eq metamethod. | 2836 | It is worth noting the order of the case comparison expression. The case's expression is on the left hand side. This can be useful if the case's expression wants to overwrite how the comparison is done by defining an eq metamethod. |
| 2796 | 2837 | ||
| 2797 | ### Table Matching | 2838 | ### Table Matching |
| 2798 | 2839 | ||
| @@ -3079,7 +3120,7 @@ class BackPack extends Inventory | |||
| 3079 | 3120 | ||
| 3080 | Here we extend our Inventory class, and limit the amount of items it can carry. | 3121 | Here we extend our Inventory class, and limit the amount of items it can carry. |
| 3081 | 3122 | ||
| 3082 | In this example, we don’t define a constructor on the subclass, so the parent class' constructor is called when we make a new instance. If we did define a constructor then we can use the super method to call the parent constructor. | 3123 | In this example, we don't define a constructor on the subclass, so the parent class' constructor is called when we make a new instance. If we did define a constructor then we can use the super method to call the parent constructor. |
| 3083 | 3124 | ||
| 3084 | Whenever a class inherits from another, it sends a message to the parent class by calling the method __inherited on the parent class if it exists. The function receives two arguments, the class that is being inherited and the child class. | 3125 | Whenever a class inherits from another, it sends a message to the parent class by calling the method __inherited on the parent class if it exists. The function receives two arguments, the class that is being inherited and the child class. |
| 3085 | 3126 | ||
| @@ -3166,13 +3207,13 @@ print BackPack.size -- prints 10 | |||
| 3166 | 3207 | ||
| 3167 | The class object is what we create when we use a class statement. The class object is stored in a variable of the same name of the class. | 3208 | The class object is what we create when we use a class statement. The class object is stored in a variable of the same name of the class. |
| 3168 | 3209 | ||
| 3169 | The class object can be called like a function in order to create new instances. That’s how we created instances of classes in the examples above. | 3210 | The class object can be called like a function in order to create new instances. That's how we created instances of classes in the examples above. |
| 3170 | 3211 | ||
| 3171 | A class is made up of two tables. The class table itself, and the base table. The base is used as the metatable for all the instances. All properties listed in the class declaration are placed in the base. | 3212 | A class is made up of two tables. The class table itself, and the base table. The base is used as the metatable for all the instances. All properties listed in the class declaration are placed in the base. |
| 3172 | 3213 | ||
| 3173 | The class object’s metatable reads properties from the base if they don’t exist in the class object. This means we can access functions and properties directly from the class. | 3214 | The class object's metatable reads properties from the base if they don't exist in the class object. This means we can access functions and properties directly from the class. |
| 3174 | 3215 | ||
| 3175 | It is important to note that assigning to the class object does not assign into the base, so it’s not a valid way to add new methods to instances. Instead the base must explicitly be changed. See the __base field below. | 3216 | It is important to note that assigning to the class object does not assign into the base, so it's not a valid way to add new methods to instances. Instead the base must explicitly be changed. See the __base field below. |
| 3176 | 3217 | ||
| 3177 | The class object has a couple special properties: | 3218 | The class object has a couple special properties: |
| 3178 | 3219 | ||
| @@ -3245,7 +3286,7 @@ print Counter.count -- prints 2 | |||
| 3245 | </pre> | 3286 | </pre> |
| 3246 | </YueDisplay> | 3287 | </YueDisplay> |
| 3247 | 3288 | ||
| 3248 | The calling semantics of @@ are similar to @. Calling a @@ name will pass the class in as the first argument using Lua’s colon syntax. | 3289 | The calling semantics of @@ are similar to @. Calling a @@ name will pass the class in as the first argument using Lua's colon syntax. |
| 3249 | 3290 | ||
| 3250 | ```moonscript | 3291 | ```moonscript |
| 3251 | @@hello 1,2,3,4 | 3292 | @@hello 1,2,3,4 |
| @@ -3260,7 +3301,7 @@ The calling semantics of @@ are similar to @. Calling a @@ name will pass the cl | |||
| 3260 | 3301 | ||
| 3261 | In the body of a class declaration, we can have normal expressions in addition to key/value pairs. In this context, self is equal to the class object. | 3302 | In the body of a class declaration, we can have normal expressions in addition to key/value pairs. In this context, self is equal to the class object. |
| 3262 | 3303 | ||
| 3263 | Here is an alternative way to create a class variable compared to what’s described above: | 3304 | Here is an alternative way to create a class variable compared to what's described above: |
| 3264 | 3305 | ||
| 3265 | ```moonscript | 3306 | ```moonscript |
| 3266 | class Things | 3307 | class Things |
| @@ -3593,7 +3634,7 @@ print var -- nil here | |||
| 3593 | </pre> | 3634 | </pre> |
| 3594 | </YueDisplay> | 3635 | </YueDisplay> |
| 3595 | 3636 | ||
| 3596 | YueScript’s **do** can also be used an expression . Allowing you to combine multiple lines into one. The result of the do expression is the last statement in its body. | 3637 | YueScript's **do** can also be used an expression . Allowing you to combine multiple lines into one. The result of the do expression is the last statement in its body. |
| 3597 | 3638 | ||
| 3598 | ```moonscript | 3639 | ```moonscript |
| 3599 | counter = do | 3640 | counter = do |
| @@ -3719,7 +3760,7 @@ print i -- will print 0 | |||
| 3719 | </pre> | 3760 | </pre> |
| 3720 | </YueDisplay> | 3761 | </YueDisplay> |
| 3721 | 3762 | ||
| 3722 | In my_func, we've overwritten the value of i mistakenly. In this example it is quite obvious, but consider a large, or foreign code base where it isn’t clear what names have already been declared. | 3763 | In my_func, we've overwritten the value of i mistakenly. In this example it is quite obvious, but consider a large, or foreign code base where it isn't clear what names have already been declared. |
| 3723 | 3764 | ||
| 3724 | It would be helpful to say which variables from the enclosing scope we intend on change, in order to prevent us from changing others by accident. | 3765 | It would be helpful to say which variables from the enclosing scope we intend on change, in order to prevent us from changing others by accident. |
| 3725 | 3766 | ||
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md index 2d4af18..0fa1fed 100755 --- a/doc/docs/zh/doc/README.md +++ b/doc/docs/zh/doc/README.md | |||
| @@ -1514,6 +1514,47 @@ catch err | |||
| 1514 | </pre> | 1514 | </pre> |
| 1515 | </YueDisplay> | 1515 | </YueDisplay> |
| 1516 | 1516 | ||
| 1517 | ### 错误处理简化 | ||
| 1518 | |||
| 1519 | `try!` 是 `try` 的简化语法,它不再返回 `try` 语句的布尔状态,并在成功时直接返回 `try` 代码块的结果,失败时返回 `nil` 值而非错误对象。 | ||
| 1520 | |||
| 1521 | ```moonscript | ||
| 1522 | a, b, c = try! func! | ||
| 1523 | |||
| 1524 | -- 与空值合并运算符一起使用 | ||
| 1525 | a = (try! func!) ?? "default" | ||
| 1526 | |||
| 1527 | -- 作为函数参数 | ||
| 1528 | f try! func! | ||
| 1529 | |||
| 1530 | -- 带 catch 块的 try! | ||
| 1531 | f try! | ||
| 1532 | print 123 | ||
| 1533 | func! | ||
| 1534 | catch e | ||
| 1535 | print e | ||
| 1536 | e | ||
| 1537 | ``` | ||
| 1538 | <YueDisplay> | ||
| 1539 | <pre> | ||
| 1540 | a, b, c = try! func! | ||
| 1541 | |||
| 1542 | -- 与空值合并运算符一起使用 | ||
| 1543 | a = (try! func!) ?? "default" | ||
| 1544 | |||
| 1545 | -- 作为函数参数 | ||
| 1546 | f try! func! | ||
| 1547 | |||
| 1548 | -- 带 catch 块的 try! | ||
| 1549 | f try! | ||
| 1550 | print 123 | ||
| 1551 | func! | ||
| 1552 | catch e | ||
| 1553 | print e | ||
| 1554 | e | ||
| 1555 | </pre> | ||
| 1556 | </YueDisplay> | ||
| 1557 | |||
| 1517 | ## 属性 | 1558 | ## 属性 |
| 1518 | 1559 | ||
| 1519 | 月之脚本现在提供了Lua 5.4新增的叫做属性的语法支持。在月之脚本编译到的Lua目标版本低于5.4时,你仍然可以同时使用`const`和`close`的属性声明语法,并获得常量检查和作用域回调的功能。 | 1560 | 月之脚本现在提供了Lua 5.4新增的叫做属性的语法支持。在月之脚本编译到的Lua目标版本低于5.4时,你仍然可以同时使用`const`和`close`的属性声明语法,并获得常量检查和作用域回调的功能。 |
diff --git a/spec/inputs/try_catch.yue b/spec/inputs/try_catch.yue index 4e05bc6..f2583b7 100644 --- a/spec/inputs/try_catch.yue +++ b/spec/inputs/try_catch.yue | |||
| @@ -62,6 +62,126 @@ f = -> | |||
| 62 | do | 62 | do |
| 63 | <- x | 63 | <- x |
| 64 | local tb, a, b, c | 64 | local tb, a, b, c |
| 65 | f = -> try tb.f a, b, c | 65 | f1 = -> try tb.f a, b, c |
| 66 | |||
| 67 | do | ||
| 68 | f1 = -> do | ||
| 69 | ok, ... = try func! | ||
| 70 | ... | ||
| 71 | |||
| 72 | do | ||
| 73 | local func | ||
| 74 | a, b, c = try! func! | ||
| 75 | |||
| 76 | do | ||
| 77 | a, b, c = try! func! | ||
| 78 | |||
| 79 | do | ||
| 80 | a = (try! func!) ?? "default" | ||
| 81 | |||
| 82 | do | ||
| 83 | f try! func! | ||
| 84 | |||
| 85 | do | ||
| 86 | f try! | ||
| 87 | print 123 | ||
| 88 | func! | ||
| 89 | catch e | ||
| 90 | print e | ||
| 91 | e | ||
| 66 | 92 | ||
| 67 | nil | 93 | nil |
| 94 | |||
| 95 | do | ||
| 96 | try | ||
| 97 | func 1, 2, 3 | ||
| 98 | catch err | ||
| 99 | print err | ||
| 100 | |||
| 101 | try func 1, 2, 3 | ||
| 102 | catch err | ||
| 103 | print err | ||
| 104 | |||
| 105 | try | ||
| 106 | print "trying" | ||
| 107 | func 1, 2, 3 | ||
| 108 | |||
| 109 | do | ||
| 110 | success, result = try | ||
| 111 | func 1, 2, 3 | ||
| 112 | catch err | ||
| 113 | print err | ||
| 114 | |||
| 115 | success, result = try func 1, 2, 3 | ||
| 116 | |||
| 117 | tb = {} | ||
| 118 | |||
| 119 | try tb.func | ||
| 120 | try tb.func! | ||
| 121 | try tb.func() | ||
| 122 | try (tb.func!) | ||
| 123 | try (tb\func(1, 2, 3)) | ||
| 124 | |||
| 125 | try tb.func 1 | ||
| 126 | try tb.func(1) | ||
| 127 | |||
| 128 | if (try func 1 | ||
| 129 | catch err | ||
| 130 | print err) | ||
| 131 | print "OK" | ||
| 132 | |||
| 133 | if try (func 1) | ||
| 134 | catch err | ||
| 135 | print err | ||
| 136 | print "OK" | ||
| 137 | |||
| 138 | do | ||
| 139 | if success, result := try func "abc", 123 | ||
| 140 | print result | ||
| 141 | |||
| 142 | success, result = try func "abc", 123 | ||
| 143 | catch err | ||
| 144 | print err | ||
| 145 | |||
| 146 | print result if success, result := try func "abc", 123 | ||
| 147 | catch err | ||
| 148 | print err | ||
| 149 | |||
| 150 | do | ||
| 151 | try | ||
| 152 | func 1, 2, 3 | ||
| 153 | |||
| 154 | try func 1, 2, 3 | ||
| 155 | |||
| 156 | do | ||
| 157 | <- x | ||
| 158 | local tb, a, b, c | ||
| 159 | f1 = -> try tb.f a, b, c | ||
| 160 | |||
| 161 | do | ||
| 162 | f1 = -> do | ||
| 163 | ok, ... = try func! | ||
| 164 | ... | ||
| 165 | |||
| 166 | do | ||
| 167 | local func | ||
| 168 | a, b, c = try! func! | ||
| 169 | |||
| 170 | do | ||
| 171 | a, b, c = try! func! | ||
| 172 | |||
| 173 | do | ||
| 174 | a = (try! func!) ?? "default" | ||
| 175 | |||
| 176 | do | ||
| 177 | f try! func! | ||
| 178 | |||
| 179 | do | ||
| 180 | f try! | ||
| 181 | print 123 | ||
| 182 | func! | ||
| 183 | catch e | ||
| 184 | print e | ||
| 185 | e | ||
| 186 | |||
| 187 | nil | ||
diff --git a/spec/outputs/5.1/try_catch.lua b/spec/outputs/5.1/try_catch.lua index efd92c6..d2b58bc 100644 --- a/spec/outputs/5.1/try_catch.lua +++ b/spec/outputs/5.1/try_catch.lua | |||
| @@ -22,6 +22,43 @@ end | |||
| 22 | local _anon_func_7 = function(a, b, c, tb) | 22 | local _anon_func_7 = function(a, b, c, tb) |
| 23 | return tb.f(a, b, c) | 23 | return tb.f(a, b, c) |
| 24 | end | 24 | end |
| 25 | local _anon_func_8 = function(_arg_0, ...) | ||
| 26 | local ok = _arg_0 | ||
| 27 | return ... | ||
| 28 | end | ||
| 29 | local _anon_func_10 = function(_arg_0, ...) | ||
| 30 | local _ok_0 = _arg_0 | ||
| 31 | if _ok_0 then | ||
| 32 | return ... | ||
| 33 | end | ||
| 34 | end | ||
| 35 | local _anon_func_9 = function(func, pcall) | ||
| 36 | return _anon_func_10(pcall(func)) | ||
| 37 | end | ||
| 38 | local _anon_func_12 = function(_arg_0, ...) | ||
| 39 | local _ok_0 = _arg_0 | ||
| 40 | if _ok_0 then | ||
| 41 | return ... | ||
| 42 | end | ||
| 43 | end | ||
| 44 | local _anon_func_11 = function(func, pcall) | ||
| 45 | return _anon_func_12(pcall(func)) | ||
| 46 | end | ||
| 47 | local _anon_func_14 = function(_arg_0, ...) | ||
| 48 | local _ok_0 = _arg_0 | ||
| 49 | if _ok_0 then | ||
| 50 | return ... | ||
| 51 | end | ||
| 52 | end | ||
| 53 | local _anon_func_13 = function(func, print, xpcall) | ||
| 54 | return _anon_func_14(xpcall(function() | ||
| 55 | print(123) | ||
| 56 | return func() | ||
| 57 | end, function(e) | ||
| 58 | print(e) | ||
| 59 | return e | ||
| 60 | end)) | ||
| 61 | end | ||
| 25 | local f | 62 | local f |
| 26 | f = function() | 63 | f = function() |
| 27 | xpcall(function() | 64 | xpcall(function() |
| @@ -104,10 +141,236 @@ f = function() | |||
| 104 | do | 141 | do |
| 105 | x(function() | 142 | x(function() |
| 106 | local tb, a, b, c | 143 | local tb, a, b, c |
| 107 | f = function() | 144 | local f1 |
| 145 | f1 = function() | ||
| 108 | return pcall(_anon_func_7, a, b, c, tb) | 146 | return pcall(_anon_func_7, a, b, c, tb) |
| 109 | end | 147 | end |
| 110 | end) | 148 | end) |
| 111 | end | 149 | end |
| 150 | do | ||
| 151 | local f1 | ||
| 152 | f1 = function() | ||
| 153 | do | ||
| 154 | return _anon_func_8(pcall(function() | ||
| 155 | return func() | ||
| 156 | end)) | ||
| 157 | end | ||
| 158 | end | ||
| 159 | end | ||
| 160 | do | ||
| 161 | local func | ||
| 162 | local a, b, c | ||
| 163 | local _ok_0, _ret_0, _ret_1, _ret_2 = pcall(func) | ||
| 164 | if _ok_0 then | ||
| 165 | a, b, c = _ret_0, _ret_1, _ret_2 | ||
| 166 | end | ||
| 167 | end | ||
| 168 | do | ||
| 169 | local a, b, c | ||
| 170 | local _ok_0, _ret_0, _ret_1, _ret_2 = pcall(function() | ||
| 171 | return func() | ||
| 172 | end) | ||
| 173 | if _ok_0 then | ||
| 174 | a, b, c = _ret_0, _ret_1, _ret_2 | ||
| 175 | end | ||
| 176 | end | ||
| 177 | do | ||
| 178 | local a | ||
| 179 | local _exp_0 = (_anon_func_9(func, pcall)) | ||
| 180 | if _exp_0 ~= nil then | ||
| 181 | a = _exp_0 | ||
| 182 | else | ||
| 183 | a = "default" | ||
| 184 | end | ||
| 185 | end | ||
| 186 | do | ||
| 187 | f(_anon_func_11(func, pcall)) | ||
| 188 | end | ||
| 189 | do | ||
| 190 | f(_anon_func_13(func, print, xpcall)) | ||
| 191 | end | ||
| 112 | return nil | 192 | return nil |
| 113 | end | 193 | end |
| 194 | local _anon_func_15 = function(a, b, c, tb) | ||
| 195 | return tb.f(a, b, c) | ||
| 196 | end | ||
| 197 | local _anon_func_16 = function(_arg_0, ...) | ||
| 198 | local ok = _arg_0 | ||
| 199 | return ... | ||
| 200 | end | ||
| 201 | do | ||
| 202 | xpcall(function() | ||
| 203 | return func(1, 2, 3) | ||
| 204 | end, function(err) | ||
| 205 | return print(err) | ||
| 206 | end) | ||
| 207 | xpcall(function() | ||
| 208 | return func(1, 2, 3) | ||
| 209 | end, function(err) | ||
| 210 | return print(err) | ||
| 211 | end) | ||
| 212 | pcall(function() | ||
| 213 | print("trying") | ||
| 214 | return func(1, 2, 3) | ||
| 215 | end) | ||
| 216 | do | ||
| 217 | local success, result = xpcall(function() | ||
| 218 | return func(1, 2, 3) | ||
| 219 | end, function(err) | ||
| 220 | return print(err) | ||
| 221 | end) | ||
| 222 | success, result = pcall(function() | ||
| 223 | return func(1, 2, 3) | ||
| 224 | end) | ||
| 225 | end | ||
| 226 | local tb = { } | ||
| 227 | pcall(function() | ||
| 228 | return tb.func | ||
| 229 | end) | ||
| 230 | pcall(function() | ||
| 231 | return tb.func() | ||
| 232 | end) | ||
| 233 | pcall(function() | ||
| 234 | return tb.func() | ||
| 235 | end) | ||
| 236 | pcall(function() | ||
| 237 | return (tb.func()) | ||
| 238 | end) | ||
| 239 | pcall(function() | ||
| 240 | return (tb:func(1, 2, 3)) | ||
| 241 | end) | ||
| 242 | pcall(function() | ||
| 243 | return tb.func(1) | ||
| 244 | end) | ||
| 245 | pcall(function() | ||
| 246 | return tb.func(1) | ||
| 247 | end) | ||
| 248 | if (xpcall(function() | ||
| 249 | return func(1) | ||
| 250 | end, function(err) | ||
| 251 | return print(err) | ||
| 252 | end)) then | ||
| 253 | print("OK") | ||
| 254 | end | ||
| 255 | if xpcall(function() | ||
| 256 | return (func(1)) | ||
| 257 | end, function(err) | ||
| 258 | return print(err) | ||
| 259 | end) then | ||
| 260 | print("OK") | ||
| 261 | end | ||
| 262 | do | ||
| 263 | do | ||
| 264 | local success, result = pcall(function() | ||
| 265 | return func("abc", 123) | ||
| 266 | end) | ||
| 267 | if success then | ||
| 268 | print(result) | ||
| 269 | end | ||
| 270 | end | ||
| 271 | local success, result = xpcall(function() | ||
| 272 | return func("abc", 123) | ||
| 273 | end, function(err) | ||
| 274 | return print(err) | ||
| 275 | end) | ||
| 276 | success, result = xpcall(function() | ||
| 277 | return func("abc", 123) | ||
| 278 | end, function(err) | ||
| 279 | return print(err) | ||
| 280 | end) | ||
| 281 | if success then | ||
| 282 | print(result) | ||
| 283 | end | ||
| 284 | end | ||
| 285 | do | ||
| 286 | pcall(function() | ||
| 287 | return func(1, 2, 3) | ||
| 288 | end) | ||
| 289 | pcall(function() | ||
| 290 | return func(1, 2, 3) | ||
| 291 | end) | ||
| 292 | end | ||
| 293 | do | ||
| 294 | x(function() | ||
| 295 | local tb, a, b, c | ||
| 296 | local f1 | ||
| 297 | f1 = function() | ||
| 298 | return pcall(_anon_func_15, a, b, c, tb) | ||
| 299 | end | ||
| 300 | end) | ||
| 301 | end | ||
| 302 | do | ||
| 303 | local f1 | ||
| 304 | f1 = function() | ||
| 305 | do | ||
| 306 | return _anon_func_16(pcall(function() | ||
| 307 | return func() | ||
| 308 | end)) | ||
| 309 | end | ||
| 310 | end | ||
| 311 | end | ||
| 312 | do | ||
| 313 | local func | ||
| 314 | local a, b, c | ||
| 315 | local _ok_0, _ret_0, _ret_1, _ret_2 = pcall(func) | ||
| 316 | if _ok_0 then | ||
| 317 | a, b, c = _ret_0, _ret_1, _ret_2 | ||
| 318 | end | ||
| 319 | end | ||
| 320 | do | ||
| 321 | local a, b, c | ||
| 322 | local _ok_0, _ret_0, _ret_1, _ret_2 = pcall(function() | ||
| 323 | return func() | ||
| 324 | end) | ||
| 325 | if _ok_0 then | ||
| 326 | a, b, c = _ret_0, _ret_1, _ret_2 | ||
| 327 | end | ||
| 328 | end | ||
| 329 | do | ||
| 330 | local a | ||
| 331 | local _exp_0 = ((function() | ||
| 332 | return (function(_arg_0, ...) | ||
| 333 | local _ok_0 = _arg_0 | ||
| 334 | if _ok_0 then | ||
| 335 | return ... | ||
| 336 | end | ||
| 337 | end)(pcall(function() | ||
| 338 | return func() | ||
| 339 | end)) | ||
| 340 | end)()) | ||
| 341 | if _exp_0 ~= nil then | ||
| 342 | a = _exp_0 | ||
| 343 | else | ||
| 344 | a = "default" | ||
| 345 | end | ||
| 346 | end | ||
| 347 | do | ||
| 348 | f((function() | ||
| 349 | return (function(_arg_0, ...) | ||
| 350 | local _ok_0 = _arg_0 | ||
| 351 | if _ok_0 then | ||
| 352 | return ... | ||
| 353 | end | ||
| 354 | end)(pcall(function() | ||
| 355 | return func() | ||
| 356 | end)) | ||
| 357 | end)()) | ||
| 358 | end | ||
| 359 | do | ||
| 360 | f((function() | ||
| 361 | return (function(_arg_0, ...) | ||
| 362 | local _ok_0 = _arg_0 | ||
| 363 | if _ok_0 then | ||
| 364 | return ... | ||
| 365 | end | ||
| 366 | end)(xpcall(function() | ||
| 367 | print(123) | ||
| 368 | return func() | ||
| 369 | end, function(e) | ||
| 370 | print(e) | ||
| 371 | return e | ||
| 372 | end)) | ||
| 373 | end)()) | ||
| 374 | end | ||
| 375 | end | ||
| 376 | return nil | ||
diff --git a/spec/outputs/assign.lua b/spec/outputs/assign.lua index 162c5a8..89c5f8a 100644 --- a/spec/outputs/assign.lua +++ b/spec/outputs/assign.lua | |||
| @@ -43,10 +43,8 @@ do | |||
| 43 | end | 43 | end |
| 44 | end | 44 | end |
| 45 | local _anon_func_0 = function(print) | 45 | local _anon_func_0 = function(print) |
| 46 | do | 46 | print(123) |
| 47 | print(123) | 47 | return { } |
| 48 | return { } | ||
| 49 | end | ||
| 50 | end | 48 | end |
| 51 | return _(function() | 49 | return _(function() |
| 52 | setmetatable(a, _anon_func_0(print)) | 50 | setmetatable(a, _anon_func_0(print)) |
diff --git a/spec/outputs/codes_from_doc.lua b/spec/outputs/codes_from_doc.lua index 55be7df..cce0516 100644 --- a/spec/outputs/codes_from_doc.lua +++ b/spec/outputs/codes_from_doc.lua | |||
| @@ -688,6 +688,56 @@ end) | |||
| 688 | if success then | 688 | if success then |
| 689 | print(result) | 689 | print(result) |
| 690 | end | 690 | end |
| 691 | local a, b, c | ||
| 692 | do | ||
| 693 | local _ok_0, _ret_0, _ret_1, _ret_2 = pcall(function() | ||
| 694 | return func() | ||
| 695 | end) | ||
| 696 | if _ok_0 then | ||
| 697 | a, b, c = _ret_0, _ret_1, _ret_2 | ||
| 698 | end | ||
| 699 | end | ||
| 700 | do | ||
| 701 | local _exp_0 = ((function() | ||
| 702 | return (function(_arg_0, ...) | ||
| 703 | local _ok_0 = _arg_0 | ||
| 704 | if _ok_0 then | ||
| 705 | return ... | ||
| 706 | end | ||
| 707 | end)(pcall(function() | ||
| 708 | return func() | ||
| 709 | end)) | ||
| 710 | end)()) | ||
| 711 | if _exp_0 ~= nil then | ||
| 712 | a = _exp_0 | ||
| 713 | else | ||
| 714 | a = "default" | ||
| 715 | end | ||
| 716 | end | ||
| 717 | f((function() | ||
| 718 | return (function(_arg_0, ...) | ||
| 719 | local _ok_0 = _arg_0 | ||
| 720 | if _ok_0 then | ||
| 721 | return ... | ||
| 722 | end | ||
| 723 | end)(pcall(function() | ||
| 724 | return func() | ||
| 725 | end)) | ||
| 726 | end)()) | ||
| 727 | f((function() | ||
| 728 | return (function(_arg_0, ...) | ||
| 729 | local _ok_0 = _arg_0 | ||
| 730 | if _ok_0 then | ||
| 731 | return ... | ||
| 732 | end | ||
| 733 | end)(xpcall(function() | ||
| 734 | print(123) | ||
| 735 | return func() | ||
| 736 | end, function(e) | ||
| 737 | print(e) | ||
| 738 | return e | ||
| 739 | end)) | ||
| 740 | end)()) | ||
| 691 | local a <const> = 123 | 741 | local a <const> = 123 |
| 692 | local _ <close> = setmetatable({ }, { | 742 | local _ <close> = setmetatable({ }, { |
| 693 | __close = function() | 743 | __close = function() |
| @@ -2909,6 +2959,56 @@ end) | |||
| 2909 | if success then | 2959 | if success then |
| 2910 | print(result) | 2960 | print(result) |
| 2911 | end | 2961 | end |
| 2962 | local a, b, c | ||
| 2963 | do | ||
| 2964 | local _ok_0, _ret_0, _ret_1, _ret_2 = pcall(function() | ||
| 2965 | return func() | ||
| 2966 | end) | ||
| 2967 | if _ok_0 then | ||
| 2968 | a, b, c = _ret_0, _ret_1, _ret_2 | ||
| 2969 | end | ||
| 2970 | end | ||
| 2971 | do | ||
| 2972 | local _exp_0 = ((function() | ||
| 2973 | return (function(_arg_0, ...) | ||
| 2974 | local _ok_0 = _arg_0 | ||
| 2975 | if _ok_0 then | ||
| 2976 | return ... | ||
| 2977 | end | ||
| 2978 | end)(pcall(function() | ||
| 2979 | return func() | ||
| 2980 | end)) | ||
| 2981 | end)()) | ||
| 2982 | if _exp_0 ~= nil then | ||
| 2983 | a = _exp_0 | ||
| 2984 | else | ||
| 2985 | a = "default" | ||
| 2986 | end | ||
| 2987 | end | ||
| 2988 | f((function() | ||
| 2989 | return (function(_arg_0, ...) | ||
| 2990 | local _ok_0 = _arg_0 | ||
| 2991 | if _ok_0 then | ||
| 2992 | return ... | ||
| 2993 | end | ||
| 2994 | end)(pcall(function() | ||
| 2995 | return func() | ||
| 2996 | end)) | ||
| 2997 | end)()) | ||
| 2998 | f((function() | ||
| 2999 | return (function(_arg_0, ...) | ||
| 3000 | local _ok_0 = _arg_0 | ||
| 3001 | if _ok_0 then | ||
| 3002 | return ... | ||
| 3003 | end | ||
| 3004 | end)(xpcall(function() | ||
| 3005 | print(123) | ||
| 3006 | return func() | ||
| 3007 | end, function(e) | ||
| 3008 | print(e) | ||
| 3009 | return e | ||
| 3010 | end)) | ||
| 3011 | end)()) | ||
| 2912 | local a <const> = 123 | 3012 | local a <const> = 123 |
| 2913 | local _ <close> = setmetatable({ }, { | 3013 | local _ <close> = setmetatable({ }, { |
| 2914 | __close = function() | 3014 | __close = function() |
diff --git a/spec/outputs/codes_from_doc_zh.lua b/spec/outputs/codes_from_doc_zh.lua index 399f8c1..e267709 100644 --- a/spec/outputs/codes_from_doc_zh.lua +++ b/spec/outputs/codes_from_doc_zh.lua | |||
| @@ -688,6 +688,56 @@ end) | |||
| 688 | if success then | 688 | if success then |
| 689 | print(result) | 689 | print(result) |
| 690 | end | 690 | end |
| 691 | local a, b, c | ||
| 692 | do | ||
| 693 | local _ok_0, _ret_0, _ret_1, _ret_2 = pcall(function() | ||
| 694 | return func() | ||
| 695 | end) | ||
| 696 | if _ok_0 then | ||
| 697 | a, b, c = _ret_0, _ret_1, _ret_2 | ||
| 698 | end | ||
| 699 | end | ||
| 700 | do | ||
| 701 | local _exp_0 = ((function() | ||
| 702 | return (function(_arg_0, ...) | ||
| 703 | local _ok_0 = _arg_0 | ||
| 704 | if _ok_0 then | ||
| 705 | return ... | ||
| 706 | end | ||
| 707 | end)(pcall(function() | ||
| 708 | return func() | ||
| 709 | end)) | ||
| 710 | end)()) | ||
| 711 | if _exp_0 ~= nil then | ||
| 712 | a = _exp_0 | ||
| 713 | else | ||
| 714 | a = "default" | ||
| 715 | end | ||
| 716 | end | ||
| 717 | f((function() | ||
| 718 | return (function(_arg_0, ...) | ||
| 719 | local _ok_0 = _arg_0 | ||
| 720 | if _ok_0 then | ||
| 721 | return ... | ||
| 722 | end | ||
| 723 | end)(pcall(function() | ||
| 724 | return func() | ||
| 725 | end)) | ||
| 726 | end)()) | ||
| 727 | f((function() | ||
| 728 | return (function(_arg_0, ...) | ||
| 729 | local _ok_0 = _arg_0 | ||
| 730 | if _ok_0 then | ||
| 731 | return ... | ||
| 732 | end | ||
| 733 | end)(xpcall(function() | ||
| 734 | print(123) | ||
| 735 | return func() | ||
| 736 | end, function(e) | ||
| 737 | print(e) | ||
| 738 | return e | ||
| 739 | end)) | ||
| 740 | end)()) | ||
| 691 | local a <const> = 123 | 741 | local a <const> = 123 |
| 692 | local _ <close> = setmetatable({ }, { | 742 | local _ <close> = setmetatable({ }, { |
| 693 | __close = function() | 743 | __close = function() |
| @@ -2903,6 +2953,56 @@ end) | |||
| 2903 | if success then | 2953 | if success then |
| 2904 | print(result) | 2954 | print(result) |
| 2905 | end | 2955 | end |
| 2956 | local a, b, c | ||
| 2957 | do | ||
| 2958 | local _ok_0, _ret_0, _ret_1, _ret_2 = pcall(function() | ||
| 2959 | return func() | ||
| 2960 | end) | ||
| 2961 | if _ok_0 then | ||
| 2962 | a, b, c = _ret_0, _ret_1, _ret_2 | ||
| 2963 | end | ||
| 2964 | end | ||
| 2965 | do | ||
| 2966 | local _exp_0 = ((function() | ||
| 2967 | return (function(_arg_0, ...) | ||
| 2968 | local _ok_0 = _arg_0 | ||
| 2969 | if _ok_0 then | ||
| 2970 | return ... | ||
| 2971 | end | ||
| 2972 | end)(pcall(function() | ||
| 2973 | return func() | ||
| 2974 | end)) | ||
| 2975 | end)()) | ||
| 2976 | if _exp_0 ~= nil then | ||
| 2977 | a = _exp_0 | ||
| 2978 | else | ||
| 2979 | a = "default" | ||
| 2980 | end | ||
| 2981 | end | ||
| 2982 | f((function() | ||
| 2983 | return (function(_arg_0, ...) | ||
| 2984 | local _ok_0 = _arg_0 | ||
| 2985 | if _ok_0 then | ||
| 2986 | return ... | ||
| 2987 | end | ||
| 2988 | end)(pcall(function() | ||
| 2989 | return func() | ||
| 2990 | end)) | ||
| 2991 | end)()) | ||
| 2992 | f((function() | ||
| 2993 | return (function(_arg_0, ...) | ||
| 2994 | local _ok_0 = _arg_0 | ||
| 2995 | if _ok_0 then | ||
| 2996 | return ... | ||
| 2997 | end | ||
| 2998 | end)(xpcall(function() | ||
| 2999 | print(123) | ||
| 3000 | return func() | ||
| 3001 | end, function(e) | ||
| 3002 | print(e) | ||
| 3003 | return e | ||
| 3004 | end)) | ||
| 3005 | end)()) | ||
| 2906 | local a <const> = 123 | 3006 | local a <const> = 123 |
| 2907 | local _ <close> = setmetatable({ }, { | 3007 | local _ <close> = setmetatable({ }, { |
| 2908 | __close = function() | 3008 | __close = function() |
diff --git a/spec/outputs/try_catch.lua b/spec/outputs/try_catch.lua index efd92c6..edb2341 100644 --- a/spec/outputs/try_catch.lua +++ b/spec/outputs/try_catch.lua | |||
| @@ -22,6 +22,44 @@ end | |||
| 22 | local _anon_func_7 = function(a, b, c, tb) | 22 | local _anon_func_7 = function(a, b, c, tb) |
| 23 | return tb.f(a, b, c) | 23 | return tb.f(a, b, c) |
| 24 | end | 24 | end |
| 25 | local _anon_func_8 = function(_arg_0, ...) | ||
| 26 | local ok = _arg_0 | ||
| 27 | return ... | ||
| 28 | end | ||
| 29 | local _anon_func_10 = function(_arg_0, ...) | ||
| 30 | local _ok_0 = _arg_0 | ||
| 31 | if _ok_0 then | ||
| 32 | return ... | ||
| 33 | end | ||
| 34 | end | ||
| 35 | local _anon_func_9 = function(func, pcall) | ||
| 36 | return _anon_func_10(pcall(func)) | ||
| 37 | end | ||
| 38 | local _anon_func_12 = function(_arg_0, ...) | ||
| 39 | local _ok_0 = _arg_0 | ||
| 40 | if _ok_0 then | ||
| 41 | return ... | ||
| 42 | end | ||
| 43 | end | ||
| 44 | local _anon_func_11 = function(func, pcall) | ||
| 45 | return _anon_func_12(pcall(func)) | ||
| 46 | end | ||
| 47 | local _anon_func_14 = function(_arg_0, ...) | ||
| 48 | local _ok_0 = _arg_0 | ||
| 49 | if _ok_0 then | ||
| 50 | return ... | ||
| 51 | end | ||
| 52 | end | ||
| 53 | local _anon_func_15 = function(func, print) | ||
| 54 | print(123) | ||
| 55 | return func() | ||
| 56 | end | ||
| 57 | local _anon_func_13 = function(func, print, xpcall) | ||
| 58 | return _anon_func_14(xpcall(_anon_func_15, function(e) | ||
| 59 | print(e) | ||
| 60 | return e | ||
| 61 | end, func, print)) | ||
| 62 | end | ||
| 25 | local f | 63 | local f |
| 26 | f = function() | 64 | f = function() |
| 27 | xpcall(function() | 65 | xpcall(function() |
| @@ -104,10 +142,236 @@ f = function() | |||
| 104 | do | 142 | do |
| 105 | x(function() | 143 | x(function() |
| 106 | local tb, a, b, c | 144 | local tb, a, b, c |
| 107 | f = function() | 145 | local f1 |
| 146 | f1 = function() | ||
| 108 | return pcall(_anon_func_7, a, b, c, tb) | 147 | return pcall(_anon_func_7, a, b, c, tb) |
| 109 | end | 148 | end |
| 110 | end) | 149 | end) |
| 111 | end | 150 | end |
| 151 | do | ||
| 152 | local f1 | ||
| 153 | f1 = function() | ||
| 154 | do | ||
| 155 | return _anon_func_8(pcall(function() | ||
| 156 | return func() | ||
| 157 | end)) | ||
| 158 | end | ||
| 159 | end | ||
| 160 | end | ||
| 161 | do | ||
| 162 | local func | ||
| 163 | local a, b, c | ||
| 164 | local _ok_0, _ret_0, _ret_1, _ret_2 = pcall(func) | ||
| 165 | if _ok_0 then | ||
| 166 | a, b, c = _ret_0, _ret_1, _ret_2 | ||
| 167 | end | ||
| 168 | end | ||
| 169 | do | ||
| 170 | local a, b, c | ||
| 171 | local _ok_0, _ret_0, _ret_1, _ret_2 = pcall(function() | ||
| 172 | return func() | ||
| 173 | end) | ||
| 174 | if _ok_0 then | ||
| 175 | a, b, c = _ret_0, _ret_1, _ret_2 | ||
| 176 | end | ||
| 177 | end | ||
| 178 | do | ||
| 179 | local a | ||
| 180 | local _exp_0 = (_anon_func_9(func, pcall)) | ||
| 181 | if _exp_0 ~= nil then | ||
| 182 | a = _exp_0 | ||
| 183 | else | ||
| 184 | a = "default" | ||
| 185 | end | ||
| 186 | end | ||
| 187 | do | ||
| 188 | f(_anon_func_11(func, pcall)) | ||
| 189 | end | ||
| 190 | do | ||
| 191 | f(_anon_func_13(func, print, xpcall)) | ||
| 192 | end | ||
| 112 | return nil | 193 | return nil |
| 113 | end | 194 | end |
| 195 | local _anon_func_16 = function(a, b, c, tb) | ||
| 196 | return tb.f(a, b, c) | ||
| 197 | end | ||
| 198 | local _anon_func_17 = function(_arg_0, ...) | ||
| 199 | local ok = _arg_0 | ||
| 200 | return ... | ||
| 201 | end | ||
| 202 | do | ||
| 203 | xpcall(function() | ||
| 204 | return func(1, 2, 3) | ||
| 205 | end, function(err) | ||
| 206 | return print(err) | ||
| 207 | end) | ||
| 208 | xpcall(function() | ||
| 209 | return func(1, 2, 3) | ||
| 210 | end, function(err) | ||
| 211 | return print(err) | ||
| 212 | end) | ||
| 213 | pcall(function() | ||
| 214 | print("trying") | ||
| 215 | return func(1, 2, 3) | ||
| 216 | end) | ||
| 217 | do | ||
| 218 | local success, result = xpcall(function() | ||
| 219 | return func(1, 2, 3) | ||
| 220 | end, function(err) | ||
| 221 | return print(err) | ||
| 222 | end) | ||
| 223 | success, result = pcall(function() | ||
| 224 | return func(1, 2, 3) | ||
| 225 | end) | ||
| 226 | end | ||
| 227 | local tb = { } | ||
| 228 | pcall(function() | ||
| 229 | return tb.func | ||
| 230 | end) | ||
| 231 | pcall(function() | ||
| 232 | return tb.func() | ||
| 233 | end) | ||
| 234 | pcall(function() | ||
| 235 | return tb.func() | ||
| 236 | end) | ||
| 237 | pcall(function() | ||
| 238 | return (tb.func()) | ||
| 239 | end) | ||
| 240 | pcall(function() | ||
| 241 | return (tb:func(1, 2, 3)) | ||
| 242 | end) | ||
| 243 | pcall(function() | ||
| 244 | return tb.func(1) | ||
| 245 | end) | ||
| 246 | pcall(function() | ||
| 247 | return tb.func(1) | ||
| 248 | end) | ||
| 249 | if (xpcall(function() | ||
| 250 | return func(1) | ||
| 251 | end, function(err) | ||
| 252 | return print(err) | ||
| 253 | end)) then | ||
| 254 | print("OK") | ||
| 255 | end | ||
| 256 | if xpcall(function() | ||
| 257 | return (func(1)) | ||
| 258 | end, function(err) | ||
| 259 | return print(err) | ||
| 260 | end) then | ||
| 261 | print("OK") | ||
| 262 | end | ||
| 263 | do | ||
| 264 | do | ||
| 265 | local success, result = pcall(function() | ||
| 266 | return func("abc", 123) | ||
| 267 | end) | ||
| 268 | if success then | ||
| 269 | print(result) | ||
| 270 | end | ||
| 271 | end | ||
| 272 | local success, result = xpcall(function() | ||
| 273 | return func("abc", 123) | ||
| 274 | end, function(err) | ||
| 275 | return print(err) | ||
| 276 | end) | ||
| 277 | success, result = xpcall(function() | ||
| 278 | return func("abc", 123) | ||
| 279 | end, function(err) | ||
| 280 | return print(err) | ||
| 281 | end) | ||
| 282 | if success then | ||
| 283 | print(result) | ||
| 284 | end | ||
| 285 | end | ||
| 286 | do | ||
| 287 | pcall(function() | ||
| 288 | return func(1, 2, 3) | ||
| 289 | end) | ||
| 290 | pcall(function() | ||
| 291 | return func(1, 2, 3) | ||
| 292 | end) | ||
| 293 | end | ||
| 294 | do | ||
| 295 | x(function() | ||
| 296 | local tb, a, b, c | ||
| 297 | local f1 | ||
| 298 | f1 = function() | ||
| 299 | return pcall(_anon_func_16, a, b, c, tb) | ||
| 300 | end | ||
| 301 | end) | ||
| 302 | end | ||
| 303 | do | ||
| 304 | local f1 | ||
| 305 | f1 = function() | ||
| 306 | do | ||
| 307 | return _anon_func_17(pcall(function() | ||
| 308 | return func() | ||
| 309 | end)) | ||
| 310 | end | ||
| 311 | end | ||
| 312 | end | ||
| 313 | do | ||
| 314 | local func | ||
| 315 | local a, b, c | ||
| 316 | local _ok_0, _ret_0, _ret_1, _ret_2 = pcall(func) | ||
| 317 | if _ok_0 then | ||
| 318 | a, b, c = _ret_0, _ret_1, _ret_2 | ||
| 319 | end | ||
| 320 | end | ||
| 321 | do | ||
| 322 | local a, b, c | ||
| 323 | local _ok_0, _ret_0, _ret_1, _ret_2 = pcall(function() | ||
| 324 | return func() | ||
| 325 | end) | ||
| 326 | if _ok_0 then | ||
| 327 | a, b, c = _ret_0, _ret_1, _ret_2 | ||
| 328 | end | ||
| 329 | end | ||
| 330 | do | ||
| 331 | local a | ||
| 332 | local _exp_0 = ((function() | ||
| 333 | return (function(_arg_0, ...) | ||
| 334 | local _ok_0 = _arg_0 | ||
| 335 | if _ok_0 then | ||
| 336 | return ... | ||
| 337 | end | ||
| 338 | end)(pcall(function() | ||
| 339 | return func() | ||
| 340 | end)) | ||
| 341 | end)()) | ||
| 342 | if _exp_0 ~= nil then | ||
| 343 | a = _exp_0 | ||
| 344 | else | ||
| 345 | a = "default" | ||
| 346 | end | ||
| 347 | end | ||
| 348 | do | ||
| 349 | f((function() | ||
| 350 | return (function(_arg_0, ...) | ||
| 351 | local _ok_0 = _arg_0 | ||
| 352 | if _ok_0 then | ||
| 353 | return ... | ||
| 354 | end | ||
| 355 | end)(pcall(function() | ||
| 356 | return func() | ||
| 357 | end)) | ||
| 358 | end)()) | ||
| 359 | end | ||
| 360 | do | ||
| 361 | f((function() | ||
| 362 | return (function(_arg_0, ...) | ||
| 363 | local _ok_0 = _arg_0 | ||
| 364 | if _ok_0 then | ||
| 365 | return ... | ||
| 366 | end | ||
| 367 | end)(xpcall(function() | ||
| 368 | print(123) | ||
| 369 | return func() | ||
| 370 | end, function(e) | ||
| 371 | print(e) | ||
| 372 | return e | ||
| 373 | end)) | ||
| 374 | end)()) | ||
| 375 | end | ||
| 376 | end | ||
| 377 | return nil | ||
diff --git a/spec/outputs/unicode/assign.lua b/spec/outputs/unicode/assign.lua index d4ad56a..e00d016 100644 --- a/spec/outputs/unicode/assign.lua +++ b/spec/outputs/unicode/assign.lua | |||
| @@ -43,10 +43,8 @@ do | |||
| 43 | end | 43 | end |
| 44 | end | 44 | end |
| 45 | local _anon_func_0 = function(_u6253_u5370) | 45 | local _anon_func_0 = function(_u6253_u5370) |
| 46 | do | 46 | _u6253_u5370(123) |
| 47 | _u6253_u5370(123) | 47 | return { } |
| 48 | return { } | ||
| 49 | end | ||
| 50 | end | 48 | end |
| 51 | return __u65e0_u6548_u53d8_u91cf(function() | 49 | return __u65e0_u6548_u53d8_u91cf(function() |
| 52 | setmetatable(a_u53d8_u91cf, _anon_func_0(_u6253_u5370)) | 50 | setmetatable(a_u53d8_u91cf, _anon_func_0(_u6253_u5370)) |
diff --git a/spec/outputs/unicode/macro.lua b/spec/outputs/unicode/macro.lua index 3b9327a..b4e78cd 100644 --- a/spec/outputs/unicode/macro.lua +++ b/spec/outputs/unicode/macro.lua | |||
| @@ -216,17 +216,15 @@ do | |||
| 216 | end | 216 | end |
| 217 | local _ = require('下划线') | 217 | local _ = require('下划线') |
| 218 | local _anon_func_0 = function(_) | 218 | local _anon_func_0 = function(_) |
| 219 | do | 219 | local _call_0 = (_({ |
| 220 | local _call_0 = (_({ | 220 | 1, |
| 221 | 1, | 221 | 2, |
| 222 | 2, | 222 | 3, |
| 223 | 3, | 223 | 4, |
| 224 | 4, | 224 | -2, |
| 225 | -2, | 225 | 3 |
| 226 | 3 | 226 | })) |
| 227 | })) | 227 | return _call_0["链"](_call_0) |
| 228 | return _call_0["链"](_call_0) | ||
| 229 | end | ||
| 230 | end | 228 | end |
| 231 | local _call_0 = ((function() | 229 | local _call_0 = ((function() |
| 232 | local _call_0 = ((function() | 230 | local _call_0 = ((function() |
| @@ -241,17 +239,15 @@ local _call_0 = ((function() | |||
| 241 | end)()) | 239 | end)()) |
| 242 | local _u7ed3_u679ca = _call_0["取值"](_call_0) | 240 | local _u7ed3_u679ca = _call_0["取值"](_call_0) |
| 243 | local _anon_func_1 = function(_) | 241 | local _anon_func_1 = function(_) |
| 244 | do | 242 | local _call_1 = (_({ |
| 245 | local _call_1 = (_({ | 243 | 1, |
| 246 | 1, | 244 | 2, |
| 247 | 2, | 245 | 3, |
| 248 | 3, | 246 | 4, |
| 249 | 4, | 247 | -2, |
| 250 | -2, | 248 | 3 |
| 251 | 3 | 249 | })) |
| 252 | })) | 250 | return _call_1["链"](_call_1) |
| 253 | return _call_1["链"](_call_1) | ||
| 254 | end | ||
| 255 | end | 251 | end |
| 256 | do | 252 | do |
| 257 | local _call_1 = ((function() | 253 | local _call_1 = ((function() |
| @@ -270,10 +266,8 @@ do | |||
| 270 | end) | 266 | end) |
| 271 | end | 267 | end |
| 272 | local _anon_func_2 = function(_u539f_u70b9) | 268 | local _anon_func_2 = function(_u539f_u70b9) |
| 273 | do | 269 | local _call_1 = _u539f_u70b9["变换"]["根节点"]["游戏对象"] |
| 274 | local _call_1 = _u539f_u70b9["变换"]["根节点"]["游戏对象"] | 270 | return _call_1["父节点"](_call_1) |
| 275 | return _call_1["父节点"](_call_1) | ||
| 276 | end | ||
| 277 | end | 271 | end |
| 278 | local _call_1 = ((function() | 272 | local _call_1 = ((function() |
| 279 | local _call_1 = ((function() | 273 | local _call_1 = ((function() |
diff --git a/spec/outputs/unicode/multiline_chain.lua b/spec/outputs/unicode/multiline_chain.lua index c1da13f..61e7057 100644 --- a/spec/outputs/unicode/multiline_chain.lua +++ b/spec/outputs/unicode/multiline_chain.lua | |||
| @@ -59,10 +59,8 @@ _u51fd_u6570 = function() | |||
| 59 | return _accum_0 | 59 | return _accum_0 |
| 60 | end | 60 | end |
| 61 | local _anon_func_0 = function(_u53d8_u91cfa) | 61 | local _anon_func_0 = function(_u53d8_u91cfa) |
| 62 | do | 62 | local _call_1 = _u53d8_u91cfa |
| 63 | local _call_1 = _u53d8_u91cfa | 63 | return (_call_1["变量b"](_call_1, 123))["变量c"]("abc") |
| 64 | return (_call_1["变量b"](_call_1, 123))["变量c"]("abc") | ||
| 65 | end | ||
| 66 | end | 64 | end |
| 67 | local _u51fd_u65701 | 65 | local _u51fd_u65701 |
| 68 | _u51fd_u65701 = function() | 66 | _u51fd_u65701 = function() |
diff --git a/spec/outputs/unicode/syntax.lua b/spec/outputs/unicode/syntax.lua index 1984f40..a13302b 100644 --- a/spec/outputs/unicode/syntax.lua +++ b/spec/outputs/unicode/syntax.lua | |||
| @@ -286,10 +286,8 @@ _ = 5 - _u4ec0_u4e48(_u65e0_u804a) | |||
| 286 | _u4ec0_u4e48(_u65e0_u804a - 5) | 286 | _u4ec0_u4e48(_u65e0_u804a - 5) |
| 287 | _u53d8_u91cfx = _u4f60_u597d - _u4e16_u754c - _u67d0_u7269 | 287 | _u53d8_u91cfx = _u4f60_u597d - _u4e16_u754c - _u67d0_u7269 |
| 288 | local _anon_func_0 = function(_u4ec0_u4e48) | 288 | local _anon_func_0 = function(_u4ec0_u4e48) |
| 289 | do | 289 | local _call_8 = _u4ec0_u4e48 |
| 290 | local _call_8 = _u4ec0_u4e48 | 290 | return _call_8["酷"](_call_8, 100) |
| 291 | return _call_8["酷"](_call_8, 100) | ||
| 292 | end | ||
| 293 | end | 291 | end |
| 294 | (function(_u67d0_u7269) | 292 | (function(_u67d0_u7269) |
| 295 | if _u67d0_u7269 == nil then | 293 | if _u67d0_u7269 == nil then |
diff --git a/spec/outputs/unicode/vararg.lua b/spec/outputs/unicode/vararg.lua index b837006..fc894ff 100644 --- a/spec/outputs/unicode/vararg.lua +++ b/spec/outputs/unicode/vararg.lua | |||
| @@ -125,14 +125,10 @@ local _anon_func_11 = function(_u9879_u76ee, ...) | |||
| 125 | return _tbl_0 | 125 | return _tbl_0 |
| 126 | end | 126 | end |
| 127 | local _anon_func_12 = function(_u51fd_u6570) | 127 | local _anon_func_12 = function(_u51fd_u6570) |
| 128 | do | 128 | return _u51fd_u6570() |
| 129 | return _u51fd_u6570() | ||
| 130 | end | ||
| 131 | end | 129 | end |
| 132 | local _anon_func_13 = function(_u51fd_u6570, ...) | 130 | local _anon_func_13 = function(_u51fd_u6570, ...) |
| 133 | do | 131 | return _u51fd_u6570(...) |
| 134 | return _u51fd_u6570(...) | ||
| 135 | end | ||
| 136 | end | 132 | end |
| 137 | local _anon_func_14 = function(_u51fd_u6570) | 133 | local _anon_func_14 = function(_u51fd_u6570) |
| 138 | local _accum_0 = { } | 134 | local _accum_0 = { } |
| @@ -195,15 +191,11 @@ local _anon_func_23 = function(_u51fd_u6570, ...) | |||
| 195 | return nil | 191 | return nil |
| 196 | end | 192 | end |
| 197 | local _anon_func_24 = function(_u6253_u5370, select, ...) | 193 | local _anon_func_24 = function(_u6253_u5370, select, ...) |
| 198 | do | 194 | _u6253_u5370(select("#", ...)) |
| 199 | _u6253_u5370(select("#", ...)) | 195 | return _u6253_u5370(...) |
| 200 | return _u6253_u5370(...) | ||
| 201 | end | ||
| 202 | end | 196 | end |
| 203 | local _anon_func_25 = function(_u6253_u5370, ...) | 197 | local _anon_func_25 = function(_u6253_u5370, ...) |
| 204 | do | 198 | return _u6253_u5370(...) |
| 205 | return _u6253_u5370(...) | ||
| 206 | end | ||
| 207 | end | 199 | end |
| 208 | local _anon_func_26 = function(_u53d8_u91cfx, _u8868, _u88682) | 200 | local _anon_func_26 = function(_u53d8_u91cfx, _u8868, _u88682) |
| 209 | if 1 == _u53d8_u91cfx then | 201 | if 1 == _u53d8_u91cfx then |
| @@ -214,9 +206,7 @@ local _anon_func_26 = function(_u53d8_u91cfx, _u8868, _u88682) | |||
| 214 | end | 206 | end |
| 215 | end | 207 | end |
| 216 | local _anon_func_27 = function(_u6253_u5370, ...) | 208 | local _anon_func_27 = function(_u6253_u5370, ...) |
| 217 | do | 209 | return _u6253_u5370(...) |
| 218 | return _u6253_u5370(...) | ||
| 219 | end | ||
| 220 | end | 210 | end |
| 221 | local _anon_func_28 = function(_u6761_u4ef6) | 211 | local _anon_func_28 = function(_u6761_u4ef6) |
| 222 | if _u6761_u4ef6 then | 212 | if _u6761_u4ef6 then |
| @@ -224,10 +214,8 @@ local _anon_func_28 = function(_u6761_u4ef6) | |||
| 224 | end | 214 | end |
| 225 | end | 215 | end |
| 226 | local _anon_func_29 = function(_u6253_u5370, _arg_0, ...) | 216 | local _anon_func_29 = function(_u6253_u5370, _arg_0, ...) |
| 227 | do | 217 | local _u8868 = _arg_0 |
| 228 | local _u8868 = _arg_0 | 218 | return _u6253_u5370(...) |
| 229 | return _u6253_u5370(...) | ||
| 230 | end | ||
| 231 | end | 219 | end |
| 232 | local _u8fde_u63a5 | 220 | local _u8fde_u63a5 |
| 233 | _u8fde_u63a5 = function(...) | 221 | _u8fde_u63a5 = function(...) |
diff --git a/spec/outputs/upvalue_func.lua b/spec/outputs/upvalue_func.lua index 3181adf..3e088be 100644 --- a/spec/outputs/upvalue_func.lua +++ b/spec/outputs/upvalue_func.lua | |||
| @@ -214,10 +214,8 @@ local _anon_func_1 = function(valueB) | |||
| 214 | end | 214 | end |
| 215 | end | 215 | end |
| 216 | local _anon_func_2 = function(print, select, _arg_0, ...) | 216 | local _anon_func_2 = function(print, select, _arg_0, ...) |
| 217 | do | 217 | local ok = _arg_0 |
| 218 | local ok = _arg_0 | 218 | return print(select(3, ...)) |
| 219 | return print(select(3, ...)) | ||
| 220 | end | ||
| 221 | end | 219 | end |
| 222 | local _anon_func_3 = function(tb) | 220 | local _anon_func_3 = function(tb) |
| 223 | if tb ~= nil then | 221 | if tb ~= nil then |
| @@ -242,11 +240,9 @@ local _anon_func_5 = function(getmetatable, tb) | |||
| 242 | return _obj_0[1 + 1](_obj_0, "abc") | 240 | return _obj_0[1 + 1](_obj_0, "abc") |
| 243 | end | 241 | end |
| 244 | local _anon_func_6 = function(tb) | 242 | local _anon_func_6 = function(tb) |
| 245 | do | 243 | local _call_0 = tb |
| 246 | local _call_0 = tb | 244 | local _call_1 = _call_0["end"](_call_0) |
| 247 | local _call_1 = _call_0["end"](_call_0) | 245 | return _call_1["🤣"](_call_1, 123) |
| 248 | return _call_1["🤣"](_call_1, 123) | ||
| 249 | end | ||
| 250 | end | 246 | end |
| 251 | local _anon_func_7 = function(itemA, listA) | 247 | local _anon_func_7 = function(itemA, listA) |
| 252 | for _index_0 = 1, #listA do | 248 | for _index_0 = 1, #listA do |
| @@ -354,17 +350,13 @@ local _anon_func_16 = function(pairs, tb, tostring) | |||
| 354 | return _tbl_0 | 350 | return _tbl_0 |
| 355 | end | 351 | end |
| 356 | local _anon_func_17 = function(print) | 352 | local _anon_func_17 = function(print) |
| 357 | do | 353 | print(123) |
| 358 | print(123) | 354 | return "abc" |
| 359 | return "abc" | ||
| 360 | end | ||
| 361 | end | 355 | end |
| 362 | local _anon_func_18 = function(print, select, _arg_0, ...) | 356 | local _anon_func_18 = function(print, select, _arg_0, ...) |
| 363 | do | 357 | local success = _arg_0 |
| 364 | local success = _arg_0 | 358 | if success then |
| 365 | if success then | 359 | return print(select('#', ...)) |
| 366 | return print(select('#', ...)) | ||
| 367 | end | ||
| 368 | end | 360 | end |
| 369 | end | 361 | end |
| 370 | local _anon_func_19 = function(cond, i) | 362 | local _anon_func_19 = function(cond, i) |
| @@ -459,11 +451,9 @@ local _anon_func_25 = function(itemA, listA) | |||
| 459 | return false | 451 | return false |
| 460 | end | 452 | end |
| 461 | local _anon_func_24 = function(itemA, listA, tb) | 453 | local _anon_func_24 = function(itemA, listA, tb) |
| 462 | do | 454 | local _call_0 = tb |
| 463 | local _call_0 = tb | 455 | local _call_1 = _call_0["end"](_call_0) |
| 464 | local _call_1 = _call_0["end"](_call_0) | 456 | return _call_1["🤣"](_call_1, 123 and (#listA > 0 and _anon_func_25(itemA, listA))) |
| 465 | return _call_1["🤣"](_call_1, 123 and (#listA > 0 and _anon_func_25(itemA, listA))) | ||
| 466 | end | ||
| 467 | end | 457 | end |
| 468 | GameEngine:onEvent("SomeEvent", function() | 458 | GameEngine:onEvent("SomeEvent", function() |
| 469 | return func(value + (_anon_func_21(cond)) + (_anon_func_22(valueB)) > _anon_func_23(tb) + _anon_func_24(itemA, listA, tb)) | 459 | return func(value + (_anon_func_21(cond)) + (_anon_func_22(valueB)) > _anon_func_23(tb) + _anon_func_24(itemA, listA, tb)) |
| @@ -503,13 +493,11 @@ local _anon_func_27 = function(char) | |||
| 503 | return nil | 493 | return nil |
| 504 | end | 494 | end |
| 505 | local _anon_func_28 = function(os, _arg_0, ...) | 495 | local _anon_func_28 = function(os, _arg_0, ...) |
| 506 | do | 496 | local ok = _arg_0 |
| 507 | local ok = _arg_0 | 497 | if ok then |
| 508 | if ok then | 498 | return ... |
| 509 | return ... | 499 | else |
| 510 | else | 500 | return os.exit(1) |
| 511 | return os.exit(1) | ||
| 512 | end | ||
| 513 | end | 501 | end |
| 514 | end | 502 | end |
| 515 | local _anon_func_29 = function(debug_env_after, debug_env_before, env, func) | 503 | local _anon_func_29 = function(debug_env_after, debug_env_before, env, func) |
diff --git a/spec/outputs/vararg.lua b/spec/outputs/vararg.lua index dabba44..254aa6a 100644 --- a/spec/outputs/vararg.lua +++ b/spec/outputs/vararg.lua | |||
| @@ -125,14 +125,10 @@ local _anon_func_11 = function(items, ...) | |||
| 125 | return _tbl_0 | 125 | return _tbl_0 |
| 126 | end | 126 | end |
| 127 | local _anon_func_12 = function(func) | 127 | local _anon_func_12 = function(func) |
| 128 | do | 128 | return func() |
| 129 | return func() | ||
| 130 | end | ||
| 131 | end | 129 | end |
| 132 | local _anon_func_13 = function(func, ...) | 130 | local _anon_func_13 = function(func, ...) |
| 133 | do | 131 | return func(...) |
| 134 | return func(...) | ||
| 135 | end | ||
| 136 | end | 132 | end |
| 137 | local _anon_func_14 = function(func) | 133 | local _anon_func_14 = function(func) |
| 138 | local _accum_0 = { } | 134 | local _accum_0 = { } |
| @@ -195,15 +191,11 @@ local _anon_func_23 = function(func, ...) | |||
| 195 | return nil | 191 | return nil |
| 196 | end | 192 | end |
| 197 | local _anon_func_24 = function(print, select, ...) | 193 | local _anon_func_24 = function(print, select, ...) |
| 198 | do | 194 | print(select("#", ...)) |
| 199 | print(select("#", ...)) | 195 | return print(...) |
| 200 | return print(...) | ||
| 201 | end | ||
| 202 | end | 196 | end |
| 203 | local _anon_func_25 = function(print, ...) | 197 | local _anon_func_25 = function(print, ...) |
| 204 | do | 198 | return print(...) |
| 205 | return print(...) | ||
| 206 | end | ||
| 207 | end | 199 | end |
| 208 | local _anon_func_26 = function(tb, tb2, x) | 200 | local _anon_func_26 = function(tb, tb2, x) |
| 209 | if 1 == x then | 201 | if 1 == x then |
| @@ -214,9 +206,7 @@ local _anon_func_26 = function(tb, tb2, x) | |||
| 214 | end | 206 | end |
| 215 | end | 207 | end |
| 216 | local _anon_func_27 = function(print, ...) | 208 | local _anon_func_27 = function(print, ...) |
| 217 | do | 209 | return print(...) |
| 218 | return print(...) | ||
| 219 | end | ||
| 220 | end | 210 | end |
| 221 | local _anon_func_28 = function(cond) | 211 | local _anon_func_28 = function(cond) |
| 222 | if cond then | 212 | if cond then |
| @@ -224,10 +214,8 @@ local _anon_func_28 = function(cond) | |||
| 224 | end | 214 | end |
| 225 | end | 215 | end |
| 226 | local _anon_func_29 = function(print, _arg_0, ...) | 216 | local _anon_func_29 = function(print, _arg_0, ...) |
| 227 | do | 217 | local tb = _arg_0 |
| 228 | local tb = _arg_0 | 218 | return print(...) |
| 229 | return print(...) | ||
| 230 | end | ||
| 231 | end | 219 | end |
| 232 | local join | 220 | local join |
| 233 | join = function(...) | 221 | join = function(...) |
diff --git a/src/yuescript/yue_ast.cpp b/src/yuescript/yue_ast.cpp index 9d68161..be10859 100644 --- a/src/yuescript/yue_ast.cpp +++ b/src/yuescript/yue_ast.cpp | |||
| @@ -609,13 +609,19 @@ std::string CatchBlock_t::to_string(void* ud) const { | |||
| 609 | info->popScope(); | 609 | info->popScope(); |
| 610 | return line + '\n' + blockStr; | 610 | return line + '\n' + blockStr; |
| 611 | } | 611 | } |
| 612 | std::string Omit_t::to_string(void*) const { | ||
| 613 | return "!"s; | ||
| 614 | } | ||
| 612 | std::string Try_t::to_string(void* ud) const { | 615 | std::string Try_t::to_string(void* ud) const { |
| 613 | auto info = reinterpret_cast<YueFormat*>(ud); | 616 | auto info = reinterpret_cast<YueFormat*>(ud); |
| 614 | str_list temp; | 617 | str_list temp; |
| 618 | temp.emplace_back("try"s); | ||
| 619 | if (omit) { | ||
| 620 | temp.back() += '!'; | ||
| 621 | } | ||
| 615 | if (func.is<Exp_t>()) { | 622 | if (func.is<Exp_t>()) { |
| 616 | temp.emplace_back("try "s + func->to_string(ud)); | 623 | temp.back() += (" "s + func->to_string(ud)); |
| 617 | } else { | 624 | } else { |
| 618 | temp.emplace_back("try"s); | ||
| 619 | info->pushScope(); | 625 | info->pushScope(); |
| 620 | temp.emplace_back(func->to_string(ud)); | 626 | temp.emplace_back(func->to_string(ud)); |
| 621 | if (temp.back().empty()) { | 627 | if (temp.back().empty()) { |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index d3e6368..393f374 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
| @@ -383,10 +383,14 @@ AST_NODE(CatchBlock) | |||
| 383 | AST_MEMBER(CatchBlock, &err, &block) | 383 | AST_MEMBER(CatchBlock, &err, &block) |
| 384 | AST_END(CatchBlock) | 384 | AST_END(CatchBlock) |
| 385 | 385 | ||
| 386 | AST_LEAF(Omit) | ||
| 387 | AST_END(Omit) | ||
| 388 | |||
| 386 | AST_NODE(Try) | 389 | AST_NODE(Try) |
| 390 | ast_ptr<false, Omit_t> omit; | ||
| 387 | ast_sel<true, Block_t, Exp_t> func; | 391 | ast_sel<true, Block_t, Exp_t> func; |
| 388 | ast_ptr<false, CatchBlock_t> catchBlock; | 392 | ast_ptr<false, CatchBlock_t> catchBlock; |
| 389 | AST_MEMBER(Try, &func, &catchBlock) | 393 | AST_MEMBER(Try, &omit, &func, &catchBlock) |
| 390 | AST_END(Try) | 394 | AST_END(Try) |
| 391 | 395 | ||
| 392 | AST_NODE(Comprehension) | 396 | AST_NODE(Comprehension) |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 2312025..35745f2 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -78,7 +78,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
| 78 | "close"s // Lua 5.4 | 78 | "close"s // Lua 5.4 |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | const std::string_view version = "0.28.5"sv; | 81 | const std::string_view version = "0.28.6"sv; |
| 82 | const std::string_view extension = "yue"sv; | 82 | const std::string_view extension = "yue"sv; |
| 83 | 83 | ||
| 84 | class CompileError : public std::logic_error { | 84 | class CompileError : public std::logic_error { |
| @@ -165,12 +165,12 @@ public: | |||
| 165 | double compileTime = 0.0; | 165 | double compileTime = 0.0; |
| 166 | if (config.profiling) { | 166 | if (config.profiling) { |
| 167 | auto start = std::chrono::high_resolution_clock::now(); | 167 | auto start = std::chrono::high_resolution_clock::now(); |
| 168 | _info = _parser.parse<File_t>(codes); | 168 | _info = _parser.parse<File_t>(codes, config.lax); |
| 169 | auto stop = std::chrono::high_resolution_clock::now(); | 169 | auto stop = std::chrono::high_resolution_clock::now(); |
| 170 | std::chrono::duration<double> diff = stop - start; | 170 | std::chrono::duration<double> diff = stop - start; |
| 171 | parseTime = diff.count(); | 171 | parseTime = diff.count(); |
| 172 | } else { | 172 | } else { |
| 173 | _info = _parser.parse<File_t>(codes); | 173 | _info = _parser.parse<File_t>(codes, config.lax); |
| 174 | } | 174 | } |
| 175 | std::unique_ptr<GlobalVars> globals; | 175 | std::unique_ptr<GlobalVars> globals; |
| 176 | std::unique_ptr<Options> options; | 176 | std::unique_ptr<Options> options; |
| @@ -1258,7 +1258,7 @@ private: | |||
| 1258 | 1258 | ||
| 1259 | template <class T> | 1259 | template <class T> |
| 1260 | ast_ptr<false, T> toAst(std::string_view codes, ast_node* parent) { | 1260 | ast_ptr<false, T> toAst(std::string_view codes, ast_node* parent) { |
| 1261 | auto res = _parser.parse<T>(std::string(codes)); | 1261 | auto res = _parser.parse<T>(std::string(codes), false); |
| 1262 | if (res.error) { | 1262 | if (res.error) { |
| 1263 | throw CompileError(res.error.value().msg, parent); | 1263 | throw CompileError(res.error.value().msg, parent); |
| 1264 | } | 1264 | } |
| @@ -2330,6 +2330,17 @@ private: | |||
| 2330 | out.back().insert(0, preDefine); | 2330 | out.back().insert(0, preDefine); |
| 2331 | return false; | 2331 | return false; |
| 2332 | } | 2332 | } |
| 2333 | case id<Try_t>(): { | ||
| 2334 | auto tryNode = static_cast<Try_t*>(value); | ||
| 2335 | if (tryNode->omit) { | ||
| 2336 | auto assignList = assignment->expList.get(); | ||
| 2337 | std::string preDefine = getPreDefineLine(assignment); | ||
| 2338 | transformTry(tryNode, out, ExpUsage::Assignment, assignList); | ||
| 2339 | out.back().insert(0, preDefine); | ||
| 2340 | return false; | ||
| 2341 | } | ||
| 2342 | break; | ||
| 2343 | } | ||
| 2333 | case id<Switch_t>(): { | 2344 | case id<Switch_t>(): { |
| 2334 | auto switchNode = static_cast<Switch_t*>(value); | 2345 | auto switchNode = static_cast<Switch_t*>(value); |
| 2335 | auto assignList = assignment->expList.get(); | 2346 | auto assignList = assignment->expList.get(); |
| @@ -4272,12 +4283,22 @@ private: | |||
| 4272 | 4283 | ||
| 4273 | std::optional<std::pair<std::string, str_list>> upValueFuncFromExp(Exp_t* exp, str_list* ensureArgListInTheEnd, bool blockRewrite) { | 4284 | std::optional<std::pair<std::string, str_list>> upValueFuncFromExp(Exp_t* exp, str_list* ensureArgListInTheEnd, bool blockRewrite) { |
| 4274 | if (checkUpValueFuncAvailable(exp)) { | 4285 | if (checkUpValueFuncAvailable(exp)) { |
| 4286 | auto block = exp->new_ptr<Block_t>(); | ||
| 4287 | if (auto sVal = simpleSingleValueFrom(exp)) { | ||
| 4288 | if (auto doNode = sVal->value.as<Do_t>()) { | ||
| 4289 | if (auto blk = doNode->body->content.as<Block_t>()) { | ||
| 4290 | block->statements.dup(blk->statements); | ||
| 4291 | } else { | ||
| 4292 | block->statements.push_back(doNode->body->content.to<Statement_t>()); | ||
| 4293 | } | ||
| 4294 | return getUpValueFuncFromBlock(block, ensureArgListInTheEnd, false, blockRewrite); | ||
| 4295 | } | ||
| 4296 | } | ||
| 4275 | auto returnNode = exp->new_ptr<Return_t>(); | 4297 | auto returnNode = exp->new_ptr<Return_t>(); |
| 4276 | returnNode->explicitReturn = false; | 4298 | returnNode->explicitReturn = false; |
| 4277 | auto returnList = exp->new_ptr<ExpListLow_t>(); | 4299 | auto returnList = exp->new_ptr<ExpListLow_t>(); |
| 4278 | returnList->exprs.push_back(exp); | 4300 | returnList->exprs.push_back(exp); |
| 4279 | returnNode->valueList.set(returnList); | 4301 | returnNode->valueList.set(returnList); |
| 4280 | auto block = exp->new_ptr<Block_t>(); | ||
| 4281 | auto stmt = exp->new_ptr<Statement_t>(); | 4302 | auto stmt = exp->new_ptr<Statement_t>(); |
| 4282 | stmt->content.set(returnNode); | 4303 | stmt->content.set(returnNode); |
| 4283 | block->statements.push_back(stmt); | 4304 | block->statements.push_back(stmt); |
| @@ -4799,11 +4820,7 @@ private: | |||
| 4799 | auto newBody = x->new_ptr<Body_t>(); | 4820 | auto newBody = x->new_ptr<Body_t>(); |
| 4800 | newBody->content.set(followingBlock); | 4821 | newBody->content.set(followingBlock); |
| 4801 | { | 4822 | { |
| 4802 | auto doNode = x->new_ptr<Do_t>(); | 4823 | if (auto result = upValueFuncFromBlock(followingBlock.get(), &argNames, false, true)) { |
| 4803 | doNode->body.set(newBody); | ||
| 4804 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | ||
| 4805 | simpleValue->value.set(doNode); | ||
| 4806 | if (auto result = upValueFuncFromExp(newExp(simpleValue, x), &argNames, true)) { | ||
| 4807 | auto [funcName, args] = std::move(*result); | 4824 | auto [funcName, args] = std::move(*result); |
| 4808 | str_list finalArgs; | 4825 | str_list finalArgs; |
| 4809 | for (const auto& arg : args) { | 4826 | for (const auto& arg : args) { |
| @@ -4811,9 +4828,13 @@ private: | |||
| 4811 | finalArgs.push_back(arg); | 4828 | finalArgs.push_back(arg); |
| 4812 | } | 4829 | } |
| 4813 | } | 4830 | } |
| 4814 | newBlock->statements.push_back(toAst<Statement_t>(funcName + ' ' + join(finalArgs, ","sv), x)); | 4831 | newBlock->statements.push_back(toAst<Statement_t>(funcName + ' ' + (finalArgs.empty() ? "nil"s : join(finalArgs, ","sv)), x)); |
| 4815 | auto sVal = singleValueFrom(static_cast<Statement_t*>(newBlock->statements.back())->content.to<ExpListAssign_t>()->expList); | 4832 | auto sVal = singleValueFrom(static_cast<Statement_t*>(newBlock->statements.back())->content.to<ExpListAssign_t>()->expList); |
| 4816 | ast_to<InvokeArgs_t>(sVal->item.to<ChainValue_t>()->items.back())->args.dup(newInvoke->args); | 4833 | auto invokArgs = ast_to<InvokeArgs_t>(sVal->item.to<ChainValue_t>()->items.back()); |
| 4834 | if (finalArgs.empty()) { | ||
| 4835 | invokArgs->args.clear(); | ||
| 4836 | } | ||
| 4837 | invokArgs->args.dup(newInvoke->args); | ||
| 4817 | transformBlock(newBlock, out, usage, assignList, isRoot); | 4838 | transformBlock(newBlock, out, usage, assignList, isRoot); |
| 4818 | return; | 4839 | return; |
| 4819 | } | 4840 | } |
| @@ -5093,36 +5114,45 @@ private: | |||
| 5093 | if (!nodes.empty()) { | 5114 | if (!nodes.empty()) { |
| 5094 | str_list temp; | 5115 | str_list temp; |
| 5095 | for (auto node : nodes) { | 5116 | for (auto node : nodes) { |
| 5096 | currentScope().lastStatement = (node == nodes.back()) && currentScope().mode == GlobalMode::None; | 5117 | auto transformNode = [&]() { |
| 5097 | transformStatement(static_cast<Statement_t*>(node), temp); | 5118 | currentScope().lastStatement = (node == nodes.back()) && currentScope().mode == GlobalMode::None; |
| 5098 | if (isRoot && !_rootDefs.empty()) { | 5119 | transformStatement(static_cast<Statement_t*>(node), temp); |
| 5099 | auto last = std::move(temp.back()); | 5120 | if (isRoot && !_rootDefs.empty()) { |
| 5100 | temp.pop_back(); | 5121 | auto last = std::move(temp.back()); |
| 5101 | temp.insert(temp.end(), _rootDefs.begin(), _rootDefs.end()); | 5122 | temp.pop_back(); |
| 5102 | _rootDefs.clear(); | 5123 | temp.insert(temp.end(), _rootDefs.begin(), _rootDefs.end()); |
| 5103 | temp.push_back(std::move(last)); | 5124 | _rootDefs.clear(); |
| 5104 | } | 5125 | temp.push_back(std::move(last)); |
| 5105 | if (!temp.empty() && _parser.startWith<StatementSep_t>(temp.back())) { | 5126 | } |
| 5106 | auto rit = ++temp.rbegin(); | 5127 | if (!temp.empty() && _parser.startWith<StatementSep_t>(temp.back())) { |
| 5107 | if (rit != temp.rend() && !rit->empty()) { | 5128 | auto rit = ++temp.rbegin(); |
| 5108 | auto index = std::string::npos; | 5129 | if (rit != temp.rend() && !rit->empty()) { |
| 5109 | if (_config.reserveLineNumber) { | 5130 | auto index = std::string::npos; |
| 5110 | index = rit->rfind(" -- "sv); | 5131 | if (_config.reserveLineNumber) { |
| 5111 | } else { | 5132 | index = rit->rfind(" -- "sv); |
| 5112 | index = rit->find_last_not_of('\n'); | 5133 | } else { |
| 5113 | if (index != std::string::npos) index++; | 5134 | index = rit->find_last_not_of('\n'); |
| 5114 | } | 5135 | if (index != std::string::npos) index++; |
| 5115 | if (index != std::string::npos) { | ||
| 5116 | auto ending = rit->substr(0, index); | ||
| 5117 | auto ind = ending.find_last_of(" \t\n"sv); | ||
| 5118 | if (ind != std::string::npos) { | ||
| 5119 | ending = ending.substr(ind + 1); | ||
| 5120 | } | 5136 | } |
| 5121 | if (LuaKeywords.find(ending) == LuaKeywords.end()) { | 5137 | if (index != std::string::npos) { |
| 5122 | rit->insert(index, ";"sv); | 5138 | auto ending = rit->substr(0, index); |
| 5139 | auto ind = ending.find_last_of(" \t\n"sv); | ||
| 5140 | if (ind != std::string::npos) { | ||
| 5141 | ending = ending.substr(ind + 1); | ||
| 5142 | } | ||
| 5143 | if (LuaKeywords.find(ending) == LuaKeywords.end()) { | ||
| 5144 | rit->insert(index, ";"sv); | ||
| 5145 | } | ||
| 5123 | } | 5146 | } |
| 5124 | } | 5147 | } |
| 5125 | } | 5148 | } |
| 5149 | }; | ||
| 5150 | if (_config.lax) { | ||
| 5151 | try { | ||
| 5152 | transformNode(); | ||
| 5153 | } catch (const CompileError&) { } | ||
| 5154 | } else { | ||
| 5155 | transformNode(); | ||
| 5126 | } | 5156 | } |
| 5127 | } | 5157 | } |
| 5128 | out.push_back(join(temp)); | 5158 | out.push_back(join(temp)); |
| @@ -6193,7 +6223,7 @@ private: | |||
| 6193 | case id<ColonChainItem_t>(): | 6223 | case id<ColonChainItem_t>(): |
| 6194 | case id<Exp_t>(): | 6224 | case id<Exp_t>(): |
| 6195 | if (_withVars.empty()) { | 6225 | if (_withVars.empty()) { |
| 6196 | throw CompileError("short dot/colon and indexing syntax must be called within a with block"sv, x); | 6226 | throw CompileError("short dot/colon/indexing syntax must be called within a with block"sv, x); |
| 6197 | } else { | 6227 | } else { |
| 6198 | temp.push_back(_withVars.top()); | 6228 | temp.push_back(_withVars.top()); |
| 6199 | } | 6229 | } |
| @@ -6714,14 +6744,14 @@ private: | |||
| 6714 | } else { | 6744 | } else { |
| 6715 | if (!codes.empty()) { | 6745 | if (!codes.empty()) { |
| 6716 | if (isBlock) { | 6746 | if (isBlock) { |
| 6717 | info = _parser.parse<BlockEnd_t>(codes); | 6747 | info = _parser.parse<BlockEnd_t>(codes, false); |
| 6718 | if (info.error) { | 6748 | if (info.error) { |
| 6719 | throw CompileError("failed to expand macro as block: "s + info.error.value().msg, x); | 6749 | throw CompileError("failed to expand macro as block: "s + info.error.value().msg, x); |
| 6720 | } | 6750 | } |
| 6721 | } else { | 6751 | } else { |
| 6722 | info = _parser.parse<Exp_t>(codes); | 6752 | info = _parser.parse<Exp_t>(codes, false); |
| 6723 | if (!info.node && allowBlockMacroReturn) { | 6753 | if (!info.node && allowBlockMacroReturn) { |
| 6724 | info = _parser.parse<BlockEnd_t>(codes); | 6754 | info = _parser.parse<BlockEnd_t>(codes, false); |
| 6725 | if (info.error) { | 6755 | if (info.error) { |
| 6726 | throw CompileError("failed to expand macro as expr or block: "s + info.error.value().msg, x); | 6756 | throw CompileError("failed to expand macro as expr or block: "s + info.error.value().msg, x); |
| 6727 | } | 6757 | } |
| @@ -10023,8 +10053,47 @@ private: | |||
| 10023 | out.push_back(join(temp)); | 10053 | out.push_back(join(temp)); |
| 10024 | } | 10054 | } |
| 10025 | 10055 | ||
| 10026 | void transformTry(Try_t* tryNode, str_list& out, ExpUsage usage) { | 10056 | void transformTry(Try_t* tryNode, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { |
| 10027 | auto x = tryNode; | 10057 | auto x = tryNode; |
| 10058 | if (tryNode->omit && usage == ExpUsage::Assignment) { | ||
| 10059 | str_list rets; | ||
| 10060 | pushScope(); | ||
| 10061 | auto okVar = getUnusedName("_ok_"sv); | ||
| 10062 | for (size_t i = 0; i < assignList->exprs.size(); i++) { | ||
| 10063 | auto retVar = getUnusedName("_ret_"sv); | ||
| 10064 | rets.emplace_back(retVar); | ||
| 10065 | addToScope(retVar); | ||
| 10066 | } | ||
| 10067 | popScope(); | ||
| 10068 | auto varList = join(rets, ","sv); | ||
| 10069 | auto ifNode = toAst<If_t>("if "s + okVar + ',' + varList + ":=try nil then "s + varList, x); | ||
| 10070 | auto exp = ast_to<IfCond_t>(ifNode->nodes.front())->assignment->assign->values.front(); | ||
| 10071 | auto sVal = simpleSingleValueFrom(exp); | ||
| 10072 | auto newTry = sVal->value.to<Try_t>(); | ||
| 10073 | newTry->func.set(tryNode->func); | ||
| 10074 | newTry->catchBlock.set(tryNode->catchBlock); | ||
| 10075 | auto assignment = x->new_ptr<ExpListAssign_t>(); | ||
| 10076 | assignment->expList.set(assignList); | ||
| 10077 | auto assign = x->new_ptr<Assign_t>(); | ||
| 10078 | assign->values.push_back(ifNode); | ||
| 10079 | assignment->action.set(assign); | ||
| 10080 | transformAssignment(assignment, out); | ||
| 10081 | return; | ||
| 10082 | } | ||
| 10083 | if (tryNode->omit && usage != ExpUsage::Common) { | ||
| 10084 | auto okVar = getUnusedName("_ok_"sv); | ||
| 10085 | auto code = "do\n\t"s + okVar + ", ... = try nil\n\t... if "s + okVar; | ||
| 10086 | auto doNode = toAst<Do_t>(code, x); | ||
| 10087 | auto block = doNode->body->content.to<Block_t>(); | ||
| 10088 | auto asmt = static_cast<Statement_t*>(block->statements.front())->content.to<ExpListAssign_t>(); | ||
| 10089 | auto assign = asmt->action.to<Assign_t>(); | ||
| 10090 | auto sVal = simpleSingleValueFrom(assign->values.back()); | ||
| 10091 | auto newTry = sVal->value.to<Try_t>(); | ||
| 10092 | newTry->func.set(tryNode->func); | ||
| 10093 | newTry->catchBlock.set(tryNode->catchBlock); | ||
| 10094 | transformDo(doNode, out, usage); | ||
| 10095 | return; | ||
| 10096 | } | ||
| 10028 | ast_ptr<true, Exp_t> errHandler; | 10097 | ast_ptr<true, Exp_t> errHandler; |
| 10029 | if (tryNode->catchBlock) { | 10098 | if (tryNode->catchBlock) { |
| 10030 | auto catchBlock = tryNode->catchBlock.get(); | 10099 | auto catchBlock = tryNode->catchBlock.get(); |
diff --git a/src/yuescript/yue_compiler.h b/src/yuescript/yue_compiler.h index d352636..aff5978 100644 --- a/src/yuescript/yue_compiler.h +++ b/src/yuescript/yue_compiler.h | |||
| @@ -31,6 +31,7 @@ struct YueConfig { | |||
| 31 | bool reserveLineNumber = true; | 31 | bool reserveLineNumber = true; |
| 32 | bool useSpaceOverTab = false; | 32 | bool useSpaceOverTab = false; |
| 33 | bool reserveComment = false; | 33 | bool reserveComment = false; |
| 34 | bool lax = false; | ||
| 34 | // internal options | 35 | // internal options |
| 35 | bool exporting = false; | 36 | bool exporting = false; |
| 36 | bool profiling = false; | 37 | bool profiling = false; |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index e5bdc26..2b0aea8 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -332,7 +332,7 @@ YueParser::YueParser() { | |||
| 332 | Exp; | 332 | Exp; |
| 333 | import_tab_list = import_tab_item >> *(space >> ',' >> space >> import_tab_item); | 333 | import_tab_list = import_tab_item >> *(space >> ',' >> space >> import_tab_item); |
| 334 | import_tab_line = ( | 334 | import_tab_line = ( |
| 335 | push_indent_match >> (space >> import_tab_list >> pop_indent | pop_indent) | 335 | push_indent_match >> ensure(space >> import_tab_list, pop_indent) |
| 336 | ) | space; | 336 | ) | space; |
| 337 | import_tab_lines = space_break >> import_tab_line >> *(-(space >> ',') >> space_break >> import_tab_line) >> -(space >> ','); | 337 | import_tab_lines = space_break >> import_tab_line >> *(-(space >> ',') >> space_break >> import_tab_line) >> -(space >> ','); |
| 338 | import_tab_key_value = key_value | ':' >> MacroName | MacroNamePair | ImportAllMacro; | 338 | import_tab_key_value = key_value | ':' >> MacroName | MacroNamePair | ImportAllMacro; |
| @@ -501,8 +501,9 @@ YueParser::YueParser() { | |||
| 501 | return true; | 501 | return true; |
| 502 | }); | 502 | }); |
| 503 | 503 | ||
| 504 | Omit = expr('!'); | ||
| 504 | CatchBlock = line_break >> *space_break >> check_indent_match >> space >> key("catch") >> space >> Variable >> space >> in_block; | 505 | CatchBlock = line_break >> *space_break >> check_indent_match >> space >> key("catch") >> space >> Variable >> space >> in_block; |
| 505 | Try = key("try") >> space >> (in_block | Exp) >> -CatchBlock; | 506 | Try = key("try") >> -Omit >> space >> (in_block | Exp) >> -CatchBlock; |
| 506 | 507 | ||
| 507 | list_value = | 508 | list_value = |
| 508 | and_( | 509 | and_( |
| @@ -667,7 +668,7 @@ YueParser::YueParser() { | |||
| 667 | fn_args_value_list = Exp >> *(space >> ',' >> space >> Exp); | 668 | fn_args_value_list = Exp >> *(space >> ',' >> space >> Exp); |
| 668 | 669 | ||
| 669 | fn_args_lit_line = ( | 670 | fn_args_lit_line = ( |
| 670 | push_indent_match >> (space >> fn_args_value_list >> pop_indent | pop_indent) | 671 | push_indent_match >> ensure(space >> fn_args_value_list, pop_indent) |
| 671 | ) | ( | 672 | ) | ( |
| 672 | space | 673 | space |
| 673 | ); | 674 | ); |
| @@ -875,7 +876,7 @@ YueParser::YueParser() { | |||
| 875 | fn_arg_def_list = FnArgDef >> *(space >> ',' >> space >> FnArgDef); | 876 | fn_arg_def_list = FnArgDef >> *(space >> ',' >> space >> FnArgDef); |
| 876 | 877 | ||
| 877 | fn_arg_def_lit_line = ( | 878 | fn_arg_def_lit_line = ( |
| 878 | push_indent_match >> (space >> fn_arg_def_list >> pop_indent | pop_indent) | 879 | push_indent_match >> ensure(space >> fn_arg_def_list, pop_indent) |
| 879 | ) | ( | 880 | ) | ( |
| 880 | space | 881 | space |
| 881 | ); | 882 | ); |
| @@ -1030,11 +1031,16 @@ YueParser::YueParser() { | |||
| 1030 | empty_line_break | | 1031 | empty_line_break | |
| 1031 | advance_match >> ensure(space >> (indentation_error | Statement), pop_indent) | 1032 | advance_match >> ensure(space >> (indentation_error | Statement), pop_indent) |
| 1032 | ); | 1033 | ); |
| 1033 | Block = Seperator >> line >> *(+line_break >> line); | 1034 | Block = Seperator >> (pl::user(true_(), [](const item_t& item) { |
| 1035 | State* st = reinterpret_cast<State*>(item.user_data); | ||
| 1036 | return st->lax; | ||
| 1037 | }) >> lax_line >> *(+line_break >> lax_line) | line >> *(+line_break >> line)); | ||
| 1034 | 1038 | ||
| 1035 | shebang = "#!" >> *(not_(stop) >> any_char); | 1039 | shebang = "#!" >> *(not_(stop) >> any_char); |
| 1036 | BlockEnd = Block >> white >> stop; | 1040 | BlockEnd = Block >> white >> stop; |
| 1037 | File = -shebang >> -Block >> white >> stop; | 1041 | File = -shebang >> -Block >> white >> stop; |
| 1042 | |||
| 1043 | lax_line = advance_match >> ensure(*(not_(stop) >> any()), pop_indent) | line >> and_(stop) | check_indent_match >> *(not_(stop) >> any()); | ||
| 1038 | } | 1044 | } |
| 1039 | // clang-format on | 1045 | // clang-format on |
| 1040 | 1046 | ||
| @@ -1064,7 +1070,7 @@ bool YueParser::startWith(std::string_view codes, rule& r) { | |||
| 1064 | return true; | 1070 | return true; |
| 1065 | } | 1071 | } |
| 1066 | 1072 | ||
| 1067 | ParseInfo YueParser::parse(std::string_view codes, rule& r) { | 1073 | ParseInfo YueParser::parse(std::string_view codes, rule& r, bool lax) { |
| 1068 | ParseInfo res; | 1074 | ParseInfo res; |
| 1069 | if (codes.substr(0, 3) == "\xEF\xBB\xBF"sv) { | 1075 | if (codes.substr(0, 3) == "\xEF\xBB\xBF"sv) { |
| 1070 | codes = codes.substr(3); | 1076 | codes = codes.substr(3); |
| @@ -1082,6 +1088,7 @@ ParseInfo YueParser::parse(std::string_view codes, rule& r) { | |||
| 1082 | error_list errors; | 1088 | error_list errors; |
| 1083 | try { | 1089 | try { |
| 1084 | State state; | 1090 | State state; |
| 1091 | state.lax = lax; | ||
| 1085 | res.node.set(::yue::parse(*(res.codes), r, errors, &state)); | 1092 | res.node.set(::yue::parse(*(res.codes), r, errors, &state)); |
| 1086 | if (state.exportCount > 0) { | 1093 | if (state.exportCount > 0) { |
| 1087 | int index = 0; | 1094 | int index = 0; |
| @@ -1119,10 +1126,10 @@ ParseInfo YueParser::parse(std::string_view codes, rule& r) { | |||
| 1119 | return res; | 1126 | return res; |
| 1120 | } | 1127 | } |
| 1121 | 1128 | ||
| 1122 | ParseInfo YueParser::parse(std::string_view astName, std::string_view codes) { | 1129 | ParseInfo YueParser::parse(std::string_view astName, std::string_view codes, bool lax) { |
| 1123 | auto it = _rules.find(astName); | 1130 | auto it = _rules.find(astName); |
| 1124 | if (it != _rules.end()) { | 1131 | if (it != _rules.end()) { |
| 1125 | return parse(codes, *it->second); | 1132 | return parse(codes, *it->second, lax); |
| 1126 | } | 1133 | } |
| 1127 | return {}; | 1134 | return {}; |
| 1128 | } | 1135 | } |
| @@ -1131,7 +1138,7 @@ bool YueParser::match(std::string_view astName, std::string_view codes) { | |||
| 1131 | auto it = _rules.find(astName); | 1138 | auto it = _rules.find(astName); |
| 1132 | if (it != _rules.end()) { | 1139 | if (it != _rules.end()) { |
| 1133 | auto rEnd = rule(*it->second >> eof()); | 1140 | auto rEnd = rule(*it->second >> eof()); |
| 1134 | return parse(codes, rEnd).node; | 1141 | return parse(codes, rEnd, false).node; |
| 1135 | } | 1142 | } |
| 1136 | return false; | 1143 | return false; |
| 1137 | } | 1144 | } |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 773bdbe..99f3d45 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
| @@ -74,16 +74,16 @@ extern std::unordered_set<std::string> Keywords; | |||
| 74 | class YueParser { | 74 | class YueParser { |
| 75 | public: | 75 | public: |
| 76 | template <class AST> | 76 | template <class AST> |
| 77 | ParseInfo parse(std::string_view codes) { | 77 | ParseInfo parse(std::string_view codes, bool lax) { |
| 78 | return parse(codes, getRule<AST>()); | 78 | return parse(codes, getRule<AST>(), lax); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | ParseInfo parse(std::string_view astName, std::string_view codes); | 81 | ParseInfo parse(std::string_view astName, std::string_view codes, bool lax); |
| 82 | 82 | ||
| 83 | template <class AST> | 83 | template <class AST> |
| 84 | bool match(std::string_view codes) { | 84 | bool match(std::string_view codes) { |
| 85 | auto rEnd = rule(getRule<AST>() >> eof()); | 85 | auto rEnd = rule(getRule<AST>() >> eof()); |
| 86 | return parse(codes, rEnd).node; | 86 | return parse(codes, rEnd, false).node; |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | bool match(std::string_view astName, std::string_view codes); | 89 | bool match(std::string_view astName, std::string_view codes); |
| @@ -102,13 +102,14 @@ public: | |||
| 102 | 102 | ||
| 103 | protected: | 103 | protected: |
| 104 | YueParser(); | 104 | YueParser(); |
| 105 | ParseInfo parse(std::string_view codes, rule& r); | 105 | ParseInfo parse(std::string_view codes, rule& r, bool lax); |
| 106 | bool startWith(std::string_view codes, rule& r); | 106 | bool startWith(std::string_view codes, rule& r); |
| 107 | 107 | ||
| 108 | struct State { | 108 | struct State { |
| 109 | State() { | 109 | State() { |
| 110 | indents.push(0); | 110 | indents.push(0); |
| 111 | } | 111 | } |
| 112 | bool lax = false; | ||
| 112 | bool exportDefault = false; | 113 | bool exportDefault = false; |
| 113 | bool exportMacro = false; | 114 | bool exportMacro = false; |
| 114 | bool exportMetatable = false; | 115 | bool exportMetatable = false; |
| @@ -287,6 +288,7 @@ private: | |||
| 287 | NONE_AST_RULE(yue_line_comment); | 288 | NONE_AST_RULE(yue_line_comment); |
| 288 | NONE_AST_RULE(line); | 289 | NONE_AST_RULE(line); |
| 289 | NONE_AST_RULE(shebang); | 290 | NONE_AST_RULE(shebang); |
| 291 | NONE_AST_RULE(lax_line); | ||
| 290 | 292 | ||
| 291 | AST_RULE(Num); | 293 | AST_RULE(Num); |
| 292 | AST_RULE(Name); | 294 | AST_RULE(Name); |
| @@ -345,6 +347,7 @@ private: | |||
| 345 | AST_RULE(ForEach); | 347 | AST_RULE(ForEach); |
| 346 | AST_RULE(Do); | 348 | AST_RULE(Do); |
| 347 | AST_RULE(CatchBlock); | 349 | AST_RULE(CatchBlock); |
| 350 | AST_RULE(Omit); | ||
| 348 | AST_RULE(Try); | 351 | AST_RULE(Try); |
| 349 | AST_RULE(Comprehension); | 352 | AST_RULE(Comprehension); |
| 350 | AST_RULE(CompValue); | 353 | AST_RULE(CompValue); |
diff --git a/src/yuescript/yuescript.cpp b/src/yuescript/yuescript.cpp index 7e8e8b7..aa19b70 100644 --- a/src/yuescript/yuescript.cpp +++ b/src/yuescript/yuescript.cpp | |||
| @@ -93,6 +93,12 @@ static void get_config(lua_State* L, yue::YueConfig& config) { | |||
| 93 | config.useSpaceOverTab = lua_toboolean(L, -1) != 0; | 93 | config.useSpaceOverTab = lua_toboolean(L, -1) != 0; |
| 94 | } | 94 | } |
| 95 | lua_pop(L, 1); | 95 | lua_pop(L, 1); |
| 96 | lua_pushliteral(L, "lax"); | ||
| 97 | lua_gettable(L, -2); | ||
| 98 | if (lua_isboolean(L, -1) != 0) { | ||
| 99 | config.lax = lua_toboolean(L, -1) != 0; | ||
| 100 | } | ||
| 101 | lua_pop(L, 1); | ||
| 96 | lua_pushliteral(L, "options"); | 102 | lua_pushliteral(L, "options"); |
| 97 | lua_gettable(L, -2); | 103 | lua_gettable(L, -2); |
| 98 | if (lua_istable(L, -1) != 0) { | 104 | if (lua_istable(L, -1) != 0) { |
| @@ -180,7 +186,7 @@ static int yueformat(lua_State* L) { | |||
| 180 | tabSize = static_cast<int>(luaL_checkinteger(L, 2)); | 186 | tabSize = static_cast<int>(luaL_checkinteger(L, 2)); |
| 181 | } | 187 | } |
| 182 | std::string_view codes(input, len); | 188 | std::string_view codes(input, len); |
| 183 | auto info = yue::YueParser::shared().parse<yue::File_t>(codes); | 189 | auto info = yue::YueParser::shared().parse<yue::File_t>(codes, false); |
| 184 | if (info.error) { | 190 | if (info.error) { |
| 185 | const auto& error = info.error.value(); | 191 | const auto& error = info.error.value(); |
| 186 | if (!info.codes) { | 192 | if (!info.codes) { |
| @@ -282,8 +288,13 @@ static int yuetoast(lua_State* L) { | |||
| 282 | ruleName = {name, nameSize}; | 288 | ruleName = {name, nameSize}; |
| 283 | } | 289 | } |
| 284 | } | 290 | } |
| 291 | bool lax = false; | ||
| 292 | if (!lua_isnoneornil(L, 4)) { | ||
| 293 | luaL_checktype(L, 4, LUA_TBOOLEAN); | ||
| 294 | lax = lua_toboolean(L, 4) != 0; | ||
| 295 | } | ||
| 285 | auto& yueParser = yue::YueParser::shared(); | 296 | auto& yueParser = yue::YueParser::shared(); |
| 286 | auto info = ruleName.empty() ? yueParser.parse<yue::File_t>({input, size}) : yueParser.parse(ruleName, {input, size}); | 297 | auto info = ruleName.empty() ? yueParser.parse<yue::File_t>({input, size}, lax) : yueParser.parse(ruleName, {input, size}, lax); |
| 287 | if (!info.error) { | 298 | if (!info.error) { |
| 288 | lua_createtable(L, 0, 0); | 299 | lua_createtable(L, 0, 0); |
| 289 | int tableIndex = lua_gettop(L); | 300 | int tableIndex = lua_gettop(L); |
