aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2025-09-15 18:20:15 +0800
committerLi Jin <dragon-fly@qq.com>2025-09-15 18:20:15 +0800
commit55149f8864c6c3e1c1fff9268384f8302dc5488d (patch)
tree83dcb6ce5d1eb17294ec9032e807d1ad0120d008
parentf7269a635e31e075c45ec9d10e4c1df5cf9f8a33 (diff)
downloadyuescript-55149f8864c6c3e1c1fff9268384f8302dc5488d.tar.gz
yuescript-55149f8864c6c3e1c1fff9268384f8302dc5488d.tar.bz2
yuescript-55149f8864c6c3e1c1fff9268384f8302dc5488d.zip
Fixed issue for reversed indexing.
-rwxr-xr-xdoc/docs/doc/README.md2
-rwxr-xr-xdoc/docs/zh/doc/README.md2
-rw-r--r--spec/inputs/lists.yue133
-rw-r--r--spec/outputs/codes_from_doc.lua4
-rw-r--r--spec/outputs/codes_from_doc_zh.lua4
-rw-r--r--spec/outputs/lists.lua339
-rw-r--r--src/yuescript/yue_compiler.cpp83
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
642last = data.items[#] 642last = data.items[#]
643second_last = data.items[#-1] 643second_last = data.items[#-1]
644data.items[#] = 1
644``` 645```
645<YueDisplay> 646<YueDisplay>
646<pre> 647<pre>
647last = data.items[#] 648last = data.items[#]
648second_last = data.items[#-1] 649second_last = data.items[#-1]
650data.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
641last = data.items[#] 641last = data.items[#]
642second_last = data.items[#-1] 642second_last = data.items[#-1]
643data.items[#] = 1
643``` 644```
644<YueDisplay> 645<YueDisplay>
645<pre> 646<pre>
646last = data.items[#] 647last = data.items[#]
647second_last = data.items[#-1] 648second_last = data.items[#-1]
649data.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
137do
138 tb = [1, 2, 3]
139 tb[#] = 40
140 tb[# - 1] = 20
141
142do
143 a = b = c = "x"
144 lst = []
145 lst[#] = a
146 lst[# - 1] = b
147
148do
149 x, y, z = 1, 2, 3
150 arr = []
151 arr[#], head = x, y
152 arr[#] = z
153
154do
155 triple = ["keep", "skip", "tail"]
156 [head, _, tailv] = triple
157 buf = []
158 buf[#] = head
159 buf[#] = tailv
160
161do
162 src = ["a", "", "c", nil, "d"]
163 collected = []
164 for item in *src
165 if item and #item > 0
166 collected[#] = item
167
168do
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
174do
175 store = []
176 store[#] = { meta: { id: 1, ok: true }, payload: [10, 20] }
177 store[#] = { meta: { id: 1, ok: false }, payload: [10, 20, 30] }
178
179do
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
186do
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
194do
195 cfg = {mode: "safe", tags: []}
196 if cfg.mode == "safe"
197 cfg.mode = "fast"
198 cfg.tags[#] = "newbie"
199
200do
201 mat = [ [1,2], [3,4], [5,6]]
202 last_row = mat[#]
203 rows = []
204 rows[#] = last_row[1]
205
206do
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
215do
216 base = [ i for i = 1, 4 ]
217 pack = []
218 pack[#] = [ base[1], base[#] ]
219 pack[#] = { first: base[1], last: base[#] }
220
221do
222 opts = {limit: 10}
223 {:limit, :offset = 0} = opts
224 pages = []
225 pages[#] = {limit: limit, offset: offset}
226
227do
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
234do
235 node = {left: {v:0}, right: {v:0}}
236 bag = []
237 { :left, :right } = node
238 bag[#], left.v, right.v = "k", 1, 2
239
240do
241 a1, a2, a3 = 100, 200, 300
242 mix = []
243 mix[#], mix[#], meta = a1, a2, {tag: "ok"}
244
245do
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
251do
252 ret2 = ()-> 7, 8
253 box = []
254 box[#], x1 = ret2!
255
256do
257 q = [1, 2]
258 lastq = q[#]
259 q[# - 1] = lastq * 10
260
261do
262 mat2 = [[9,8], [7,6]]
263 t = { hold: nil }
264 t.hold = mat2[#][1]
265
266do
267 f = -> globalTB[#][#] = 1
268 f1 = -> globalTB[#][# - 1]
269
137nil 270nil
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]
227end 227end
228local _obj_0 = data.items
229_obj_0[#_obj_0] = 1
228local mt = { } 230local mt = { }
229local add 231local add
230add = function(self, right) 232add = 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]
2666end 2668end
2669local _obj_0 = data.items
2670_obj_0[#_obj_0] = 1
2667local mt = { } 2671local mt = { }
2668local add 2672local add
2669add = function(self, right) 2673add = 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]
227end 227end
228local _obj_0 = data.items
229_obj_0[#_obj_0] = 1
228local mt = { } 230local mt = { }
229local add 231local add
230add = function(self, right) 232add = 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]
2660end 2662end
2663local _obj_0 = data.items
2664_obj_0[#_obj_0] = 1
2661local mt = { } 2665local mt = { }
2662local add 2666local add
2663add = function(self, right) 2667add = 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)())
471end 471end
472local _anon_func_0 = function(globalTB) 472local _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)
476end 479end
477local _anon_func_1 = function(a) 480local _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
524end 527end
528do
529 local tb = {
530 1,
531 2,
532 3
533 }
534 tb[#tb] = 40
535 tb[#tb - 1] = 20
536end
537do
538 a = "x"
539 b = a
540 c = a
541 local lst = { }
542 lst[#lst] = a
543 lst[#lst - 1] = b
544end
545do
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
552end
553do
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
563end
564do
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
579end
580do
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]
603end
604do
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 }
627end
628local _anon_func_3 = function(tb)
629 local _item_0 = tb.tmp
630 return _item_0[#_item_0]
631end
632do
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
652end
653do
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 }
669end
670do
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
680end
681do
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]
699end
700do
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
714end
715do
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 }
735end
736do
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 }
749end
750do
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 }
776end
777do
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
789end
790do
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 }
797end
798do
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
814end
815do
816 local ret2
817 ret2 = function()
818 return 7, 8
819 end
820 local box = { }
821 local x1
822 box[#box], x1 = ret2()
823end
824do
825 local q = {
826 1,
827 2
828 }
829 local lastq = q[#q]
830 q[#q - 1] = lastq * 10
831end
832do
833 local mat2 = [[9,8], [7,6]]
834 local t = {
835 hold = nil
836 }
837 t.hold = mat2[#mat2][1]
838end
839do
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
859end
525return nil 860return 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
81const std::string_view version = "0.29.4"sv; 81const std::string_view version = "0.29.5"sv;
82const std::string_view extension = "yue"sv; 82const std::string_view extension = "yue"sv;
83 83
84class CompileError : public std::logic_error { 84class 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 }