diff options
| author | Li Jin <dragon-fly@qq.com> | 2025-09-15 18:20:15 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2025-09-15 18:20:15 +0800 |
| commit | 55149f8864c6c3e1c1fff9268384f8302dc5488d (patch) | |
| tree | 83dcb6ce5d1eb17294ec9032e807d1ad0120d008 | |
| parent | f7269a635e31e075c45ec9d10e4c1df5cf9f8a33 (diff) | |
| download | yuescript-55149f8864c6c3e1c1fff9268384f8302dc5488d.tar.gz yuescript-55149f8864c6c3e1c1fff9268384f8302dc5488d.tar.bz2 yuescript-55149f8864c6c3e1c1fff9268384f8302dc5488d.zip | |
Fixed issue for reversed indexing.
| -rwxr-xr-x | doc/docs/doc/README.md | 2 | ||||
| -rwxr-xr-x | doc/docs/zh/doc/README.md | 2 | ||||
| -rw-r--r-- | spec/inputs/lists.yue | 133 | ||||
| -rw-r--r-- | spec/outputs/codes_from_doc.lua | 4 | ||||
| -rw-r--r-- | spec/outputs/codes_from_doc_zh.lua | 4 | ||||
| -rw-r--r-- | spec/outputs/lists.lua | 339 | ||||
| -rw-r--r-- | src/yuescript/yue_compiler.cpp | 83 |
7 files changed, 557 insertions, 10 deletions
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/README.md index 57f27c8..5c26dac 100755 --- a/doc/docs/doc/README.md +++ b/doc/docs/doc/README.md | |||
| @@ -641,11 +641,13 @@ You can use the **#** operator to get the last elements of a table. | |||
| 641 | ```moonscript | 641 | ```moonscript |
| 642 | last = data.items[#] | 642 | last = data.items[#] |
| 643 | second_last = data.items[#-1] | 643 | second_last = data.items[#-1] |
| 644 | data.items[#] = 1 | ||
| 644 | ``` | 645 | ``` |
| 645 | <YueDisplay> | 646 | <YueDisplay> |
| 646 | <pre> | 647 | <pre> |
| 647 | last = data.items[#] | 648 | last = data.items[#] |
| 648 | second_last = data.items[#-1] | 649 | second_last = data.items[#-1] |
| 650 | data.items[#] = 1 | ||
| 649 | </pre> | 651 | </pre> |
| 650 | </YueDisplay> | 652 | </YueDisplay> |
| 651 | 653 | ||
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md index 5cfe4e6..29cd032 100755 --- a/doc/docs/zh/doc/README.md +++ b/doc/docs/zh/doc/README.md | |||
| @@ -640,11 +640,13 @@ merge = {...a, ...b} | |||
| 640 | ```moonscript | 640 | ```moonscript |
| 641 | last = data.items[#] | 641 | last = data.items[#] |
| 642 | second_last = data.items[#-1] | 642 | second_last = data.items[#-1] |
| 643 | data.items[#] = 1 | ||
| 643 | ``` | 644 | ``` |
| 644 | <YueDisplay> | 645 | <YueDisplay> |
| 645 | <pre> | 646 | <pre> |
| 646 | last = data.items[#] | 647 | last = data.items[#] |
| 647 | second_last = data.items[#-1] | 648 | second_last = data.items[#-1] |
| 649 | data.items[#] = 1 | ||
| 648 | </pre> | 650 | </pre> |
| 649 | </YueDisplay> | 651 | </YueDisplay> |
| 650 | 652 | ||
diff --git a/spec/inputs/lists.yue b/spec/inputs/lists.yue index c493b68..f754cc1 100644 --- a/spec/inputs/lists.yue +++ b/spec/inputs/lists.yue | |||
| @@ -134,4 +134,137 @@ do | |||
| 134 | x?\y?!.z?[# - 3]?[, -3] | 134 | x?\y?!.z?[# - 3]?[, -3] |
| 135 | ) | 135 | ) |
| 136 | 136 | ||
| 137 | do | ||
| 138 | tb = [1, 2, 3] | ||
| 139 | tb[#] = 40 | ||
| 140 | tb[# - 1] = 20 | ||
| 141 | |||
| 142 | do | ||
| 143 | a = b = c = "x" | ||
| 144 | lst = [] | ||
| 145 | lst[#] = a | ||
| 146 | lst[# - 1] = b | ||
| 147 | |||
| 148 | do | ||
| 149 | x, y, z = 1, 2, 3 | ||
| 150 | arr = [] | ||
| 151 | arr[#], head = x, y | ||
| 152 | arr[#] = z | ||
| 153 | |||
| 154 | do | ||
| 155 | triple = ["keep", "skip", "tail"] | ||
| 156 | [head, _, tailv] = triple | ||
| 157 | buf = [] | ||
| 158 | buf[#] = head | ||
| 159 | buf[#] = tailv | ||
| 160 | |||
| 161 | do | ||
| 162 | src = ["a", "", "c", nil, "d"] | ||
| 163 | collected = [] | ||
| 164 | for item in *src | ||
| 165 | if item and #item > 0 | ||
| 166 | collected[#] = item | ||
| 167 | |||
| 168 | do | ||
| 169 | nums = [1, 2, 3, 4, 5] | ||
| 170 | last_two = [v for v in *nums when v > 3] | ||
| 171 | nums[#] = last_two[1] | ||
| 172 | nums[#] = last_two[2] | ||
| 173 | |||
| 174 | do | ||
| 175 | store = [] | ||
| 176 | store[#] = { meta: { id: 1, ok: true }, payload: [10, 20] } | ||
| 177 | store[#] = { meta: { id: 1, ok: false }, payload: [10, 20, 30] } | ||
| 178 | |||
| 179 | do | ||
| 180 | f = -> | ||
| 181 | q = [] | ||
| 182 | tb.tmp = [n for n = 1, 4] | ||
| 183 | if #tb.tmp >= 3 | ||
| 184 | q[#] = {head: tb.tmp[1], tail: tb.tmp[#]} | ||
| 185 | |||
| 186 | do | ||
| 187 | make_pair = (a, b) -> [a, b] | ||
| 188 | pairs = [] | ||
| 189 | p1 = make_pair 7, 8 | ||
| 190 | pairs[#] = p1 | ||
| 191 | k, v = "key", 42 | ||
| 192 | pairs[#] = {k: k, v: v} | ||
| 193 | |||
| 194 | do | ||
| 195 | cfg = {mode: "safe", tags: []} | ||
| 196 | if cfg.mode == "safe" | ||
| 197 | cfg.mode = "fast" | ||
| 198 | cfg.tags[#] = "newbie" | ||
| 199 | |||
| 200 | do | ||
| 201 | mat = [ [1,2], [3,4], [5,6]] | ||
| 202 | last_row = mat[#] | ||
| 203 | rows = [] | ||
| 204 | rows[#] = last_row[1] | ||
| 205 | |||
| 206 | do | ||
| 207 | kv = [] | ||
| 208 | kv[#] = {k: "a", v: 1} | ||
| 209 | kv[#] = {k: "b", v: 2} | ||
| 210 | pair_last = kv[#] | ||
| 211 | dict = {} | ||
| 212 | dict[pair_last.k] = pair_last.v | ||
| 213 | dict[pair_last.k] = 3 | ||
| 214 | |||
| 215 | do | ||
| 216 | base = [ i for i = 1, 4 ] | ||
| 217 | pack = [] | ||
| 218 | pack[#] = [ base[1], base[#] ] | ||
| 219 | pack[#] = { first: base[1], last: base[#] } | ||
| 220 | |||
| 221 | do | ||
| 222 | opts = {limit: 10} | ||
| 223 | {:limit, :offset = 0} = opts | ||
| 224 | pages = [] | ||
| 225 | pages[#] = {limit: limit, offset: offset} | ||
| 226 | |||
| 227 | do | ||
| 228 | chain = { a: { b: { c: 0 } }, list: [ {x:0}, {x:0} ] } | ||
| 229 | chain.a.b.c = 1 | ||
| 230 | chain.list[1].x = 10 | ||
| 231 | chain.list[#].x = 20 | ||
| 232 | chain.list[# - 1] = { x: 30 } | ||
| 233 | |||
| 234 | do | ||
| 235 | node = {left: {v:0}, right: {v:0}} | ||
| 236 | bag = [] | ||
| 237 | { :left, :right } = node | ||
| 238 | bag[#], left.v, right.v = "k", 1, 2 | ||
| 239 | |||
| 240 | do | ||
| 241 | a1, a2, a3 = 100, 200, 300 | ||
| 242 | mix = [] | ||
| 243 | mix[#], mix[#], meta = a1, a2, {tag: "ok"} | ||
| 244 | |||
| 245 | do | ||
| 246 | cfg2 = {limit: 5, opts: {flag: false}} | ||
| 247 | {limit: lim, opts: opt2} = cfg2 | ||
| 248 | bucket = {xs: []} | ||
| 249 | bucket.xs[#], bucket.flag, opt2.flags[] = lim, true, 123 | ||
| 250 | |||
| 251 | do | ||
| 252 | ret2 = ()-> 7, 8 | ||
| 253 | box = [] | ||
| 254 | box[#], x1 = ret2! | ||
| 255 | |||
| 256 | do | ||
| 257 | q = [1, 2] | ||
| 258 | lastq = q[#] | ||
| 259 | q[# - 1] = lastq * 10 | ||
| 260 | |||
| 261 | do | ||
| 262 | mat2 = [[9,8], [7,6]] | ||
| 263 | t = { hold: nil } | ||
| 264 | t.hold = mat2[#][1] | ||
| 265 | |||
| 266 | do | ||
| 267 | f = -> globalTB[#][#] = 1 | ||
| 268 | f1 = -> globalTB[#][# - 1] | ||
| 269 | |||
| 137 | nil | 270 | nil |
diff --git a/spec/outputs/codes_from_doc.lua b/spec/outputs/codes_from_doc.lua index 055e79b..b25753d 100644 --- a/spec/outputs/codes_from_doc.lua +++ b/spec/outputs/codes_from_doc.lua | |||
| @@ -225,6 +225,8 @@ do | |||
| 225 | local _item_0 = data.items | 225 | local _item_0 = data.items |
| 226 | second_last = _item_0[#_item_0 - 1] | 226 | second_last = _item_0[#_item_0 - 1] |
| 227 | end | 227 | end |
| 228 | local _obj_0 = data.items | ||
| 229 | _obj_0[#_obj_0] = 1 | ||
| 228 | local mt = { } | 230 | local mt = { } |
| 229 | local add | 231 | local add |
| 230 | add = function(self, right) | 232 | add = function(self, right) |
| @@ -2664,6 +2666,8 @@ do | |||
| 2664 | local _item_0 = data.items | 2666 | local _item_0 = data.items |
| 2665 | second_last = _item_0[#_item_0 - 1] | 2667 | second_last = _item_0[#_item_0 - 1] |
| 2666 | end | 2668 | end |
| 2669 | local _obj_0 = data.items | ||
| 2670 | _obj_0[#_obj_0] = 1 | ||
| 2667 | local mt = { } | 2671 | local mt = { } |
| 2668 | local add | 2672 | local add |
| 2669 | add = function(self, right) | 2673 | add = function(self, right) |
diff --git a/spec/outputs/codes_from_doc_zh.lua b/spec/outputs/codes_from_doc_zh.lua index de76829..e70c20c 100644 --- a/spec/outputs/codes_from_doc_zh.lua +++ b/spec/outputs/codes_from_doc_zh.lua | |||
| @@ -225,6 +225,8 @@ do | |||
| 225 | local _item_0 = data.items | 225 | local _item_0 = data.items |
| 226 | second_last = _item_0[#_item_0 - 1] | 226 | second_last = _item_0[#_item_0 - 1] |
| 227 | end | 227 | end |
| 228 | local _obj_0 = data.items | ||
| 229 | _obj_0[#_obj_0] = 1 | ||
| 228 | local mt = { } | 230 | local mt = { } |
| 229 | local add | 231 | local add |
| 230 | add = function(self, right) | 232 | add = function(self, right) |
| @@ -2658,6 +2660,8 @@ do | |||
| 2658 | local _item_0 = data.items | 2660 | local _item_0 = data.items |
| 2659 | second_last = _item_0[#_item_0 - 1] | 2661 | second_last = _item_0[#_item_0 - 1] |
| 2660 | end | 2662 | end |
| 2663 | local _obj_0 = data.items | ||
| 2664 | _obj_0[#_obj_0] = 1 | ||
| 2661 | local mt = { } | 2665 | local mt = { } |
| 2662 | local add | 2666 | local add |
| 2663 | add = function(self, right) | 2667 | add = function(self, right) |
diff --git a/spec/outputs/lists.lua b/spec/outputs/lists.lua index 2ed7b95..2dd19e5 100644 --- a/spec/outputs/lists.lua +++ b/spec/outputs/lists.lua | |||
| @@ -470,8 +470,11 @@ do | |||
| 470 | end)()) | 470 | end)()) |
| 471 | end | 471 | end |
| 472 | local _anon_func_0 = function(globalTB) | 472 | local _anon_func_0 = function(globalTB) |
| 473 | local _item_0 = globalTB | 473 | local _call_0 |
| 474 | local _call_0 = _item_0[#_item_0] | 474 | do |
| 475 | local _item_0 = globalTB | ||
| 476 | _call_0 = _item_0[#_item_0] | ||
| 477 | end | ||
| 475 | return _call_0["end"](_call_0, 123) | 478 | return _call_0["end"](_call_0, 123) |
| 476 | end | 479 | end |
| 477 | local _anon_func_1 = function(a) | 480 | local _anon_func_1 = function(a) |
| @@ -522,4 +525,336 @@ do | |||
| 522 | return print(_anon_func_0(globalTB), _anon_func_1(a), _anon_func_2(x)) | 525 | return print(_anon_func_0(globalTB), _anon_func_1(a), _anon_func_2(x)) |
| 523 | end | 526 | end |
| 524 | end | 527 | end |
| 528 | do | ||
| 529 | local tb = { | ||
| 530 | 1, | ||
| 531 | 2, | ||
| 532 | 3 | ||
| 533 | } | ||
| 534 | tb[#tb] = 40 | ||
| 535 | tb[#tb - 1] = 20 | ||
| 536 | end | ||
| 537 | do | ||
| 538 | a = "x" | ||
| 539 | b = a | ||
| 540 | c = a | ||
| 541 | local lst = { } | ||
| 542 | lst[#lst] = a | ||
| 543 | lst[#lst - 1] = b | ||
| 544 | end | ||
| 545 | do | ||
| 546 | local y, z | ||
| 547 | x, y, z = 1, 2, 3 | ||
| 548 | local arr = { } | ||
| 549 | local head | ||
| 550 | arr[#arr], head = x, y | ||
| 551 | arr[#arr] = z | ||
| 552 | end | ||
| 553 | do | ||
| 554 | local triple = { | ||
| 555 | "keep", | ||
| 556 | "skip", | ||
| 557 | "tail" | ||
| 558 | } | ||
| 559 | local head, tailv = triple[1], triple[3] | ||
| 560 | local buf = { } | ||
| 561 | buf[#buf] = head | ||
| 562 | buf[#buf] = tailv | ||
| 563 | end | ||
| 564 | do | ||
| 565 | local src = { | ||
| 566 | "a", | ||
| 567 | "", | ||
| 568 | "c", | ||
| 569 | nil, | ||
| 570 | "d" | ||
| 571 | } | ||
| 572 | local collected = { } | ||
| 573 | for _index_0 = 1, #src do | ||
| 574 | local item = src[_index_0] | ||
| 575 | if item and #item > 0 then | ||
| 576 | collected[#collected] = item | ||
| 577 | end | ||
| 578 | end | ||
| 579 | end | ||
| 580 | do | ||
| 581 | local nums = { | ||
| 582 | 1, | ||
| 583 | 2, | ||
| 584 | 3, | ||
| 585 | 4, | ||
| 586 | 5 | ||
| 587 | } | ||
| 588 | local last_two | ||
| 589 | do | ||
| 590 | local _accum_0 = { } | ||
| 591 | local _len_0 = 1 | ||
| 592 | for _index_0 = 1, #nums do | ||
| 593 | local v = nums[_index_0] | ||
| 594 | if v > 3 then | ||
| 595 | _accum_0[_len_0] = v | ||
| 596 | _len_0 = _len_0 + 1 | ||
| 597 | end | ||
| 598 | end | ||
| 599 | last_two = _accum_0 | ||
| 600 | end | ||
| 601 | nums[#nums] = last_two[1] | ||
| 602 | nums[#nums] = last_two[2] | ||
| 603 | end | ||
| 604 | do | ||
| 605 | local store = { } | ||
| 606 | store[#store] = { | ||
| 607 | meta = { | ||
| 608 | id = 1, | ||
| 609 | ok = true | ||
| 610 | }, | ||
| 611 | payload = { | ||
| 612 | 10, | ||
| 613 | 20 | ||
| 614 | } | ||
| 615 | } | ||
| 616 | store[#store] = { | ||
| 617 | meta = { | ||
| 618 | id = 1, | ||
| 619 | ok = false | ||
| 620 | }, | ||
| 621 | payload = { | ||
| 622 | 10, | ||
| 623 | 20, | ||
| 624 | 30 | ||
| 625 | } | ||
| 626 | } | ||
| 627 | end | ||
| 628 | local _anon_func_3 = function(tb) | ||
| 629 | local _item_0 = tb.tmp | ||
| 630 | return _item_0[#_item_0] | ||
| 631 | end | ||
| 632 | do | ||
| 633 | local f | ||
| 634 | f = function() | ||
| 635 | local q = { } | ||
| 636 | do | ||
| 637 | local _accum_0 = { } | ||
| 638 | local _len_0 = 1 | ||
| 639 | for n = 1, 4 do | ||
| 640 | _accum_0[_len_0] = n | ||
| 641 | _len_0 = _len_0 + 1 | ||
| 642 | end | ||
| 643 | tb.tmp = _accum_0 | ||
| 644 | end | ||
| 645 | if #tb.tmp >= 3 then | ||
| 646 | q[#q] = { | ||
| 647 | head = tb.tmp[1], | ||
| 648 | tail = _anon_func_3(tb) | ||
| 649 | } | ||
| 650 | end | ||
| 651 | end | ||
| 652 | end | ||
| 653 | do | ||
| 654 | local make_pair | ||
| 655 | make_pair = function(a, b) | ||
| 656 | return { | ||
| 657 | a, | ||
| 658 | b | ||
| 659 | } | ||
| 660 | end | ||
| 661 | local pairs = { } | ||
| 662 | local p1 = make_pair(7, 8) | ||
| 663 | pairs[#pairs] = p1 | ||
| 664 | local k, v = "key", 42 | ||
| 665 | pairs[#pairs] = { | ||
| 666 | k = k, | ||
| 667 | v = v | ||
| 668 | } | ||
| 669 | end | ||
| 670 | do | ||
| 671 | local cfg = { | ||
| 672 | mode = "safe", | ||
| 673 | tags = { } | ||
| 674 | } | ||
| 675 | if cfg.mode == "safe" then | ||
| 676 | cfg.mode = "fast" | ||
| 677 | local _obj_0 = cfg.tags | ||
| 678 | _obj_0[#_obj_0] = "newbie" | ||
| 679 | end | ||
| 680 | end | ||
| 681 | do | ||
| 682 | local mat = { | ||
| 683 | { | ||
| 684 | 1, | ||
| 685 | 2 | ||
| 686 | }, | ||
| 687 | { | ||
| 688 | 3, | ||
| 689 | 4 | ||
| 690 | }, | ||
| 691 | { | ||
| 692 | 5, | ||
| 693 | 6 | ||
| 694 | } | ||
| 695 | } | ||
| 696 | local last_row = mat[#mat] | ||
| 697 | local rows = { } | ||
| 698 | rows[#rows] = last_row[1] | ||
| 699 | end | ||
| 700 | do | ||
| 701 | local kv = { } | ||
| 702 | kv[#kv] = { | ||
| 703 | k = "a", | ||
| 704 | v = 1 | ||
| 705 | } | ||
| 706 | kv[#kv] = { | ||
| 707 | k = "b", | ||
| 708 | v = 2 | ||
| 709 | } | ||
| 710 | local pair_last = kv[#kv] | ||
| 711 | local dict = { } | ||
| 712 | dict[pair_last.k] = pair_last.v | ||
| 713 | dict[pair_last.k] = 3 | ||
| 714 | end | ||
| 715 | do | ||
| 716 | local base | ||
| 717 | do | ||
| 718 | local _accum_0 = { } | ||
| 719 | local _len_0 = 1 | ||
| 720 | for i = 1, 4 do | ||
| 721 | _accum_0[_len_0] = i | ||
| 722 | _len_0 = _len_0 + 1 | ||
| 723 | end | ||
| 724 | base = _accum_0 | ||
| 725 | end | ||
| 726 | local pack = { } | ||
| 727 | pack[#pack] = { | ||
| 728 | base[1], | ||
| 729 | base[#base] | ||
| 730 | } | ||
| 731 | pack[#pack] = { | ||
| 732 | first = base[1], | ||
| 733 | last = base[#base] | ||
| 734 | } | ||
| 735 | end | ||
| 736 | do | ||
| 737 | local opts = { | ||
| 738 | limit = 10 | ||
| 739 | } | ||
| 740 | local limit, offset = opts.limit, opts.offset | ||
| 741 | if offset == nil then | ||
| 742 | offset = 0 | ||
| 743 | end | ||
| 744 | local pages = { } | ||
| 745 | pages[#pages] = { | ||
| 746 | limit = limit, | ||
| 747 | offset = offset | ||
| 748 | } | ||
| 749 | end | ||
| 750 | do | ||
| 751 | local chain = { | ||
| 752 | a = { | ||
| 753 | b = { | ||
| 754 | c = 0 | ||
| 755 | } | ||
| 756 | }, | ||
| 757 | list = { | ||
| 758 | { | ||
| 759 | x = 0 | ||
| 760 | }, | ||
| 761 | { | ||
| 762 | x = 0 | ||
| 763 | } | ||
| 764 | } | ||
| 765 | } | ||
| 766 | chain.a.b.c = 1 | ||
| 767 | chain.list[1].x = 10; | ||
| 768 | ((function() | ||
| 769 | local _item_0 = chain.list | ||
| 770 | return _item_0[#_item_0] | ||
| 771 | end)()).x = 20 | ||
| 772 | local _obj_0 = chain.list | ||
| 773 | _obj_0[#_obj_0 - 1] = { | ||
| 774 | x = 30 | ||
| 775 | } | ||
| 776 | end | ||
| 777 | do | ||
| 778 | local node = { | ||
| 779 | left = { | ||
| 780 | v = 0 | ||
| 781 | }, | ||
| 782 | right = { | ||
| 783 | v = 0 | ||
| 784 | } | ||
| 785 | } | ||
| 786 | local bag = { } | ||
| 787 | local left, right = node.left, node.right | ||
| 788 | bag[#bag], left.v, right.v = "k", 1, 2 | ||
| 789 | end | ||
| 790 | do | ||
| 791 | local a1, a2, a3 = 100, 200, 300 | ||
| 792 | local mix = { } | ||
| 793 | local meta | ||
| 794 | mix[#mix], mix[#mix], meta = a1, a2, { | ||
| 795 | tag = "ok" | ||
| 796 | } | ||
| 797 | end | ||
| 798 | do | ||
| 799 | local cfg2 = { | ||
| 800 | limit = 5, | ||
| 801 | opts = { | ||
| 802 | flag = false | ||
| 803 | } | ||
| 804 | } | ||
| 805 | local lim, opt2 = cfg2.limit, cfg2.opts | ||
| 806 | local bucket = { | ||
| 807 | xs = { } | ||
| 808 | } | ||
| 809 | local _obj_0 = bucket.xs | ||
| 810 | _obj_0[#_obj_0] = lim | ||
| 811 | bucket.flag = true | ||
| 812 | local _obj_1 = opt2.flags | ||
| 813 | _obj_1[#_obj_1 + 1] = 123 | ||
| 814 | end | ||
| 815 | do | ||
| 816 | local ret2 | ||
| 817 | ret2 = function() | ||
| 818 | return 7, 8 | ||
| 819 | end | ||
| 820 | local box = { } | ||
| 821 | local x1 | ||
| 822 | box[#box], x1 = ret2() | ||
| 823 | end | ||
| 824 | do | ||
| 825 | local q = { | ||
| 826 | 1, | ||
| 827 | 2 | ||
| 828 | } | ||
| 829 | local lastq = q[#q] | ||
| 830 | q[#q - 1] = lastq * 10 | ||
| 831 | end | ||
| 832 | do | ||
| 833 | local mat2 = [[9,8], [7,6]] | ||
| 834 | local t = { | ||
| 835 | hold = nil | ||
| 836 | } | ||
| 837 | t.hold = mat2[#mat2][1] | ||
| 838 | end | ||
| 839 | do | ||
| 840 | local f | ||
| 841 | f = function() | ||
| 842 | local _obj_0 | ||
| 843 | do | ||
| 844 | local _item_0 = globalTB | ||
| 845 | _obj_0 = _item_0[#_item_0] | ||
| 846 | end | ||
| 847 | _obj_0[#_obj_0] = 1 | ||
| 848 | end | ||
| 849 | local f1 | ||
| 850 | f1 = function() | ||
| 851 | do | ||
| 852 | local _item_0 = globalTB | ||
| 853 | do | ||
| 854 | local _item_1 = _item_0[#_item_0] | ||
| 855 | return _item_1[#_item_1 - 1] | ||
| 856 | end | ||
| 857 | end | ||
| 858 | end | ||
| 859 | end | ||
| 525 | return nil | 860 | return nil |
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 33161a7..d7d117a 100644 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp | |||
| @@ -78,7 +78,7 @@ static std::unordered_set<std::string> Metamethods = { | |||
| 78 | "close"s // Lua 5.4 | 78 | "close"s // Lua 5.4 |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | const std::string_view version = "0.29.4"sv; | 81 | const std::string_view version = "0.29.5"sv; |
| 82 | const std::string_view extension = "yue"sv; | 82 | const std::string_view extension = "yue"sv; |
| 83 | 83 | ||
| 84 | class CompileError : public std::logic_error { | 84 | class CompileError : public std::logic_error { |
| @@ -1445,6 +1445,7 @@ private: | |||
| 1445 | case id<DotChainItem_t>(): | 1445 | case id<DotChainItem_t>(): |
| 1446 | case id<Exp_t>(): | 1446 | case id<Exp_t>(): |
| 1447 | case id<TableAppendingOp_t>(): | 1447 | case id<TableAppendingOp_t>(): |
| 1448 | case id<ReversedIndex_t>(): | ||
| 1448 | return true; | 1449 | return true; |
| 1449 | } | 1450 | } |
| 1450 | } | 1451 | } |
| @@ -2254,7 +2255,8 @@ private: | |||
| 2254 | BREAK_IF(!value); | 2255 | BREAK_IF(!value); |
| 2255 | auto chainValue = value->item.as<ChainValue_t>(); | 2256 | auto chainValue = value->item.as<ChainValue_t>(); |
| 2256 | BREAK_IF(!chainValue); | 2257 | BREAK_IF(!chainValue); |
| 2257 | if (auto dot = ast_cast<DotChainItem_t>(chainValue->items.back())) { | 2258 | auto last = chainValue->items.back(); |
| 2259 | if (auto dot = ast_cast<DotChainItem_t>(last)) { | ||
| 2258 | BREAK_IF(!dot->name.is<Metatable_t>()); | 2260 | BREAK_IF(!dot->name.is<Metatable_t>()); |
| 2259 | str_list temp; | 2261 | str_list temp; |
| 2260 | auto [beforeAssignment, afterAssignment] = splitAssignment(); | 2262 | auto [beforeAssignment, afterAssignment] = splitAssignment(); |
| @@ -2285,7 +2287,7 @@ private: | |||
| 2285 | } | 2287 | } |
| 2286 | out.push_back(join(temp)); | 2288 | out.push_back(join(temp)); |
| 2287 | return false; | 2289 | return false; |
| 2288 | } else if (ast_is<TableAppendingOp_t>(chainValue->items.back())) { | 2290 | } else if (ast_is<TableAppendingOp_t>(last)) { |
| 2289 | str_list temp; | 2291 | str_list temp; |
| 2290 | auto [beforeAssignment, afterAssignment] = splitAssignment(); | 2292 | auto [beforeAssignment, afterAssignment] = splitAssignment(); |
| 2291 | if (!beforeAssignment->expList->exprs.empty()) { | 2293 | if (!beforeAssignment->expList->exprs.empty()) { |
| @@ -2337,6 +2339,44 @@ private: | |||
| 2337 | } | 2339 | } |
| 2338 | out.push_back(join(temp)); | 2340 | out.push_back(join(temp)); |
| 2339 | return false; | 2341 | return false; |
| 2342 | } else if (ast_is<ReversedIndex_t>(last)) { | ||
| 2343 | if (chainValue->items.size() == 1) { | ||
| 2344 | if (_withVars.empty()) { | ||
| 2345 | throw CompileError("short dot/colon syntax must be called within a with block"sv, x); | ||
| 2346 | } else { | ||
| 2347 | break; | ||
| 2348 | } | ||
| 2349 | } | ||
| 2350 | auto tmpChain = chainValue->new_ptr<ChainValue_t>(); | ||
| 2351 | tmpChain->items.dup(chainValue->items); | ||
| 2352 | tmpChain->items.pop_back(); | ||
| 2353 | auto tmpLeft = newExp(tmpChain, tmpChain); | ||
| 2354 | auto leftVar = singleVariableFrom(tmpLeft, AccessType::Read); | ||
| 2355 | if (!leftVar.empty() && isLocal(leftVar)) { | ||
| 2356 | break; | ||
| 2357 | } | ||
| 2358 | leftVar = getUnusedName("_obj_"sv); | ||
| 2359 | auto tmpAsmt = assignmentFrom(toAst<Exp_t>(leftVar, tmpLeft), tmpLeft, tmpLeft); | ||
| 2360 | str_list temp; | ||
| 2361 | transformAssignment(tmpAsmt, temp); | ||
| 2362 | auto [beforeAssignment, afterAssignment] = splitAssignment(); | ||
| 2363 | if (!beforeAssignment->expList->exprs.empty()) { | ||
| 2364 | transformAssignment(beforeAssignment, temp); | ||
| 2365 | } | ||
| 2366 | if (vit == values.end()) { | ||
| 2367 | throw CompileError("right value missing"sv, values.front()); | ||
| 2368 | } | ||
| 2369 | auto newChain = chainValue->new_ptr<ChainValue_t>(); | ||
| 2370 | newChain->items.push_back(toAst<Callable_t>(leftVar, newChain)); | ||
| 2371 | newChain->items.push_back(chainValue->items.back()); | ||
| 2372 | auto newLeft = newExp(newChain, newChain); | ||
| 2373 | auto newAsmt = assignmentFrom(newLeft, *vit, newLeft); | ||
| 2374 | transformAssignment(newAsmt, temp); | ||
| 2375 | if (!afterAssignment->expList->exprs.empty()) { | ||
| 2376 | transformAssignment(afterAssignment, temp); | ||
| 2377 | } | ||
| 2378 | out.push_back(join(temp)); | ||
| 2379 | return false; | ||
| 2340 | } else { | 2380 | } else { |
| 2341 | break; | 2381 | break; |
| 2342 | } | 2382 | } |
| @@ -6608,11 +6648,6 @@ private: | |||
| 6608 | indexNode->nilCoalesed.set(rIndex->modifier->nilCoalesed); | 6648 | indexNode->nilCoalesed.set(rIndex->modifier->nilCoalesed); |
| 6609 | } | 6649 | } |
| 6610 | newChain->items.push_back(indexNode); | 6650 | newChain->items.push_back(indexNode); |
| 6611 | auto next = current; | ||
| 6612 | ++next; | ||
| 6613 | for (auto i = next; i != chainList.end(); ++i) { | ||
| 6614 | newChain->items.push_back(*i); | ||
| 6615 | } | ||
| 6616 | auto expList = x->new_ptr<ExpList_t>(); | 6651 | auto expList = x->new_ptr<ExpList_t>(); |
| 6617 | expList->exprs.push_back(newExp(newChain, x)); | 6652 | expList->exprs.push_back(newExp(newChain, x)); |
| 6618 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); | 6653 | auto expListAssign = x->new_ptr<ExpListAssign_t>(); |
| @@ -6627,6 +6662,11 @@ private: | |||
| 6627 | auto doNode = x->new_ptr<Do_t>(); | 6662 | auto doNode = x->new_ptr<Do_t>(); |
| 6628 | doNode->body.set(body); | 6663 | doNode->body.set(body); |
| 6629 | if (usage == ExpUsage::Assignment) { | 6664 | if (usage == ExpUsage::Assignment) { |
| 6665 | auto next = current; | ||
| 6666 | ++next; | ||
| 6667 | for (auto i = next; i != chainList.end(); ++i) { | ||
| 6668 | newChain->items.push_back(*i); | ||
| 6669 | } | ||
| 6630 | auto assignment = x->new_ptr<ExpListAssign_t>(); | 6670 | auto assignment = x->new_ptr<ExpListAssign_t>(); |
| 6631 | assignment->expList.set(assignList); | 6671 | assignment->expList.set(assignList); |
| 6632 | auto assign = x->new_ptr<Assign_t>(); | 6672 | auto assign = x->new_ptr<Assign_t>(); |
| @@ -6637,6 +6677,33 @@ private: | |||
| 6637 | transformAssignment(assignment, out); | 6677 | transformAssignment(assignment, out); |
| 6638 | return; | 6678 | return; |
| 6639 | } | 6679 | } |
| 6680 | if (usage == ExpUsage::Closure) { | ||
| 6681 | auto next = current; | ||
| 6682 | ++next; | ||
| 6683 | if (next != chainList.end()) { | ||
| 6684 | doNode->new_ptr<ChainValue_t>(); | ||
| 6685 | auto dVal = doNode->new_ptr<SimpleValue_t>(); | ||
| 6686 | dVal->value.set(doNode); | ||
| 6687 | auto dExp = newExp(dVal, dVal); | ||
| 6688 | auto dParen = dExp->new_ptr<Parens_t>(); | ||
| 6689 | dParen->extra = true; | ||
| 6690 | dParen->expr.set(dExp); | ||
| 6691 | auto dCallable = dExp->new_ptr<Callable_t>(); | ||
| 6692 | dCallable->item.set(dParen); | ||
| 6693 | auto dChain = doNode->new_ptr<ChainValue_t>(); | ||
| 6694 | dChain->items.push_back(dCallable); | ||
| 6695 | for (auto i = next; i != chainList.end(); ++i) { | ||
| 6696 | dChain->items.push_back(*i); | ||
| 6697 | } | ||
| 6698 | transformExp(newExp(dChain, dExp), out, usage); | ||
| 6699 | return; | ||
| 6700 | } | ||
| 6701 | } | ||
| 6702 | auto next = current; | ||
| 6703 | ++next; | ||
| 6704 | for (auto i = next; i != chainList.end(); ++i) { | ||
| 6705 | newChain->items.push_back(*i); | ||
| 6706 | } | ||
| 6640 | transformDo(doNode, out, usage); | 6707 | transformDo(doNode, out, usage); |
| 6641 | return; | 6708 | return; |
| 6642 | } | 6709 | } |
