diff options
-rwxr-xr-x | doc/docs/doc/README.md | 22 | ||||
-rwxr-xr-x | doc/docs/zh/doc/README.md | 22 | ||||
-rw-r--r-- | spec/inputs/assign.yue | 2 | ||||
-rw-r--r-- | spec/inputs/compile_doc.yue | 4 | ||||
-rw-r--r-- | spec/inputs/cond.yue | 28 | ||||
-rw-r--r-- | spec/inputs/destructure.yue | 8 | ||||
-rw-r--r-- | spec/inputs/existential.yue | 2 | ||||
-rw-r--r-- | spec/inputs/macro_teal.yue | 2 | ||||
-rw-r--r-- | spec/inputs/pipe.yue | 2 | ||||
-rw-r--r-- | spec/inputs/plus.yue | 8 | ||||
-rw-r--r-- | spec/inputs/try_catch.yue | 4 | ||||
-rw-r--r-- | spec/inputs/unicode/assign.yue | 2 | ||||
-rw-r--r-- | spec/inputs/unicode/cond.yue | 28 | ||||
-rw-r--r-- | spec/inputs/unicode/destructure.yue | 8 | ||||
-rw-r--r-- | spec/inputs/unicode/existential.yue | 2 | ||||
-rw-r--r-- | spec/inputs/unicode/pipe.yue | 2 | ||||
-rw-r--r-- | spec/inputs/unicode/plus.yue | 8 | ||||
-rw-r--r-- | spec/inputs/unicode/try_catch.yue | 4 | ||||
-rw-r--r-- | src/yuescript/yue_ast.h | 7 | ||||
-rw-r--r-- | src/yuescript/yue_compiler.cpp | 23 | ||||
-rw-r--r-- | src/yuescript/yue_parser.cpp | 9 | ||||
-rw-r--r-- | src/yuescript/yue_parser.h | 1 |
22 files changed, 104 insertions, 94 deletions
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/README.md index 54c6b72..041120b 100755 --- a/doc/docs/doc/README.md +++ b/doc/docs/doc/README.md | |||
@@ -1225,32 +1225,32 @@ We know each element in the array table is a two item tuple, so we can unpack it | |||
1225 | 1225 | ||
1226 | ## If Assignment | 1226 | ## If Assignment |
1227 | 1227 | ||
1228 | if and elseif blocks can take an assignment in place of a conditional expression. Upon evaluating the conditional, the assignment will take place and the value that was assigned to will be used as the conditional expression. The assigned variable is only in scope for the body of the conditional, meaning it is never available if the value is not truthy. | 1228 | `if` and `elseif` blocks can take an assignment in place of a conditional expression. Upon evaluating the conditional, the assignment will take place and the value that was assigned to will be used as the conditional expression. The assigned variable is only in scope for the body of the conditional, meaning it is never available if the value is not truthy. And you have to use "the walrus operator" `:=` instead of `=` to do assignment. |
1229 | 1229 | ||
1230 | ```moonscript | 1230 | ```moonscript |
1231 | if user = database.find_user "moon" | 1231 | if user := database.find_user "moon" |
1232 | print user.name | 1232 | print user.name |
1233 | ``` | 1233 | ``` |
1234 | <YueDisplay> | 1234 | <YueDisplay> |
1235 | <pre> | 1235 | <pre> |
1236 | if user = database.find_user "moon" | 1236 | if user := database.find_user "moon" |
1237 | print user.name | 1237 | print user.name |
1238 | </pre> | 1238 | </pre> |
1239 | </YueDisplay> | 1239 | </YueDisplay> |
1240 | 1240 | ||
1241 | ```moonscript | 1241 | ```moonscript |
1242 | if hello = os.getenv "hello" | 1242 | if hello := os.getenv "hello" |
1243 | print "You have hello", hello | 1243 | print "You have hello", hello |
1244 | elseif world = os.getenv "world" | 1244 | elseif world := os.getenv "world" |
1245 | print "you have world", world | 1245 | print "you have world", world |
1246 | else | 1246 | else |
1247 | print "nothing :(" | 1247 | print "nothing :(" |
1248 | ``` | 1248 | ``` |
1249 | <YueDisplay> | 1249 | <YueDisplay> |
1250 | <pre> | 1250 | <pre> |
1251 | if hello = os.getenv "hello" | 1251 | if hello := os.getenv "hello" |
1252 | print "You have hello", hello | 1252 | print "You have hello", hello |
1253 | elseif world = os.getenv "world" | 1253 | elseif world := os.getenv "world" |
1254 | print "you have world", world | 1254 | print "you have world", world |
1255 | else | 1255 | else |
1256 | print "nothing :(" | 1256 | print "nothing :(" |
@@ -1259,13 +1259,13 @@ else | |||
1259 | 1259 | ||
1260 | If assignment with multiple return values. Only the first value is getting checked, other values are scoped. | 1260 | If assignment with multiple return values. Only the first value is getting checked, other values are scoped. |
1261 | ```moonscript | 1261 | ```moonscript |
1262 | if success, result = pcall -> "get result without problems" | 1262 | if success, result := pcall -> "get result without problems" |
1263 | print result -- variable result is scoped | 1263 | print result -- variable result is scoped |
1264 | print "OK" | 1264 | print "OK" |
1265 | ``` | 1265 | ``` |
1266 | <YueDisplay> | 1266 | <YueDisplay> |
1267 | <pre> | 1267 | <pre> |
1268 | if success, result = pcall -> "get result without problems" | 1268 | if success, result := pcall -> "get result without problems" |
1269 | print result -- variable result is scoped | 1269 | print result -- variable result is scoped |
1270 | print "OK" | 1270 | print "OK" |
1271 | </pre> | 1271 | </pre> |
@@ -1374,7 +1374,7 @@ try | |||
1374 | func 1, 2, 3 | 1374 | func 1, 2, 3 |
1375 | 1375 | ||
1376 | -- working with if assignment pattern | 1376 | -- working with if assignment pattern |
1377 | if success, result = try func 1, 2, 3 | 1377 | if success, result := try func 1, 2, 3 |
1378 | catch err | 1378 | catch err |
1379 | print yue.traceback err | 1379 | print yue.traceback err |
1380 | print result | 1380 | print result |
@@ -1402,7 +1402,7 @@ try | |||
1402 | func 1, 2, 3 | 1402 | func 1, 2, 3 |
1403 | 1403 | ||
1404 | -- working with if assignment pattern | 1404 | -- working with if assignment pattern |
1405 | if success, result = try func 1, 2, 3 | 1405 | if success, result := try func 1, 2, 3 |
1406 | catch err | 1406 | catch err |
1407 | print yue.traceback err | 1407 | print yue.traceback err |
1408 | print result | 1408 | print result |
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md index 7e17b80..a856e7b 100755 --- a/doc/docs/zh/doc/README.md +++ b/doc/docs/zh/doc/README.md | |||
@@ -1223,32 +1223,32 @@ for [left, right] in *tuples | |||
1223 | 1223 | ||
1224 | ## If 赋值 | 1224 | ## If 赋值 |
1225 | 1225 | ||
1226 | `if` 和 `elseif` 代码块可以在条件表达式的位置进行赋值。在代码执行到要计算条件时,会首先进行赋值计算,并使用赋与的值作为分支判断的条件。赋值的变量仅在条件分支的代码块内有效,这意味着如果值不是真值,那么它就不会被用到。 | 1226 | `if` 和 `elseif` 代码块可以在条件表达式的位置进行赋值。在代码执行到要计算条件时,会首先进行赋值计算,并使用赋与的值作为分支判断的条件。赋值的变量仅在条件分支的代码块内有效,这意味着如果值不是真值,那么它就不会被用到。注意,你必须使用“海象运算符” `:=` 而不是 `=` 来做赋值。 |
1227 | 1227 | ||
1228 | ```moonscript | 1228 | ```moonscript |
1229 | if user = database.find_user "moon" | 1229 | if user := database.find_user "moon" |
1230 | print user.name | 1230 | print user.name |
1231 | ``` | 1231 | ``` |
1232 | <YueDisplay> | 1232 | <YueDisplay> |
1233 | <pre> | 1233 | <pre> |
1234 | if user = database.find_user "moon" | 1234 | if user := database.find_user "moon" |
1235 | print user.name | 1235 | print user.name |
1236 | </pre> | 1236 | </pre> |
1237 | </YueDisplay> | 1237 | </YueDisplay> |
1238 | 1238 | ||
1239 | ```moonscript | 1239 | ```moonscript |
1240 | if hello = os.getenv "hello" | 1240 | if hello := os.getenv "hello" |
1241 | print "你有 hello", hello | 1241 | print "你有 hello", hello |
1242 | elseif world = os.getenv "world" | 1242 | elseif world := os.getenv "world" |
1243 | print "你有 world", world | 1243 | print "你有 world", world |
1244 | else | 1244 | else |
1245 | print "什么都没有 :(" | 1245 | print "什么都没有 :(" |
1246 | ``` | 1246 | ``` |
1247 | <YueDisplay> | 1247 | <YueDisplay> |
1248 | <pre> | 1248 | <pre> |
1249 | if hello = os.getenv "hello" | 1249 | if hello := os.getenv "hello" |
1250 | print "你有 hello", hello | 1250 | print "你有 hello", hello |
1251 | elseif world = os.getenv "world" | 1251 | elseif world := os.getenv "world" |
1252 | print "你有 world", world | 1252 | print "你有 world", world |
1253 | else | 1253 | else |
1254 | print "什么都没有 :(" | 1254 | print "什么都没有 :(" |
@@ -1257,13 +1257,13 @@ else | |||
1257 | 1257 | ||
1258 | 使用多个返回值的 If 赋值。只有第一个值会被检查,其他值都有同样的作用域。 | 1258 | 使用多个返回值的 If 赋值。只有第一个值会被检查,其他值都有同样的作用域。 |
1259 | ```moonscript | 1259 | ```moonscript |
1260 | if success, result = pcall -> "无报错地获取结果" | 1260 | if success, result := pcall -> "无报错地获取结果" |
1261 | print result -- 变量 result 是有作用域的 | 1261 | print result -- 变量 result 是有作用域的 |
1262 | print "好的" | 1262 | print "好的" |
1263 | ``` | 1263 | ``` |
1264 | <YueDisplay> | 1264 | <YueDisplay> |
1265 | <pre> | 1265 | <pre> |
1266 | if success, result = pcall -> "无报错地获取结果" | 1266 | if success, result := pcall -> "无报错地获取结果" |
1267 | print result -- 变量 result 是有作用域的 | 1267 | print result -- 变量 result 是有作用域的 |
1268 | print "好的" | 1268 | print "好的" |
1269 | </pre> | 1269 | </pre> |
@@ -1372,7 +1372,7 @@ try | |||
1372 | func 1, 2, 3 | 1372 | func 1, 2, 3 |
1373 | 1373 | ||
1374 | -- 使用if赋值模式 | 1374 | -- 使用if赋值模式 |
1375 | if success, result = try func 1, 2, 3 | 1375 | if success, result := try func 1, 2, 3 |
1376 | catch err | 1376 | catch err |
1377 | print yue.traceback err | 1377 | print yue.traceback err |
1378 | print result | 1378 | print result |
@@ -1400,7 +1400,7 @@ try | |||
1400 | func 1, 2, 3 | 1400 | func 1, 2, 3 |
1401 | 1401 | ||
1402 | -- 使用if赋值模式 | 1402 | -- 使用if赋值模式 |
1403 | if success, result = try func 1, 2, 3 | 1403 | if success, result := try func 1, 2, 3 |
1404 | catch err | 1404 | catch err |
1405 | print yue.traceback err | 1405 | print yue.traceback err |
1406 | print result | 1406 | print result |
diff --git a/spec/inputs/assign.yue b/spec/inputs/assign.yue index 8ae5cac..2c89a99 100644 --- a/spec/inputs/assign.yue +++ b/spec/inputs/assign.yue | |||
@@ -30,7 +30,7 @@ c, d = 1, 2 if true | |||
30 | 30 | ||
31 | x = (do | 31 | x = (do |
32 | f! | 32 | f! |
33 | 123) if f = getHandler! | 33 | 123) if f := getHandler! |
34 | 34 | ||
35 | (using nil) <- _ | 35 | (using nil) <- _ |
36 | 36 | ||
diff --git a/spec/inputs/compile_doc.yue b/spec/inputs/compile_doc.yue index 4ce2b13..64d7d40 100644 --- a/spec/inputs/compile_doc.yue +++ b/spec/inputs/compile_doc.yue | |||
@@ -8,13 +8,13 @@ for [compiledFile, docFile] in *[ | |||
8 | text = \read "*a" | 8 | text = \read "*a" |
9 | codes = [] | 9 | codes = [] |
10 | for code in text\gmatch "```moonscript(.-)```" | 10 | for code in text\gmatch "```moonscript(.-)```" |
11 | if result, err = to_lua code, implicit_return_root: false, reserve_line_number: false | 11 | if result, err := to_lua code, implicit_return_root: false, reserve_line_number: false |
12 | codes[] = result | 12 | codes[] = result |
13 | elseif not err\match "macro exporting module only accepts macro definition" | 13 | elseif not err\match "macro exporting module only accepts macro definition" |
14 | print err | 14 | print err |
15 | os.exit 1 | 15 | os.exit 1 |
16 | for code in text\gmatch "<pre>(.-)</pre>" | 16 | for code in text\gmatch "<pre>(.-)</pre>" |
17 | if result, err = to_lua code\gsub("<", "<")\gsub(">", ">"), implicit_return_root: false, reserve_line_number: false | 17 | if result, err := to_lua code\gsub("<", "<")\gsub(">", ">"), implicit_return_root: false, reserve_line_number: false |
18 | codes[] = result | 18 | codes[] = result |
19 | else | 19 | else |
20 | print err | 20 | print err |
diff --git a/spec/inputs/cond.yue b/spec/inputs/cond.yue index 5bc6c9b..cce96df 100644 --- a/spec/inputs/cond.yue +++ b/spec/inputs/cond.yue | |||
@@ -52,18 +52,18 @@ elseif "just us" | |||
52 | 52 | ||
53 | -- | 53 | -- |
54 | 54 | ||
55 | if something = 10 | 55 | if something := 10 |
56 | print something | 56 | print something |
57 | else | 57 | else |
58 | print "else" | 58 | print "else" |
59 | 59 | ||
60 | hello = if something = 10 | 60 | hello = if something := 10 |
61 | print something | 61 | print something |
62 | else | 62 | else |
63 | print "else" | 63 | print "else" |
64 | 64 | ||
65 | 65 | ||
66 | hello = 5 + if something = 10 | 66 | hello = 5 + if something := 10 |
67 | print something | 67 | print something |
68 | 68 | ||
69 | --- | 69 | --- |
@@ -72,9 +72,9 @@ z = false | |||
72 | 72 | ||
73 | _ = if false | 73 | _ = if false |
74 | one | 74 | one |
75 | elseif x = true | 75 | elseif x := true |
76 | two | 76 | two |
77 | elseif z = true | 77 | elseif z := true |
78 | three | 78 | three |
79 | else | 79 | else |
80 | four | 80 | four |
@@ -82,17 +82,17 @@ else | |||
82 | 82 | ||
83 | out = if false | 83 | out = if false |
84 | one | 84 | one |
85 | elseif x = true | 85 | elseif x := true |
86 | two | 86 | two |
87 | elseif z = true | 87 | elseif z := true |
88 | three | 88 | three |
89 | else | 89 | else |
90 | four | 90 | four |
91 | 91 | ||
92 | kzy = -> | 92 | kzy = -> |
93 | if something = true | 93 | if something := true |
94 | 1 | 94 | 1 |
95 | elseif another = false | 95 | elseif another := false |
96 | 2 | 96 | 2 |
97 | 97 | ||
98 | --- | 98 | --- |
@@ -152,7 +152,7 @@ dddd = {1,2,3} unless value | |||
152 | 152 | ||
153 | do | 153 | do |
154 | j = 100 | 154 | j = 100 |
155 | unless j = hi! | 155 | unless j := hi! |
156 | error "not j!" | 156 | error "not j!" |
157 | 157 | ||
158 | ---------------- | 158 | ---------------- |
@@ -200,22 +200,22 @@ do | |||
200 | elseif c | 200 | elseif c |
201 | d: e = tb | 201 | d: e = tb |
202 | 202 | ||
203 | if :pi = math | 203 | if :pi := math |
204 | print pi | 204 | print pi |
205 | 205 | ||
206 | do | 206 | do |
207 | local math | 207 | local math |
208 | if :pi = math | 208 | if :pi := math |
209 | print pi | 209 | print pi |
210 | 210 | ||
211 | do | 211 | do |
212 | if _M = {} | 212 | if _M := {} |
213 | :Thing = _M | 213 | :Thing = _M |
214 | :a, :b = _M | 214 | :a, :b = _M |
215 | 215 | ||
216 | do | 216 | do |
217 | global _M | 217 | global _M |
218 | if _M = {} | 218 | if _M := {} |
219 | :Thing = _M | 219 | :Thing = _M |
220 | :a, :b = _M | 220 | :a, :b = _M |
221 | 221 | ||
diff --git a/spec/inputs/destructure.yue b/spec/inputs/destructure.yue index 73e4d33..5017ee1 100644 --- a/spec/inputs/destructure.yue +++ b/spec/inputs/destructure.yue | |||
@@ -94,18 +94,18 @@ do | |||
94 | 94 | ||
95 | do | 95 | do |
96 | thing = nil | 96 | thing = nil |
97 | if {a} = thing | 97 | if {a} := thing |
98 | print a | 98 | print a |
99 | else | 99 | else |
100 | print "nothing" | 100 | print "nothing" |
101 | 101 | ||
102 | thang = {1,2} | 102 | thang = {1,2} |
103 | if {a,b} = thang | 103 | if {a,b} := thang |
104 | print a,b | 104 | print a,b |
105 | 105 | ||
106 | if {a,b} = thing | 106 | if {a,b} := thing |
107 | print a,b | 107 | print a,b |
108 | elseif {c,d} = thang | 108 | elseif {c,d} := thang |
109 | print c,d | 109 | print c,d |
110 | else | 110 | else |
111 | print "NO" | 111 | print "NO" |
diff --git a/spec/inputs/existential.yue b/spec/inputs/existential.yue index 27891dc..ec38897 100644 --- a/spec/inputs/existential.yue +++ b/spec/inputs/existential.yue | |||
@@ -16,7 +16,7 @@ with abc?!\func?! | |||
16 | if \p? "abc" | 16 | if \p? "abc" |
17 | return 123 | 17 | return 123 |
18 | 18 | ||
19 | if {:x} = a?.if?\then?(123)? @?\function 998 | 19 | if {:x} := a?.if?\then?(123)? @?\function 998 |
20 | print x | 20 | print x |
21 | 21 | ||
22 | res = b.function\do!\while?("OK")\if("def",998)\f? | 22 | res = b.function\do!\while?("OK")\if("def",998)\f? |
diff --git a/spec/inputs/macro_teal.yue b/spec/inputs/macro_teal.yue index a443614..0cfd862 100644 --- a/spec/inputs/macro_teal.yue +++ b/spec/inputs/macro_teal.yue | |||
@@ -8,7 +8,7 @@ macro to_lua = (code)-> | |||
8 | "require('yue').to_lua(#{code}, reserve_line_number:false, same_module:true)" | 8 | "require('yue').to_lua(#{code}, reserve_line_number:false, same_module:true)" |
9 | 9 | ||
10 | macro trim = (name)-> | 10 | macro trim = (name)-> |
11 | "if result = #{name}\\match '[\\'\"](.*)[\\'\"]' then result else #{name}" | 11 | "if result := #{name}\\match '[\\'\"](.*)[\\'\"]' then result else #{name}" |
12 | 12 | ||
13 | export macro local = (decl, value = nil)-> | 13 | export macro local = (decl, value = nil)-> |
14 | import "yue" as {options:{:tl_enabled}} | 14 | import "yue" as {options:{:tl_enabled}} |
diff --git a/spec/inputs/pipe.yue b/spec/inputs/pipe.yue index 02f87a3..b5bae1d 100644 --- a/spec/inputs/pipe.yue +++ b/spec/inputs/pipe.yue | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | b = 1 + 2 + (4 |> tostring |> print(1) or 123) | 12 | b = 1 + 2 + (4 |> tostring |> print(1) or 123) |
13 | 13 | ||
14 | if x = 233 |> math.max 998 | 14 | if x := 233 |> math.max 998 |
15 | print x | 15 | print x |
16 | 16 | ||
17 | with b |> create? "new" | 17 | with b |> create? "new" |
diff --git a/spec/inputs/plus.yue b/spec/inputs/plus.yue index e387090..9c500a4 100644 --- a/spec/inputs/plus.yue +++ b/spec/inputs/plus.yue | |||
@@ -8,13 +8,13 @@ c.repeat.if\then("xyz")\else res | |||
8 | 8 | ||
9 | print @for,@@function 123 | 9 | print @for,@@function 123 |
10 | 10 | ||
11 | if fcolor = message\match "<%w*>" then message = message\gsub "<%->", fcolor | 11 | if fcolor := message\match "<%w*>" then message = message\gsub "<%->", fcolor |
12 | 12 | ||
13 | message = message\gsub "<%->", fcolor if fcolor = message\match "<%w*>" | 13 | message = message\gsub "<%->", fcolor if fcolor := message\match "<%w*>" |
14 | 14 | ||
15 | valA = func! if func = getfunc! | 15 | valA = func! if func := getfunc! |
16 | 16 | ||
17 | local valA = func! if func = getfunc! | 17 | local valA = func! if func := getfunc! |
18 | 18 | ||
19 | valB = do | 19 | valB = do |
20 | func = getfunc! | 20 | func = getfunc! |
diff --git a/spec/inputs/try_catch.yue b/spec/inputs/try_catch.yue index 96a87fc..ccb3f52 100644 --- a/spec/inputs/try_catch.yue +++ b/spec/inputs/try_catch.yue | |||
@@ -39,14 +39,14 @@ catch err | |||
39 | print "OK" | 39 | print "OK" |
40 | 40 | ||
41 | do | 41 | do |
42 | if success, result = try func "abc", 123 | 42 | if success, result := try func "abc", 123 |
43 | print result | 43 | print result |
44 | 44 | ||
45 | success, result = try func "abc", 123 | 45 | success, result = try func "abc", 123 |
46 | catch err | 46 | catch err |
47 | print err | 47 | print err |
48 | 48 | ||
49 | print result if success, result = try func "abc", 123 | 49 | print result if success, result := try func "abc", 123 |
50 | catch err | 50 | catch err |
51 | print err | 51 | print err |
52 | 52 | ||
diff --git a/spec/inputs/unicode/assign.yue b/spec/inputs/unicode/assign.yue index 5392a92..6c03f86 100644 --- a/spec/inputs/unicode/assign.yue +++ b/spec/inputs/unicode/assign.yue | |||
@@ -30,7 +30,7 @@ else | |||
30 | 30 | ||
31 | 变量x = (do | 31 | 变量x = (do |
32 | 函数! | 32 | 函数! |
33 | 123) if 函数 = 获取处理函数! | 33 | 123) if 函数 := 获取处理函数! |
34 | 34 | ||
35 | (using nil) <- _无效变量 | 35 | (using nil) <- _无效变量 |
36 | 36 | ||
diff --git a/spec/inputs/unicode/cond.yue b/spec/inputs/unicode/cond.yue index fca6d60..dde5c99 100644 --- a/spec/inputs/unicode/cond.yue +++ b/spec/inputs/unicode/cond.yue | |||
@@ -52,18 +52,18 @@ elseif "只有我们" | |||
52 | 52 | ||
53 | -- | 53 | -- |
54 | 54 | ||
55 | if 某东西 = 10 | 55 | if 某东西 := 10 |
56 | 打印 某东西 | 56 | 打印 某东西 |
57 | else | 57 | else |
58 | 打印 "其它" | 58 | 打印 "其它" |
59 | 59 | ||
60 | 你好 = if 某东西 = 10 | 60 | 你好 = if 某东西 := 10 |
61 | 打印 某东西 | 61 | 打印 某东西 |
62 | else | 62 | else |
63 | 打印 "其它" | 63 | 打印 "其它" |
64 | 64 | ||
65 | 65 | ||
66 | 你好 = 5 + if 某东西 = 10 | 66 | 你好 = 5 + if 某东西 := 10 |
67 | 打印 某东西 | 67 | 打印 某东西 |
68 | 68 | ||
69 | --- | 69 | --- |
@@ -72,9 +72,9 @@ z变量 = false | |||
72 | 72 | ||
73 | _无效变量 = if false | 73 | _无效变量 = if false |
74 | 一 | 74 | 一 |
75 | elseif 条件x = true | 75 | elseif 条件x := true |
76 | 二 | 76 | 二 |
77 | elseif 条件z = true | 77 | elseif 条件z := true |
78 | 三 | 78 | 三 |
79 | else | 79 | else |
80 | 四 | 80 | 四 |
@@ -82,17 +82,17 @@ else | |||
82 | 82 | ||
83 | 输出 = if false | 83 | 输出 = if false |
84 | 一 | 84 | 一 |
85 | elseif 条件x = true | 85 | elseif 条件x := true |
86 | 二 | 86 | 二 |
87 | elseif 条件z = true | 87 | elseif 条件z := true |
88 | 三 | 88 | 三 |
89 | else | 89 | else |
90 | 四 | 90 | 四 |
91 | 91 | ||
92 | 变量 = -> | 92 | 变量 = -> |
93 | if 某东西 = true | 93 | if 某东西 := true |
94 | 1 | 94 | 1 |
95 | elseif 另一个 = false | 95 | elseif 另一个 := false |
96 | 2 | 96 | 2 |
97 | 97 | ||
98 | --- | 98 | --- |
@@ -152,7 +152,7 @@ else | |||
152 | 152 | ||
153 | do | 153 | do |
154 | j变量 = 100 | 154 | j变量 = 100 |
155 | unless j变量 = 嗨! | 155 | unless j变量 := 嗨! |
156 | 错误 "不是 j变量!" | 156 | 错误 "不是 j变量!" |
157 | 157 | ||
158 | ---------------- | 158 | ---------------- |
@@ -200,22 +200,22 @@ do | |||
200 | elseif 条件c | 200 | elseif 条件c |
201 | 字段d: 变量e = 变量tb | 201 | 字段d: 变量e = 变量tb |
202 | 202 | ||
203 | if :派 = 数学库 | 203 | if :派 := 数学库 |
204 | 打印 派 | 204 | 打印 派 |
205 | 205 | ||
206 | do | 206 | do |
207 | local 数学库 | 207 | local 数学库 |
208 | if :派 = 数学库 | 208 | if :派 := 数学库 |
209 | 打印 派 | 209 | 打印 派 |
210 | 210 | ||
211 | do | 211 | do |
212 | if _模块 = {} | 212 | if _模块 := {} |
213 | :东西 = _模块 | 213 | :东西 = _模块 |
214 | :a功能, :b功能 = _模块 | 214 | :a功能, :b功能 = _模块 |
215 | 215 | ||
216 | do | 216 | do |
217 | global _模块 | 217 | global _模块 |
218 | if _模块 = {} | 218 | if _模块 := {} |
219 | :东西 = _模块 | 219 | :东西 = _模块 |
220 | :a功能, :b功能 = _模块 | 220 | :a功能, :b功能 = _模块 |
221 | 221 | ||
diff --git a/spec/inputs/unicode/destructure.yue b/spec/inputs/unicode/destructure.yue index 5efdf82..3c3a369 100644 --- a/spec/inputs/unicode/destructure.yue +++ b/spec/inputs/unicode/destructure.yue | |||
@@ -92,18 +92,18 @@ do | |||
92 | 92 | ||
93 | do | 93 | do |
94 | 东西 = nil | 94 | 东西 = nil |
95 | if {元素a} = 东西 | 95 | if {元素a} := 东西 |
96 | 打印 元素a | 96 | 打印 元素a |
97 | else | 97 | else |
98 | 打印 "没东西" | 98 | 打印 "没东西" |
99 | 99 | ||
100 | 东东 = {1,2} | 100 | 东东 = {1,2} |
101 | if {元素a,元素b} = 东东 | 101 | if {元素a,元素b} := 东东 |
102 | 打印 元素a,元素b | 102 | 打印 元素a,元素b |
103 | 103 | ||
104 | if {元素a,元素b} = 东西 | 104 | if {元素a,元素b} := 东西 |
105 | 打印 元素a,元素b | 105 | 打印 元素a,元素b |
106 | elseif {元素c,元素d} = 东东 | 106 | elseif {元素c,元素d} := 东东 |
107 | 打印 元素c,元素d | 107 | 打印 元素c,元素d |
108 | else | 108 | else |
109 | 打印 "不" | 109 | 打印 "不" |
diff --git a/spec/inputs/unicode/existential.yue b/spec/inputs/unicode/existential.yue index 0e35a39..de65027 100644 --- a/spec/inputs/unicode/existential.yue +++ b/spec/inputs/unicode/existential.yue | |||
@@ -16,7 +16,7 @@ with 对象abc?!\函数?! | |||
16 | if \函数p? "abc" | 16 | if \函数p? "abc" |
17 | return 123 | 17 | return 123 |
18 | 18 | ||
19 | if {:x字段} = 对象a?.如果?\然后?(123)? @?\方法 998 | 19 | if {:x字段} := 对象a?.如果?\然后?(123)? @?\方法 998 |
20 | 打印 x字段 | 20 | 打印 x字段 |
21 | 21 | ||
22 | 结果 = 对象b.方法\执行!\当?("没问题")\如果("默认",998)\函数? | 22 | 结果 = 对象b.方法\执行!\当?("没问题")\如果("默认",998)\函数? |
diff --git a/spec/inputs/unicode/pipe.yue b/spec/inputs/unicode/pipe.yue index 2cd41ee..085a2cf 100644 --- a/spec/inputs/unicode/pipe.yue +++ b/spec/inputs/unicode/pipe.yue | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | 变量b = 1 + 2 + (4 |> tostring |> 打印(1) or 123) | 12 | 变量b = 1 + 2 + (4 |> tostring |> 打印(1) or 123) |
13 | 13 | ||
14 | if 变量x = 233 |> math.max 998 | 14 | if 变量x := 233 |> math.max 998 |
15 | 打印 变量x | 15 | 打印 变量x |
16 | 16 | ||
17 | with 变量b |> 创建? "new" | 17 | with 变量b |> 创建? "new" |
diff --git a/spec/inputs/unicode/plus.yue b/spec/inputs/unicode/plus.yue index b08974f..70b57bb 100644 --- a/spec/inputs/unicode/plus.yue +++ b/spec/inputs/unicode/plus.yue | |||
@@ -8,13 +8,13 @@ | |||
8 | 8 | ||
9 | 打印 @循环, @@函数 123 | 9 | 打印 @循环, @@函数 123 |
10 | 10 | ||
11 | if 颜色 = 消息\匹配 "<%w*>" then 消息 = 消息\替换 "<%->", 颜色 | 11 | if 颜色 := 消息\匹配 "<%w*>" then 消息 = 消息\替换 "<%->", 颜色 |
12 | 12 | ||
13 | 消息 = 消息\替换 "<%->", 颜色 if 颜色 = 消息\匹配 "<%w*>" | 13 | 消息 = 消息\替换 "<%->", 颜色 if 颜色 := 消息\匹配 "<%w*>" |
14 | 14 | ||
15 | 数值A = 方法! if 方法 = 获取方法! | 15 | 数值A = 方法! if 方法 := 获取方法! |
16 | 16 | ||
17 | local 数值A = 方法! if 方法 = 获取方法! | 17 | local 数值A = 方法! if 方法 := 获取方法! |
18 | 18 | ||
19 | 数值B = do | 19 | 数值B = do |
20 | 方法 = 获取方法! | 20 | 方法 = 获取方法! |
diff --git a/spec/inputs/unicode/try_catch.yue b/spec/inputs/unicode/try_catch.yue index 71e03ee..1156d8e 100644 --- a/spec/inputs/unicode/try_catch.yue +++ b/spec/inputs/unicode/try_catch.yue | |||
@@ -39,14 +39,14 @@ catch 错误 | |||
39 | 打印 "好的" | 39 | 打印 "好的" |
40 | 40 | ||
41 | do | 41 | do |
42 | if 成功, 结果 = try 函数 "abc", 123 | 42 | if 成功, 结果 := try 函数 "abc", 123 |
43 | 打印 结果 | 43 | 打印 结果 |
44 | 44 | ||
45 | 成功, 结果 = try 函数 "abc", 123 | 45 | 成功, 结果 = try 函数 "abc", 123 |
46 | catch 错误 | 46 | catch 错误 |
47 | 打印 错误 | 47 | 打印 错误 |
48 | 48 | ||
49 | 打印 结果 if 成功, 结果 = try 函数 "abc", 123 | 49 | 打印 结果 if 成功, 结果 := try 函数 "abc", 123 |
50 | catch 错误 | 50 | catch 错误 |
51 | 打印 错误 | 51 | 打印 错误 |
52 | 52 | ||
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index fa47559..6b2b7f8 100644 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
@@ -302,14 +302,15 @@ AST_NODE(Switch) | |||
302 | AST_END(Switch, "switch"sv) | 302 | AST_END(Switch, "switch"sv) |
303 | 303 | ||
304 | AST_NODE(Assignment) | 304 | AST_NODE(Assignment) |
305 | ast_ptr<true, ExpList_t> expList; | 305 | ast_ptr<false, ExpList_t> expList; |
306 | ast_ptr<true, Assign_t> assign; | 306 | ast_ptr<true, Assign_t> assign; |
307 | AST_MEMBER(Assignment, &expList, &assign) | 307 | AST_MEMBER(Assignment, &expList, &assign) |
308 | AST_END(Assignment, "assignment"sv) | 308 | AST_END(Assignment, "assignment"sv) |
309 | 309 | ||
310 | AST_NODE(IfCond) | 310 | AST_NODE(IfCond) |
311 | ast_sel<true, Exp_t, Assignment_t> condition; | 311 | ast_ptr<true, Exp_t> condition; |
312 | AST_MEMBER(IfCond, &condition) | 312 | ast_ptr<false, Assignment_t> assignment; |
313 | AST_MEMBER(IfCond, &condition, &assignment) | ||
313 | AST_END(IfCond, "if_cond"sv) | 314 | AST_END(IfCond, "if_cond"sv) |
314 | 315 | ||
315 | AST_LEAF(IfType) | 316 | AST_LEAF(IfType) |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 69a028f..d37f911 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -75,7 +75,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
75 | "close"s // Lua 5.4 | 75 | "close"s // Lua 5.4 |
76 | }; | 76 | }; |
77 | 77 | ||
78 | const std::string_view version = "0.20.7"sv; | 78 | const std::string_view version = "0.21.0"sv; |
79 | const std::string_view extension = "yue"sv; | 79 | const std::string_view extension = "yue"sv; |
80 | 80 | ||
81 | class CompileError : public std::logic_error { | 81 | class CompileError : public std::logic_error { |
@@ -3088,7 +3088,7 @@ private: | |||
3088 | for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) { | 3088 | for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) { |
3089 | ns.push_back(*it); | 3089 | ns.push_back(*it); |
3090 | if (auto cond = ast_cast<IfCond_t>(*it)) { | 3090 | if (auto cond = ast_cast<IfCond_t>(*it)) { |
3091 | if (*it != nodes.front() && cond->condition.is<Assignment_t>()) { | 3091 | if (*it != nodes.front() && cond->assignment) { |
3092 | auto x = *it; | 3092 | auto x = *it; |
3093 | auto newIf = x->new_ptr<If_t>(); | 3093 | auto newIf = x->new_ptr<If_t>(); |
3094 | newIf->type.set(toAst<IfType_t>("if"sv, x)); | 3094 | newIf->type.set(toAst<IfType_t>("if"sv, x)); |
@@ -3142,11 +3142,12 @@ private: | |||
3142 | default: YUEE("AST node mismatch", node); break; | 3142 | default: YUEE("AST node mismatch", node); break; |
3143 | } | 3143 | } |
3144 | } | 3144 | } |
3145 | auto asmt = ifCondPairs.front().first->condition.as<Assignment_t>(); | 3145 | auto firstIfCond = ifCondPairs.front().first; |
3146 | auto asmt = firstIfCond->assignment.get(); | ||
3146 | bool storingValue = false; | 3147 | bool storingValue = false; |
3147 | ast_ptr<false, ExpListAssign_t> extraAssignment; | 3148 | ast_ptr<false, ExpListAssign_t> extraAssignment; |
3148 | if (asmt) { | 3149 | if (asmt) { |
3149 | ast_ptr<false, ast_node> exp = asmt->expList->exprs.front(); | 3150 | auto exp = firstIfCond->condition.get(); |
3150 | auto x = exp; | 3151 | auto x = exp; |
3151 | auto var = singleVariableFrom(exp, false); | 3152 | auto var = singleVariableFrom(exp, false); |
3152 | if (var.empty() || isGlobal(var)) { | 3153 | if (var.empty() || isGlobal(var)) { |
@@ -3164,11 +3165,12 @@ private: | |||
3164 | temp.push_back(indent() + "do"s + nll(asmt)); | 3165 | temp.push_back(indent() + "do"s + nll(asmt)); |
3165 | pushScope(); | 3166 | pushScope(); |
3166 | } | 3167 | } |
3167 | asmt->expList->exprs.pop_front(); | ||
3168 | auto expList = toAst<ExpList_t>(desVar, x); | 3168 | auto expList = toAst<ExpList_t>(desVar, x); |
3169 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 3169 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
3170 | for (auto expr : asmt->expList->exprs.objects()) { | 3170 | if (asmt->expList) { |
3171 | expList->exprs.push_back(expr); | 3171 | for (auto expr : asmt->expList->exprs.objects()) { |
3172 | expList->exprs.push_back(expr); | ||
3173 | } | ||
3172 | } | 3174 | } |
3173 | assignment->expList.set(expList); | 3175 | assignment->expList.set(expList); |
3174 | assignment->action.set(asmt->assign); | 3176 | assignment->action.set(asmt->assign); |
@@ -3196,9 +3198,10 @@ private: | |||
3196 | } | 3198 | } |
3197 | auto expList = x->new_ptr<ExpList_t>(); | 3199 | auto expList = x->new_ptr<ExpList_t>(); |
3198 | expList->exprs.push_back(exp); | 3200 | expList->exprs.push_back(exp); |
3199 | asmt->expList->exprs.pop_front(); | 3201 | if (asmt->expList) { |
3200 | for (auto expr : asmt->expList->exprs.objects()) { | 3202 | for (auto expr : asmt->expList->exprs.objects()) { |
3201 | expList->exprs.push_back(expr); | 3203 | expList->exprs.push_back(expr); |
3204 | } | ||
3202 | } | 3205 | } |
3203 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 3206 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
3204 | assignment->expList.set(expList); | 3207 | assignment->expList.set(expList); |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index 2206686..5b97a25 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
@@ -114,6 +114,11 @@ YueParser::YueParser() { | |||
114 | return false; | 114 | return false; |
115 | }); | 115 | }); |
116 | 116 | ||
117 | if_assignment_syntax_error = pl::user(true_(), [](const item_t& item) { | ||
118 | throw ParserError("use := for if-assignment expression"sv, item.begin); | ||
119 | return false; | ||
120 | }); | ||
121 | |||
117 | #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut) | 122 | #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut) |
118 | 123 | ||
119 | #define key(str) (expr(str) >> not_alpha_num) | 124 | #define key(str) (expr(str) >> not_alpha_num) |
@@ -369,8 +374,8 @@ YueParser::YueParser() { | |||
369 | +space_break >> advance_match >> space >> SwitchCase >> switch_block >> pop_indent | 374 | +space_break >> advance_match >> space >> SwitchCase >> switch_block >> pop_indent |
370 | ) >> switch_block; | 375 | ) >> switch_block; |
371 | 376 | ||
372 | Assignment = ExpList >> space >> Assign; | 377 | Assignment = -(',' >> space >> ExpList >> space) >> (':' >> Assign | and_('=') >> if_assignment_syntax_error); |
373 | IfCond = disable_chain_rule(disable_arg_table_block_rule(Assignment | Exp)); | 378 | IfCond = disable_chain_rule(disable_arg_table_block_rule(Exp >> -(space >> Assignment))); |
374 | if_else_if = -(line_break >> *space_break >> check_indent_match) >> space >> key("elseif") >> space >> IfCond >> space >> body_with("then"); | 379 | if_else_if = -(line_break >> *space_break >> check_indent_match) >> space >> key("elseif") >> space >> IfCond >> space >> body_with("then"); |
375 | if_else = -(line_break >> *space_break >> check_indent_match) >> space >> key("else") >> space >> body; | 380 | if_else = -(line_break >> *space_break >> check_indent_match) >> space >> key("else") >> space >> body; |
376 | IfType = (expr("if") | "unless") >> not_alpha_num; | 381 | IfType = (expr("if") | "unless") >> not_alpha_num; |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index 16b57b2..c3d5d7d 100644 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
@@ -141,6 +141,7 @@ private: | |||
141 | NONE_AST_RULE(invalid_interpolation_error); | 141 | NONE_AST_RULE(invalid_interpolation_error); |
142 | NONE_AST_RULE(confusing_unary_not_error); | 142 | NONE_AST_RULE(confusing_unary_not_error); |
143 | NONE_AST_RULE(table_key_pair_error); | 143 | NONE_AST_RULE(table_key_pair_error); |
144 | NONE_AST_RULE(if_assignment_syntax_error); | ||
144 | 145 | ||
145 | NONE_AST_RULE(inc_exp_level); | 146 | NONE_AST_RULE(inc_exp_level); |
146 | NONE_AST_RULE(dec_exp_level); | 147 | NONE_AST_RULE(dec_exp_level); |