diff options
author | Li Jin <dragon-fly@qq.com> | 2022-09-08 09:26:49 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2022-09-08 09:26:49 +0800 |
commit | d4af1fa275b1d27229fc995f4a45137380040933 (patch) | |
tree | 955c76511d7021e6d1a0f06b46de3852eeac4176 | |
parent | df85ad2e7f975026ca1e6bd84b26fff81c8d99c8 (diff) | |
download | yuescript-d4af1fa275b1d27229fc995f4a45137380040933.tar.gz yuescript-d4af1fa275b1d27229fc995f4a45137380040933.tar.bz2 yuescript-d4af1fa275b1d27229fc995f4a45137380040933.zip |
redesigned metatable syntax. add support for destructuring a field with string and expression
-rwxr-xr-x | doc/docs/doc/README.md | 53 | ||||
-rw-r--r-- | spec/inputs/assign.yue | 4 | ||||
-rw-r--r-- | spec/inputs/class.yue | 6 | ||||
-rw-r--r-- | spec/inputs/destructure.yue | 31 | ||||
-rw-r--r-- | spec/inputs/existential.yue | 4 | ||||
-rw-r--r-- | spec/inputs/import.yue | 6 | ||||
-rw-r--r-- | spec/inputs/macro.yue | 2 | ||||
-rw-r--r-- | spec/inputs/metatable.yue | 92 | ||||
-rw-r--r-- | spec/inputs/switch.yue | 4 | ||||
-rw-r--r-- | spec/outputs/destructure.lua | 61 | ||||
-rw-r--r-- | spec/outputs/metatable.lua | 33 | ||||
-rwxr-xr-x | src/yuescript/yue_ast.h | 17 | ||||
-rwxr-xr-x | src/yuescript/yue_compiler.cpp | 556 | ||||
-rwxr-xr-x | src/yuescript/yue_parser.cpp | 32 | ||||
-rwxr-xr-x | src/yuescript/yue_parser.h | 1 |
15 files changed, 605 insertions, 297 deletions
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/README.md index 5f00860..5e81d4c 100755 --- a/doc/docs/doc/README.md +++ b/doc/docs/doc/README.md | |||
@@ -37,8 +37,8 @@ inventory = | |||
37 | -- metatable manipulation | 37 | -- metatable manipulation |
38 | apple = | 38 | apple = |
39 | size: 15 | 39 | size: 15 |
40 | index#: {color: 0x00ffff} | 40 | <index>: {color: 0x00ffff} |
41 | p apple.color, apple.index# if apple.#? | 41 | p apple.color, apple.<index> if apple.<>? |
42 | 42 | ||
43 | -- js-like export syntax | 43 | -- js-like export syntax |
44 | export yuescript = "月之脚本" | 44 | export yuescript = "月之脚本" |
@@ -69,8 +69,8 @@ inventory = | |||
69 | -- metatable manipulation | 69 | -- metatable manipulation |
70 | apple = | 70 | apple = |
71 | size: 15 | 71 | size: 15 |
72 | index#: {color: 0x00ffff} | 72 | <index>: {color: 0x00ffff} |
73 | p apple.color, apple.index# if apple.#? | 73 | p apple.color, apple.<index> if apple.<>? |
74 | 74 | ||
75 | -- js-like export syntax | 75 | -- js-like export syntax |
76 | export yuescript = "月之脚本" | 76 | export yuescript = "月之脚本" |
@@ -429,77 +429,78 @@ merge = {...a, ...b} | |||
429 | 429 | ||
430 | ### Metatable | 430 | ### Metatable |
431 | 431 | ||
432 | The **#** operator can be used as a shortcut for metatable manipulation. | 432 | The **<>** operator can be used as a shortcut for metatable manipulation. |
433 | 433 | ||
434 | * **Metatable Creation** | 434 | * **Metatable Creation** |
435 | Create normal table with key **#** or metamethod key that ends with **#**. | 435 | Create normal table with empty bracekets **<>** or metamethod key which is surrounded by **<>**. |
436 | 436 | ||
437 | ```moonscript | 437 | ```moonscript |
438 | mt = {} | 438 | mt = {} |
439 | add = (right)=> #: mt, value: @value + right.value | 439 | add = (right)=> <>: mt, value: @value + right.value |
440 | mt.__add = add | 440 | mt.__add = add |
441 | 441 | ||
442 | a = #: mt, value: 1 | 442 | a = <>: mt, value: 1 |
443 | -- set field with variable of the same name | 443 | -- set field with variable of the same name |
444 | b = :add#, value: 2 | 444 | b = :<add>, value: 2 |
445 | c = add#: mt.__add, value: 3 | 445 | c = <add>: mt.__add, value: 3 |
446 | 446 | ||
447 | d = a + b + c | 447 | d = a + b + c |
448 | print d.value | 448 | print d.value |
449 | 449 | ||
450 | close _ = close#: -> print "out of scope" | 450 | close _ = <close>: -> print "out of scope" |
451 | ``` | 451 | ``` |
452 | <YueDisplay> | 452 | <YueDisplay> |
453 | <pre> | 453 | <pre> |
454 | mt = {} | 454 | mt = {} |
455 | add = (right)=> #: mt, value: @value + right.value | 455 | add = (right)=> <>: mt, value: @value + right.value |
456 | mt.__add = add | 456 | mt.__add = add |
457 | 457 | ||
458 | a = #: mt, value: 1 | 458 | a = <>: mt, value: 1 |
459 | -- set field with variable of the same name | 459 | -- set field with variable of the same name |
460 | b = :add#, value: 2 | 460 | b = :<add>, value: 2 |
461 | c = add#: mt.__add, value: 3 | 461 | c = <add>: mt.__add, value: 3 |
462 | 462 | ||
463 | d = a + b + c | 463 | d = a + b + c |
464 | print d.value | 464 | print d.value |
465 | 465 | ||
466 | close _ = close#: -> print "out of scope" | 466 | close _ = <close>: -> print "out of scope" |
467 | </pre> | 467 | </pre> |
468 | </YueDisplay> | 468 | </YueDisplay> |
469 | 469 | ||
470 | * **Metatable Accessing** | 470 | * **Metatable Accessing** |
471 | Accessing metatable with key **#** or metamethod key that ends with **#**. | 471 | Accessing metatable with **<>** or metamethod name surrounded by **<>** or writing some expression in **<>**. |
472 | 472 | ||
473 | ```moonscript | 473 | ```moonscript |
474 | -- create with metatable containing field "value" | 474 | -- create with metatable containing field "value" |
475 | tb = ["value"]#: 123 | 475 | tb = <"value">: 123 |
476 | tb.index# = tb.# | 476 | tb.<index> = tb.<> |
477 | print tb.value | 477 | print tb.value |
478 | 478 | ||
479 | tb.# = __index: {item: "hello"} | 479 | tb.<> = __index: {item: "hello"} |
480 | print tb.item | 480 | print tb.item |
481 | ``` | 481 | ``` |
482 | <YueDisplay> | 482 | <YueDisplay> |
483 | |||
483 | <pre> | 484 | <pre> |
484 | -- create with metatable containing field "value" | 485 | -- create with metatable containing field "value" |
485 | tb = ["value"]#: 123 | 486 | tb = <"value">: 123 |
486 | tb.index# = tb.# | 487 | tb.<index> = tb.<> |
487 | print tb.value | 488 | print tb.value |
488 | tb.# = __index: {item: "hello"} | 489 | tb.<> = __index: {item: "hello"} |
489 | print tb.item | 490 | print tb.item |
490 | </pre> | 491 | </pre> |
491 | </YueDisplay> | 492 | </YueDisplay> |
492 | 493 | ||
493 | * **Metatable Destructure** | 494 | * **Metatable Destructure** |
494 | Destruct metatable with metamethod key that ends with **#**. | 495 | Destruct metatable with metamethod key surrounded by **<>**. |
495 | 496 | ||
496 | ```moonscript | 497 | ```moonscript |
497 | {item, :new, :close#, index#: getter} = tb | 498 | {item, :new, :<close>, <index>: getter} = tb |
498 | print item, new, close, getter | 499 | print item, new, close, getter |
499 | ``` | 500 | ``` |
500 | <YueDisplay> | 501 | <YueDisplay> |
501 | <pre> | 502 | <pre> |
502 | {item, :new, :close#, index#: getter} = tb | 503 | {item, :new, :<close>, <index>: getter} = tb |
503 | print item, new, close, getter | 504 | print item, new, close, getter |
504 | </pre> | 505 | </pre> |
505 | </YueDisplay> | 506 | </YueDisplay> |
diff --git a/spec/inputs/assign.yue b/spec/inputs/assign.yue index d04bcb8..da44dff 100644 --- a/spec/inputs/assign.yue +++ b/spec/inputs/assign.yue | |||
@@ -34,7 +34,7 @@ x = (do | |||
34 | 34 | ||
35 | (using nil) <- _ | 35 | (using nil) <- _ |
36 | 36 | ||
37 | a.# = do | 37 | a.<> = do |
38 | print 123 | 38 | print 123 |
39 | {} | 39 | {} |
40 | 40 | ||
@@ -63,7 +63,7 @@ do | |||
63 | 123, tb | 63 | 123, tb |
64 | 64 | ||
65 | do | 65 | do |
66 | a, b[], c, d.add# = if x | 66 | a, b[], c, d.<add> = if x |
67 | switch y | 67 | switch y |
68 | when 1 | 68 | when 1 |
69 | f! | 69 | f! |
diff --git a/spec/inputs/class.yue b/spec/inputs/class.yue index 9091d23..49537c2 100644 --- a/spec/inputs/class.yue +++ b/spec/inputs/class.yue | |||
@@ -237,9 +237,9 @@ class Example | |||
237 | 237 | ||
238 | class Foo | 238 | class Foo |
239 | new: (x) => @x = x | 239 | new: (x) => @x = x |
240 | mul#: (y) => @x * y | 240 | <mul>: (y) => @x * y |
241 | ["dsd-dsd"]#: 123 | 241 | <"dsd-dsd">: 123 |
242 | :add | 242 | :add |
243 | :add# | 243 | :<add> |
244 | 244 | ||
245 | nil | 245 | nil |
diff --git a/spec/inputs/destructure.yue b/spec/inputs/destructure.yue index 53f9ea3..ce593ec 100644 --- a/spec/inputs/destructure.yue +++ b/spec/inputs/destructure.yue | |||
@@ -160,17 +160,17 @@ do | |||
160 | 160 | ||
161 | {key1: {key2: value1 = 123}, :key3 = "abc"} = tb | 161 | {key1: {key2: value1 = 123}, :key3 = "abc"} = tb |
162 | 162 | ||
163 | {#: mt = {__index: {abc: 123}}, #: {:call# = (-> {}), :add#}} = tb | 163 | {<>: mt = {__index: {abc: 123}}, <>: {:<call> = (-> {}), :<add>}} = tb |
164 | 164 | ||
165 | {x: {#: mtx = {}}, :y, z: zItem, :index# = -> nil} = tb | 165 | {x: {<>: mtx = {}}, :y, z: zItem, :<index> = -> nil} = tb |
166 | 166 | ||
167 | {#: {func: a.b(-> 123).c = item?.defVal}} = tb | 167 | {<>: {func: a.b(-> 123).c = item?.defVal}} = tb |
168 | 168 | ||
169 | do | 169 | do |
170 | {#: mt = {}, sub#: subFunc} = tb.x | 170 | {<>: mt = {}, <sub>: subFunc} = tb.x |
171 | 171 | ||
172 | do | 172 | do |
173 | {x: {#: mt = {}, sub#: subFunc}} = tb | 173 | {x: {<>: mt = {}, <sub>: subFunc}} = tb |
174 | 174 | ||
175 | do | 175 | do |
176 | {a = 1, b = 2, c: {d.e = 3}} = tb | 176 | {a = 1, b = 2, c: {d.e = 3}} = tb |
@@ -189,5 +189,24 @@ do | |||
189 | const {:x = 0.0, :y = 0.0} = point | 189 | const {:x = 0.0, :y = 0.0} = point |
190 | 190 | ||
191 | do | 191 | do |
192 | x1, x2, x3, a[], d, {b}, e, c.# = 1, 2, 3, f! | 192 | x1, x2, x3, a[], d, {b}, e, c.<> = 1, 2, 3, f! |
193 | y1, :y2, :y3, y4 = f1!, f2! | 193 | y1, :y2, :y3, y4 = f1!, f2! |
194 | |||
195 | do | ||
196 | { | ||
197 | [["abc"]]: v1 = 111, | ||
198 | [1 + 1]: {v2 = 222, v3 = 333}, | ||
199 | @x: v4 = 444 | ||
200 | }, \ | ||
201 | 'x-y-z': v5, [func!]: {[func2!]: v6, v7} = tb, tb2 | ||
202 | |||
203 | do | ||
204 | <[name]>: value_meta, [name]: value = tb | ||
205 | |||
206 | do | ||
207 | {:<tostring> = (-> "name"), :<add>} = tb | ||
208 | |||
209 | switch tb | ||
210 | when {:<name> = "item", <"123">: meta_field} | ||
211 | print name, meta_field | ||
212 | |||
diff --git a/spec/inputs/existential.yue b/spec/inputs/existential.yue index 101e1d8..e73b421 100644 --- a/spec/inputs/existential.yue +++ b/spec/inputs/existential.yue | |||
@@ -49,9 +49,9 @@ with? io.open "test.txt", "w" | |||
49 | \write "hello" | 49 | \write "hello" |
50 | \close! | 50 | \close! |
51 | 51 | ||
52 | tb?.a#? 123 | 52 | tb?.<a>? 123 |
53 | 53 | ||
54 | with? tb.#?.index# | 54 | with? tb.<>?.<index> |
55 | .a = 1 | 55 | .a = 1 |
56 | 56 | ||
57 | nil | 57 | nil |
diff --git a/spec/inputs/import.yue b/spec/inputs/import.yue index 570b909..af5545d 100644 --- a/spec/inputs/import.yue +++ b/spec/inputs/import.yue | |||
@@ -64,8 +64,8 @@ do | |||
64 | import "org.package.module" as function:func, if:ifVar | 64 | import "org.package.module" as function:func, if:ifVar |
65 | 65 | ||
66 | do | 66 | do |
67 | import "m" as {a#: b} | 67 | import "m" as {<a>: b} |
68 | import "m" as {e: f, a#: c} | 68 | import "m" as {e: f, <a>: c} |
69 | import "m" as {c: d} | 69 | import "m" as {c: d} |
70 | import "m" as {g, {h#: i}} | 70 | import "m" as {g, {<h>: i}} |
71 | 71 | ||
diff --git a/spec/inputs/macro.yue b/spec/inputs/macro.yue index 3c89c1c..ac51d85 100644 --- a/spec/inputs/macro.yue +++ b/spec/inputs/macro.yue | |||
@@ -262,7 +262,7 @@ $chainC( | |||
262 | Destroy! | 262 | Destroy! |
263 | ) | 263 | ) |
264 | 264 | ||
265 | macro tb = -> "{'abc', a:123, call#:=> 998}" | 265 | macro tb = -> "{'abc', a:123, <call>:=> 998}" |
266 | print $tb[1], $tb.a, ($tb)!, $tb! | 266 | print $tb[1], $tb.a, ($tb)!, $tb! |
267 | 267 | ||
268 | print "current line: #{ $LINE }" | 268 | print "current line: #{ $LINE }" |
diff --git a/spec/inputs/metatable.yue b/spec/inputs/metatable.yue index 86991c2..61cc266 100644 --- a/spec/inputs/metatable.yue +++ b/spec/inputs/metatable.yue | |||
@@ -1,62 +1,86 @@ | |||
1 | a = close: true, close#: => print "out of scope" | 1 | a = close: true, <close>: => print "out of scope" |
2 | b = add#: (left, right)-> right - left | 2 | b = <add>: (left, right)-> right - left |
3 | c = key1: true, :add#, key2: true | 3 | c = key1: true, :<add>, key2: true |
4 | w = [name]#:123, ["new"]#:(val)=> {val} | 4 | w = <[name]>:123, <"new">:(val)=> {val} |
5 | w.#["new"] w.#[name] | 5 | w.<>["new"] w.<>[name] |
6 | 6 | ||
7 | do close _ = close#: -> print "out of scope" | 7 | do close _ = <close>: -> print "out of scope" |
8 | 8 | ||
9 | d, e = a.close, a.close# | 9 | d, e = a.close, a.<close> |
10 | 10 | ||
11 | f = a\close# 1 | 11 | f = a\<close> 1 |
12 | a.add# = (x, y)-> x + y | 12 | a.<add> = (x, y)-> x + y |
13 | 13 | ||
14 | do | 14 | do |
15 | {:new, :close#, close#: closeA} = a | 15 | {:new, :<close>, <close>: closeA} = a |
16 | print new, close, closeA | 16 | print new, close, closeA |
17 | 17 | ||
18 | do | 18 | do |
19 | local * | 19 | local * |
20 | x, \ | 20 | x, \ |
21 | {:new, :var, :close#, close#: closeA}, \ | 21 | {:new, :var, :<close>, <close>: closeA}, \ |
22 | :num, :add#, :sub# \ | 22 | :num, :<add>, :<sub> \ |
23 | = 123, a.b.c, func! | 23 | = 123, a.b.c, func! |
24 | 24 | ||
25 | x.abc, a.b.# = 123, {} | 25 | x.abc, a.b.<> = 123, {} |
26 | func!.# = mt --, extra | 26 | func!.<> = mt --, extra |
27 | a, b.c.#, d, e = 1, mt, "abc", nil | 27 | a, b.c.<>, d, e = 1, mt, "abc", nil |
28 | 28 | ||
29 | is_same = a.#.__index == a.index# | 29 | is_same = a.<>.__index == a.<index> |
30 | 30 | ||
31 | -- | 31 | -- |
32 | a.# = __index: tb | 32 | a.<> = __index: tb |
33 | a.#.__index = tb | 33 | a.<>.__index = tb |
34 | a.index# = tb | 34 | a.<index> = tb |
35 | -- | 35 | -- |
36 | 36 | ||
37 | mt = a.# | 37 | mt = a.<> |
38 | 38 | ||
39 | tb\func #list | 39 | tb\func #list |
40 | tb\func#list | 40 | tb\<func>list |
41 | tb\func# list | 41 | tb\<func> list |
42 | 42 | ||
43 | import "module" as :index#, newindex#:setFunc | 43 | import "module" as :<index>, <newindex>:setFunc |
44 | 44 | ||
45 | with tb | 45 | with tb |
46 | print .add#, .x\index# "key" | 46 | print .<add>, .x\<index> "key" |
47 | a = .index#.add#\new# 123 | 47 | a = .<index>.<add>\<new> 123 |
48 | b = t#.close#.test | 48 | b = t#.<close>.test |
49 | c = t #.close# .test | 49 | c = t #.<close> .test |
50 | 50 | ||
51 | #:mt = a | 51 | <>:mt = a |
52 | a = #:mt | 52 | a = <>:mt |
53 | a = #:__index:mt | 53 | a = <>:__index:mt |
54 | 54 | ||
55 | local index | 55 | local index |
56 | #:__index:index = a | 56 | <>:__index:index = a |
57 | :index# = a | 57 | :<index> = a |
58 | 58 | ||
59 | do #:{new:ctor, :update} = a | 59 | do <>:{new:ctor, :update} = a |
60 | do {new:ctor, :update} = a.# | 60 | do {new:ctor, :update} = a.<> |
61 | |||
62 | tb = {} | ||
63 | do | ||
64 | f = tb\<"value#{x < y}">(123, ...) | ||
65 | f tb\<'value'> 123, ... | ||
66 | tb\<[[ | ||
67 | value | ||
68 | 1 | ||
69 | ]]>(123, ...) | ||
70 | return tb\<["value" .. tostring x > y]>(123, ...) | ||
71 | |||
72 | do | ||
73 | f = tb\<value>(123, ...) | ||
74 | f tb\<value>(123, ...) | ||
75 | tb\<value>(123, ...) | ||
76 | return tb\<value> 123, ... | ||
77 | |||
78 | do | ||
79 | f = tb.<value> 123, ... | ||
80 | f = tb.<"value#{x < y}">(123, ...) | ||
81 | f tb.<'value'> 123, ... | ||
82 | tb.<[[ value | ||
83 | 1]]>(123, ...) | ||
84 | return tb.<["value" .. tostring x > y]>(123, ...) | ||
61 | 85 | ||
62 | nil | 86 | nil |
diff --git a/spec/inputs/switch.yue b/spec/inputs/switch.yue index 442d15f..cb1eb31 100644 --- a/spec/inputs/switch.yue +++ b/spec/inputs/switch.yue | |||
@@ -101,7 +101,7 @@ do | |||
101 | print "Object A" | 101 | print "Object A" |
102 | when ClassB | 102 | when ClassB |
103 | print "Object B" | 103 | print "Object B" |
104 | when #: mt | 104 | when <>: mt |
105 | print "A table with metatable" | 105 | print "A table with metatable" |
106 | else | 106 | else |
107 | print "item not accepted!" | 107 | print "item not accepted!" |
@@ -156,7 +156,7 @@ do | |||
156 | 156 | ||
157 | do | 157 | do |
158 | switch y | 158 | switch y |
159 | when {x: #: mt} | 159 | when {x: <>: mt} |
160 | print mt | 160 | print mt |
161 | 161 | ||
162 | nil | 162 | nil |
diff --git a/spec/outputs/destructure.lua b/spec/outputs/destructure.lua index dfac42c..0da920e 100644 --- a/spec/outputs/destructure.lua +++ b/spec/outputs/destructure.lua | |||
@@ -428,3 +428,64 @@ do | |||
428 | y2, y3 = _obj_0.y2, _obj_0.y3 | 428 | y2, y3 = _obj_0.y2, _obj_0.y3 |
429 | end | 429 | end |
430 | end | 430 | end |
431 | do | ||
432 | local v1, v2, v3, v4 | ||
433 | do | ||
434 | local _obj_0 = tb | ||
435 | local _tmp_0, _tmp_1 = 1 + 1, self.x | ||
436 | v1, v2, v3, v4 = _obj_0[ [["abc"]]], _obj_0[_tmp_0][1], _obj_0[_tmp_0][2], _obj_0[_tmp_1] | ||
437 | if v1 == nil then | ||
438 | v1 = 111 | ||
439 | end | ||
440 | if v2 == nil then | ||
441 | v2 = 222 | ||
442 | end | ||
443 | if v3 == nil then | ||
444 | v3 = 333 | ||
445 | end | ||
446 | if v4 == nil then | ||
447 | v4 = 444 | ||
448 | end | ||
449 | end | ||
450 | local v5, v6, v7 | ||
451 | do | ||
452 | local _obj_0 = tb2 | ||
453 | local _tmp_2, _tmp_3 = func(), func2() | ||
454 | v5, v6, v7 = _obj_0['x-y-z'], _obj_0[_tmp_2][_tmp_3], _obj_0[_tmp_2][1] | ||
455 | end | ||
456 | end | ||
457 | do | ||
458 | local _obj_0 = tb | ||
459 | local value = _obj_0[name] | ||
460 | local value_meta = getmetatable(_obj_0)[name] | ||
461 | end | ||
462 | do | ||
463 | local tostring, add | ||
464 | do | ||
465 | local _obj_0 = getmetatable(tb) | ||
466 | tostring, add = _obj_0.__tostring, _obj_0.__add | ||
467 | if tostring == nil then | ||
468 | tostring = (function() | ||
469 | return "name" | ||
470 | end) | ||
471 | end | ||
472 | end | ||
473 | local _exp_0 = tb | ||
474 | do | ||
475 | local _tab_0 = "table" == type(_exp_0) | ||
476 | if _tab_0 then | ||
477 | local name, meta_field | ||
478 | do | ||
479 | local _obj_0 = getmetatable(_exp_0) | ||
480 | name = _obj_0.__name | ||
481 | meta_field = _obj_0["123"] | ||
482 | if name == nil then | ||
483 | name = "item" | ||
484 | end | ||
485 | end | ||
486 | if meta_field ~= nil then | ||
487 | return print(name, meta_field) | ||
488 | end | ||
489 | end | ||
490 | end | ||
491 | end | ||
diff --git a/spec/outputs/metatable.lua b/spec/outputs/metatable.lua index 6f5ceed..937136f 100644 --- a/spec/outputs/metatable.lua +++ b/spec/outputs/metatable.lua | |||
@@ -111,4 +111,37 @@ do | |||
111 | ctor, update = _obj_0.new, _obj_0.update | 111 | ctor, update = _obj_0.new, _obj_0.update |
112 | end | 112 | end |
113 | end | 113 | end |
114 | local tb = { } | ||
115 | do | ||
116 | do | ||
117 | local _obj_0 = getmetatable(tb) | ||
118 | f = _obj_0["value" .. tostring(x < y)](_obj_0, 123, ...) | ||
119 | end | ||
120 | f((function(...) | ||
121 | local _obj_0 = getmetatable(tb) | ||
122 | return _obj_0['value'](_obj_0, 123, ...) | ||
123 | end)(...)) | ||
124 | do | ||
125 | local _obj_0 = getmetatable(tb) | ||
126 | _obj_0[ [[ value | ||
127 | 1 | ||
128 | ]]](_obj_0, 123, ...) | ||
129 | end | ||
130 | local _obj_0 = getmetatable(tb) | ||
131 | return _obj_0["value" .. tostring(x > y)](_obj_0, 123, ...) | ||
132 | end | ||
133 | do | ||
134 | f = getmetatable(tb):__value(123, ...) | ||
135 | f(getmetatable(tb):__value(123, ...)) | ||
136 | getmetatable(tb):__value(123, ...) | ||
137 | return getmetatable(tb):__value(123, ...) | ||
138 | end | ||
139 | do | ||
140 | f = getmetatable(tb).__value(123, ...) | ||
141 | f = getmetatable(tb)["value" .. tostring(x < y)](123, ...) | ||
142 | f(getmetatable(tb)['value'](123, ...)) | ||
143 | getmetatable(tb)[ [[ value | ||
144 | 1]]](123, ...) | ||
145 | return getmetatable(tb)["value" .. tostring(x > y)](123, ...) | ||
146 | end | ||
114 | return nil | 147 | return nil |
diff --git a/src/yuescript/yue_ast.h b/src/yuescript/yue_ast.h index 386fa28..d8f6c95 100755 --- a/src/yuescript/yue_ast.h +++ b/src/yuescript/yue_ast.h | |||
@@ -459,18 +459,16 @@ AST_NODE(variable_pair) | |||
459 | AST_MEMBER(variable_pair, &name) | 459 | AST_MEMBER(variable_pair, &name) |
460 | AST_END(variable_pair, "variable_pair"sv) | 460 | AST_END(variable_pair, "variable_pair"sv) |
461 | 461 | ||
462 | class DoubleString_t; | 462 | class String_t; |
463 | class SingleString_t; | ||
464 | class LuaString_t; | ||
465 | 463 | ||
466 | AST_NODE(normal_pair) | 464 | AST_NODE(normal_pair) |
467 | ast_sel<true, KeyName_t, Exp_t, DoubleString_t, SingleString_t, LuaString_t> key; | 465 | ast_sel<true, KeyName_t, Exp_t, String_t> key; |
468 | ast_sel<true, Exp_t, TableBlock_t> value; | 466 | ast_sel<true, Exp_t, TableBlock_t> value; |
469 | AST_MEMBER(normal_pair, &key, &value) | 467 | AST_MEMBER(normal_pair, &key, &value) |
470 | AST_END(normal_pair, "normal_pair"sv) | 468 | AST_END(normal_pair, "normal_pair"sv) |
471 | 469 | ||
472 | AST_NODE(default_pair) | 470 | AST_NODE(default_pair) |
473 | ast_sel<true, Variable_t, KeyName_t, Exp_t> key; | 471 | ast_sel<true, Variable_t, KeyName_t, Exp_t, String_t> key; |
474 | ast_ptr<true, Seperator_t> sep; | 472 | ast_ptr<true, Seperator_t> sep; |
475 | ast_ptr<false, Exp_t> value; | 473 | ast_ptr<false, Exp_t> value; |
476 | ast_ptr<true, Exp_t> defVal; | 474 | ast_ptr<true, Exp_t> defVal; |
@@ -483,13 +481,13 @@ AST_NODE(meta_variable_pair) | |||
483 | AST_END(meta_variable_pair, "meta_variable_pair"sv) | 481 | AST_END(meta_variable_pair, "meta_variable_pair"sv) |
484 | 482 | ||
485 | AST_NODE(meta_normal_pair) | 483 | AST_NODE(meta_normal_pair) |
486 | ast_sel<false, Name_t, Exp_t> key; | 484 | ast_sel<false, Name_t, Exp_t, String_t> key; |
487 | ast_sel<true, Exp_t, TableBlock_t> value; | 485 | ast_sel<true, Exp_t, TableBlock_t> value; |
488 | AST_MEMBER(meta_normal_pair, &key, &value) | 486 | AST_MEMBER(meta_normal_pair, &key, &value) |
489 | AST_END(meta_normal_pair, "meta_normal_pair"sv) | 487 | AST_END(meta_normal_pair, "meta_normal_pair"sv) |
490 | 488 | ||
491 | AST_NODE(meta_default_pair) | 489 | AST_NODE(meta_default_pair) |
492 | ast_sel<false, Variable_t, Name_t> key; | 490 | ast_sel<false, Variable_t, Name_t, Exp_t, String_t> key; |
493 | ast_ptr<true, Seperator_t> sep; | 491 | ast_ptr<true, Seperator_t> sep; |
494 | ast_ptr<false, Exp_t> value; | 492 | ast_ptr<false, Exp_t> value; |
495 | ast_ptr<true, Exp_t> defVal; | 493 | ast_ptr<true, Exp_t> defVal; |
@@ -502,7 +500,6 @@ AST_NODE(simple_table) | |||
502 | AST_MEMBER(simple_table, &sep, &pairs) | 500 | AST_MEMBER(simple_table, &sep, &pairs) |
503 | AST_END(simple_table, "simple_table"sv) | 501 | AST_END(simple_table, "simple_table"sv) |
504 | 502 | ||
505 | class String_t; | ||
506 | class const_value_t; | 503 | class const_value_t; |
507 | class ClassDecl_t; | 504 | class ClassDecl_t; |
508 | class unary_value_t; | 505 | class unary_value_t; |
@@ -560,8 +557,8 @@ AST_LEAF(Metatable) | |||
560 | AST_END(Metatable, "metatable"sv) | 557 | AST_END(Metatable, "metatable"sv) |
561 | 558 | ||
562 | AST_NODE(Metamethod) | 559 | AST_NODE(Metamethod) |
563 | ast_ptr<true, Name_t> name; | 560 | ast_sel<true, Name_t, Exp_t, String_t> item; |
564 | AST_MEMBER(Metamethod, &name) | 561 | AST_MEMBER(Metamethod, &item) |
565 | AST_END(Metamethod, "metamethod"sv) | 562 | AST_END(Metamethod, "metamethod"sv) |
566 | 563 | ||
567 | AST_NODE(DotChainItem) | 564 | AST_NODE(DotChainItem) |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 17979ab..73b4ae9 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
@@ -59,7 +59,7 @@ namespace yue { | |||
59 | 59 | ||
60 | typedef std::list<std::string> str_list; | 60 | typedef std::list<std::string> str_list; |
61 | 61 | ||
62 | const std::string_view version = "0.14.5"sv; | 62 | const std::string_view version = "0.15.1"sv; |
63 | const std::string_view extension = "yue"sv; | 63 | const std::string_view extension = "yue"sv; |
64 | 64 | ||
65 | class YueCompilerImpl { | 65 | class YueCompilerImpl { |
@@ -296,7 +296,7 @@ private: | |||
296 | struct DestructItem { | 296 | struct DestructItem { |
297 | ast_ptr<true, Exp_t> target; | 297 | ast_ptr<true, Exp_t> target; |
298 | std::string targetVar; | 298 | std::string targetVar; |
299 | std::string structure; | 299 | ast_ptr<false, ChainValue_t> structure; |
300 | ast_ptr<true, Exp_t> defVal; | 300 | ast_ptr<true, Exp_t> defVal; |
301 | }; | 301 | }; |
302 | 302 | ||
@@ -304,6 +304,7 @@ private: | |||
304 | ast_ptr<true, ast_node> value; | 304 | ast_ptr<true, ast_node> value; |
305 | std::string valueVar; | 305 | std::string valueVar; |
306 | std::list<DestructItem> items; | 306 | std::list<DestructItem> items; |
307 | ast_ptr<false, ExpListAssign_t> inlineAssignment; | ||
307 | }; | 308 | }; |
308 | 309 | ||
309 | enum class ExpUsage { | 310 | enum class ExpUsage { |
@@ -614,6 +615,24 @@ private: | |||
614 | return nullptr; | 615 | return nullptr; |
615 | } | 616 | } |
616 | 617 | ||
618 | ast_ptr<false, Exp_t> newExp(SimpleValue_t* simpleValue, ast_node* x) { | ||
619 | auto value = x->new_ptr<Value_t>(); | ||
620 | value->item.set(simpleValue); | ||
621 | return newExp(value, x); | ||
622 | } | ||
623 | |||
624 | ast_ptr<false, Exp_t> newExp(String_t* string, ast_node* x) { | ||
625 | auto value = x->new_ptr<Value_t>(); | ||
626 | value->item.set(string); | ||
627 | return newExp(value, x); | ||
628 | } | ||
629 | |||
630 | ast_ptr<false, Exp_t> newExp(ChainValue_t* chainValue, ast_node* x) { | ||
631 | auto value = x->new_ptr<Value_t>(); | ||
632 | value->item.set(chainValue); | ||
633 | return newExp(value, x); | ||
634 | } | ||
635 | |||
617 | ast_ptr<false, Exp_t> newExp(Value_t* value, ast_node* x) { | 636 | ast_ptr<false, Exp_t> newExp(Value_t* value, ast_node* x) { |
618 | auto unary = x->new_ptr<unary_exp_t>(); | 637 | auto unary = x->new_ptr<unary_exp_t>(); |
619 | unary->expos.push_back(value); | 638 | unary->expos.push_back(value); |
@@ -772,7 +791,8 @@ private: | |||
772 | HasEOP, | 791 | HasEOP, |
773 | HasKeyword, | 792 | HasKeyword, |
774 | Macro, | 793 | Macro, |
775 | Metatable | 794 | Metatable, |
795 | MetaFieldInvocation | ||
776 | }; | 796 | }; |
777 | 797 | ||
778 | ChainType specialChainValue(ChainValue_t* chainValue) const { | 798 | ChainType specialChainValue(ChainValue_t* chainValue) const { |
@@ -795,6 +815,8 @@ private: | |||
795 | if (auto colonChain = ast_cast<ColonChainItem_t>(item)) { | 815 | if (auto colonChain = ast_cast<ColonChainItem_t>(item)) { |
796 | if (ast_is<LuaKeyword_t>(colonChain->name)) { | 816 | if (ast_is<LuaKeyword_t>(colonChain->name)) { |
797 | type = ChainType::HasKeyword; | 817 | type = ChainType::HasKeyword; |
818 | } else if (auto meta = colonChain->name.as<Metamethod_t>(); meta && !meta->item.is<Name_t>()) { | ||
819 | return ChainType::MetaFieldInvocation; | ||
798 | } | 820 | } |
799 | } else if (ast_is<existential_op_t>(item)) { | 821 | } else if (ast_is<existential_op_t>(item)) { |
800 | return ChainType::HasEOP; | 822 | return ChainType::HasEOP; |
@@ -1013,9 +1035,7 @@ private: | |||
1013 | case id<With_t>(): { | 1035 | case id<With_t>(): { |
1014 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 1036 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
1015 | simpleValue->value.set(val); | 1037 | simpleValue->value.set(val); |
1016 | auto value = x->new_ptr<Value_t>(); | 1038 | auto exp = newExp(simpleValue, x); |
1017 | value->item.set(simpleValue); | ||
1018 | auto exp = newExp(value, x); | ||
1019 | expList->exprs.push_back(exp); | 1039 | expList->exprs.push_back(exp); |
1020 | break; | 1040 | break; |
1021 | } | 1041 | } |
@@ -1025,9 +1045,7 @@ private: | |||
1025 | tabLit->values.dup(tableBlock->values); | 1045 | tabLit->values.dup(tableBlock->values); |
1026 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 1046 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
1027 | simpleValue->value.set(tabLit); | 1047 | simpleValue->value.set(tabLit); |
1028 | auto value = x->new_ptr<Value_t>(); | 1048 | auto exp = newExp(simpleValue, x); |
1029 | value->item.set(simpleValue); | ||
1030 | auto exp = newExp(value, x); | ||
1031 | expList->exprs.push_back(exp); | 1049 | expList->exprs.push_back(exp); |
1032 | break; | 1050 | break; |
1033 | } | 1051 | } |
@@ -1072,9 +1090,7 @@ private: | |||
1072 | statement->appendix.set(nullptr); | 1090 | statement->appendix.set(nullptr); |
1073 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 1091 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
1074 | simpleValue->value.set(ifNode); | 1092 | simpleValue->value.set(ifNode); |
1075 | auto value = x->new_ptr<Value_t>(); | 1093 | auto exp = newExp(simpleValue, x); |
1076 | value->item.set(simpleValue); | ||
1077 | auto exp = newExp(value, x); | ||
1078 | auto expList = x->new_ptr<ExpList_t>(); | 1094 | auto expList = x->new_ptr<ExpList_t>(); |
1079 | expList->exprs.push_back(exp); | 1095 | expList->exprs.push_back(exp); |
1080 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 1096 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -1091,9 +1107,7 @@ private: | |||
1091 | comp->value.set(stmt); | 1107 | comp->value.set(stmt); |
1092 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 1108 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
1093 | simpleValue->value.set(comp); | 1109 | simpleValue->value.set(comp); |
1094 | auto value = x->new_ptr<Value_t>(); | 1110 | auto exp = newExp(simpleValue, x); |
1095 | value->item.set(simpleValue); | ||
1096 | auto exp = newExp(value, x); | ||
1097 | auto expList = x->new_ptr<ExpList_t>(); | 1111 | auto expList = x->new_ptr<ExpList_t>(); |
1098 | expList->exprs.push_back(exp); | 1112 | expList->exprs.push_back(exp); |
1099 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 1113 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -1483,9 +1497,7 @@ private: | |||
1483 | args.push_back(_withVars.top()); | 1497 | args.push_back(_withVars.top()); |
1484 | } | 1498 | } |
1485 | } else { | 1499 | } else { |
1486 | auto value = tmpChain->new_ptr<Value_t>(); | 1500 | transformExp(newExp(tmpChain, tmpChain), args, ExpUsage::Closure); |
1487 | value->item.set(tmpChain); | ||
1488 | transformExp(newExp(value, tmpChain), args, ExpUsage::Closure); | ||
1489 | } | 1501 | } |
1490 | if (vit == values.end()) { | 1502 | if (vit == values.end()) { |
1491 | throw std::logic_error(_info.errorMessage("right value missing"sv, values.front())); | 1503 | throw std::logic_error(_info.errorMessage("right value missing"sv, values.front())); |
@@ -1514,9 +1526,7 @@ private: | |||
1514 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | 1526 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); |
1515 | newAssignment->expList.set(toAst<ExpList_t>(objVar, x)); | 1527 | newAssignment->expList.set(toAst<ExpList_t>(objVar, x)); |
1516 | auto assign = x->new_ptr<Assign_t>(); | 1528 | auto assign = x->new_ptr<Assign_t>(); |
1517 | auto value = tmpChain->new_ptr<Value_t>(); | 1529 | assign->values.push_back(newExp(tmpChain, tmpChain)); |
1518 | value->item.set(tmpChain); | ||
1519 | assign->values.push_back(newExp(value, tmpChain)); | ||
1520 | newAssignment->action.set(assign); | 1530 | newAssignment->action.set(assign); |
1521 | transformAssignment(newAssignment, temp); | 1531 | transformAssignment(newAssignment, temp); |
1522 | varName = objVar; | 1532 | varName = objVar; |
@@ -1685,7 +1695,8 @@ private: | |||
1685 | auto expList = assignment->expList.get(); | 1695 | auto expList = assignment->expList.get(); |
1686 | switch (type) { | 1696 | switch (type) { |
1687 | case ChainType::HasEOP: | 1697 | case ChainType::HasEOP: |
1688 | case ChainType::EndWithColon: { | 1698 | case ChainType::EndWithColon: |
1699 | case ChainType::MetaFieldInvocation: { | ||
1689 | std::string preDefine = getPreDefineLine(assignment); | 1700 | std::string preDefine = getPreDefineLine(assignment); |
1690 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); | 1701 | transformChainValue(chainValue, out, ExpUsage::Assignment, expList); |
1691 | out.back().insert(0, preDefine); | 1702 | out.back().insert(0, preDefine); |
@@ -1714,7 +1725,7 @@ private: | |||
1714 | for (auto& destruct : info.destructures) { | 1725 | for (auto& destruct : info.destructures) { |
1715 | std::list<std::pair<ast_ptr<true, Exp_t>, ast_ptr<true, Exp_t>>> leftPairs; | 1726 | std::list<std::pair<ast_ptr<true, Exp_t>, ast_ptr<true, Exp_t>>> leftPairs; |
1716 | bool extraScope = false; | 1727 | bool extraScope = false; |
1717 | if (destruct.items.size() == 1) { | 1728 | if (!destruct.inlineAssignment && destruct.items.size() == 1) { |
1718 | auto& pair = destruct.items.front(); | 1729 | auto& pair = destruct.items.front(); |
1719 | if (pair.targetVar.empty() && pair.defVal) { | 1730 | if (pair.targetVar.empty() && pair.defVal) { |
1720 | extraScope = true; | 1731 | extraScope = true; |
@@ -1725,21 +1736,13 @@ private: | |||
1725 | pair.targetVar = objVar; | 1736 | pair.targetVar = objVar; |
1726 | } else if (auto val = singleValueFrom(destruct.value); val->item.is<ChainValue_t>()) { | 1737 | } else if (auto val = singleValueFrom(destruct.value); val->item.is<ChainValue_t>()) { |
1727 | auto chainValue = static_cast<ChainValue_t*>(val->item.get()); | 1738 | auto chainValue = static_cast<ChainValue_t*>(val->item.get()); |
1728 | int added = 0; | 1739 | auto newChain = val->item->new_ptr<ChainValue_t>(); |
1729 | if (!pair.structure.empty()) { | 1740 | newChain->items.dup(chainValue->items); |
1730 | auto appendChain = toAst<ChainValue_t>("x"s + pair.structure, x); | 1741 | if (pair.structure) { |
1731 | appendChain->items.pop_front(); | 1742 | newChain->items.dup(pair.structure->items); |
1732 | for (auto item : appendChain->items.objects()) { | ||
1733 | chainValue->items.push_back(item); | ||
1734 | added++; | ||
1735 | } | ||
1736 | } | 1743 | } |
1737 | auto newAssignment = assignmentFrom(pair.target, destruct.value, x); | 1744 | auto newAssignment = assignmentFrom(pair.target, newExp(newChain, val->item), x); |
1738 | transformAssignment(newAssignment, temp); | 1745 | transformAssignment(newAssignment, temp); |
1739 | while (added > 0) { | ||
1740 | chainValue->items.pop_back(); | ||
1741 | added--; | ||
1742 | } | ||
1743 | if (pair.defVal) { | 1746 | if (pair.defVal) { |
1744 | bool isNil = false; | 1747 | bool isNil = false; |
1745 | if (auto v1 = singleValueFrom(pair.defVal)) { | 1748 | if (auto v1 = singleValueFrom(pair.defVal)) { |
@@ -1782,7 +1785,10 @@ private: | |||
1782 | auto newAssignment = assignmentFrom(toAst<Exp_t>(objVar, x), destruct.value, x); | 1785 | auto newAssignment = assignmentFrom(toAst<Exp_t>(objVar, x), destruct.value, x); |
1783 | transformAssignment(newAssignment, temp); | 1786 | transformAssignment(newAssignment, temp); |
1784 | } | 1787 | } |
1785 | auto valueExp = toAst<Exp_t>(objVar + pair.structure, x); | 1788 | auto chain = pair.target->new_ptr<ChainValue_t>(); |
1789 | chain->items.push_back(toAst<Callable_t>(objVar, chain)); | ||
1790 | chain->items.dup(pair.structure->items); | ||
1791 | auto valueExp = newExp(chain, pair.target); | ||
1786 | auto newAssignment = assignmentFrom(pair.target, valueExp, x); | 1792 | auto newAssignment = assignmentFrom(pair.target, valueExp, x); |
1787 | transformAssignment(newAssignment, temp); | 1793 | transformAssignment(newAssignment, temp); |
1788 | if (!isLocalValue) { | 1794 | if (!isLocalValue) { |
@@ -1791,7 +1797,8 @@ private: | |||
1791 | temp.push_back(clearBuf()); | 1797 | temp.push_back(clearBuf()); |
1792 | } | 1798 | } |
1793 | } else { | 1799 | } else { |
1794 | str_list values, defs; | 1800 | str_list defs; |
1801 | std::list<ast_ptr<false, ChainValue_t>> values; | ||
1795 | std::list<Exp_t*> names; | 1802 | std::list<Exp_t*> names; |
1796 | pushScope(); | 1803 | pushScope(); |
1797 | for (auto& item : destruct.items) { | 1804 | for (auto& item : destruct.items) { |
@@ -1813,8 +1820,9 @@ private: | |||
1813 | } | 1820 | } |
1814 | popScope(); | 1821 | popScope(); |
1815 | if (_parser.match<Name_t>(destruct.valueVar) && isLocal(destruct.valueVar)) { | 1822 | if (_parser.match<Name_t>(destruct.valueVar) && isLocal(destruct.valueVar)) { |
1823 | auto callable = toAst<Callable_t>(destruct.valueVar, destruct.value); | ||
1816 | for (auto& v : values) { | 1824 | for (auto& v : values) { |
1817 | v.insert(0, destruct.valueVar); | 1825 | v->items.push_front(callable); |
1818 | } | 1826 | } |
1819 | if (extraScope) { | 1827 | if (extraScope) { |
1820 | if (!defs.empty()) { | 1828 | if (!defs.empty()) { |
@@ -1842,17 +1850,22 @@ private: | |||
1842 | auto targetVar = toAst<Exp_t>(valVar, destruct.value); | 1850 | auto targetVar = toAst<Exp_t>(valVar, destruct.value); |
1843 | auto newAssignment = assignmentFrom(targetVar, destruct.value, destruct.value); | 1851 | auto newAssignment = assignmentFrom(targetVar, destruct.value, destruct.value); |
1844 | transformAssignment(newAssignment, temp); | 1852 | transformAssignment(newAssignment, temp); |
1853 | auto callable = singleValueFrom(targetVar)->item.to<ChainValue_t>()->items.front(); | ||
1845 | for (auto& v : values) { | 1854 | for (auto& v : values) { |
1846 | v.insert(0, valVar); | 1855 | v->items.push_front(callable); |
1847 | } | 1856 | } |
1848 | } | 1857 | } |
1858 | if (destruct.inlineAssignment) { | ||
1859 | transformAssignment(destruct.inlineAssignment, temp); | ||
1860 | } | ||
1849 | if (optionalDestruct) { | 1861 | if (optionalDestruct) { |
1850 | while (!names.empty()) { | 1862 | while (!names.empty()) { |
1851 | auto name = names.front(); | 1863 | auto name = names.front(); |
1852 | names.pop_front(); | 1864 | names.pop_front(); |
1853 | auto value = values.front(); | 1865 | auto value = values.front().get(); |
1866 | auto valueList = value->new_ptr<ExpList_t>(); | ||
1867 | valueList->exprs.push_back(newExp(value, value)); | ||
1854 | values.pop_front(); | 1868 | values.pop_front(); |
1855 | auto valueList = toAst<ExpList_t>(value, x); | ||
1856 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | 1869 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); |
1857 | auto assignList = x->new_ptr<ExpList_t>(); | 1870 | auto assignList = x->new_ptr<ExpList_t>(); |
1858 | assignList->exprs.push_back(name); | 1871 | assignList->exprs.push_back(name); |
@@ -1863,7 +1876,10 @@ private: | |||
1863 | transformAssignment(newAssignment, temp); | 1876 | transformAssignment(newAssignment, temp); |
1864 | } | 1877 | } |
1865 | } else { | 1878 | } else { |
1866 | auto valueList = toAst<ExpList_t>(join(values, ","sv), x); | 1879 | auto valueList = x->new_ptr<ExpList_t>(); |
1880 | for (const auto& v : values) { | ||
1881 | valueList->exprs.push_back(newExp(v, v)); | ||
1882 | } | ||
1867 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | 1883 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); |
1868 | auto assignList = x->new_ptr<ExpList_t>(); | 1884 | auto assignList = x->new_ptr<ExpList_t>(); |
1869 | for (auto name : names) { | 1885 | for (auto name : names) { |
@@ -1923,7 +1939,7 @@ private: | |||
1923 | 1939 | ||
1924 | std::list<DestructItem> destructFromExp(ast_node* node, bool optional) { | 1940 | std::list<DestructItem> destructFromExp(ast_node* node, bool optional) { |
1925 | const node_container* tableItems = nullptr; | 1941 | const node_container* tableItems = nullptr; |
1926 | auto sep = optional ? "?"s : Empty; | 1942 | ast_ptr<false, existential_op_t> sep = optional ? node->new_ptr<existential_op_t>() : nullptr; |
1927 | switch (node->getId()) { | 1943 | switch (node->getId()) { |
1928 | case id<Exp_t>(): { | 1944 | case id<Exp_t>(): { |
1929 | auto item = singleValueFrom(node)->item.get(); | 1945 | auto item = singleValueFrom(node)->item.get(); |
@@ -1965,17 +1981,20 @@ private: | |||
1965 | if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { | 1981 | if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { |
1966 | auto subPairs = destructFromExp(pair, optional); | 1982 | auto subPairs = destructFromExp(pair, optional); |
1967 | for (auto& p : subPairs) { | 1983 | for (auto& p : subPairs) { |
1968 | pairs.push_back({p.target, p.targetVar, | 1984 | if (sep) p.structure->items.push_front(sep); |
1969 | '[' + std::to_string(index) + ']' + sep + p.structure, | 1985 | p.structure->items.push_front( |
1970 | p.defVal}); | 1986 | toAst<Exp_t>(std::to_string(index), p.target)); |
1987 | pairs.push_back(p); | ||
1971 | } | 1988 | } |
1972 | } else { | 1989 | } else { |
1973 | auto exp = static_cast<Exp_t*>(pair); | 1990 | auto exp = static_cast<Exp_t*>(pair); |
1974 | auto varName = singleVariableFrom(exp, false); | 1991 | auto varName = singleVariableFrom(exp, false); |
1975 | if (varName == "_"sv) break; | 1992 | if (varName == "_"sv) break; |
1993 | auto chain = exp->new_ptr<ChainValue_t>(); | ||
1994 | chain->items.push_back(toAst<Exp_t>(std::to_string(index), exp)); | ||
1976 | pairs.push_back({exp, | 1995 | pairs.push_back({exp, |
1977 | varName, | 1996 | varName, |
1978 | '[' + std::to_string(index) + ']', | 1997 | chain, |
1979 | nullptr}); | 1998 | nullptr}); |
1980 | } | 1999 | } |
1981 | break; | 2000 | break; |
@@ -1983,38 +2002,55 @@ private: | |||
1983 | case id<variable_pair_t>(): { | 2002 | case id<variable_pair_t>(): { |
1984 | auto vp = static_cast<variable_pair_t*>(pair); | 2003 | auto vp = static_cast<variable_pair_t*>(pair); |
1985 | auto name = _parser.toString(vp->name); | 2004 | auto name = _parser.toString(vp->name); |
1986 | pairs.push_back({toAst<Exp_t>(name, vp).get(), name, '.' + name, nullptr}); | 2005 | auto chain = toAst<ChainValue_t>('.' + name, vp->name); |
2006 | pairs.push_back({toAst<Exp_t>(name, vp).get(), | ||
2007 | name, | ||
2008 | chain, | ||
2009 | nullptr}); | ||
1987 | break; | 2010 | break; |
1988 | } | 2011 | } |
1989 | case id<normal_pair_t>(): { | 2012 | case id<normal_pair_t>(): { |
1990 | auto np = static_cast<normal_pair_t*>(pair); | 2013 | auto np = static_cast<normal_pair_t*>(pair); |
1991 | std::string keyName; | 2014 | ast_ptr<true, ast_node> keyIndex; |
1992 | if (np->key) { | 2015 | if (np->key) { |
1993 | auto key = np->key->getByPath<Name_t>(); | 2016 | if (auto key = np->key->getByPath<Name_t>()) { |
1994 | if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, np)); | 2017 | auto keyNameStr = _parser.toString(key); |
1995 | keyName = _parser.toString(key); | 2018 | if (LuaKeywords.find(keyNameStr) != LuaKeywords.end()) { |
1996 | if (LuaKeywords.find(keyName) != LuaKeywords.end()) { | 2019 | keyIndex = toAst<Exp_t>('"' + keyNameStr + '"', key).get(); |
1997 | keyName = "[\""s + keyName + "\"]"s; | 2020 | } else { |
1998 | } else { | 2021 | keyIndex = toAst<DotChainItem_t>('.' + keyNameStr, key).get(); |
1999 | keyName = "."s + keyName; | 2022 | } |
2000 | } | 2023 | } else if (auto key = np->key->getByPath<SelfName_t>()) { |
2024 | auto callable = np->new_ptr<Callable_t>(); | ||
2025 | callable->item.set(key); | ||
2026 | auto chainValue = np->new_ptr<ChainValue_t>(); | ||
2027 | chainValue->items.push_back(callable); | ||
2028 | keyIndex = newExp(chainValue, np).get(); | ||
2029 | } else if (auto key = np->key.as<Exp_t>()) { | ||
2030 | keyIndex = key; | ||
2031 | } else if (auto key = np->key.as<String_t>()) { | ||
2032 | keyIndex = newExp(key, np->key).get(); | ||
2033 | } else throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, np)); | ||
2001 | } | 2034 | } |
2002 | if (auto exp = np->value.as<Exp_t>()) { | 2035 | if (auto exp = np->value.as<Exp_t>()) { |
2003 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); | 2036 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't do destructure value"sv, exp)); |
2004 | auto item = singleValueFrom(exp)->item.get(); | 2037 | auto item = singleValueFrom(exp)->item.get(); |
2005 | if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { | 2038 | if (ast_is<simple_table_t>(item) || item->getByPath<TableLit_t>()) { |
2006 | auto subPairs = destructFromExp(exp, optional); | 2039 | auto subPairs = destructFromExp(exp, optional); |
2007 | for (auto& p : subPairs) { | 2040 | for (auto& p : subPairs) { |
2008 | pairs.push_back({p.target, | 2041 | if (keyIndex) { |
2009 | p.targetVar, | 2042 | if (sep) p.structure->items.push_front(sep); |
2010 | keyName + sep + p.structure, | 2043 | p.structure->items.push_front(keyIndex); |
2011 | p.defVal}); | 2044 | } |
2045 | pairs.push_back(p); | ||
2012 | } | 2046 | } |
2013 | } else { | 2047 | } else { |
2048 | auto chain = exp->new_ptr<ChainValue_t>(); | ||
2049 | if (keyIndex) chain->items.push_back(keyIndex); | ||
2014 | auto varName = singleVariableFrom(exp, false); | 2050 | auto varName = singleVariableFrom(exp, false); |
2015 | pairs.push_back({exp, | 2051 | pairs.push_back({exp, |
2016 | varName, | 2052 | varName, |
2017 | keyName, | 2053 | chain, |
2018 | nullptr}); | 2054 | nullptr}); |
2019 | } | 2055 | } |
2020 | break; | 2056 | break; |
@@ -2022,10 +2058,11 @@ private: | |||
2022 | if (np->value.is<TableBlock_t>()) { | 2058 | if (np->value.is<TableBlock_t>()) { |
2023 | auto subPairs = destructFromExp(np->value, optional); | 2059 | auto subPairs = destructFromExp(np->value, optional); |
2024 | for (auto& p : subPairs) { | 2060 | for (auto& p : subPairs) { |
2025 | pairs.push_back({p.target, | 2061 | if (keyIndex) { |
2026 | p.targetVar, | 2062 | if (sep) p.structure->items.push_front(sep); |
2027 | keyName + sep + p.structure, | 2063 | p.structure->items.push_front(keyIndex); |
2028 | p.defVal}); | 2064 | } |
2065 | pairs.push_back(p); | ||
2029 | } | 2066 | } |
2030 | } | 2067 | } |
2031 | break; | 2068 | break; |
@@ -2035,10 +2072,9 @@ private: | |||
2035 | ++index; | 2072 | ++index; |
2036 | auto subPairs = destructFromExp(tb, optional); | 2073 | auto subPairs = destructFromExp(tb, optional); |
2037 | for (auto& p : subPairs) { | 2074 | for (auto& p : subPairs) { |
2038 | pairs.push_back({p.target, | 2075 | if (sep) p.structure->items.push_front(sep); |
2039 | p.targetVar, | 2076 | p.structure->items.push_front(toAst<Exp_t>(std::to_string(index), tb)); |
2040 | '[' + std::to_string(index) + ']' + sep + p.structure, | 2077 | pairs.push_back(p); |
2041 | p.defVal}); | ||
2042 | } | 2078 | } |
2043 | break; | 2079 | break; |
2044 | } | 2080 | } |
@@ -2057,34 +2093,45 @@ private: | |||
2057 | auto varName = singleVariableFrom(exp, false); | 2093 | auto varName = singleVariableFrom(exp, false); |
2058 | pairs.push_back({exp, | 2094 | pairs.push_back({exp, |
2059 | varName, | 2095 | varName, |
2060 | '[' + std::to_string(index) + ']', | 2096 | toAst<ChainValue_t>('[' + std::to_string(index) + ']', value), |
2061 | dp->defVal}); | 2097 | dp->defVal}); |
2062 | } | 2098 | } |
2063 | break; | 2099 | break; |
2064 | } | 2100 | } |
2065 | std::string keyName, valueStr; | 2101 | auto chain = dp->new_ptr<ChainValue_t>(); |
2102 | std::string valueStr; | ||
2066 | if (dp->key) { | 2103 | if (dp->key) { |
2067 | auto key = dp->key->getByPath<Name_t>(); | 2104 | if (auto key = dp->key->getByPath<Name_t>()) { |
2068 | if (!key) throw std::logic_error(_info.errorMessage("invalid key for destructure"sv, dp)); | 2105 | auto keyName = _parser.toString(key); |
2069 | keyName = _parser.toString(key); | 2106 | if (!dp->value) valueStr = keyName; |
2070 | if (!dp->value) valueStr = keyName; | 2107 | if (LuaKeywords.find(keyName) != LuaKeywords.end()) { |
2071 | if (LuaKeywords.find(keyName) != LuaKeywords.end()) { | 2108 | chain->items.push_back(toAst<Exp_t>('"' + keyName + '"', key)); |
2072 | keyName = "[\""s + keyName + "\"]"s; | 2109 | } else { |
2073 | } else { | 2110 | chain->items.push_back(toAst<DotChainItem_t>('.' + keyName, key)); |
2074 | keyName = "."s + keyName; | 2111 | } |
2075 | } | 2112 | } else if (auto key = dp->key->getByPath<SelfName_t>()) { |
2113 | auto callable = dp->new_ptr<Callable_t>(); | ||
2114 | callable->item.set(key); | ||
2115 | auto chainValue = dp->new_ptr<ChainValue_t>(); | ||
2116 | chainValue->items.push_back(callable); | ||
2117 | chain->items.push_back(newExp(chainValue, dp)); | ||
2118 | } else if (auto key = dp->key.as<String_t>()) { | ||
2119 | chain->items.push_back(newExp(key, dp)); | ||
2120 | } else if (auto key = dp->key.as<Exp_t>()) { | ||
2121 | chain->items.push_back(key); | ||
2122 | } else throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, dp)); | ||
2076 | } | 2123 | } |
2077 | if (auto exp = dp->value.get()) { | 2124 | if (auto exp = dp->value.get()) { |
2078 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); | 2125 | if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); |
2079 | auto varName = singleVariableFrom(exp, false); | 2126 | auto varName = singleVariableFrom(exp, false); |
2080 | pairs.push_back({exp, | 2127 | pairs.push_back({exp, |
2081 | varName, | 2128 | varName, |
2082 | keyName, | 2129 | chain, |
2083 | dp->defVal}); | 2130 | dp->defVal}); |
2084 | } else { | 2131 | } else { |
2085 | pairs.push_back({toAst<Exp_t>(valueStr, dp).get(), | 2132 | pairs.push_back({toAst<Exp_t>(valueStr, dp).get(), |
2086 | valueStr, | 2133 | valueStr, |
2087 | keyName, | 2134 | chain, |
2088 | dp->defVal}); | 2135 | dp->defVal}); |
2089 | } | 2136 | } |
2090 | break; | 2137 | break; |
@@ -2093,6 +2140,9 @@ private: | |||
2093 | auto mp = static_cast<meta_default_pair_t*>(pair); | 2140 | auto mp = static_cast<meta_default_pair_t*>(pair); |
2094 | auto newPair = pair->new_ptr<default_pair_t>(); | 2141 | auto newPair = pair->new_ptr<default_pair_t>(); |
2095 | if (mp->key) { | 2142 | if (mp->key) { |
2143 | if (!ast_is<Variable_t, Name_t>(mp->key)) { | ||
2144 | throw std::logic_error(_info.errorMessage("destructuring with metatable accessed by expression is not supported."sv, mp->key)); | ||
2145 | } | ||
2096 | auto key = _parser.toString(mp->key); | 2146 | auto key = _parser.toString(mp->key); |
2097 | _buf << "__"sv << key; | 2147 | _buf << "__"sv << key; |
2098 | auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); | 2148 | auto newKey = toAst<KeyName_t>(clearBuf(), mp->key); |
@@ -2145,14 +2195,16 @@ private: | |||
2145 | if (!subMetaDestruct->values.empty()) { | 2195 | if (!subMetaDestruct->values.empty()) { |
2146 | auto simpleValue = subMetaDestruct->new_ptr<SimpleValue_t>(); | 2196 | auto simpleValue = subMetaDestruct->new_ptr<SimpleValue_t>(); |
2147 | simpleValue->value.set(subMetaDestruct); | 2197 | simpleValue->value.set(subMetaDestruct); |
2148 | auto value = subMetaDestruct->new_ptr<Value_t>(); | 2198 | auto subPairs = destructFromExp(newExp(simpleValue, subMetaDestruct), optional); |
2149 | value->item.set(simpleValue); | ||
2150 | auto subPairs = destructFromExp(newExp(value, subMetaDestruct), optional); | ||
2151 | for (const auto& p : subPairs) { | 2199 | for (const auto& p : subPairs) { |
2152 | pairs.push_back({p.target, | 2200 | if (!p.structure->items.empty()) { |
2153 | p.targetVar, | 2201 | if (sep) p.structure->items.push_front(sep); |
2154 | ".#"s + (p.structure.empty() ? Empty : sep + p.structure), | 2202 | } |
2155 | p.defVal}); | 2203 | auto mt = p.structure->new_ptr<Metatable_t>(); |
2204 | auto dot = mt->new_ptr<DotChainItem_t>(); | ||
2205 | dot->name.set(mt); | ||
2206 | p.structure->items.push_front(dot); | ||
2207 | pairs.push_back(p); | ||
2156 | } | 2208 | } |
2157 | } | 2209 | } |
2158 | return pairs; | 2210 | return pairs; |
@@ -2258,6 +2310,12 @@ private: | |||
2258 | case id<Exp_t>(): | 2310 | case id<Exp_t>(): |
2259 | newPair->key.set(mp->key); | 2311 | newPair->key.set(mp->key); |
2260 | break; | 2312 | break; |
2313 | case id<String_t>(): { | ||
2314 | auto value = mp->new_ptr<Value_t>(); | ||
2315 | value->item.set(mp->key); | ||
2316 | newPair->key.set(newExp(value, mp)); | ||
2317 | break; | ||
2318 | } | ||
2261 | default: YUEE("AST node mismatch", mp->key); break; | 2319 | default: YUEE("AST node mismatch", mp->key); break; |
2262 | } | 2320 | } |
2263 | } | 2321 | } |
@@ -2289,9 +2347,7 @@ private: | |||
2289 | } | 2347 | } |
2290 | auto simpleValue = tab->new_ptr<SimpleValue_t>(); | 2348 | auto simpleValue = tab->new_ptr<SimpleValue_t>(); |
2291 | simpleValue->value.set(tab); | 2349 | simpleValue->value.set(tab); |
2292 | auto value = tab->new_ptr<Value_t>(); | 2350 | auto pairs = destructFromExp(newExp(simpleValue, expr), optional); |
2293 | value->item.set(simpleValue); | ||
2294 | auto pairs = destructFromExp(newExp(value, expr), optional); | ||
2295 | if (pairs.empty()) { | 2351 | if (pairs.empty()) { |
2296 | throw std::logic_error(_info.errorMessage("expect items to be destructured"sv, tab)); | 2352 | throw std::logic_error(_info.errorMessage("expect items to be destructured"sv, tab)); |
2297 | } | 2353 | } |
@@ -2299,15 +2355,13 @@ private: | |||
2299 | if (!varDefOnly) { | 2355 | if (!varDefOnly) { |
2300 | if (*j == nil) { | 2356 | if (*j == nil) { |
2301 | for (auto& item : destruct.items) { | 2357 | for (auto& item : destruct.items) { |
2302 | item.structure.clear(); | 2358 | item.structure = nullptr; |
2303 | } | 2359 | } |
2304 | } else if (tab == subMetaDestruct.get()) { | 2360 | } else if (tab == subMetaDestruct.get()) { |
2305 | auto p = destruct.value.get(); | 2361 | auto p = destruct.value.get(); |
2306 | auto chainValue = toAst<ChainValue_t>("getmetatable()", p); | 2362 | auto chainValue = toAst<ChainValue_t>("getmetatable()", p); |
2307 | static_cast<Invoke_t*>(chainValue->items.back())->args.push_back(destruct.value); | 2363 | static_cast<Invoke_t*>(chainValue->items.back())->args.push_back(destruct.value); |
2308 | auto value = p->new_ptr<Value_t>(); | 2364 | auto exp = newExp(chainValue, p); |
2309 | value->item.set(chainValue); | ||
2310 | auto exp = newExp(value, p); | ||
2311 | destruct.value.set(exp); | 2365 | destruct.value.set(exp); |
2312 | destruct.valueVar.clear(); | 2366 | destruct.valueVar.clear(); |
2313 | } else if (destruct.items.size() == 1 && !singleValueFrom(*j)) { | 2367 | } else if (destruct.items.size() == 1 && !singleValueFrom(*j)) { |
@@ -2318,9 +2372,7 @@ private: | |||
2318 | callable->item.set(parens); | 2372 | callable->item.set(parens); |
2319 | auto chainValue = p->new_ptr<ChainValue_t>(); | 2373 | auto chainValue = p->new_ptr<ChainValue_t>(); |
2320 | chainValue->items.push_back(callable); | 2374 | chainValue->items.push_back(callable); |
2321 | auto value = p->new_ptr<Value_t>(); | 2375 | auto exp = newExp(chainValue, p); |
2322 | value->item.set(chainValue); | ||
2323 | auto exp = newExp(value, p); | ||
2324 | destruct.value.set(exp); | 2376 | destruct.value.set(exp); |
2325 | destruct.valueVar.clear(); | 2377 | destruct.valueVar.clear(); |
2326 | } | 2378 | } |
@@ -2346,6 +2398,51 @@ private: | |||
2346 | newAssign->action.set(assign); | 2398 | newAssign->action.set(assign); |
2347 | newAssignment = newAssign; | 2399 | newAssignment = newAssign; |
2348 | } | 2400 | } |
2401 | if (!varDefOnly) { | ||
2402 | pushScope(); | ||
2403 | for (auto& des : destructs) { | ||
2404 | for (const auto& item : des.items) { | ||
2405 | for (auto node : item.structure->items.objects()) { | ||
2406 | if (auto exp = ast_cast<Exp_t>(node)) { | ||
2407 | if (auto value = simpleSingleValueFrom(node)) { | ||
2408 | if (ast_is<Num_t, const_value_t>(value->value)) { | ||
2409 | continue; | ||
2410 | } | ||
2411 | } | ||
2412 | if (auto value = singleValueFrom(exp); !value || !value->item.is<String_t>()) { | ||
2413 | auto var = singleVariableFrom(exp, false); | ||
2414 | if (var.empty()) { | ||
2415 | if (!des.inlineAssignment) { | ||
2416 | des.inlineAssignment = x->new_ptr<ExpListAssign_t>(); | ||
2417 | auto expList = x->new_ptr<ExpList_t>(); | ||
2418 | des.inlineAssignment->expList.set(expList); | ||
2419 | auto assign = x->new_ptr<Assign_t>(); | ||
2420 | des.inlineAssignment->action.set(assign); | ||
2421 | } | ||
2422 | auto assignList = des.inlineAssignment->expList.get(); | ||
2423 | auto assign = des.inlineAssignment->action.to<Assign_t>(); | ||
2424 | auto tmpVar = getUnusedName("_tmp_"sv); | ||
2425 | addToScope(tmpVar); | ||
2426 | auto tmpExp = toAst<Exp_t>(tmpVar, exp); | ||
2427 | assignList->exprs.push_back(tmpExp); | ||
2428 | auto vExp = exp->new_ptr<Exp_t>(); | ||
2429 | vExp->pipeExprs.dup(exp->pipeExprs); | ||
2430 | vExp->opValues.dup(exp->opValues); | ||
2431 | vExp->nilCoalesed.set(exp->nilCoalesed); | ||
2432 | exp->pipeExprs.clear(); | ||
2433 | exp->pipeExprs.dup(tmpExp->pipeExprs); | ||
2434 | exp->opValues.clear(); | ||
2435 | exp->opValues.dup(tmpExp->opValues); | ||
2436 | exp->nilCoalesed = tmpExp->nilCoalesed; | ||
2437 | assign->values.push_back(vExp); | ||
2438 | } | ||
2439 | } | ||
2440 | } | ||
2441 | } | ||
2442 | } | ||
2443 | } | ||
2444 | popScope(); | ||
2445 | } | ||
2349 | return {std::move(destructs), newAssignment}; | 2446 | return {std::move(destructs), newAssignment}; |
2350 | } | 2447 | } |
2351 | 2448 | ||
@@ -2385,9 +2482,7 @@ private: | |||
2385 | tmpChain->items.push_back(item); | 2482 | tmpChain->items.push_back(item); |
2386 | } | 2483 | } |
2387 | } | 2484 | } |
2388 | auto value = x->new_ptr<Value_t>(); | 2485 | auto exp = newExp(tmpChain, x); |
2389 | value->item.set(tmpChain); | ||
2390 | auto exp = newExp(value, x); | ||
2391 | auto objVar = getUnusedName("_obj_"sv); | 2486 | auto objVar = getUnusedName("_obj_"sv); |
2392 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); | 2487 | auto newAssignment = x->new_ptr<ExpListAssign_t>(); |
2393 | newAssignment->expList.set(toAst<ExpList_t>(objVar, x)); | 2488 | newAssignment->expList.set(toAst<ExpList_t>(objVar, x)); |
@@ -2518,9 +2613,7 @@ private: | |||
2518 | ns.clear(); | 2613 | ns.clear(); |
2519 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 2614 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
2520 | simpleValue->value.set(newIf); | 2615 | simpleValue->value.set(newIf); |
2521 | auto value = x->new_ptr<Value_t>(); | 2616 | auto exp = newExp(simpleValue, x); |
2522 | value->item.set(simpleValue); | ||
2523 | auto exp = newExp(value, x); | ||
2524 | auto expList = x->new_ptr<ExpList_t>(); | 2617 | auto expList = x->new_ptr<ExpList_t>(); |
2525 | expList->exprs.push_back(exp); | 2618 | expList->exprs.push_back(exp); |
2526 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 2619 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -3129,9 +3222,7 @@ private: | |||
3129 | funLit->body.set(body); | 3222 | funLit->body.set(body); |
3130 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 3223 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
3131 | simpleValue->value.set(funLit); | 3224 | simpleValue->value.set(funLit); |
3132 | auto value = x->new_ptr<Value_t>(); | 3225 | arg = newExp(simpleValue, x); |
3133 | value->item.set(simpleValue); | ||
3134 | arg = newExp(value, x); | ||
3135 | } | 3226 | } |
3136 | if (isChainValueCall(backcall->value)) { | 3227 | if (isChainValueCall(backcall->value)) { |
3137 | auto last = backcall->value->items.back(); | 3228 | auto last = backcall->value->items.back(); |
@@ -3164,9 +3255,7 @@ private: | |||
3164 | auto newStmt = x->new_ptr<Statement_t>(); | 3255 | auto newStmt = x->new_ptr<Statement_t>(); |
3165 | { | 3256 | { |
3166 | auto chainValue = backcall->value.get(); | 3257 | auto chainValue = backcall->value.get(); |
3167 | auto value = x->new_ptr<Value_t>(); | 3258 | auto exp = newExp(chainValue, x); |
3168 | value->item.set(chainValue); | ||
3169 | auto exp = newExp(value, x); | ||
3170 | auto expList = x->new_ptr<ExpList_t>(); | 3259 | auto expList = x->new_ptr<ExpList_t>(); |
3171 | expList->exprs.push_back(exp); | 3260 | expList->exprs.push_back(exp); |
3172 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 3261 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -3329,9 +3418,7 @@ private: | |||
3329 | } else { | 3418 | } else { |
3330 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 3419 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
3331 | simpleValue->value.set(last->content); | 3420 | simpleValue->value.set(last->content); |
3332 | auto value = x->new_ptr<Value_t>(); | 3421 | auto exp = newExp(simpleValue, x); |
3333 | value->item.set(simpleValue); | ||
3334 | auto exp = newExp(value, x); | ||
3335 | assign->values.push_back(exp); | 3422 | assign->values.push_back(exp); |
3336 | } | 3423 | } |
3337 | newAssignment->action.set(assign); | 3424 | newAssignment->action.set(assign); |
@@ -3857,9 +3944,7 @@ private: | |||
3857 | callable->item.set(parens); | 3944 | callable->item.set(parens); |
3858 | auto chainValue = x->new_ptr<ChainValue_t>(); | 3945 | auto chainValue = x->new_ptr<ChainValue_t>(); |
3859 | chainValue->items.push_back(callable); | 3946 | chainValue->items.push_back(callable); |
3860 | auto value = x->new_ptr<Value_t>(); | 3947 | auto exp = newExp(chainValue, x); |
3861 | value->item.set(chainValue); | ||
3862 | auto exp = newExp(value, x); | ||
3863 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 3948 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
3864 | assignment->expList.set(assignList); | 3949 | assignment->expList.set(assignList); |
3865 | auto assign = x->new_ptr<Assign_t>(); | 3950 | auto assign = x->new_ptr<Assign_t>(); |
@@ -3949,9 +4034,7 @@ private: | |||
3949 | if (!newObj.empty()) { | 4034 | if (!newObj.empty()) { |
3950 | objVar = newObj; | 4035 | objVar = newObj; |
3951 | } else { | 4036 | } else { |
3952 | auto value = x->new_ptr<Value_t>(); | 4037 | auto exp = newExp(chainValue, x); |
3953 | value->item.set(chainValue); | ||
3954 | auto exp = newExp(value, x); | ||
3955 | auto assign = x->new_ptr<Assign_t>(); | 4038 | auto assign = x->new_ptr<Assign_t>(); |
3956 | assign->values.push_back(exp); | 4039 | assign->values.push_back(exp); |
3957 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 4040 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -3981,9 +4064,7 @@ private: | |||
3981 | } | 4064 | } |
3982 | objVar = getUnusedName("_obj_"sv); | 4065 | objVar = getUnusedName("_obj_"sv); |
3983 | } | 4066 | } |
3984 | auto value = x->new_ptr<Value_t>(); | 4067 | auto exp = newExp(partOne, x); |
3985 | value->item.set(partOne); | ||
3986 | auto exp = newExp(value, x); | ||
3987 | auto assign = x->new_ptr<Assign_t>(); | 4068 | auto assign = x->new_ptr<Assign_t>(); |
3988 | assign->values.push_back(exp); | 4069 | assign->values.push_back(exp); |
3989 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 4070 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -4004,9 +4085,7 @@ private: | |||
4004 | transformChainValue(partTwo, temp, ExpUsage::Common); | 4085 | transformChainValue(partTwo, temp, ExpUsage::Common); |
4005 | break; | 4086 | break; |
4006 | case ExpUsage::Assignment: { | 4087 | case ExpUsage::Assignment: { |
4007 | auto value = x->new_ptr<Value_t>(); | 4088 | auto exp = newExp(partTwo, x); |
4008 | value->item.set(partTwo); | ||
4009 | auto exp = newExp(value, x); | ||
4010 | auto assign = x->new_ptr<Assign_t>(); | 4089 | auto assign = x->new_ptr<Assign_t>(); |
4011 | assign->values.push_back(exp); | 4090 | assign->values.push_back(exp); |
4012 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 4091 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
@@ -4017,9 +4096,7 @@ private: | |||
4017 | } | 4096 | } |
4018 | case ExpUsage::Return: | 4097 | case ExpUsage::Return: |
4019 | case ExpUsage::Closure: { | 4098 | case ExpUsage::Closure: { |
4020 | auto value = x->new_ptr<Value_t>(); | 4099 | auto exp = newExp(partTwo, x); |
4021 | value->item.set(partTwo); | ||
4022 | auto exp = newExp(value, x); | ||
4023 | auto ret = x->new_ptr<Return_t>(); | 4100 | auto ret = x->new_ptr<Return_t>(); |
4024 | auto expListLow = x->new_ptr<ExpListLow_t>(); | 4101 | auto expListLow = x->new_ptr<ExpListLow_t>(); |
4025 | expListLow->exprs.push_back(exp); | 4102 | expListLow->exprs.push_back(exp); |
@@ -4095,9 +4172,7 @@ private: | |||
4095 | auto baseVar = getUnusedName("_base_"sv); | 4172 | auto baseVar = getUnusedName("_base_"sv); |
4096 | auto fnVar = getUnusedName("_fn_"sv); | 4173 | auto fnVar = getUnusedName("_fn_"sv); |
4097 | { | 4174 | { |
4098 | auto value = x->new_ptr<Value_t>(); | 4175 | auto exp = newExp(baseChain, x); |
4099 | value->item.set(baseChain); | ||
4100 | auto exp = newExp(value, x); | ||
4101 | auto assign = x->new_ptr<Assign_t>(); | 4176 | auto assign = x->new_ptr<Assign_t>(); |
4102 | assign->values.push_back(exp); | 4177 | assign->values.push_back(exp); |
4103 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 4178 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
@@ -4183,26 +4258,124 @@ private: | |||
4183 | for (auto it = chainList.begin(); it != opIt; ++it) { | 4258 | for (auto it = chainList.begin(); it != opIt; ++it) { |
4184 | chain->items.push_back(*it); | 4259 | chain->items.push_back(*it); |
4185 | } | 4260 | } |
4186 | auto value = x->new_ptr<Value_t>(); | 4261 | { |
4187 | value->item.set(chain); | 4262 | auto exp = newExp(chain, x); |
4188 | auto exp = newExp(value, x); | 4263 | chain = toAst<ChainValue_t>("getmetatable()"sv, x); |
4189 | 4264 | ast_to<Invoke_t>(chain->items.back())->args.push_back(exp); | |
4190 | chain = toAst<ChainValue_t>("getmetatable()"sv, x); | 4265 | } |
4191 | ast_to<Invoke_t>(chain->items.back())->args.push_back(exp); | ||
4192 | switch ((*opIt)->getId()) { | 4266 | switch ((*opIt)->getId()) { |
4193 | case id<ColonChainItem_t>(): { | 4267 | case id<ColonChainItem_t>(): { |
4194 | auto colon = static_cast<ColonChainItem_t*>(*opIt); | 4268 | auto colon = static_cast<ColonChainItem_t*>(*opIt); |
4195 | auto meta = colon->name.to<Metamethod_t>(); | 4269 | auto meta = colon->name.to<Metamethod_t>(); |
4196 | auto newColon = toAst<ColonChainItem_t>("\\__"s + _parser.toString(meta->name), x); | 4270 | switch (meta->item->getId()) { |
4197 | chain->items.push_back(newColon); | 4271 | case id<Name_t>(): { |
4272 | auto newColon = toAst<ColonChainItem_t>("\\__"s + _parser.toString(meta->item), x); | ||
4273 | chain->items.push_back(newColon); | ||
4274 | break; | ||
4275 | } | ||
4276 | case id<String_t>(): | ||
4277 | case id<Exp_t>(): { | ||
4278 | str_list temp; | ||
4279 | std::string* funcStart = nullptr; | ||
4280 | if (usage == ExpUsage::Closure) { | ||
4281 | _enableReturn.push(true); | ||
4282 | pushAnonVarArg(); | ||
4283 | funcStart = &temp.emplace_back(); | ||
4284 | pushScope(); | ||
4285 | } else if (usage != ExpUsage::Return) { | ||
4286 | temp.push_back(indent() + "do"s + nll(x)); | ||
4287 | pushScope(); | ||
4288 | } | ||
4289 | auto var = getUnusedName("_obj_"sv); | ||
4290 | auto target = toAst<Exp_t>(var, x); | ||
4291 | { | ||
4292 | auto assignment = assignmentFrom(target, newExp(chain, x), x); | ||
4293 | transformAssignment(assignment, temp); | ||
4294 | } | ||
4295 | auto newChain = toAst<ChainValue_t>(var, x); | ||
4296 | if (auto str = meta->item.as<String_t>()) { | ||
4297 | newChain->items.push_back(newExp(str, x)); | ||
4298 | } else { | ||
4299 | newChain->items.push_back(meta->item); | ||
4300 | } | ||
4301 | auto newChainExp = newExp(newChain, x); | ||
4302 | for (auto it = ++opIt; it != chainList.end(); ++it) { | ||
4303 | newChain->items.push_back(*it); | ||
4304 | } | ||
4305 | auto last = newChain->items.back(); | ||
4306 | if (ast_is<Invoke_t, InvokeArgs_t>(last)) { | ||
4307 | if (auto invoke = ast_cast<InvokeArgs_t>(last)) { | ||
4308 | invoke->args.push_front(target); | ||
4309 | } else { | ||
4310 | ast_to<Invoke_t>(last)->args.push_front(target); | ||
4311 | } | ||
4312 | } | ||
4313 | switch (usage) { | ||
4314 | case ExpUsage::Closure: { | ||
4315 | auto returnNode = x->new_ptr<Return_t>(); | ||
4316 | auto values = x->new_ptr<ExpListLow_t>(); | ||
4317 | values->exprs.push_back(newChainExp); | ||
4318 | returnNode->valueList.set(values); | ||
4319 | transformReturn(returnNode, temp); | ||
4320 | popScope(); | ||
4321 | *funcStart = anonFuncStart() + nll(x); | ||
4322 | temp.push_back(indent() + anonFuncEnd()); | ||
4323 | popAnonVarArg(); | ||
4324 | _enableReturn.pop(); | ||
4325 | break; | ||
4326 | } | ||
4327 | case ExpUsage::Return: { | ||
4328 | auto returnNode = x->new_ptr<Return_t>(); | ||
4329 | auto values = x->new_ptr<ExpListLow_t>(); | ||
4330 | values->exprs.push_back(newChainExp); | ||
4331 | returnNode->valueList.set(values); | ||
4332 | transformReturn(returnNode, temp); | ||
4333 | break; | ||
4334 | } | ||
4335 | case ExpUsage::Assignment: { | ||
4336 | auto assignment = x->new_ptr<ExpListAssign_t>(); | ||
4337 | assignment->expList.set(assignList); | ||
4338 | auto assign = x->new_ptr<Assign_t>(); | ||
4339 | assign->values.push_back(newChainExp); | ||
4340 | assignment->action.set(assign); | ||
4341 | transformAssignment(assignment, temp); | ||
4342 | popScope(); | ||
4343 | temp.push_back(indent() + "end"s + nlr(x)); | ||
4344 | break; | ||
4345 | } | ||
4346 | case ExpUsage::Common: | ||
4347 | transformExp(newChainExp, temp, usage); | ||
4348 | popScope(); | ||
4349 | temp.push_back(indent() + "end"s + nlr(x)); | ||
4350 | break; | ||
4351 | } | ||
4352 | out.push_back(join(temp)); | ||
4353 | return true; | ||
4354 | } | ||
4355 | default: YUEE("AST node mismatch", meta->item); break; | ||
4356 | } | ||
4198 | break; | 4357 | break; |
4199 | } | 4358 | } |
4200 | case id<DotChainItem_t>(): { | 4359 | case id<DotChainItem_t>(): { |
4201 | auto dot = static_cast<DotChainItem_t*>(*opIt); | 4360 | auto dot = static_cast<DotChainItem_t*>(*opIt); |
4202 | if (dot->name.is<Metatable_t>()) break; | 4361 | if (dot->name.is<Metatable_t>()) break; |
4203 | auto meta = dot->name.to<Metamethod_t>(); | 4362 | auto meta = dot->name.to<Metamethod_t>(); |
4204 | auto newDot = toAst<DotChainItem_t>(".__"s + _parser.toString(meta->name), x); | 4363 | switch (meta->item->getId()) { |
4205 | chain->items.push_back(newDot); | 4364 | case id<Name_t>(): { |
4365 | auto newDot = toAst<DotChainItem_t>(".__"s + _parser.toString(meta->item), x); | ||
4366 | chain->items.push_back(newDot); | ||
4367 | break; | ||
4368 | } | ||
4369 | case id<Exp_t>(): | ||
4370 | chain->items.push_back(meta->item); | ||
4371 | break; | ||
4372 | case id<String_t>(): { | ||
4373 | auto str = static_cast<String_t*>(meta->item.get()); | ||
4374 | chain->items.push_back(newExp(str, x)); | ||
4375 | break; | ||
4376 | } | ||
4377 | default: YUEE("AST node mismatch", meta->item); break; | ||
4378 | } | ||
4206 | break; | 4379 | break; |
4207 | } | 4380 | } |
4208 | } | 4381 | } |
@@ -4276,9 +4449,7 @@ private: | |||
4276 | for (auto i = chainList.begin(); i != current; ++i) { | 4449 | for (auto i = chainList.begin(); i != current; ++i) { |
4277 | chainValue->items.push_back(*i); | 4450 | chainValue->items.push_back(*i); |
4278 | } | 4451 | } |
4279 | auto value = x->new_ptr<Value_t>(); | 4452 | auto exp = newExp(chainValue, x); |
4280 | value->item.set(chainValue); | ||
4281 | auto exp = newExp(value, x); | ||
4282 | callVar = singleVariableFrom(exp, true); | 4453 | callVar = singleVariableFrom(exp, true); |
4283 | if (callVar.empty()) { | 4454 | if (callVar.empty()) { |
4284 | callVar = getUnusedName("_call_"s); | 4455 | callVar = getUnusedName("_call_"s); |
@@ -4310,9 +4481,7 @@ private: | |||
4310 | for (auto i = next; i != chainList.end(); ++i) { | 4481 | for (auto i = next; i != chainList.end(); ++i) { |
4311 | chainValue->items.push_back(*i); | 4482 | chainValue->items.push_back(*i); |
4312 | } | 4483 | } |
4313 | auto value = x->new_ptr<Value_t>(); | 4484 | nexp = newExp(chainValue, x); |
4314 | value->item.set(chainValue); | ||
4315 | nexp = newExp(value, x); | ||
4316 | auto expList = x->new_ptr<ExpList_t>(); | 4485 | auto expList = x->new_ptr<ExpList_t>(); |
4317 | expList->exprs.push_back(nexp); | 4486 | expList->exprs.push_back(nexp); |
4318 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 4487 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
@@ -4342,9 +4511,7 @@ private: | |||
4342 | funLit->body.set(body); | 4511 | funLit->body.set(body); |
4343 | auto simpleValue = x->new_ptr<SimpleValue_t>(); | 4512 | auto simpleValue = x->new_ptr<SimpleValue_t>(); |
4344 | simpleValue->value.set(funLit); | 4513 | simpleValue->value.set(funLit); |
4345 | auto value = x->new_ptr<Value_t>(); | 4514 | auto exp = newExp(simpleValue, x); |
4346 | value->item.set(simpleValue); | ||
4347 | auto exp = newExp(value, x); | ||
4348 | auto paren = x->new_ptr<Parens_t>(); | 4515 | auto paren = x->new_ptr<Parens_t>(); |
4349 | paren->expr.set(exp); | 4516 | paren->expr.set(exp); |
4350 | auto callable = x->new_ptr<Callable_t>(); | 4517 | auto callable = x->new_ptr<Callable_t>(); |
@@ -4679,9 +4846,7 @@ private: | |||
4679 | for (; it != chainList.end(); ++it) { | 4846 | for (; it != chainList.end(); ++it) { |
4680 | newChain->items.push_back(*it); | 4847 | newChain->items.push_back(*it); |
4681 | } | 4848 | } |
4682 | auto value = x->new_ptr<Value_t>(); | 4849 | exp = newExp(newChain, x); |
4683 | value->item.set(newChain); | ||
4684 | exp = newExp(value, x); | ||
4685 | } | 4850 | } |
4686 | if (usage == ExpUsage::Common) { | 4851 | if (usage == ExpUsage::Common) { |
4687 | auto expList = x->new_ptr<ExpList_t>(); | 4852 | auto expList = x->new_ptr<ExpList_t>(); |
@@ -4961,9 +5126,7 @@ private: | |||
4961 | callable->item.set(selfName); | 5126 | callable->item.set(selfName); |
4962 | auto chainValue = x->new_ptr<ChainValue_t>(); | 5127 | auto chainValue = x->new_ptr<ChainValue_t>(); |
4963 | chainValue->items.push_back(callable); | 5128 | chainValue->items.push_back(callable); |
4964 | auto value = x->new_ptr<Value_t>(); | 5129 | auto exp = newExp(chainValue, key); |
4965 | value->item.set(chainValue); | ||
4966 | auto exp = newExp(value, key); | ||
4967 | chainItem = exp.get(); | 5130 | chainItem = exp.get(); |
4968 | } | 5131 | } |
4969 | chainValue->items.push_back(chainItem); | 5132 | chainValue->items.push_back(chainItem); |
@@ -5034,7 +5197,7 @@ private: | |||
5034 | case id<meta_variable_pair_t>(): { | 5197 | case id<meta_variable_pair_t>(): { |
5035 | auto metaVarPair = static_cast<meta_variable_pair_t*>(item); | 5198 | auto metaVarPair = static_cast<meta_variable_pair_t*>(item); |
5036 | auto nameStr = _parser.toString(metaVarPair->name); | 5199 | auto nameStr = _parser.toString(metaVarPair->name); |
5037 | auto assignment = toAst<ExpListAssign_t>(tableVar + '.' + nameStr + "#="s + nameStr, item); | 5200 | auto assignment = toAst<ExpListAssign_t>(tableVar + ".<"s + nameStr + ">="s + nameStr, item); |
5038 | transformAssignment(assignment, temp); | 5201 | transformAssignment(assignment, temp); |
5039 | break; | 5202 | break; |
5040 | } | 5203 | } |
@@ -5051,8 +5214,10 @@ private: | |||
5051 | break; | 5214 | break; |
5052 | } | 5215 | } |
5053 | case id<Exp_t>(): { | 5216 | case id<Exp_t>(): { |
5054 | auto dotItem = toAst<DotChainItem_t>(".#"sv, key); | 5217 | auto mt = key->new_ptr<Metatable_t>(); |
5055 | chainValue->items.push_back(dotItem); | 5218 | auto dot = mt->new_ptr<DotChainItem_t>(); |
5219 | dot->name.set(mt); | ||
5220 | chainValue->items.push_back(dot); | ||
5056 | chainValue->items.push_back(key); | 5221 | chainValue->items.push_back(key); |
5057 | break; | 5222 | break; |
5058 | } | 5223 | } |
@@ -5158,6 +5323,11 @@ private: | |||
5158 | case id<Exp_t>(): | 5323 | case id<Exp_t>(): |
5159 | newPair->key.set(mp->key); | 5324 | newPair->key.set(mp->key); |
5160 | break; | 5325 | break; |
5326 | case id<String_t>(): { | ||
5327 | auto str = static_cast<String_t*>(mp->key.get()); | ||
5328 | newPair->key.set(newExp(str, mp)); | ||
5329 | break; | ||
5330 | } | ||
5161 | default: YUEE("AST node mismatch", mp->key); break; | 5331 | default: YUEE("AST node mismatch", mp->key); break; |
5162 | } | 5332 | } |
5163 | newPair->value.set(mp->value); | 5333 | newPair->value.set(mp->value); |
@@ -5504,9 +5674,7 @@ private: | |||
5504 | for (auto& pair : destructPairs) { | 5674 | for (auto& pair : destructPairs) { |
5505 | auto sValue = x->new_ptr<SimpleValue_t>(); | 5675 | auto sValue = x->new_ptr<SimpleValue_t>(); |
5506 | sValue->value.set(pair.first); | 5676 | sValue->value.set(pair.first); |
5507 | auto value = x->new_ptr<Value_t>(); | 5677 | auto exp = newExp(sValue, x); |
5508 | value->item.set(sValue); | ||
5509 | auto exp = newExp(value, x); | ||
5510 | auto expList = x->new_ptr<ExpList_t>(); | 5678 | auto expList = x->new_ptr<ExpList_t>(); |
5511 | expList->exprs.push_back(exp); | 5679 | expList->exprs.push_back(exp); |
5512 | auto assign = x->new_ptr<Assign_t>(); | 5680 | auto assign = x->new_ptr<Assign_t>(); |
@@ -5918,18 +6086,26 @@ private: | |||
5918 | transformExp(static_cast<Exp_t*>(key), temp, ExpUsage::Closure); | 6086 | transformExp(static_cast<Exp_t*>(key), temp, ExpUsage::Closure); |
5919 | temp.back() = (temp.back().front() == '[' ? "[ "s : "["s) + temp.back() + ']'; | 6087 | temp.back() = (temp.back().front() == '[' ? "[ "s : "["s) + temp.back() + ']'; |
5920 | break; | 6088 | break; |
5921 | case id<DoubleString_t>(): | 6089 | case id<String_t>(): { |
5922 | transformDoubleString(static_cast<DoubleString_t*>(key), temp); | 6090 | auto strNode = static_cast<String_t*>(key); |
5923 | temp.back() = '[' + temp.back() + ']'; | 6091 | auto str = strNode->str.get(); |
5924 | break; | 6092 | switch (str->getId()) { |
5925 | case id<SingleString_t>(): | 6093 | case id<DoubleString_t>(): |
5926 | transformSingleString(static_cast<SingleString_t*>(key), temp); | 6094 | transformDoubleString(static_cast<DoubleString_t*>(str), temp); |
5927 | temp.back() = '[' + temp.back() + ']'; | 6095 | temp.back() = '[' + temp.back() + ']'; |
5928 | break; | 6096 | break; |
5929 | case id<LuaString_t>(): | 6097 | case id<SingleString_t>(): |
5930 | transformLuaString(static_cast<LuaString_t*>(key), temp); | 6098 | transformSingleString(static_cast<SingleString_t*>(str), temp); |
5931 | temp.back() = "[ "s + temp.back() + ']'; | 6099 | temp.back() = '[' + temp.back() + ']'; |
6100 | break; | ||
6101 | case id<LuaString_t>(): | ||
6102 | transformLuaString(static_cast<LuaString_t*>(str), temp); | ||
6103 | temp.back() = "[ "s + temp.back() + ']'; | ||
6104 | break; | ||
6105 | default: YUEE("AST node mismatch", str); break; | ||
6106 | } | ||
5932 | break; | 6107 | break; |
6108 | } | ||
5933 | default: YUEE("AST node mismatch", key); break; | 6109 | default: YUEE("AST node mismatch", key); break; |
5934 | } | 6110 | } |
5935 | auto value = pair->value.get(); | 6111 | auto value = pair->value.get(); |
@@ -6308,6 +6484,8 @@ private: | |||
6308 | if (auto name = mtPair->key.as<Name_t>()) { | 6484 | if (auto name = mtPair->key.as<Name_t>()) { |
6309 | auto nameStr = _parser.toString(name); | 6485 | auto nameStr = _parser.toString(name); |
6310 | normal_pair->key.set(toAst<KeyName_t>("__"s + nameStr, keyValue)); | 6486 | normal_pair->key.set(toAst<KeyName_t>("__"s + nameStr, keyValue)); |
6487 | } else if (auto str = mtPair->key.as<String_t>()) { | ||
6488 | normal_pair->key.set(newExp(str, str)); | ||
6311 | } else { | 6489 | } else { |
6312 | normal_pair->key.set(mtPair->key); | 6490 | normal_pair->key.set(mtPair->key); |
6313 | } | 6491 | } |
@@ -6624,9 +6802,7 @@ private: | |||
6624 | callable->item.set(name); | 6802 | callable->item.set(name); |
6625 | auto chainValue = x->new_ptr<ChainValue_t>(); | 6803 | auto chainValue = x->new_ptr<ChainValue_t>(); |
6626 | chainValue->items.push_back(callable); | 6804 | chainValue->items.push_back(callable); |
6627 | auto value = x->new_ptr<Value_t>(); | 6805 | auto exp = newExp(chainValue, x); |
6628 | value->item.set(chainValue); | ||
6629 | auto exp = newExp(value, x); | ||
6630 | expList->exprs.push_back(exp); | 6806 | expList->exprs.push_back(exp); |
6631 | } | 6807 | } |
6632 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 6808 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
@@ -6979,18 +7155,14 @@ private: | |||
6979 | auto chainValue = x->new_ptr<ChainValue_t>(); | 7155 | auto chainValue = x->new_ptr<ChainValue_t>(); |
6980 | chainValue->items.push_back(callable); | 7156 | chainValue->items.push_back(callable); |
6981 | chainValue->items.push_back(dotChainItem); | 7157 | chainValue->items.push_back(dotChainItem); |
6982 | auto value = x->new_ptr<Value_t>(); | 7158 | auto exp = newExp(chainValue, x); |
6983 | value->item.set(chainValue); | ||
6984 | auto exp = newExp(value, x); | ||
6985 | assign->values.push_back(exp); | 7159 | assign->values.push_back(exp); |
6986 | } | 7160 | } |
6987 | auto callable = x->new_ptr<Callable_t>(); | 7161 | auto callable = x->new_ptr<Callable_t>(); |
6988 | callable->item.set(var); | 7162 | callable->item.set(var); |
6989 | auto chainValue = x->new_ptr<ChainValue_t>(); | 7163 | auto chainValue = x->new_ptr<ChainValue_t>(); |
6990 | chainValue->items.push_back(callable); | 7164 | chainValue->items.push_back(callable); |
6991 | auto value = x->new_ptr<Value_t>(); | 7165 | auto exp = newExp(chainValue, x); |
6992 | value->item.set(chainValue); | ||
6993 | auto exp = newExp(value, x); | ||
6994 | expList->exprs.push_back(exp); | 7166 | expList->exprs.push_back(exp); |
6995 | break; | 7167 | break; |
6996 | } | 7168 | } |
@@ -7004,18 +7176,14 @@ private: | |||
7004 | auto chainValue = x->new_ptr<ChainValue_t>(); | 7176 | auto chainValue = x->new_ptr<ChainValue_t>(); |
7005 | chainValue->items.push_back(callable); | 7177 | chainValue->items.push_back(callable); |
7006 | chainValue->items.push_back(colonChain); | 7178 | chainValue->items.push_back(colonChain); |
7007 | auto value = x->new_ptr<Value_t>(); | 7179 | auto exp = newExp(chainValue, x); |
7008 | value->item.set(chainValue); | ||
7009 | auto exp = newExp(value, x); | ||
7010 | assign->values.push_back(exp); | 7180 | assign->values.push_back(exp); |
7011 | } | 7181 | } |
7012 | auto callable = x->new_ptr<Callable_t>(); | 7182 | auto callable = x->new_ptr<Callable_t>(); |
7013 | callable->item.set(var); | 7183 | callable->item.set(var); |
7014 | auto chainValue = x->new_ptr<ChainValue_t>(); | 7184 | auto chainValue = x->new_ptr<ChainValue_t>(); |
7015 | chainValue->items.push_back(callable); | 7185 | chainValue->items.push_back(callable); |
7016 | auto value = x->new_ptr<Value_t>(); | 7186 | auto exp = newExp(chainValue, x); |
7017 | value->item.set(chainValue); | ||
7018 | auto exp = newExp(value, x); | ||
7019 | expList->exprs.push_back(exp); | 7187 | expList->exprs.push_back(exp); |
7020 | break; | 7188 | break; |
7021 | } | 7189 | } |
@@ -7507,9 +7675,7 @@ private: | |||
7507 | callable->item.set(name); | 7675 | callable->item.set(name); |
7508 | auto chainValue = x->new_ptr<ChainValue_t>(); | 7676 | auto chainValue = x->new_ptr<ChainValue_t>(); |
7509 | chainValue->items.push_back(callable); | 7677 | chainValue->items.push_back(callable); |
7510 | auto value = x->new_ptr<Value_t>(); | 7678 | auto exp = newExp(chainValue, x); |
7511 | value->item.set(chainValue); | ||
7512 | auto exp = newExp(value, x); | ||
7513 | expList->exprs.push_back(exp); | 7679 | expList->exprs.push_back(exp); |
7514 | } | 7680 | } |
7515 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 7681 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index e5209ef..153babe 100755 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
@@ -351,7 +351,7 @@ YueParser::YueParser() { | |||
351 | 351 | ||
352 | unary_operator = | 352 | unary_operator = |
353 | expr('-') >> not_(set(">=") | space_one) | | 353 | expr('-') >> not_(set(">=") | space_one) | |
354 | expr('#') >> not_(':') | | 354 | expr('#') | |
355 | expr('~') >> not_(expr('=') | space_one) | | 355 | expr('~') >> not_(expr('=') | space_one) | |
356 | expr("not") >> not_(AlphaNum); | 356 | expr("not") >> not_(AlphaNum); |
357 | unary_exp = *(Space >> unary_operator) >> expo_exp; | 357 | unary_exp = *(Space >> unary_operator) >> expo_exp; |
@@ -435,8 +435,9 @@ YueParser::YueParser() { | |||
435 | FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) | | 435 | FnArgs = (symx('(') >> *SpaceBreak >> -FnArgsExpList >> *SpaceBreak >> sym(')')) | |
436 | (sym('!') >> not_(expr('='))); | 436 | (sym('!') >> not_(expr('='))); |
437 | 437 | ||
438 | Metatable = expr('#'); | 438 | meta_index = Name | Index | String; |
439 | Metamethod = Name >> expr('#'); | 439 | Metatable = expr('<') >> sym('>'); |
440 | Metamethod = expr('<') >> Space >> meta_index >> sym('>'); | ||
440 | 441 | ||
441 | existential_op = expr('?') >> not_(expr('?')); | 442 | existential_op = expr('?') >> not_(expr('?')); |
442 | table_appending_op = expr("[]"); | 443 | table_appending_op = expr("[]"); |
@@ -453,8 +454,8 @@ YueParser::YueParser() { | |||
453 | 454 | ||
454 | Index = symx('[') >> not_('[') >> Exp >> sym(']'); | 455 | Index = symx('[') >> not_('[') >> Exp >> sym(']'); |
455 | ChainItem = Invoke >> -existential_op | DotChainItem >> -existential_op | Slice | Index >> -existential_op; | 456 | ChainItem = Invoke >> -existential_op | DotChainItem >> -existential_op | Slice | Index >> -existential_op; |
456 | DotChainItem = symx('.') >> (Name >> not_('#') | Metatable | Metamethod); | 457 | DotChainItem = symx('.') >> (Name | Metatable | Metamethod); |
457 | ColonChainItem = (expr('\\') | expr("::")) >> ((LuaKeyword | Name) >> not_('#') | Metamethod); | 458 | ColonChainItem = (expr('\\') | expr("::")) >> (LuaKeyword | Name | Metamethod); |
458 | invoke_chain = Invoke >> -existential_op >> -ChainItems; | 459 | invoke_chain = Invoke >> -existential_op >> -ChainItems; |
459 | ColonChain = ColonChainItem >> -existential_op >> -invoke_chain; | 460 | ColonChain = ColonChainItem >> -existential_op >> -invoke_chain; |
460 | 461 | ||
@@ -542,26 +543,31 @@ YueParser::YueParser() { | |||
542 | return true; | 543 | return true; |
543 | })) >> not_(Space >> statement_appendix); | 544 | })) >> not_(Space >> statement_appendix); |
544 | 545 | ||
545 | variable_pair = sym(':') >> Variable >> not_('#'); | 546 | variable_pair = sym(':') >> Variable; |
546 | 547 | ||
547 | normal_pair = ( | 548 | normal_pair = ( |
548 | KeyName | | 549 | KeyName | |
549 | sym('[') >> not_('[') >> Exp >> sym(']') | | 550 | sym('[') >> not_('[') >> Exp >> sym(']') | |
550 | Space >> DoubleString | | 551 | Space >> String |
551 | Space >> SingleString | | ||
552 | Space >> LuaString | ||
553 | ) >> | 552 | ) >> |
554 | symx(':') >> not_(':') >> | 553 | symx(':') >> not_(':') >> |
555 | (Exp | TableBlock | +SpaceBreak >> Exp); | 554 | (Exp | TableBlock | +SpaceBreak >> Exp); |
556 | 555 | ||
557 | default_pair = (sym(':') >> Variable >> not_('#') >> Seperator | KeyName >> symx(':') >> Seperator >> exp_not_tab | exp_not_tab >> Seperator) >> sym('=') >> Exp; | 556 | default_pair = ( |
557 | sym(':') >> Variable >> Seperator | | ||
558 | KeyName >> symx(':') >> not_(':') >> Seperator >> exp_not_tab | | ||
559 | Space >> String >> symx(':') >> not_(':') >> Seperator >> exp_not_tab | | ||
560 | exp_not_tab >> Seperator) >> sym('=') >> Exp; | ||
558 | 561 | ||
559 | meta_variable_pair = sym(':') >> Variable >> expr('#'); | 562 | meta_variable_pair = sym(":<") >> Space >> Variable >> sym('>'); |
560 | 563 | ||
561 | meta_normal_pair = Space >> -(Name | symx('[') >> not_('[') >> Exp >> sym(']')) >> expr("#:") >> | 564 | meta_normal_pair = sym('<') >> Space >> -meta_index >> sym(">:") >> |
562 | (Exp | TableBlock | +(SpaceBreak) >> Exp); | 565 | (Exp | TableBlock | +(SpaceBreak) >> Exp); |
563 | 566 | ||
564 | meta_default_pair = (sym(':') >> Variable >> expr('#') >> Seperator | Space >> -Name >> expr("#:") >> Seperator >> exp_not_tab) >> sym('=') >> Exp; | 567 | meta_default_pair = ( |
568 | sym(":<") >> Space >> Variable >> sym('>') >> Seperator | | ||
569 | sym('<') >> Space >> -meta_index >> sym(">:") >> Seperator >> exp_not_tab | ||
570 | ) >> sym('=') >> Exp; | ||
565 | 571 | ||
566 | KeyValue = variable_pair | normal_pair | meta_variable_pair | meta_normal_pair; | 572 | KeyValue = variable_pair | normal_pair | meta_variable_pair | meta_normal_pair; |
567 | KeyValueList = KeyValue >> *(sym(',') >> KeyValue); | 573 | KeyValueList = KeyValue >> *(sym(',') >> KeyValue); |
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h index dd577b4..f83f1b9 100755 --- a/src/yuescript/yue_parser.h +++ b/src/yuescript/yue_parser.h | |||
@@ -172,6 +172,7 @@ private: | |||
172 | rule ChainItem; | 172 | rule ChainItem; |
173 | rule chain_line; | 173 | rule chain_line; |
174 | rule chain_block; | 174 | rule chain_block; |
175 | rule meta_index; | ||
175 | rule Index; | 176 | rule Index; |
176 | rule invoke_chain; | 177 | rule invoke_chain; |
177 | rule TableValue; | 178 | rule TableValue; |