aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2022-11-08 10:20:52 +0800
committerLi Jin <dragon-fly@qq.com>2022-11-09 11:29:32 +0800
commitb9b1cf94e1324e344df6f7204c8d479329c56718 (patch)
treeb288f3c48bfd17f673968f101f0f6f886f00c3c9
parent95fd6ea93c2af6fb1707e480669d84ebe37fccbe (diff)
downloadyuescript-b9b1cf94e1324e344df6f7204c8d479329c56718.tar.gz
yuescript-b9b1cf94e1324e344df6f7204c8d479329c56718.tar.bz2
yuescript-b9b1cf94e1324e344df6f7204c8d479329c56718.zip
fix issue #114.
-rw-r--r--spec/inputs/test/class_spec.yue13
-rw-r--r--spec/outputs/class.lua55
-rw-r--r--spec/outputs/test/class_spec.lua186
-rw-r--r--src/yuescript/yue_compiler.cpp16
-rw-r--r--src/yuescript/yue_parser.cpp18
-rw-r--r--src/yuescript/yue_parser.h7
6 files changed, 280 insertions, 15 deletions
diff --git a/spec/inputs/test/class_spec.yue b/spec/inputs/test/class_spec.yue
index df8bc96..4f7af7c 100644
--- a/spec/inputs/test/class_spec.yue
+++ b/spec/inputs/test/class_spec.yue
@@ -293,3 +293,16 @@ describe "class", ->
293 assert.same 1 + 100 + 12, Sub!\value! 293 assert.same 1 + 100 + 12, Sub!\value!
294 assert.same 6, OtherSub!\value! 294 assert.same 6, OtherSub!\value!
295 295
296 it "should copy metamethod from super", ->
297 class A
298 val: 1
299 <tostring>: => "Object #{ @val }"
300
301 class B extends A
302 val: 2
303
304 a, b = A!, B!
305
306 assert.same "Object 1", tostring a
307 assert.same "Object 2", tostring b
308
diff --git a/spec/outputs/class.lua b/spec/outputs/class.lua
index 9a61a67..d13b738 100644
--- a/spec/outputs/class.lua
+++ b/spec/outputs/class.lua
@@ -65,6 +65,11 @@ do
65 local _class_0 65 local _class_0
66 local _parent_0 = Simple 66 local _parent_0 = Simple
67 local _base_0 = { } 67 local _base_0 = { }
68 for _key_0, _val_0 in pairs(_parent_0.__base) do
69 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
70 _base_0[_key_0] = _val_0
71 end
72 end
68 if _base_0.__index == nil then 73 if _base_0.__index == nil then
69 _base_0.__index = _base_0 74 _base_0.__index = _base_0
70 end 75 end
@@ -138,6 +143,11 @@ do
138 return _class_0.__parent.__base.cool(self, 120302) 143 return _class_0.__parent.__base.cool(self, 120302)
139 end 144 end
140 } 145 }
146 for _key_0, _val_0 in pairs(_parent_0.__base) do
147 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
148 _base_0[_key_0] = _val_0
149 end
150 end
141 if _base_0.__index == nil then 151 if _base_0.__index == nil then
142 _base_0.__index = _base_0 152 _base_0.__index = _base_0
143 end 153 end
@@ -211,6 +221,11 @@ do
211 return assert(_class_0.__parent == Okay) 221 return assert(_class_0.__parent == Okay)
212 end 222 end
213 } 223 }
224 for _key_0, _val_0 in pairs(_parent_0.__base) do
225 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
226 _base_0[_key_0] = _val_0
227 end
228 end
214 if _base_0.__index == nil then 229 if _base_0.__index == nil then
215 _base_0.__index = _base_0 230 _base_0.__index = _base_0
216 end 231 end
@@ -311,6 +326,11 @@ do
311 end 326 end
312 end 327 end
313 } 328 }
329 for _key_0, _val_0 in pairs(_parent_0.__base) do
330 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
331 _base_0[_key_0] = _val_0
332 end
333 end
314 if _base_0.__index == nil then 334 if _base_0.__index == nil then
315 _base_0.__index = _base_0 335 _base_0.__index = _base_0
316 end 336 end
@@ -551,6 +571,11 @@ do
551 local _class_0 571 local _class_0
552 local _parent_0 = Hello.World 572 local _parent_0 = Hello.World
553 local _base_0 = { } 573 local _base_0 = { }
574 for _key_0, _val_0 in pairs(_parent_0.__base) do
575 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
576 _base_0[_key_0] = _val_0
577 end
578 end
554 if _base_0.__index == nil then 579 if _base_0.__index == nil then
555 _base_0.__index = _base_0 580 _base_0.__index = _base_0
556 end 581 end
@@ -641,6 +666,11 @@ do
641 local _class_0 666 local _class_0
642 local _parent_0 = Hello 667 local _parent_0 = Hello
643 local _base_0 = { } 668 local _base_0 = { }
669 for _key_0, _val_0 in pairs(_parent_0.__base) do
670 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
671 _base_0[_key_0] = _val_0
672 end
673 end
644 if _base_0.__index == nil then 674 if _base_0.__index == nil then
645 _base_0.__index = _base_0 675 _base_0.__index = _base_0
646 end 676 end
@@ -682,6 +712,11 @@ do
682 local _class_0 712 local _class_0
683 local _parent_0 = World 713 local _parent_0 = World
684 local _base_0 = { } 714 local _base_0 = { }
715 for _key_0, _val_0 in pairs(_parent_0.__base) do
716 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
717 _base_0[_key_0] = _val_0
718 end
719 end
685 if _base_0.__index == nil then 720 if _base_0.__index == nil then
686 _base_0.__index = _base_0 721 _base_0.__index = _base_0
687 end 722 end
@@ -828,6 +863,11 @@ do
828 } 863 }
829 end 864 end
830 } 865 }
866 for _key_0, _val_0 in pairs(_parent_0.__base) do
867 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
868 _base_0[_key_0] = _val_0
869 end
870 end
831 if _base_0.__index == nil then 871 if _base_0.__index == nil then
832 _base_0.__index = _base_0 872 _base_0.__index = _base_0
833 end 873 end
@@ -871,6 +911,11 @@ do
871 return _class_0.__parent.__base.dang(self) 911 return _class_0.__parent.__base.dang(self)
872 end) 912 end)
873 } 913 }
914 for _key_0, _val_0 in pairs(_parent_0.__base) do
915 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
916 _base_0[_key_0] = _val_0
917 end
918 end
874 if _base_0.__index == nil then 919 if _base_0.__index == nil then
875 _base_0.__index = _base_0 920 _base_0.__index = _base_0
876 end 921 end
@@ -910,6 +955,11 @@ do
910 local _class_0 955 local _class_0
911 local _parent_0 = Thing 956 local _parent_0 = Thing
912 local _base_0 = { } 957 local _base_0 = { }
958 for _key_0, _val_0 in pairs(_parent_0.__base) do
959 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
960 _base_0[_key_0] = _val_0
961 end
962 end
913 if _base_0.__index == nil then 963 if _base_0.__index == nil then
914 _base_0.__index = _base_0 964 _base_0.__index = _base_0
915 end 965 end
@@ -1051,6 +1101,11 @@ do
1051 } 1101 }
1052 end 1102 end
1053 } 1103 }
1104 for _key_0, _val_0 in pairs(_parent_0.__base) do
1105 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1106 _base_0[_key_0] = _val_0
1107 end
1108 end
1054 if _base_0.__index == nil then 1109 if _base_0.__index == nil then
1055 _base_0.__index = _base_0 1110 _base_0.__index = _base_0
1056 end 1111 end
diff --git a/spec/outputs/test/class_spec.lua b/spec/outputs/test/class_spec.lua
index b4062e0..e08b5aa 100644
--- a/spec/outputs/test/class_spec.lua
+++ b/spec/outputs/test/class_spec.lua
@@ -129,6 +129,11 @@ return describe("class", function()
129 local _base_0 = { 129 local _base_0 = {
130 color = "green" 130 color = "green"
131 } 131 }
132 for _key_0, _val_0 in pairs(_parent_0.__base) do
133 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
134 _base_0[_key_0] = _val_0
135 end
136 end
132 if _base_0.__index == nil then 137 if _base_0.__index == nil then
133 _base_0.__index = _base_0 138 _base_0.__index = _base_0
134 end 139 end
@@ -195,6 +200,11 @@ return describe("class", function()
195 local _class_0 200 local _class_0
196 local _parent_0 = Base 201 local _parent_0 = Base
197 local _base_0 = { } 202 local _base_0 = { }
203 for _key_0, _val_0 in pairs(_parent_0.__base) do
204 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
205 _base_0[_key_0] = _val_0
206 end
207 end
198 if _base_0.__index == nil then 208 if _base_0.__index == nil then
199 _base_0.__index = _base_0 209 _base_0.__index = _base_0
200 end 210 end
@@ -416,6 +426,11 @@ return describe("class", function()
416 local _class_0 426 local _class_0
417 local _parent_0 = Base 427 local _parent_0 = Base
418 local _base_0 = { } 428 local _base_0 = { }
429 for _key_0, _val_0 in pairs(_parent_0.__base) do
430 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
431 _base_0[_key_0] = _val_0
432 end
433 end
419 if _base_0.__index == nil then 434 if _base_0.__index == nil then
420 _base_0.__index = _base_0 435 _base_0.__index = _base_0
421 end 436 end
@@ -493,6 +508,11 @@ return describe("class", function()
493 return ("%08d"):format(_class_0.__parent.__base.counter(self)) 508 return ("%08d"):format(_class_0.__parent.__base.counter(self))
494 end 509 end
495 } 510 }
511 for _key_0, _val_0 in pairs(_parent_0.__base) do
512 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
513 _base_0[_key_0] = _val_0
514 end
515 end
496 if _base_0.__index == nil then 516 if _base_0.__index == nil then
497 _base_0.__index = _base_0 517 _base_0.__index = _base_0
498 end 518 end
@@ -568,6 +588,11 @@ return describe("class", function()
568 return _class_0.__parent.counter(self) 588 return _class_0.__parent.counter(self)
569 end 589 end
570 } 590 }
591 for _key_0, _val_0 in pairs(_parent_0.__base) do
592 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
593 _base_0[_key_0] = _val_0
594 end
595 end
571 if _base_0.__index == nil then 596 if _base_0.__index == nil then
572 _base_0.__index = _base_0 597 _base_0.__index = _base_0
573 end 598 end
@@ -638,6 +663,11 @@ return describe("class", function()
638 return _class_0.__parent 663 return _class_0.__parent
639 end 664 end
640 } 665 }
666 for _key_0, _val_0 in pairs(_parent_0.__base) do
667 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
668 _base_0[_key_0] = _val_0
669 end
670 end
641 if _base_0.__index == nil then 671 if _base_0.__index == nil then
642 _base_0.__index = _base_0 672 _base_0.__index = _base_0
643 end 673 end
@@ -720,6 +750,11 @@ return describe("class", function()
720 end 750 end
721 end 751 end
722 } 752 }
753 for _key_0, _val_0 in pairs(_parent_0.__base) do
754 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
755 _base_0[_key_0] = _val_0
756 end
757 end
723 if _base_0.__index == nil then 758 if _base_0.__index == nil then
724 _base_0.__index = _base_0 759 _base_0.__index = _base_0
725 end 760 end
@@ -790,6 +825,11 @@ return describe("class", function()
790 local _class_0 825 local _class_0
791 local _parent_0 = Thing 826 local _parent_0 = Thing
792 local _base_0 = { } 827 local _base_0 = { }
828 for _key_0, _val_0 in pairs(_parent_0.__base) do
829 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
830 _base_0[_key_0] = _val_0
831 end
832 end
793 if _base_0.__index == nil then 833 if _base_0.__index == nil then
794 _base_0.__index = _base_0 834 _base_0.__index = _base_0
795 end 835 end
@@ -857,6 +897,11 @@ return describe("class", function()
857 local _class_0 897 local _class_0
858 local _parent_0 = Thing 898 local _parent_0 = Thing
859 local _base_0 = { } 899 local _base_0 = { }
900 for _key_0, _val_0 in pairs(_parent_0.__base) do
901 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
902 _base_0[_key_0] = _val_0
903 end
904 end
860 if _base_0.__index == nil then 905 if _base_0.__index == nil then
861 _base_0.__index = _base_0 906 _base_0.__index = _base_0
862 end 907 end
@@ -969,6 +1014,11 @@ return describe("class", function()
969 return _class_0.__parent 1014 return _class_0.__parent
970 end 1015 end
971 } 1016 }
1017 for _key_0, _val_0 in pairs(_parent_0.__base) do
1018 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1019 _base_0[_key_0] = _val_0
1020 end
1021 end
972 if _base_0.__index == nil then 1022 if _base_0.__index == nil then
973 _base_0.__index = _base_0 1023 _base_0.__index = _base_0
974 end 1024 end
@@ -1050,6 +1100,11 @@ return describe("class", function()
1050 return _class_0.__parent.__base.a(self) + 2 1100 return _class_0.__parent.__base.a(self) + 2
1051 end 1101 end
1052 } 1102 }
1103 for _key_0, _val_0 in pairs(_parent_0.__base) do
1104 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1105 _base_0[_key_0] = _val_0
1106 end
1107 end
1053 if _base_0.__index == nil then 1108 if _base_0.__index == nil then
1054 _base_0.__index = _base_0 1109 _base_0.__index = _base_0
1055 end 1110 end
@@ -1094,6 +1149,11 @@ return describe("class", function()
1094 return _class_0.__parent.__base.a(self) + 3 1149 return _class_0.__parent.__base.a(self) + 3
1095 end 1150 end
1096 } 1151 }
1152 for _key_0, _val_0 in pairs(_parent_0.__base) do
1153 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1154 _base_0[_key_0] = _val_0
1155 end
1156 end
1097 if _base_0.__index == nil then 1157 if _base_0.__index == nil then
1098 _base_0.__index = _base_0 1158 _base_0.__index = _base_0
1099 end 1159 end
@@ -1164,6 +1224,11 @@ return describe("class", function()
1164 local _class_0 1224 local _class_0
1165 local _parent_0 = One 1225 local _parent_0 = One
1166 local _base_0 = { } 1226 local _base_0 = { }
1227 for _key_0, _val_0 in pairs(_parent_0.__base) do
1228 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1229 _base_0[_key_0] = _val_0
1230 end
1231 end
1167 if _base_0.__index == nil then 1232 if _base_0.__index == nil then
1168 _base_0.__index = _base_0 1233 _base_0.__index = _base_0
1169 end 1234 end
@@ -1208,6 +1273,11 @@ return describe("class", function()
1208 return _class_0.__parent.__base.a(self) + 3 1273 return _class_0.__parent.__base.a(self) + 3
1209 end 1274 end
1210 } 1275 }
1276 for _key_0, _val_0 in pairs(_parent_0.__base) do
1277 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1278 _base_0[_key_0] = _val_0
1279 end
1280 end
1211 if _base_0.__index == nil then 1281 if _base_0.__index == nil then
1212 _base_0.__index = _base_0 1282 _base_0.__index = _base_0
1213 end 1283 end
@@ -1252,6 +1322,11 @@ return describe("class", function()
1252 return _class_0.__parent.__base.a(self) + 4 1322 return _class_0.__parent.__base.a(self) + 4
1253 end 1323 end
1254 } 1324 }
1325 for _key_0, _val_0 in pairs(_parent_0.__base) do
1326 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1327 _base_0[_key_0] = _val_0
1328 end
1329 end
1255 if _base_0.__index == nil then 1330 if _base_0.__index == nil then
1256 _base_0.__index = _base_0 1331 _base_0.__index = _base_0
1257 end 1332 end
@@ -1330,6 +1405,11 @@ return describe("class", function()
1330 return _class_0.__parent.__base.doit(self) 1405 return _class_0.__parent.__base.doit(self)
1331 end 1406 end
1332 } 1407 }
1408 for _key_0, _val_0 in pairs(_parent_0.__base) do
1409 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1410 _base_0[_key_0] = _val_0
1411 end
1412 end
1333 if _base_0.__index == nil then 1413 if _base_0.__index == nil then
1334 _base_0.__index = _base_0 1414 _base_0.__index = _base_0
1335 end 1415 end
@@ -1404,6 +1484,11 @@ return describe("class", function()
1404 local _class_0 1484 local _class_0
1405 local _parent_0 = One 1485 local _parent_0 = One
1406 local _base_0 = { } 1486 local _base_0 = { }
1487 for _key_0, _val_0 in pairs(_parent_0.__base) do
1488 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1489 _base_0[_key_0] = _val_0
1490 end
1491 end
1407 if _base_0.__index == nil then 1492 if _base_0.__index == nil then
1408 _base_0.__index = _base_0 1493 _base_0.__index = _base_0
1409 end 1494 end
@@ -1444,6 +1529,11 @@ return describe("class", function()
1444 local _class_0 1529 local _class_0
1445 local _parent_0 = Two 1530 local _parent_0 = Two
1446 local _base_0 = { } 1531 local _base_0 = { }
1532 for _key_0, _val_0 in pairs(_parent_0.__base) do
1533 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1534 _base_0[_key_0] = _val_0
1535 end
1536 end
1447 if _base_0.__index == nil then 1537 if _base_0.__index == nil then
1448 _base_0.__index = _base_0 1538 _base_0.__index = _base_0
1449 end 1539 end
@@ -1488,6 +1578,11 @@ return describe("class", function()
1488 local _class_0 1578 local _class_0
1489 local _parent_0 = Three 1579 local _parent_0 = Three
1490 local _base_0 = { } 1580 local _base_0 = { }
1581 for _key_0, _val_0 in pairs(_parent_0.__base) do
1582 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1583 _base_0[_key_0] = _val_0
1584 end
1585 end
1491 if _base_0.__index == nil then 1586 if _base_0.__index == nil then
1492 _base_0.__index = _base_0 1587 _base_0.__index = _base_0
1493 end 1588 end
@@ -1529,7 +1624,7 @@ return describe("class", function()
1529 end 1624 end
1530 return assert.same(8, Four:a()) 1625 return assert.same(8, Four:a())
1531 end) 1626 end)
1532 return it("super should still work when method wrapped", function() 1627 it("super should still work when method wrapped", function()
1533 local add_some 1628 local add_some
1534 add_some = function(opts) 1629 add_some = function(opts)
1535 return function(self) 1630 return function(self)
@@ -1574,6 +1669,11 @@ return describe("class", function()
1574 end 1669 end
1575 }) 1670 })
1576 } 1671 }
1672 for _key_0, _val_0 in pairs(_parent_0.__base) do
1673 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1674 _base_0[_key_0] = _val_0
1675 end
1676 end
1577 if _base_0.__index == nil then 1677 if _base_0.__index == nil then
1578 _base_0.__index = _base_0 1678 _base_0.__index = _base_0
1579 end 1679 end
@@ -1626,6 +1726,11 @@ return describe("class", function()
1626 end 1726 end
1627 end)() 1727 end)()
1628 } 1728 }
1729 for _key_0, _val_0 in pairs(_parent_0.__base) do
1730 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1731 _base_0[_key_0] = _val_0
1732 end
1733 end
1629 if _base_0.__index == nil then 1734 if _base_0.__index == nil then
1630 _base_0.__index = _base_0 1735 _base_0.__index = _base_0
1631 end 1736 end
@@ -1664,5 +1769,84 @@ return describe("class", function()
1664 assert.same(1 + 100 + 12, Sub():value()) 1769 assert.same(1 + 100 + 12, Sub():value())
1665 return assert.same(6, OtherSub():value()) 1770 return assert.same(6, OtherSub():value())
1666 end) 1771 end)
1772 return it("should copy metamethod from super", function()
1773 local A
1774 do
1775 local _class_0
1776 local _base_0 = {
1777 val = 1,
1778 __tostring = function(self)
1779 return "Object " .. tostring(self.val)
1780 end
1781 }
1782 if _base_0.__index == nil then
1783 _base_0.__index = _base_0
1784 end
1785 _class_0 = setmetatable({
1786 __init = function() end,
1787 __base = _base_0,
1788 __name = "A"
1789 }, {
1790 __index = _base_0,
1791 __call = function(cls, ...)
1792 local _self_0 = setmetatable({ }, _base_0)
1793 cls.__init(_self_0, ...)
1794 return _self_0
1795 end
1796 })
1797 _base_0.__class = _class_0
1798 A = _class_0
1799 end
1800 local B
1801 do
1802 local _class_0
1803 local _parent_0 = A
1804 local _base_0 = {
1805 val = 2
1806 }
1807 for _key_0, _val_0 in pairs(_parent_0.__base) do
1808 if _base_0[_key_0] == nil and _key_0:match("^__") and not (_key_0 == "__index" and _val_0 == _parent_0.__base) then
1809 _base_0[_key_0] = _val_0
1810 end
1811 end
1812 if _base_0.__index == nil then
1813 _base_0.__index = _base_0
1814 end
1815 setmetatable(_base_0, _parent_0.__base)
1816 _class_0 = setmetatable({
1817 __init = function(self, ...)
1818 return _class_0.__parent.__init(self, ...)
1819 end,
1820 __base = _base_0,
1821 __name = "B",
1822 __parent = _parent_0
1823 }, {
1824 __index = function(cls, name)
1825 local val = rawget(_base_0, name)
1826 if val == nil then
1827 local parent = rawget(cls, "__parent")
1828 if parent then
1829 return parent[name]
1830 end
1831 else
1832 return val
1833 end
1834 end,
1835 __call = function(cls, ...)
1836 local _self_0 = setmetatable({ }, _base_0)
1837 cls.__init(_self_0, ...)
1838 return _self_0
1839 end
1840 })
1841 _base_0.__class = _class_0
1842 if _parent_0.__inherited then
1843 _parent_0.__inherited(_parent_0, _class_0)
1844 end
1845 B = _class_0
1846 end
1847 local a, b = A(), B()
1848 assert.same("Object 1", tostring(a))
1849 return assert.same("Object 2", tostring(b))
1850 end)
1667 end) 1851 end)
1668end) 1852end)
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index e061604..d0f2dbb 100644
--- a/src/yuescript/yue_compiler.cpp
+++ b/src/yuescript/yue_compiler.cpp
@@ -14,7 +14,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
14#include <unordered_map> 14#include <unordered_map>
15#include <unordered_set> 15#include <unordered_set>
16#include <vector> 16#include <vector>
17#include <optional>
18 17
19#include "yuescript/yue_compiler.h" 18#include "yuescript/yue_compiler.h"
20#include "yuescript/yue_parser.h" 19#include "yuescript/yue_parser.h"
@@ -60,7 +59,7 @@ namespace yue {
60 59
61typedef std::list<std::string> str_list; 60typedef std::list<std::string> str_list;
62 61
63const std::string_view version = "0.15.8"sv; 62const std::string_view version = "0.15.9"sv;
64const std::string_view extension = "yue"sv; 63const std::string_view extension = "yue"sv;
65 64
66class YueCompilerImpl { 65class YueCompilerImpl {
@@ -2122,7 +2121,8 @@ private:
2122 keyIndex = key; 2121 keyIndex = key;
2123 } else if (auto key = np->key.as<String_t>()) { 2122 } else if (auto key = np->key.as<String_t>()) {
2124 keyIndex = newExp(key, np->key).get(); 2123 keyIndex = newExp(key, np->key).get();
2125 } else throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, np)); 2124 } else
2125 throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, np));
2126 } 2126 }
2127 if (auto exp = np->value.as<Exp_t>()) { 2127 if (auto exp = np->value.as<Exp_t>()) {
2128 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't do destructure value"sv, exp)); 2128 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't do destructure value"sv, exp));
@@ -2211,7 +2211,8 @@ private:
2211 chain->items.push_back(newExp(key, dp)); 2211 chain->items.push_back(newExp(key, dp));
2212 } else if (auto key = dp->key.as<Exp_t>()) { 2212 } else if (auto key = dp->key.as<Exp_t>()) {
2213 chain->items.push_back(key); 2213 chain->items.push_back(key);
2214 } else throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, dp)); 2214 } else
2215 throw std::logic_error(_info.errorMessage("unsupported key for destructuring"sv, dp));
2215 } 2216 }
2216 if (auto exp = dp->value.get()) { 2217 if (auto exp = dp->value.get()) {
2217 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp)); 2218 if (!isAssignable(exp)) throw std::logic_error(_info.errorMessage("can't destructure value"sv, exp));
@@ -6520,6 +6521,13 @@ private:
6520 _buf << "\t\t"sv << baseVar << '[' << key << "]="sv << val << " if "sv << baseVar << '[' << key << "]==nil and (not "sv << cls << " or not "sv << key << "\\match \"^__\")"sv; 6521 _buf << "\t\t"sv << baseVar << '[' << key << "]="sv << val << " if "sv << baseVar << '[' << key << "]==nil and (not "sv << cls << " or not "sv << key << "\\match \"^__\")"sv;
6521 transformBlock(toAst<Block_t>(clearBuf(), x), temp, ExpUsage::Common); 6522 transformBlock(toAst<Block_t>(clearBuf(), x), temp, ExpUsage::Common);
6522 } 6523 }
6524 if (!parentVar.empty()) {
6525 auto key = getUnusedName("_key_"sv);
6526 auto val = getUnusedName("_val_"sv);
6527 _buf << "for "sv << key << ',' << val << " in pairs "sv << parentVar << ".__base"sv << '\n'
6528 << '\t' << baseVar << '[' << key << "]="sv << val << " if "sv << baseVar << '[' << key << "]==nil and "sv << key << "\\match(\"^__\") and not ("sv << key << "==\"__index\" and "sv << val << "=="sv << parentVar << ".__base)"sv;
6529 transformBlock(toAst<Block_t>(clearBuf(), x), temp, ExpUsage::Common);
6530 }
6523 transformAssignment(toAst<ExpListAssign_t>(baseVar + ".__index ?\?= "s + baseVar, classDecl), temp); 6531 transformAssignment(toAst<ExpListAssign_t>(baseVar + ".__index ?\?= "s + baseVar, classDecl), temp);
6524 str_list tmp; 6532 str_list tmp;
6525 if (usage == ExpUsage::Assignment) { 6533 if (usage == ExpUsage::Assignment) {
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index 4aeb79a..e4de0b5 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -71,7 +71,7 @@ YueParser::YueParser() {
71 Cut = false_(); 71 Cut = false_();
72 Seperator = true_(); 72 Seperator = true_();
73 73
74 invalid_empty_block = pl::user(true_(), [](const item_t& item) { 74 empty_block_error = pl::user(true_(), [](const item_t& item) {
75 throw ParserError("must be followed by a statement or an indented block", *item.begin, *item.end); 75 throw ParserError("must be followed by a statement or an indented block", *item.begin, *item.end);
76 return false; 76 return false;
77 }); 77 });
@@ -84,9 +84,9 @@ YueParser::YueParser() {
84 #define disable_chain(patt) (DisableChain >> ((patt) >> EnableChain | EnableChain >> Cut)) 84 #define disable_chain(patt) (DisableChain >> ((patt) >> EnableChain | EnableChain >> Cut))
85 #define disable_do_chain_arg_table_block(patt) (DisableDoChainArgTableBlock >> ((patt) >> EnableDoChainArgTableBlock | EnableDoChainArgTableBlock >> Cut)) 85 #define disable_do_chain_arg_table_block(patt) (DisableDoChainArgTableBlock >> ((patt) >> EnableDoChainArgTableBlock | EnableDoChainArgTableBlock >> Cut))
86 #define disable_arg_table_block(patt) (DisableArgTableBlock >> ((patt) >> EnableArgTableBlock | EnableArgTableBlock >> Cut)) 86 #define disable_arg_table_block(patt) (DisableArgTableBlock >> ((patt) >> EnableArgTableBlock | EnableArgTableBlock >> Cut))
87 #define body_with(str) (Space >> (key(str) >> Space >> (InBlock | Statement) | InBlock | invalid_empty_block)) 87 #define body_with(str) (Space >> (key(str) >> Space >> (InBlock | Statement) | InBlock | empty_block_error))
88 #define opt_body_with(str) (Space >> (key(str) >> Space >> (InBlock | Statement) | InBlock)) 88 #define opt_body_with(str) (Space >> (key(str) >> Space >> (InBlock | Statement) | InBlock))
89 #define body (Space >> (InBlock | Statement | invalid_empty_block)) 89 #define body (Space >> (InBlock | Statement | empty_block_error))
90 90
91 Variable = pl::user(Name, [](const item_t& item) { 91 Variable = pl::user(Name, [](const item_t& item) {
92 State* st = reinterpret_cast<State*>(item.user_data); 92 State* st = reinterpret_cast<State*>(item.user_data);
@@ -630,15 +630,17 @@ YueParser::YueParser() {
630 SpaceBreak >> Advance >> ArgBlock >> -arg_table_block 630 SpaceBreak >> Advance >> ArgBlock >> -arg_table_block
631 ) | arg_table_block; 631 ) | arg_table_block;
632 632
633 leading_spaces_error = pl::user(+space_one >> expr('(') >> Exp >> +(sym(',') >> Exp) >> sym(')'), [](const item_t& item) {
634 throw ParserError("write invoke arguments in parentheses without leading spaces or leading spaces without parentheses", *item.begin, *item.end);
635 return false;
636 });
637
633 InvokeArgs = 638 InvokeArgs =
634 not_(set("-~")) >> Seperator >> 639 not_(set("-~")) >> Seperator >>
635 ( 640 (
636 (Exp >> *(sym(',') >> Exp) >> -invoke_args_with_table) | 641 (Exp >> *(sym(',') >> Exp) >> -invoke_args_with_table) |
637 arg_table_block | 642 arg_table_block |
638 pl::user(+space_one >> expr('(') >> Exp >> +(sym(',') >> Exp) >> sym(')'), [](const item_t& item) { 643 leading_spaces_error
639 throw ParserError("write invoke arguments in parentheses without spaces or space seperated without parentheses", *item.begin, *item.end);
640 return false;
641 })
642 ); 644 );
643 645
644 const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum); 646 const_value = (expr("nil") | expr("true") | expr("false")) >> not_(AlphaNum);
@@ -666,7 +668,7 @@ YueParser::YueParser() {
666 Return | Local | Global | Export | Macro | 668 Return | Local | Global | Export | Macro |
667 MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending | 669 MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending |
668 LocalAttrib | Backcall | PipeBody | ExpListAssign | 670 LocalAttrib | Backcall | PipeBody | ExpListAssign |
669 statement_appendix >> invalid_empty_block 671 statement_appendix >> empty_block_error
670 ) >> Space >> 672 ) >> Space >>
671 -statement_appendix >> -statement_sep; 673 -statement_appendix >> -statement_sep;
672 674
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index 461b381..9e2a621 100644
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -48,7 +48,9 @@ public:
48}; 48};
49 49
50template <typename T> 50template <typename T>
51struct identity { typedef T type; }; 51struct identity {
52 typedef T type;
53};
52 54
53#define AST_RULE(type) \ 55#define AST_RULE(type) \
54 rule type; \ 56 rule type; \
@@ -113,7 +115,8 @@ private:
113 return Cut; 115 return Cut;
114 } 116 }
115 117
116 rule invalid_empty_block; 118 rule empty_block_error;
119 rule leading_spaces_error;
117 120
118 rule num_char; 121 rule num_char;
119 rule num_char_hex; 122 rule num_char_hex;