aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2026-01-26 17:45:26 +0800
committerLi Jin <dragon-fly@qq.com>2026-01-26 17:45:56 +0800
commite02321107277a63e7dcb12ab163c9942ac101b87 (patch)
treef38c6f2fbf4ee35df4938933dbc1e645733356f4
parent5d5b657f606b5939062983b1f90c3359d542672e (diff)
downloadyuescript-e02321107277a63e7dcb12ab163c9942ac101b87.tar.gz
yuescript-e02321107277a63e7dcb12ab163c9942ac101b87.tar.bz2
yuescript-e02321107277a63e7dcb12ab163c9942ac101b87.zip
Updated tests.
-rw-r--r--makefile37
-rw-r--r--spec/inputs/test/attrib_spec.yue12
-rw-r--r--spec/inputs/test/backcall_spec.yue5
-rw-r--r--spec/inputs/test/config_spec.yue2
-rw-r--r--spec/inputs/test/existential_spec.yue4
-rw-r--r--spec/inputs/test/export_spec.yue5
-rw-r--r--spec/inputs/test/goto_spec.yue2
-rw-r--r--spec/inputs/test/import_spec.yue4
-rw-r--r--spec/inputs/test/literals_spec.yue4
-rw-r--r--spec/inputs/test/macro_spec.yue10
-rw-r--r--spec/inputs/test/return_spec.yue4
-rw-r--r--spec/inputs/test/string_spec.yue12
-rw-r--r--spec/inputs/test/switch_spec.yue4
-rw-r--r--spec/inputs/test/try_catch_spec.yue1
-rw-r--r--spec/inputs/test/with_spec.yue23
-rw-r--r--spec/inputs/with.yue5
-rw-r--r--spec/outputs/5.1/test/attrib_spec.lua86
-rw-r--r--spec/outputs/5.1/test/cond_spec.lua237
-rw-r--r--spec/outputs/5.1/test/existential_spec.lua243
-rw-r--r--spec/outputs/5.1/test/export_spec.lua159
-rw-r--r--spec/outputs/5.1/test/goto_spec.lua103
-rw-r--r--spec/outputs/5.1/test/import_spec.lua196
-rw-r--r--spec/outputs/5.1/test/literals_spec.lua90
-rw-r--r--spec/outputs/5.1/test/macro_spec.lua161
-rw-r--r--spec/outputs/5.1/test/metatable_spec.lua141
-rw-r--r--spec/outputs/5.1/test/operators_spec.lua142
-rw-r--r--spec/outputs/5.1/test/return_spec.lua145
-rw-r--r--spec/outputs/5.1/test/string_spec.lua138
-rw-r--r--spec/outputs/5.1/test/switch_spec.lua743
-rw-r--r--spec/outputs/5.1/test/try_catch_spec.lua22
-rw-r--r--spec/outputs/5.1/test/vararg_spec.lua164
-rw-r--r--spec/outputs/5.1/test/with_spec.lua170
-rw-r--r--spec/outputs/test/attrib_spec.lua96
-rw-r--r--spec/outputs/test/backcall_spec.lua64
-rw-r--r--spec/outputs/test/cond_spec.lua237
-rw-r--r--spec/outputs/test/config_spec.lua195
-rw-r--r--spec/outputs/test/existential_spec.lua244
-rw-r--r--spec/outputs/test/export_spec.lua153
-rw-r--r--spec/outputs/test/goto_spec.lua103
-rw-r--r--spec/outputs/test/import_spec.lua196
-rw-r--r--spec/outputs/test/literals_spec.lua90
-rw-r--r--spec/outputs/test/macro_spec.lua166
-rw-r--r--spec/outputs/test/metatable_spec.lua141
-rw-r--r--spec/outputs/test/operators_spec.lua142
-rw-r--r--spec/outputs/test/return_spec.lua147
-rw-r--r--spec/outputs/test/string_spec.lua138
-rw-r--r--spec/outputs/test/switch_spec.lua742
-rw-r--r--spec/outputs/test/try_catch_spec.lua20
-rw-r--r--spec/outputs/test/vararg_spec.lua164
-rw-r--r--spec/outputs/test/with_spec.lua166
-rw-r--r--spec/outputs/with.lua24
-rw-r--r--src/yuescript/yue_compiler.cpp34
52 files changed, 3328 insertions, 3008 deletions
diff --git a/makefile b/makefile
index 3220aa5..09aa86d 100644
--- a/makefile
+++ b/makefile
@@ -63,25 +63,25 @@ ANDROID_ROOT_VAR := $(shell echo $$ANDROID_ROOT)
63PREFIX_VAR := $(shell echo $$PREFIX) 63PREFIX_VAR := $(shell echo $$PREFIX)
64ifneq ($(ANDROID_ROOT_VAR),) 64ifneq ($(ANDROID_ROOT_VAR),)
65 # Check if PREFIX environment variable points to Termux directory 65 # Check if PREFIX environment variable points to Termux directory
66ifneq ($(PREFIX_VAR),) 66 ifneq ($(PREFIX_VAR),)
67ifneq ($(findstring com.termux,$(PREFIX_VAR)),) 67 ifneq ($(findstring com.termux,$(PREFIX_VAR)),)
68 IS_TERMUX := true 68 IS_TERMUX := true
69endif 69 endif
70endif 70 endif
71 # Alternative check: verify if Termux installation path exists 71 # Alternative check: verify if Termux installation path exists
72ifeq ($(IS_TERMUX),false) 72 ifeq ($(IS_TERMUX),false)
73ifneq ($(shell test -d /data/data/com.termux/files/usr && echo yes),) 73 ifneq ($(shell test -d /data/data/com.termux/files/usr && echo yes),)
74 IS_TERMUX := true 74 IS_TERMUX := true
75endif 75 endif
76endif 76 endif
77endif 77endif
78 78
79# Auto-set NO_WATCHER for Termux environment if not explicitly set 79# Auto-set NO_WATCHER for Termux environment if not explicitly set
80ifeq ($(IS_TERMUX),true) 80ifeq ($(IS_TERMUX),true)
81ifeq ($(NO_WATCHER),) 81 ifeq ($(NO_WATCHER),)
82 NO_WATCHER := true 82 NO_WATCHER := true
83$(info Detected Android Termux environment, automatically setting NO_WATCHER=true) 83 $(info Detected Android Termux environment, automatically setting NO_WATCHER=true)
84endif 84 endif
85endif 85endif
86 86
87ifeq ($(NO_WATCHER),true) 87ifeq ($(NO_WATCHER),true)
@@ -192,9 +192,9 @@ ifeq ($(UNAME_S),Darwin)
192 $(RM) $(TIME_FILE) ; \ 192 $(RM) $(TIME_FILE) ; \
193 st=$$((`$(CUR_TIME)` - $$st)) ; \ 193 st=$$((`$(CUR_TIME)` - $$st)) ; \
194 echo $$st 194 echo $$st
195ifneq ($(NO_WATCHER),true) 195 ifneq ($(NO_WATCHER),true)
196 SOURCES += $(SRC_PATH)/3rdParty/efsw/FileWatcherFSEvents.cpp $(SRC_PATH)/3rdParty/efsw/FileWatcherKqueue.cpp $(SRC_PATH)/3rdParty/efsw/WatcherFSEvents.cpp $(SRC_PATH)/3rdParty/efsw/WatcherKqueue.cpp 196 SOURCES += $(SRC_PATH)/3rdParty/efsw/FileWatcherFSEvents.cpp $(SRC_PATH)/3rdParty/efsw/FileWatcherKqueue.cpp $(SRC_PATH)/3rdParty/efsw/WatcherFSEvents.cpp $(SRC_PATH)/3rdParty/efsw/WatcherKqueue.cpp
197endif 197 endif
198else 198else
199 TIME_FILE = $(dir $@).$(notdir $@)_time 199 TIME_FILE = $(dir $@).$(notdir $@)_time
200 START_TIME = date '+%s' > $(TIME_FILE) 200 START_TIME = date '+%s' > $(TIME_FILE)
@@ -202,9 +202,9 @@ else
202 $(RM) $(TIME_FILE) ; \ 202 $(RM) $(TIME_FILE) ; \
203 st=$$((`date '+%s'` - $$st - 86400)) ; \ 203 st=$$((`date '+%s'` - $$st - 86400)) ; \
204 echo `date -u -d @$$st '+%H:%M:%S'` 204 echo `date -u -d @$$st '+%H:%M:%S'`
205ifneq ($(NO_WATCHER),true) 205 ifneq ($(NO_WATCHER),true)
206 SOURCES += $(SRC_PATH)/3rdParty/efsw/FileWatcherFSEvents.cpp $(SRC_PATH)/3rdParty/efsw/FileWatcherKqueue.cpp $(SRC_PATH)/3rdParty/efsw/WatcherFSEvents.cpp $(SRC_PATH)/3rdParty/efsw/WatcherKqueue.cpp $(SRC_PATH)/3rdParty/efsw/FileWatcherInotify.cpp $(SRC_PATH)/3rdParty/efsw/WatcherInotify.cpp 206 SOURCES += $(SRC_PATH)/3rdParty/efsw/FileWatcherFSEvents.cpp $(SRC_PATH)/3rdParty/efsw/FileWatcherKqueue.cpp $(SRC_PATH)/3rdParty/efsw/WatcherFSEvents.cpp $(SRC_PATH)/3rdParty/efsw/WatcherKqueue.cpp $(SRC_PATH)/3rdParty/efsw/FileWatcherInotify.cpp $(SRC_PATH)/3rdParty/efsw/WatcherInotify.cpp
207endif 207 endif
208endif 208endif
209 209
210# Version macros 210# Version macros
@@ -437,6 +437,7 @@ test: debug
437 @./$(BIN_NAME) $(TEST_INPUT)/attrib.yue -o $(TEST_OUTPUT)/5.1/attrib.lua --target 5.1 437 @./$(BIN_NAME) $(TEST_INPUT)/attrib.yue -o $(TEST_OUTPUT)/5.1/attrib.lua --target 5.1
438 @./$(BIN_NAME) $(TEST_INPUT)/import_global.yue -o $(TEST_OUTPUT)/5.1/import_global.lua --target 5.1 438 @./$(BIN_NAME) $(TEST_INPUT)/import_global.yue -o $(TEST_OUTPUT)/5.1/import_global.lua --target 5.1
439 @./$(BIN_NAME) $(TEST_INPUT)/test/loops_spec.yue -o $(TEST_OUTPUT)/5.1/test/loops_spec.lua --target 5.1 439 @./$(BIN_NAME) $(TEST_INPUT)/test/loops_spec.yue -o $(TEST_OUTPUT)/5.1/test/loops_spec.lua --target 5.1
440 @./$(BIN_NAME) $(TEST_INPUT)/test/try_catch_spec.yue -o $(TEST_OUTPUT)/5.1/test/try_catch_spec.lua --target 5.1
440 @./$(BIN_NAME) -e spec/inputs/compile_doc.yue $(TEST_OUTPUT) 441 @./$(BIN_NAME) -e spec/inputs/compile_doc.yue $(TEST_OUTPUT)
441 @echo -en "Compile time: " 442 @echo -en "Compile time: "
442 @$(END_TIME) 443 @$(END_TIME)
@@ -457,6 +458,7 @@ gen: release
457 @./$(BIN_NAME) $(TEST_INPUT)/attrib.yue -o $(GEN_OUTPUT)/5.1/attrib.lua --target 5.1 458 @./$(BIN_NAME) $(TEST_INPUT)/attrib.yue -o $(GEN_OUTPUT)/5.1/attrib.lua --target 5.1
458 @./$(BIN_NAME) $(TEST_INPUT)/import_global.yue -o $(GEN_OUTPUT)/5.1/import_global.lua --target 5.1 459 @./$(BIN_NAME) $(TEST_INPUT)/import_global.yue -o $(GEN_OUTPUT)/5.1/import_global.lua --target 5.1
459 @./$(BIN_NAME) $(TEST_INPUT)/test/loops_spec.yue -o $(GEN_OUTPUT)/5.1/test/loops_spec.lua --target 5.1 460 @./$(BIN_NAME) $(TEST_INPUT)/test/loops_spec.yue -o $(GEN_OUTPUT)/5.1/test/loops_spec.lua --target 5.1
461 @./$(BIN_NAME) $(TEST_INPUT)/test/try_catch_spec.yue -o $(GEN_OUTPUT)/5.1/test/try_catch_spec.lua --target 5.1
460 @./$(BIN_NAME) -e spec/inputs/compile_doc.yue $(GEN_OUTPUT) 462 @./$(BIN_NAME) -e spec/inputs/compile_doc.yue $(GEN_OUTPUT)
461 @echo -en "Compile time: " 463 @echo -en "Compile time: "
462 @$(END_TIME) 464 @$(END_TIME)
@@ -495,3 +497,4 @@ $(BUILD_PATH)/%.o: $(SRC_PATH)/%.c
495 $(CMD_PREFIX)$(CC) $(CFLAGS) $(INCLUDES) -MP -MMD -c $< -o $@ 497 $(CMD_PREFIX)$(CC) $(CFLAGS) $(INCLUDES) -MP -MMD -c $< -o $@
496 @echo -en "\t Compile time: " 498 @echo -en "\t Compile time: "
497 @$(END_TIME) 499 @$(END_TIME)
500
diff --git a/spec/inputs/test/attrib_spec.yue b/spec/inputs/test/attrib_spec.yue
index 4a1fcab..ce9956a 100644
--- a/spec/inputs/test/attrib_spec.yue
+++ b/spec/inputs/test/attrib_spec.yue
@@ -14,12 +14,12 @@ describe "attrib", ->
14 it "should support close attribute", -> 14 it "should support close attribute", ->
15 -- close attribute for to-be-closed variables 15 -- close attribute for to-be-closed variables
16 do 16 do
17 close x = 1 17 close x = <close>: ->
18 assert.same x, 1 18 assert.same "table", type x
19 19
20 it "should work with destructuring", -> 20 it "should work with destructuring", ->
21 do 21 do
22 const {a, b} = {a: 1, b: 2} 22 const :a, :b = {a: 1, b: 2}
23 assert.same a, 1 23 assert.same a, 1
24 assert.same b, 2 24 assert.same b, 2
25 25
@@ -45,7 +45,7 @@ describe "attrib", ->
45 it "should support close in expressions", -> 45 it "should support close in expressions", ->
46 do 46 do
47 close result = if true 47 close result = if true
48 42 48 value: 42, <close>: ->
49 else 49 else
50 0 50 value: 0, <close>: ->
51 assert.same result, 42 51 assert.same result.value, 42
diff --git a/spec/inputs/test/backcall_spec.yue b/spec/inputs/test/backcall_spec.yue
index 9534e7c..e7d03ce 100644
--- a/spec/inputs/test/backcall_spec.yue
+++ b/spec/inputs/test/backcall_spec.yue
@@ -4,8 +4,9 @@ describe "backcall", ->
4 mock_map = (list, fn) -> 4 mock_map = (list, fn) ->
5 for item in *list 5 for item in *list
6 table.insert results, fn(item) 6 table.insert results, fn(item)
7 (x) <- mock_map {1, 2, 3} 7 do
8 x * 2 8 (x) <- mock_map {1, 2, 3}
9 x * 2
9 assert.same results, {2, 4, 6} 10 assert.same results, {2, 4, 6}
10 11
11 it "should support nested backcalls", -> 12 it "should support nested backcalls", ->
diff --git a/spec/inputs/test/config_spec.yue b/spec/inputs/test/config_spec.yue
index 2df8ef3..1c87955 100644
--- a/spec/inputs/test/config_spec.yue
+++ b/spec/inputs/test/config_spec.yue
@@ -57,7 +57,7 @@ describe "config", ->
57 it "should handle with statements", -> 57 it "should handle with statements", ->
58 obj = {x: 10, y: 20} 58 obj = {x: 10, y: 20}
59 result = with obj 59 result = with obj
60 .x + .y 60 break .x + .y
61 assert.same result, 30 61 assert.same result, 30
62 62
63 it "should handle existential operators", -> 63 it "should handle existential operators", ->
diff --git a/spec/inputs/test/existential_spec.yue b/spec/inputs/test/existential_spec.yue
index f63967a..2d516a9 100644
--- a/spec/inputs/test/existential_spec.yue
+++ b/spec/inputs/test/existential_spec.yue
@@ -36,8 +36,8 @@ describe "existential", ->
36 36
37 it "should work with ? in if condition", -> 37 it "should work with ? in if condition", ->
38 obj = {value: 5} 38 obj = {value: 5}
39 if obj?.value 39 result = if obj?.value
40 result = "exists" 40 "exists"
41 assert.same result, "exists" 41 assert.same result, "exists"
42 42
43 it "should combine ?. with and/or", -> 43 it "should combine ?. with and/or", ->
diff --git a/spec/inputs/test/export_spec.yue b/spec/inputs/test/export_spec.yue
index c6ea99b..20c0630 100644
--- a/spec/inputs/test/export_spec.yue
+++ b/spec/inputs/test/export_spec.yue
@@ -77,11 +77,6 @@ describe "export", ->
77 assert.same count, 42 77 assert.same count, 42
78 assert.same price, 19.99 78 assert.same price, 19.99
79 79
80 it "should work in nested scope", ->
81 do
82 nested = "value"
83 assert.same nested, "value"
84
85 it "should export function with parameters", -> 80 it "should export function with parameters", ->
86 add = (a, b) -> a + b 81 add = (a, b) -> a + b
87 assert.same add(5, 3), 8 82 assert.same add(5, 3), 8
diff --git a/spec/inputs/test/goto_spec.yue b/spec/inputs/test/goto_spec.yue
index fd2f401..9dad0a7 100644
--- a/spec/inputs/test/goto_spec.yue
+++ b/spec/inputs/test/goto_spec.yue
@@ -24,7 +24,7 @@ describe "goto", ->
24 if x == 2 and y == 2 24 if x == 2 and y == 2
25 goto found 25 goto found
26 ::found:: 26 ::found::
27 assert.same count, 4 -- (1,1), (1,2), (1,3), (2,1), (2,2) 27 assert.same count, 5 -- (1,1), (1,2), (1,3), (2,1), (2,2)
28 28
29 it "should support multiple labels", -> 29 it "should support multiple labels", ->
30 a = 0 30 a = 0
diff --git a/spec/inputs/test/import_spec.yue b/spec/inputs/test/import_spec.yue
index deeb4a0..7952ac0 100644
--- a/spec/inputs/test/import_spec.yue
+++ b/spec/inputs/test/import_spec.yue
@@ -6,10 +6,10 @@ describe "import", ->
6 assert.same foo, "bar" 6 assert.same foo, "bar"
7 7
8 it "should import with backslash escaping", -> 8 it "should import with backslash escaping", ->
9 source = {x: 1, y: 2, z: 3} 9 source = {x: 1, y: =>, z: 3}
10 import x, \y, z from source 10 import x, \y, z from source
11 assert.same x, 1 11 assert.same x, 1
12 assert.same y, 2 12 assert.same "function", type y
13 assert.same z, 3 13 assert.same z, 3
14 14
15 it "should import from string module", -> 15 it "should import from string module", ->
diff --git a/spec/inputs/test/literals_spec.yue b/spec/inputs/test/literals_spec.yue
index 10bd6b3..4c0b8c1 100644
--- a/spec/inputs/test/literals_spec.yue
+++ b/spec/inputs/test/literals_spec.yue
@@ -40,13 +40,13 @@ describe "literals", ->
40 hello 40 hello
41 world 41 world
42 ]] 42 ]]
43 assert.is_true s\match "hello" 43 assert.is_true s\match("hello")?
44 44
45 it "should support multi-line strings with [=[", -> 45 it "should support multi-line strings with [=[", ->
46 s = [==[ 46 s = [==[
47 test 47 test
48 ]==] 48 ]==]
49 assert.is_true s\match "test" 49 assert.is_true s\match("test")?
50 50
51 it "should support boolean true", -> 51 it "should support boolean true", ->
52 assert.same true, true 52 assert.same true, true
diff --git a/spec/inputs/test/macro_spec.yue b/spec/inputs/test/macro_spec.yue
index a4a170b..e254454 100644
--- a/spec/inputs/test/macro_spec.yue
+++ b/spec/inputs/test/macro_spec.yue
@@ -16,7 +16,7 @@ describe "macro", ->
16 it "should validate AST types", -> 16 it "should validate AST types", ->
17 macro NumAndStr = (num`Num, str`SingleString) -> "[#{num}, #{str}]" 17 macro NumAndStr = (num`Num, str`SingleString) -> "[#{num}, #{str}]"
18 result = $NumAndStr 123, 'xyz' 18 result = $NumAndStr 123, 'xyz'
19 assert.same result, "[123, xyz]" 19 assert.same result, [123, 'xyz']
20 20
21 it "should support simple code generation", -> 21 it "should support simple code generation", ->
22 macro add_one = (x) -> "#{x} + 1" 22 macro add_one = (x) -> "#{x} + 1"
@@ -30,9 +30,9 @@ describe "macro", ->
30 assert.same result, 7 30 assert.same result, 7
31 31
32 it "should respect macro scope in do blocks", -> 32 it "should respect macro scope in do blocks", ->
33 macro outer = -> "outer" 33 macro outer = -> "'outer'"
34 do 34 do
35 macro inner = -> "inner" 35 macro inner = -> "'inner'"
36 result = $inner! 36 result = $inner!
37 assert.same result, "inner" 37 assert.same result, "inner"
38 result = $outer! 38 result = $outer!
@@ -94,7 +94,7 @@ describe "macro", ->
94 it "should work with string interpolation", -> 94 it "should work with string interpolation", ->
95 macro format_result = (name, value) -> "#{name}: #{value}" 95 macro format_result = (name, value) -> "#{name}: #{value}"
96 result = $format_result "test", 123 96 result = $format_result "test", 123
97 assert.same result, "test: 123" 97 assert.same result, test: 123
98 98
99 it "should support function call syntax", -> 99 it "should support function call syntax", ->
100 macro my_func = (x, y) -> "#{x} + #{y}" 100 macro my_func = (x, y) -> "#{x} + #{y}"
@@ -130,6 +130,6 @@ describe "macro", ->
130 assert.same result, 7 130 assert.same result, 7
131 131
132 it "should work with string literals", -> 132 it "should work with string literals", ->
133 macro greet = (name) -> '"Hello, #{name}"' 133 macro greet = (name) -> "'Hello, ' .. #{name}"
134 result = $greet "World" 134 result = $greet "World"
135 assert.same result, "Hello, World" 135 assert.same result, "Hello, World"
diff --git a/spec/inputs/test/return_spec.yue b/spec/inputs/test/return_spec.yue
index 3bf0bed..9cedc40 100644
--- a/spec/inputs/test/return_spec.yue
+++ b/spec/inputs/test/return_spec.yue
@@ -59,11 +59,11 @@ describe "return", ->
59 assert.same fn({value: 100}), 100 59 assert.same fn({value: 100}), 100
60 60
61 it "should return nil implicitly", -> 61 it "should return nil implicitly", ->
62 fn -> print "no return" 62 fn = -> _ = "no return"
63 assert.same fn!, nil 63 assert.same fn!, nil
64 64
65 it "should return multiple values", -> 65 it "should return multiple values", ->
66 fn -> 1, 2, 3 66 fn = -> 1, 2, 3
67 a, b, c = fn! 67 a, b, c = fn!
68 assert.same a, 1 68 assert.same a, 1
69 assert.same b, 2 69 assert.same b, 2
diff --git a/spec/inputs/test/string_spec.yue b/spec/inputs/test/string_spec.yue
index b790518..2afbb13 100644
--- a/spec/inputs/test/string_spec.yue
+++ b/spec/inputs/test/string_spec.yue
@@ -48,12 +48,12 @@ describe "string", ->
48 it "should not interpolate in single quotes", -> 48 it "should not interpolate in single quotes", ->
49 name = "world" 49 name = "world"
50 s = 'hello #{name}' 50 s = 'hello #{name}'
51 assert.same s, "hello #{name}" 51 assert.same s, "hello \#{name}"
52 52
53 it "should escape interpolation with \\#", -> 53 it "should escape interpolation with \\\#", ->
54 name = "world" 54 name = "world"
55 s = "hello \\#{name}" 55 s = "hello \#{name}"
56 assert.same s, "hello #{name}" 56 assert.same s, 'hello #{name}'
57 57
58 it "should support method calls on string literals", -> 58 it "should support method calls on string literals", ->
59 result = "hello"\upper! 59 result = "hello"\upper!
@@ -74,7 +74,7 @@ describe "string", ->
74 name = "test" 74 name = "test"
75 s = | 75 s = |
76 hello #{name} 76 hello #{name}
77 assert.same s, "hello test\n" 77 assert.same s, "hello test"
78 78
79 it "should support string concatenation", -> 79 it "should support string concatenation", ->
80 s = "hello" .. " " .. "world" 80 s = "hello" .. " " .. "world"
@@ -109,7 +109,7 @@ describe "string", ->
109 assert.is_true s\match("y: 20") ~= nil 109 assert.is_true s\match("y: 20") ~= nil
110 110
111 it "should support function call in interpolation", -> 111 it "should support function call in interpolation", ->
112 s = "result: #{-> 42}" 112 s = "result: #{(-> 42)!}"
113 assert.same s, "result: 42" 113 assert.same s, "result: 42"
114 114
115 it "should support table indexing in interpolation", -> 115 it "should support table indexing in interpolation", ->
diff --git a/spec/inputs/test/switch_spec.yue b/spec/inputs/test/switch_spec.yue
index 3696cbe..0865e5a 100644
--- a/spec/inputs/test/switch_spec.yue
+++ b/spec/inputs/test/switch_spec.yue
@@ -73,7 +73,7 @@ describe "switch", ->
73 a: b: :c 73 a: b: :c
74 x: y: :z 74 x: y: :z
75 } 75 }
76 matched = first == {} and one == 1 and two == 2 and three == 3 and c == 1 and z == 1 76 matched = type(first) == 'table' and one == 1 and two == 2 and three == 3 and c == 1 and z == 1
77 assert.is_true matched 77 assert.is_true matched
78 78
79 it "should destructure arrays with exact match", -> 79 it "should destructure arrays with exact match", ->
@@ -259,9 +259,9 @@ describe "switch", ->
259 assert.same result, "matched cool" 259 assert.same result, "matched cool"
260 260
261 it "should handle switch in function call", -> 261 it "should handle switch in function call", ->
262 something = 1
262 getValue = -> 263 getValue = ->
263 switch something 264 switch something
264 when 1 then "yes" 265 when 1 then "yes"
265 else "no" 266 else "no"
266 something = 1
267 assert.same getValue!, "yes" 267 assert.same getValue!, "yes"
diff --git a/spec/inputs/test/try_catch_spec.yue b/spec/inputs/test/try_catch_spec.yue
index ed8fef0..7447886 100644
--- a/spec/inputs/test/try_catch_spec.yue
+++ b/spec/inputs/test/try_catch_spec.yue
@@ -1,5 +1,6 @@
1describe "try/catch", -> 1describe "try/catch", ->
2 it "catch and rethrow", -> 2 it "catch and rethrow", ->
3 import global
3 ok, success, err = pcall -> 4 ok, success, err = pcall ->
4 try 5 try
5 error "boom" 6 error "boom"
diff --git a/spec/inputs/test/with_spec.yue b/spec/inputs/test/with_spec.yue
index c3b8428..70b50ee 100644
--- a/spec/inputs/test/with_spec.yue
+++ b/spec/inputs/test/with_spec.yue
@@ -3,13 +3,13 @@ describe "with", ->
3 obj = {value: 42} 3 obj = {value: 42}
4 with obj 4 with obj
5 result = .value 5 result = .value
6 assert.same result, 42 6 assert.same result, 42
7 7
8 it "should call method with : syntax", -> 8 it "should call method with : syntax", ->
9 obj = {func: -> "result"} 9 obj = {func: -> "result"}
10 with obj 10 with obj
11 result = \func! 11 result = \func!
12 assert.same result, "result" 12 assert.same result, "result"
13 13
14 it "should work as statement", -> 14 it "should work as statement", ->
15 obj = {x: 10, y: 20} 15 obj = {x: 10, y: 20}
@@ -21,20 +21,20 @@ describe "with", ->
21 outer = {inner: {value: 100}} 21 outer = {inner: {value: 100}}
22 with outer.inner 22 with outer.inner
23 result = .value 23 result = .value
24 assert.same result, 100 24 assert.same result, 100
25 25
26 it "should work with? safely", -> 26 it "should work with? safely", ->
27 obj = {x: 5} 27 obj = {x: 5}
28 with obj 28 with obj
29 result = .x 29 result = .x
30 assert.same result, 5 30 assert.same result, 5
31 31
32 it "should work with if inside with", -> 32 it "should work with if inside with", ->
33 obj = {x: 10, y: 20} 33 obj = {x: 10, y: 20}
34 with obj 34 with obj
35 if .x > 5 35 if .x > 5
36 result = .x + .y 36 result = .x + .y
37 assert.same result, 30 37 assert.same result, 30
38 38
39 it "should work with switch inside with", -> 39 it "should work with switch inside with", ->
40 obj = {type: "add", a: 5, b: 3} 40 obj = {type: "add", a: 5, b: 3}
@@ -42,7 +42,7 @@ describe "with", ->
42 result = switch .type 42 result = switch .type
43 when "add" then .a + .b 43 when "add" then .a + .b
44 else 0 44 else 0
45 assert.same result, 8 45 assert.same result, 8
46 46
47 it "should work with loop inside with", -> 47 it "should work with loop inside with", ->
48 obj = {items: {1, 2, 3}} 48 obj = {items: {1, 2, 3}}
@@ -54,11 +54,10 @@ describe "with", ->
54 54
55 it "should work with destructure", -> 55 it "should work with destructure", ->
56 obj = {x: 1, y: 2, z: 3} 56 obj = {x: 1, y: 2, z: 3}
57 with obj 57 with {:x, :y, :z} := obj
58 {x, y, z} = obj 58 assert.same x, 1
59 assert.same x, 1 59 assert.same y, 2
60 assert.same y, 2 60 assert.same z, 3
61 assert.same z, 3
62 61
63 it "should handle simple with body", -> 62 it "should handle simple with body", ->
64 obj = {value: 42} 63 obj = {value: 42}
@@ -87,7 +86,7 @@ describe "with", ->
87 obj = {a: {b: {c: 42}}} 86 obj = {a: {b: {c: 42}}}
88 with obj.a.b 87 with obj.a.b
89 result = .c 88 result = .c
90 assert.same result, 42 89 assert.same result, 42
91 90
92 it "should work with multiple statements", -> 91 it "should work with multiple statements", ->
93 obj = {x: 1, y: 2} 92 obj = {x: 1, y: 2}
diff --git a/spec/inputs/with.yue b/spec/inputs/with.yue
index 19ed2a7..cdb365e 100644
--- a/spec/inputs/with.yue
+++ b/spec/inputs/with.yue
@@ -170,4 +170,9 @@ do
170 with? x := tb[i] 170 with? x := tb[i]
171 break x if .id := 1 171 break x if .id := 1
172 172
173do
174 tb = x: 1, y: 2
175 a = with tb
176 break .x + .y
177
173nil 178nil
diff --git a/spec/outputs/5.1/test/attrib_spec.lua b/spec/outputs/5.1/test/attrib_spec.lua
deleted file mode 100644
index 6fd2287..0000000
--- a/spec/outputs/5.1/test/attrib_spec.lua
+++ /dev/null
@@ -1,86 +0,0 @@
1return describe("attrib", function() -- 1
2 it("should support const attribute", function() -- 2
3 do -- 3
4 local x <const> = 10 -- 4
5 return assert.same(x, 10) -- 5
6 end -- 3
7 end) -- 2
8 it("should support const with multiple variables", function() -- 7
9 do -- 8
10 local a <const>, b <const>, c <const> = 1, 2, 3 -- 9
11 assert.same(a, 1) -- 10
12 assert.same(b, 2) -- 11
13 return assert.same(c, 3) -- 12
14 end -- 8
15 end) -- 7
16 it("should support close attribute", function() -- 14
17 do -- 16
18 local x <close> = 1 -- 17
19 return assert.same(x, 1) -- 18
20 end -- 16
21 end) -- 14
22 it("should work with destructuring", function() -- 20
23 do -- 21
24 local a, b -- 22
25 do -- 22
26 local _obj_0 = { -- 22
27 a = 1, -- 22
28 b = 2 -- 22
29 } -- 22
30 a, b = _obj_0[1], _obj_0[2] -- 22
31 end -- 22
32 assert.same(a, 1) -- 23
33 return assert.same(b, 2) -- 24
34 end -- 21
35 end) -- 20
36 it("should work in conditional", function() -- 26
37 do -- 27
38 local flag = true -- 28
39 local x -- 29
40 if flag then -- 29
41 x = 5 -- 29
42 end -- 29
43 return assert.same(x, 5) -- 30
44 end -- 27
45 end) -- 26
46 it("should work with switch", function() -- 32
47 do -- 33
48 local y -- 34
49 do -- 34
50 local _exp_0 = 2 -- 34
51 if 2 == _exp_0 then -- 35
52 y = 100 -- 35
53 else -- 36
54 y = 0 -- 36
55 end -- 34
56 end -- 34
57 return assert.same(y, 100) -- 37
58 end -- 33
59 end) -- 32
60 it("should work with table literals", function() -- 39
61 do -- 40
62 local a, b -- 41
63 do -- 41
64 local _obj_0 = { -- 41
65 1, -- 41
66 2 -- 41
67 } -- 41
68 a, b = _obj_0[1], _obj_0[2] -- 41
69 end -- 41
70 assert.same(a, 1) -- 42
71 return assert.same(b, 2) -- 43
72 end -- 40
73 end) -- 39
74 return it("should support close in expressions", function() -- 45
75 do -- 46
76 local result -- 47
77 if true then -- 47
78 result = 42 -- 48
79 else -- 50
80 result = 0 -- 50
81 end -- 47
82 local _close_0 <close> = result -- 47
83 return assert.same(result, 42) -- 51
84 end -- 46
85 end) -- 45
86end) -- 1
diff --git a/spec/outputs/5.1/test/cond_spec.lua b/spec/outputs/5.1/test/cond_spec.lua
deleted file mode 100644
index c89a1cc..0000000
--- a/spec/outputs/5.1/test/cond_spec.lua
+++ /dev/null
@@ -1,237 +0,0 @@
1local _anon_func_0 = function(flag) -- 37
2 if flag then -- 37
3 return 1 -- 37
4 else -- 37
5 return 0 -- 37
6 end -- 37
7end -- 37
8local _anon_func_1 = function() -- 85
9 if nil then -- 85
10 return true -- 85
11 else -- 85
12 return false -- 85
13 end -- 85
14end -- 85
15local _anon_func_2 = function() -- 86
16 if false then -- 86
17 return true -- 86
18 else -- 86
19 return false -- 86
20 end -- 86
21end -- 86
22local _anon_func_3 = function() -- 89
23 if 0 then -- 89
24 return true -- 89
25 else -- 89
26 return false -- 89
27 end -- 89
28end -- 89
29local _anon_func_4 = function() -- 90
30 if "" then -- 90
31 return true -- 90
32 else -- 90
33 return false -- 90
34 end -- 90
35end -- 90
36local _anon_func_5 = function() -- 91
37 if { } then -- 91
38 return true -- 91
39 else -- 91
40 return false -- 91
41 end -- 91
42end -- 91
43local _anon_func_6 = function() -- 92
44 if 1 then -- 92
45 return true -- 92
46 else -- 92
47 return false -- 92
48 end -- 92
49end -- 92
50return describe("cond", function() -- 1
51 it("should execute if branch when condition is true", function() -- 2
52 local result = nil -- 3
53 if true then -- 4
54 result = "yes" -- 5
55 end -- 4
56 return assert.same(result, "yes") -- 6
57 end) -- 2
58 it("should execute else branch when condition is false", function() -- 8
59 local result = nil -- 9
60 if false then -- 10
61 result = "yes" -- 11
62 else -- 13
63 result = "no" -- 13
64 end -- 10
65 return assert.same(result, "no") -- 14
66 end) -- 8
67 it("should support elseif chain", function() -- 16
68 local value = 2 -- 17
69 local result -- 18
70 if 1 == value then -- 19
71 result = "one" -- 19
72 elseif 2 == value then -- 20
73 result = "two" -- 20
74 else -- 21
75 result = "other" -- 21
76 end -- 18
77 return assert.same(result, "two") -- 22
78 end) -- 16
79 it("should handle nested conditions", function() -- 24
80 local result = nil -- 25
81 if true then -- 26
82 if true then -- 27
83 result = "nested" -- 28
84 end -- 27
85 end -- 26
86 return assert.same(result, "nested") -- 29
87 end) -- 24
88 it("should work as expression", function() -- 31
89 local value -- 32
90 if true then -- 32
91 value = "yes" -- 32
92 else -- 32
93 value = "no" -- 32
94 end -- 32
95 return assert.same(value, "yes") -- 33
96 end) -- 31
97 it("should work in string interpolation", function() -- 35
98 local flag = true -- 36
99 local result = "value is " .. tostring(_anon_func_0(flag)) -- 37
100 return assert.same(result, "value is 1") -- 38
101 end) -- 35
102 it("should support chained comparisons", function() -- 40
103 return assert.is_true(1 < 2 and 2 <= 2 and 2 < 3) -- 41
104 end) -- 40
105 it("should short-circuit and expression", function() -- 43
106 local count = 0 -- 44
107 local inc -- 45
108 inc = function() -- 45
109 count = count + 1 -- 46
110 return false -- 47
111 end -- 45
112 local result = inc() and inc() -- 48
113 return assert.same(count, 1) -- 49
114 end) -- 43
115 it("should short-circuit or expression", function() -- 51
116 local count = 0 -- 52
117 local inc -- 53
118 inc = function() -- 53
119 count = count + 1 -- 54
120 return true -- 55
121 end -- 53
122 local result = inc() or inc() -- 56
123 return assert.same(count, 1) -- 57
124 end) -- 51
125 it("should support unless keyword", function() -- 59
126 local result = nil -- 60
127 if not false then -- 61
128 result = "executed" -- 62
129 end -- 61
130 return assert.same(result, "executed") -- 63
131 end) -- 59
132 it("should support unless with else", function() -- 65
133 local result = nil -- 66
134 if not true then -- 67
135 result = "no" -- 68
136 else -- 70
137 result = "yes" -- 70
138 end -- 67
139 return assert.same(result, "yes") -- 71
140 end) -- 65
141 it("should handle postfix if", function() -- 73
142 local result = nil -- 74
143 if true then -- 75
144 result = "yes" -- 75
145 end -- 75
146 return assert.same(result, "yes") -- 76
147 end) -- 73
148 it("should handle postfix unless", function() -- 78
149 local result = nil -- 79
150 if not false then -- 80
151 result = "yes" -- 80
152 end -- 80
153 return assert.same(result, "yes") -- 81
154 end) -- 78
155 it("should evaluate truthiness correctly", function() -- 83
156 assert.is_false(_anon_func_1()) -- 85
157 assert.is_false(_anon_func_2()) -- 86
158 assert.is_true(_anon_func_3()) -- 89
159 assert.is_true(_anon_func_4()) -- 90
160 assert.is_true(_anon_func_5()) -- 91
161 return assert.is_true(_anon_func_6()) -- 92
162 end) -- 83
163 it("should support and/or operators", function() -- 94
164 assert.same(true and false, false) -- 95
165 assert.same(false or true, true) -- 96
166 assert.same(nil or "default", "default") -- 97
167 return assert.same("value" or "default", "value") -- 98
168 end) -- 94
169 it("should handle complex boolean expressions", function() -- 100
170 local a, b, c = true, false, true -- 101
171 local result = a and b or c -- 102
172 return assert.same(result, c) -- 103
173 end) -- 100
174 it("should support not operator", function() -- 105
175 assert.is_true(not false) -- 106
176 assert.is_true(not nil) -- 107
177 assert.is_false(not true) -- 108
178 return assert.is_false(not 1) -- 109
179 end) -- 105
180 it("should work with table as condition", function() -- 111
181 local result = nil -- 112
182 if { } then -- 113
183 result = "truthy" -- 114
184 end -- 113
185 return assert.same(result, "truthy") -- 115
186 end) -- 111
187 it("should work with string as condition", function() -- 117
188 local result = nil -- 118
189 if "" then -- 119
190 result = "truthy" -- 120
191 end -- 119
192 return assert.same(result, "truthy") -- 121
193 end) -- 117
194 it("should work with zero as condition", function() -- 123
195 local result = nil -- 124
196 if 0 then -- 125
197 result = "truthy" -- 126
198 end -- 125
199 return assert.same(result, "truthy") -- 127
200 end) -- 123
201 it("should support multiple elseif branches", function() -- 129
202 local value = 3 -- 130
203 local result -- 131
204 if value == 1 then -- 131
205 result = "one" -- 132
206 elseif value == 2 then -- 133
207 result = "two" -- 134
208 elseif value == 3 then -- 135
209 result = "three" -- 136
210 else -- 138
211 result = "other" -- 138
212 end -- 131
213 return assert.same(result, "three") -- 139
214 end) -- 129
215 it("should handle then keyword syntax", function() -- 141
216 local result -- 142
217 if true then -- 142
218 result = "yes" -- 142
219 else -- 142
220 result = "no" -- 142
221 end -- 142
222 return assert.same(result, "yes") -- 143
223 end) -- 141
224 return it("should work with function call in condition", function() -- 145
225 local return_true -- 146
226 return_true = function() -- 146
227 return true -- 146
228 end -- 146
229 local result -- 147
230 if return_true() then -- 147
231 result = "yes" -- 147
232 else -- 147
233 result = "no" -- 147
234 end -- 147
235 return assert.same(result, "yes") -- 148
236 end) -- 145
237end) -- 1
diff --git a/spec/outputs/5.1/test/existential_spec.lua b/spec/outputs/5.1/test/existential_spec.lua
deleted file mode 100644
index 8b8064a..0000000
--- a/spec/outputs/5.1/test/existential_spec.lua
+++ /dev/null
@@ -1,243 +0,0 @@
1local _anon_func_0 = function(obj) -- 39
2 if obj ~= nil then -- 39
3 return obj.value -- 39
4 end -- 39
5 return nil -- 39
6end -- 39
7local _anon_func_1 = function(obj) -- 45
8 if obj ~= nil then -- 45
9 return obj.value -- 45
10 end -- 45
11 return nil -- 45
12end -- 45
13local _anon_func_2 = function(obj) -- 50
14 if obj ~= nil then -- 50
15 return obj.x -- 50
16 end -- 50
17 return nil -- 50
18end -- 50
19local _anon_func_3 = function(obj) -- 50
20 if obj ~= nil then -- 50
21 return obj.y -- 50
22 end -- 50
23 return nil -- 50
24end -- 50
25return describe("existential", function() -- 1
26 it("should handle ?. with existing object", function() -- 2
27 local obj = { -- 3
28 value = 42 -- 3
29 } -- 3
30 local result -- 4
31 if obj ~= nil then -- 4
32 result = obj.value -- 4
33 end -- 4
34 return assert.same(result, 42) -- 5
35 end) -- 2
36 it("should handle ?. with nil object", function() -- 7
37 local obj = nil -- 8
38 local result -- 9
39 if obj ~= nil then -- 9
40 result = obj.value -- 9
41 end -- 9
42 return assert.same(result, nil) -- 10
43 end) -- 7
44 it("should chain ?. calls", function() -- 12
45 local obj = { -- 13
46 nested = { -- 13
47 value = 100 -- 13
48 } -- 13
49 } -- 13
50 local result -- 14
51 if obj ~= nil then -- 14
52 do -- 14
53 local _obj_0 = obj.nested -- 14
54 if _obj_0 ~= nil then -- 14
55 result = _obj_0.value -- 14
56 end -- 14
57 end -- 14
58 end -- 14
59 return assert.same(result, 100) -- 15
60 end) -- 12
61 it("should return nil in chain with nil", function() -- 17
62 local obj = nil -- 18
63 local result -- 19
64 if obj ~= nil then -- 19
65 do -- 19
66 local _obj_0 = obj.nested -- 19
67 if _obj_0 ~= nil then -- 19
68 result = _obj_0.value -- 19
69 end -- 19
70 end -- 19
71 end -- 19
72 return assert.same(result, nil) -- 20
73 end) -- 17
74 it("should handle ?. with method call", function() -- 22
75 local obj = { -- 23
76 func = function() -- 23
77 return "result" -- 23
78 end -- 23
79 } -- 23
80 local result -- 24
81 if obj ~= nil then -- 24
82 result = obj.func() -- 24
83 end -- 24
84 return assert.same(result, "result") -- 25
85 end) -- 22
86 it("should handle ? on table index", function() -- 27
87 local tb = { -- 28
88 [1] = "first" -- 28
89 } -- 28
90 local result -- 29
91 if tb ~= nil then -- 29
92 result = tb[1] -- 29
93 end -- 29
94 return assert.same(result, "first") -- 30
95 end) -- 27
96 it("should return nil for missing index", function() -- 32
97 local tb = { } -- 33
98 local result -- 34
99 if tb ~= nil then -- 34
100 result = tb[99] -- 34
101 end -- 34
102 return assert.same(result, nil) -- 35
103 end) -- 32
104 it("should work with ? in if condition", function() -- 37
105 local obj = { -- 38
106 value = 5 -- 38
107 } -- 38
108 if _anon_func_0(obj) then -- 39
109 local result = "exists" -- 40
110 end -- 39
111 return assert.same(result, "exists") -- 41
112 end) -- 37
113 it("should combine ?. with and/or", function() -- 43
114 local obj = { -- 44
115 value = 10 -- 44
116 } -- 44
117 local result = _anon_func_1(obj) and 20 or 30 -- 45
118 return assert.same(result, 20) -- 46
119 end) -- 43
120 it("should handle with? safely", function() -- 48
121 local obj = { -- 49
122 x = 1, -- 49
123 y = 2 -- 49
124 } -- 49
125 local sum = _anon_func_2(obj) + _anon_func_3(obj) -- 50
126 return assert.same(sum, 3) -- 51
127 end) -- 48
128 it("should return nil with with? on nil", function() -- 53
129 local obj = nil -- 54
130 local result -- 55
131 if obj ~= nil then -- 55
132 result = obj.x -- 55
133 end -- 55
134 return assert.same(result, nil) -- 56
135 end) -- 53
136 it("should handle false value correctly", function() -- 58
137 local obj = { -- 60
138 value = false -- 60
139 } -- 60
140 local result -- 61
141 if obj ~= nil then -- 61
142 result = obj.value -- 61
143 end -- 61
144 return assert.same(result, false) -- 62
145 end) -- 58
146 it("should handle 0 value correctly", function() -- 64
147 local obj = { -- 66
148 value = 0 -- 66
149 } -- 66
150 local result -- 67
151 if obj ~= nil then -- 67
152 result = obj.value -- 67
153 end -- 67
154 return assert.same(result, 0) -- 68
155 end) -- 64
156 it("should handle empty string correctly", function() -- 70
157 local obj = { -- 72
158 value = "" -- 72
159 } -- 72
160 local result -- 73
161 if obj ~= nil then -- 73
162 result = obj.value -- 73
163 end -- 73
164 return assert.same(result, "") -- 74
165 end) -- 70
166 it("should handle empty table correctly", function() -- 76
167 local obj = { -- 78
168 value = { } -- 78
169 } -- 78
170 local result -- 79
171 if obj ~= nil then -- 79
172 result = obj.value -- 79
173 end -- 79
174 return assert.same(type(result), "table") -- 80
175 end) -- 76
176 it("should work with deep chains", function() -- 82
177 local obj = { -- 83
178 a = { -- 83
179 b = { -- 83
180 c = { -- 83
181 d = "deep" -- 83
182 } -- 83
183 } -- 83
184 } -- 83
185 } -- 83
186 local result -- 84
187 if obj ~= nil then -- 84
188 do -- 84
189 local _obj_0 = obj.a -- 84
190 if _obj_0 ~= nil then -- 84
191 do -- 84
192 local _obj_1 = _obj_0.b -- 84
193 if _obj_1 ~= nil then -- 84
194 do -- 84
195 local _obj_2 = _obj_1.c -- 84
196 if _obj_2 ~= nil then -- 84
197 result = _obj_2.d -- 84
198 end -- 84
199 end -- 84
200 end -- 84
201 end -- 84
202 end -- 84
203 end -- 84
204 end -- 84
205 return assert.same(result, "deep") -- 85
206 end) -- 82
207 it("should break chain on first nil", function() -- 87
208 local obj = { -- 88
209 a = nil -- 88
210 } -- 88
211 local result -- 89
212 if obj ~= nil then -- 89
213 do -- 89
214 local _obj_0 = obj.a -- 89
215 if _obj_0 ~= nil then -- 89
216 do -- 89
217 local _obj_1 = _obj_0.b -- 89
218 if _obj_1 ~= nil then -- 89
219 result = _obj_1.c -- 89
220 end -- 89
221 end -- 89
222 end -- 89
223 end -- 89
224 end -- 89
225 return assert.same(result, nil) -- 90
226 end) -- 87
227 it("should handle ?. with string methods", function() -- 92
228 local s = "hello" -- 93
229 local result -- 94
230 if s ~= nil then -- 94
231 result = s:upper() -- 94
232 end -- 94
233 return assert.same(result, "HELLO") -- 95
234 end) -- 92
235 return it("should handle ?. with nil string", function() -- 97
236 local s = nil -- 98
237 local result -- 99
238 if s ~= nil then -- 99
239 result = s:upper() -- 99
240 end -- 99
241 return assert.same(result, nil) -- 100
242 end) -- 97
243end) -- 1
diff --git a/spec/outputs/5.1/test/export_spec.lua b/spec/outputs/5.1/test/export_spec.lua
deleted file mode 100644
index f40a298..0000000
--- a/spec/outputs/5.1/test/export_spec.lua
+++ /dev/null
@@ -1,159 +0,0 @@
1return describe("export", function() -- 1
2 it("should export basic variables", function() -- 2
3 local a = 1 -- 3
4 local b = 2 -- 4
5 local c = 3 -- 5
6 assert.same(a, 1) -- 6
7 assert.same(b, 2) -- 7
8 return assert.same(c, 3) -- 8
9 end) -- 2
10 it("should export multiple variables at once", function() -- 10
11 local x, y, z = 10, 20, 30 -- 11
12 assert.same(x, 10) -- 12
13 assert.same(y, 20) -- 13
14 return assert.same(z, 30) -- 14
15 end) -- 10
16 it("should export class definitions", function() -- 16
17 local MyClass -- 17
18 do -- 17
19 local _class_0 -- 17
20 local _base_0 = { -- 17
21 value = 100 -- 17
22 } -- 17
23 if _base_0.__index == nil then -- 17
24 _base_0.__index = _base_0 -- 17
25 end -- 17
26 _class_0 = setmetatable({ -- 17
27 __init = function() end, -- 17
28 __base = _base_0, -- 17
29 __name = "MyClass" -- 17
30 }, { -- 17
31 __index = _base_0, -- 17
32 __call = function(cls, ...) -- 17
33 local _self_0 = setmetatable({ }, _base_0) -- 17
34 cls.__init(_self_0, ...) -- 17
35 return _self_0 -- 17
36 end -- 17
37 }) -- 17
38 _base_0.__class = _class_0 -- 17
39 MyClass = _class_0 -- 17
40 end -- 17
41 return assert.same(MyClass.value, 100) -- 19
42 end) -- 16
43 it("should export function expressions", function() -- 21
44 local my_func -- 22
45 my_func = function() -- 22
46 return 42 -- 22
47 end -- 22
48 return assert.same(my_func(), 42) -- 23
49 end) -- 21
50 it("should export conditional expressions", function() -- 25
51 local result -- 26
52 if true then -- 26
53 result = "yes" -- 27
54 else -- 29
55 result = "no" -- 29
56 end -- 26
57 return assert.same(result, "yes") -- 30
58 end) -- 25
59 it("should export switch expressions", function() -- 32
60 local value -- 33
61 do -- 33
62 local _exp_0 = 5 -- 33
63 if 5 == _exp_0 then -- 34
64 value = 100 -- 34
65 else -- 35
66 value = 0 -- 35
67 end -- 33
68 end -- 33
69 return assert.same(value, 100) -- 36
70 end) -- 32
71 it("should export with do block", function() -- 38
72 local result -- 39
73 do -- 39
74 local x = 5 -- 40
75 result = x * 2 -- 41
76 end -- 39
77 return assert.same(result, 10) -- 42
78 end) -- 38
79 it("should export comprehension", function() -- 44
80 local doubled -- 45
81 do -- 45
82 local _accum_0 = { } -- 45
83 local _len_0 = 1 -- 45
84 for i = 1, 5 do -- 45
85 _accum_0[_len_0] = i * 2 -- 45
86 _len_0 = _len_0 + 1 -- 45
87 end -- 45
88 doubled = _accum_0 -- 45
89 end -- 45
90 return assert.same(doubled, { -- 46
91 2, -- 46
92 4, -- 46
93 6, -- 46
94 8, -- 46
95 10 -- 46
96 }) -- 46
97 end) -- 44
98 it("should export with pipe operator", function() -- 48
99 local result = table.concat({ -- 49
100 1, -- 49
101 2, -- 49
102 3 -- 49
103 }) -- 49
104 return assert.same(result, "123") -- 50
105 end) -- 48
106 it("should export nil values", function() -- 52
107 local empty = nil -- 53
108 return assert.same(empty, nil) -- 54
109 end) -- 52
110 it("should export tables", function() -- 56
111 local config = { -- 58
112 key1 = "value1", -- 58
113 key2 = "value2" -- 59
114 } -- 57
115 assert.same(config.key1, "value1") -- 61
116 return assert.same(config.key2, "value2") -- 62
117 end) -- 56
118 it("should export string values", function() -- 64
119 local message = "hello world" -- 65
120 return assert.same(message, "hello world") -- 66
121 end) -- 64
122 it("should export boolean values", function() -- 68
123 local flag_true = true -- 69
124 local flag_false = false -- 70
125 assert.is_true(flag_true) -- 71
126 return assert.is_false(flag_false) -- 72
127 end) -- 68
128 it("should export number values", function() -- 74
129 local count = 42 -- 75
130 local price = 19.99 -- 76
131 assert.same(count, 42) -- 77
132 return assert.same(price, 19.99) -- 78
133 end) -- 74
134 it("should work in nested scope", function() -- 80
135 do -- 81
136 local nested = "value" -- 82
137 end -- 81
138 return assert.same(nested, "value") -- 83
139 end) -- 80
140 it("should export function with parameters", function() -- 85
141 local add -- 86
142 add = function(a, b) -- 86
143 return a + b -- 86
144 end -- 86
145 return assert.same(add(5, 3), 8) -- 87
146 end) -- 85
147 it("should maintain export order", function() -- 89
148 local first = 1 -- 90
149 local second = 2 -- 91
150 local third = 3 -- 92
151 assert.same(first, 1) -- 93
152 assert.same(second, 2) -- 94
153 return assert.same(third, 3) -- 95
154 end) -- 89
155 return it("should work with complex expressions", function() -- 97
156 local calc = (10 + 20) * 2 -- 98
157 return assert.same(calc, 60) -- 99
158 end) -- 97
159end) -- 1
diff --git a/spec/outputs/5.1/test/goto_spec.lua b/spec/outputs/5.1/test/goto_spec.lua
deleted file mode 100644
index e0921c8..0000000
--- a/spec/outputs/5.1/test/goto_spec.lua
+++ /dev/null
@@ -1,103 +0,0 @@
1return describe("goto", function() -- 1
2 it("should support basic goto and label", function() -- 2
3 local a = 0 -- 3
4 ::start:: -- 4
5 a = a + 1 -- 5
6 if a < 5 then -- 6
7 goto start -- 7
8 end -- 6
9 return assert.same(a, 5) -- 8
10 end) -- 2
11 it("should support conditional goto", function() -- 10
12 local a = 0 -- 11
13 ::loop:: -- 12
14 a = a + 1 -- 13
15 if a == 3 then -- 14
16 goto done -- 14
17 end -- 14
18 goto loop -- 15
19 ::done:: -- 16
20 return assert.same(a, 3) -- 17
21 end) -- 10
22 it("should support goto in nested loops", function() -- 19
23 local count = 0 -- 20
24 for x = 1, 3 do -- 21
25 for y = 1, 3 do -- 22
26 count = count + 1 -- 23
27 if x == 2 and y == 2 then -- 24
28 goto found -- 25
29 end -- 24
30 end -- 22
31 end -- 21
32 ::found:: -- 26
33 return assert.same(count, 4) -- 27
34 end) -- 19
35 it("should support multiple labels", function() -- 29
36 local a = 0 -- 30
37 ::first:: -- 31
38 a = a + 1 -- 32
39 if a == 2 then -- 33
40 goto second -- 33
41 end -- 33
42 goto first -- 34
43 ::second:: -- 35
44 return assert.same(a, 2) -- 36
45 end) -- 29
46 it("should work with for loops", function() -- 38
47 local sum = 0 -- 39
48 for i = 1, 10 do -- 40
49 sum = sum + i -- 41
50 if i == 5 then -- 42
51 goto done -- 42
52 end -- 42
53 end -- 40
54 ::done:: -- 43
55 return assert.same(sum, 15) -- 44
56 end) -- 38
57 it("should work with while loops", function() -- 46
58 local count = 0 -- 47
59 while true do -- 48
60 count = count + 1 -- 49
61 if count == 3 then -- 50
62 goto endwhile -- 50
63 end -- 50
64 end -- 48
65 ::endwhile:: -- 51
66 return assert.same(count, 3) -- 52
67 end) -- 46
68 it("should skip rest of loop with goto", function() -- 54
69 local values = { } -- 55
70 for i = 1, 5 do -- 56
71 if i % 2 == 0 then -- 57
72 goto continue -- 57
73 end -- 57
74 table.insert(values, i) -- 58
75 ::continue:: -- 59
76 end -- 56
77 return assert.same(values, { -- 60
78 1, -- 60
79 3, -- 60
80 5 -- 60
81 }) -- 60
82 end) -- 54
83 return it("should support goto with switch", function() -- 62
84 local result = "default" -- 63
85 local value = 2 -- 64
86 if 1 == value then -- 66
87 goto case_one -- 67
88 elseif 2 == value then -- 68
89 goto case_two -- 69
90 end -- 65
91 goto default_label -- 70
92 ::case_one:: -- 71
93 result = "one" -- 72
94 goto finish -- 73
95 ::case_two:: -- 74
96 result = "two" -- 75
97 goto finish -- 76
98 ::default_label:: -- 77
99 result = "default" -- 78
100 ::finish:: -- 79
101 return assert.same(result, "two") -- 80
102 end) -- 62
103end) -- 1
diff --git a/spec/outputs/5.1/test/import_spec.lua b/spec/outputs/5.1/test/import_spec.lua
deleted file mode 100644
index f77ef04..0000000
--- a/spec/outputs/5.1/test/import_spec.lua
+++ /dev/null
@@ -1,196 +0,0 @@
1return describe("import", function() -- 1
2 it("should import from table expression", function() -- 2
3 local source = { -- 3
4 hello = "world", -- 3
5 foo = "bar" -- 3
6 } -- 3
7 local hello, foo = source.hello, source.foo -- 4
8 assert.same(hello, "world") -- 5
9 return assert.same(foo, "bar") -- 6
10 end) -- 2
11 it("should import with backslash escaping", function() -- 8
12 local source = { -- 9
13 x = 1, -- 9
14 y = 2, -- 9
15 z = 3 -- 9
16 } -- 9
17 local x, y, z = source.x, (function() -- 10
18 local _base_0 = source -- 10
19 local _fn_0 = _base_0.y -- 10
20 return _fn_0 and function(...) -- 10
21 return _fn_0(_base_0, ...) -- 10
22 end -- 10
23 end)(), source.z -- 10
24 assert.same(x, 1) -- 11
25 assert.same(y, 2) -- 12
26 return assert.same(z, 3) -- 13
27 end) -- 8
28 it("should import from string module", function() -- 15
29 local format -- 17
30 do -- 17
31 local _obj_0 = require("string") -- 17
32 format = _obj_0.format -- 17
33 end -- 17
34 return assert.is_true(type(format) == "function") -- 18
35 end) -- 15
36 it("should import from table with dot path", function() -- 20
37 local sub -- 22
38 do -- 22
39 local _obj_0 = require("string") -- 22
40 sub = _obj_0.sub -- 22
41 end -- 22
42 local result = sub("hello", 1, 2) -- 23
43 return assert.same(result, "he") -- 24
44 end) -- 20
45 it("should import multiple values with table destructuring", function() -- 26
46 local source = { -- 27
47 a = 1, -- 27
48 b = 2, -- 27
49 c = 3 -- 27
50 } -- 27
51 local a, b, c = source.a, source.b, source.c -- 28
52 assert.same(a, 1) -- 29
53 assert.same(b, 2) -- 30
54 return assert.same(c, 3) -- 31
55 end) -- 26
56 it("should import with multi-line format", function() -- 33
57 local source = { -- 34
58 x = 1, -- 34
59 y = 2, -- 34
60 z = 3 -- 34
61 } -- 34
62 local x, y, z = source.x, source.y, source.z -- 35
63 assert.same(x, 1) -- 36
64 assert.same(y, 2) -- 37
65 return assert.same(z, 3) -- 38
66 end) -- 33
67 it("should import using from syntax", function() -- 40
68 local source = { -- 41
69 foo = "bar", -- 41
70 baz = "qux" -- 41
71 } -- 41
72 local foo, baz = source.foo, source.baz -- 42
73 assert.same(foo, "bar") -- 43
74 return assert.same(baz, "qux") -- 44
75 end) -- 40
76 it("should handle import with computed expressions", function() -- 46
77 local source = { -- 47
78 first = 1, -- 47
79 second = 2 -- 47
80 } -- 47
81 local target = source -- 48
82 local first, second = target.first, target.second -- 49
83 assert.same(first, 1) -- 50
84 return assert.same(second, 2) -- 51
85 end) -- 46
86 it("should import from nested table paths", function() -- 53
87 local deep = { -- 54
88 outer = { -- 54
89 inner = "value" -- 54
90 } -- 54
91 } -- 54
92 local outer = deep.outer -- 55
93 return assert.same(outer.inner, "value") -- 56
94 end) -- 53
95 it("should support importing Lua standard library functions", function() -- 58
96 local print, type -- 59
97 do -- 59
98 local _obj_0 = require("_G") -- 59
99 print, type = _obj_0.print, _obj_0.type -- 59
100 end -- 59
101 assert.is_true(type(print) == "function") -- 60
102 return assert.is_true(type(type) == "function") -- 61
103 end) -- 58
104 it("should handle empty import gracefully", function() -- 63
105 local source = { } -- 65
106 local dummy = source.dummy -- 66
107 return assert.same(dummy, nil) -- 67
108 end) -- 63
109 it("should work with table index expressions", function() -- 69
110 local source = { -- 70
111 normal = "ok" -- 70
112 } -- 70
113 local normal = source.normal -- 71
114 return assert.same(normal, "ok") -- 72
115 end) -- 69
116 it("should support chaining imports from same source", function() -- 74
117 local source = { -- 75
118 a = 1, -- 75
119 b = 2, -- 75
120 c = 3 -- 75
121 } -- 75
122 local a, b = source.a, source.b -- 76
123 local c = source.c -- 77
124 assert.same(a, 1) -- 78
125 assert.same(b, 2) -- 79
126 return assert.same(c, 3) -- 80
127 end) -- 74
128 it("should handle importing from table returned by function", function() -- 82
129 local get_table -- 83
130 get_table = function() -- 83
131 return { -- 83
132 x = 100, -- 83
133 y = 200 -- 83
134 } -- 83
135 end -- 83
136 local x, y -- 84
137 do -- 84
138 local _obj_0 = get_table() -- 84
139 x, y = _obj_0.x, _obj_0.y -- 84
140 end -- 84
141 assert.same(x, 100) -- 85
142 return assert.same(y, 200) -- 86
143 end) -- 82
144 it("should support from with multi-line import", function() -- 88
145 local source = { -- 89
146 item1 = 1, -- 89
147 item2 = 2, -- 89
148 item3 = 3 -- 89
149 } -- 89
150 local item1, item2, item3 = source.item1, source.item2, source.item3 -- 90
151 assert.same(item1, 1) -- 91
152 assert.same(item2, 2) -- 92
153 return assert.same(item3, 3) -- 93
154 end) -- 88
155 it("should work with import from string literal", function() -- 95
156 local char -- 96
157 do -- 96
158 local _obj_0 = require("string") -- 96
159 char = _obj_0.char -- 96
160 end -- 96
161 return assert.same(char(65), "A") -- 97
162 end) -- 95
163 it("should support import with table literal keys", function() -- 99
164 local source = { -- 100
165 normal_key = "value2" -- 100
166 } -- 100
167 local normal_key = source.normal_key -- 101
168 return assert.same(normal_key, "value2") -- 102
169 end) -- 99
170 it("should handle consecutive imports", function() -- 104
171 local source1 = { -- 105
172 a = 1 -- 105
173 } -- 105
174 local source2 = { -- 106
175 b = 2 -- 106
176 } -- 106
177 local a = source1.a -- 107
178 local b = source2.b -- 108
179 assert.same(a, 1) -- 109
180 return assert.same(b, 2) -- 110
181 end) -- 104
182 return it("should support importing from complex expressions", function() -- 112
183 local get_source -- 113
184 get_source = function() -- 113
185 return { -- 113
186 result = 42 -- 113
187 } -- 113
188 end -- 113
189 local result -- 114
190 do -- 114
191 local _obj_0 = get_source() -- 114
192 result = _obj_0.result -- 114
193 end -- 114
194 return assert.same(result, 42) -- 115
195 end) -- 112
196end) -- 1
diff --git a/spec/outputs/5.1/test/literals_spec.lua b/spec/outputs/5.1/test/literals_spec.lua
deleted file mode 100644
index 3bbfb37..0000000
--- a/spec/outputs/5.1/test/literals_spec.lua
+++ /dev/null
@@ -1,90 +0,0 @@
1return describe("literals", function() -- 1
2 it("should support integer literals", function() -- 2
3 return assert.same(123, 123) -- 3
4 end) -- 2
5 it("should support float literals", function() -- 5
6 return assert.same(1.5, 1.5) -- 6
7 end) -- 5
8 it("should support scientific notation", function() -- 8
9 return assert.same(1.5e2, 150) -- 9
10 end) -- 8
11 it("should support negative numbers", function() -- 11
12 return assert.same(-42, -42) -- 12
13 end) -- 11
14 it("should support hexadecimal literals", function() -- 14
15 return assert.same(0xff, 255) -- 15
16 end) -- 14
17 it("should support hexadecimal with uppercase", function() -- 17
18 return assert.same(0XFF, 255) -- 18
19 end) -- 17
20 it("should support binary literals", function() -- 20
21 return assert.same(5, 5) -- 21
22 end) -- 20
23 it("should support binary with uppercase", function() -- 23
24 return assert.same(5, 5) -- 24
25 end) -- 23
26 it("should support number with underscores", function() -- 26
27 return assert.same(1000000, 1000000) -- 27
28 end) -- 26
29 it("should support hex with underscores", function() -- 29
30 return assert.same(0xDEADBEEF, 0xDEADBEEF) -- 30
31 end) -- 29
32 it("should support double quote strings", function() -- 32
33 return assert.same("hello", "hello") -- 33
34 end) -- 32
35 it("should support single quote strings", function() -- 35
36 return assert.same('world', 'world') -- 36
37 end) -- 35
38 it("should support multi-line strings with [[", function() -- 38
39 local s = [[ hello
40 world
41 ]] -- 39
42 return assert.is_true(s:match("hello")) -- 43
43 end) -- 38
44 it("should support multi-line strings with [=[", function() -- 45
45 local s = [==[ test
46 ]==] -- 46
47 return assert.is_true(s:match("test")) -- 49
48 end) -- 45
49 it("should support boolean true", function() -- 51
50 return assert.same(true, true) -- 52
51 end) -- 51
52 it("should support boolean false", function() -- 54
53 return assert.same(false, false) -- 55
54 end) -- 54
55 it("should support nil", function() -- 57
56 return assert.same(nil, nil) -- 58
57 end) -- 57
58 it("should support empty table", function() -- 60
59 local t = { } -- 61
60 return assert.same(#t, 0) -- 62
61 end) -- 60
62 it("should support table with keys", function() -- 64
63 local t = { -- 65
64 a = 1, -- 65
65 b = 2 -- 65
66 } -- 65
67 assert.same(t.a, 1) -- 66
68 return assert.same(t.b, 2) -- 67
69 end) -- 64
70 it("should support array literal", function() -- 69
71 local t = { -- 70
72 1, -- 70
73 2, -- 70
74 3 -- 70
75 } -- 70
76 assert.same(t[1], 1) -- 71
77 assert.same(t[2], 2) -- 72
78 return assert.same(t[3], 3) -- 73
79 end) -- 69
80 return it("should support mixed table", function() -- 75
81 local t = { -- 77
82 1, -- 77
83 2, -- 77
84 3, -- 77
85 key = "value" -- 78
86 } -- 76
87 assert.same(t[1], 1) -- 80
88 return assert.same(t.key, "value") -- 81
89 end) -- 75
90end) -- 1
diff --git a/spec/outputs/5.1/test/macro_spec.lua b/spec/outputs/5.1/test/macro_spec.lua
deleted file mode 100644
index 3d60580..0000000
--- a/spec/outputs/5.1/test/macro_spec.lua
+++ /dev/null
@@ -1,161 +0,0 @@
1return describe("macro", function() -- 1
2 it("should define and call basic macro", function() -- 2
3 local result = (5 * 2) -- 4
4 return assert.same(result, 10) -- 5
5 end) -- 2
6 it("should maintain hygiene in macros", function() -- 7
7 local a = 8 -- 12
8 local result = 2 -- 13
9 return assert.same(result, 2) -- 14
10 end) -- 7
11 it("should validate AST types", function() -- 16
12 local result = { -- 18
13 123, -- 18
14 'xyz' -- 18
15 } -- 18
16 return assert.same(result, "[123, xyz]") -- 19
17 end) -- 16
18 it("should support simple code generation", function() -- 21
19 local result = (10 + 1) -- 23
20 return assert.same(result, 11) -- 24
21 end) -- 21
22 it("should support nested macro calls", function() -- 26
23 local result = 7 -- 29
24 return assert.same(result, 7) -- 30
25 end) -- 26
26 it("should respect macro scope in do blocks", function() -- 32
27 do -- 34
28 local result = inner -- 36
29 assert.same(result, "inner") -- 37
30 end -- 34
31 local result = outer -- 38
32 return assert.same(result, "outer") -- 39
33 end) -- 32
34 it("should provide $LINE macro", function() -- 41
35 local line_num = 42 -- 42
36 return assert.is_true(line_num > 0) -- 43
37 end) -- 41
38 it("should inject Lua code", function() -- 45
39 local x = 0 -- 47
40 do -- 48
41local function f(a)
42 return a + 1
43 end
44 x = x + f(3)
45 end -- 48
46 return assert.same(x, 4) -- 54
47 end) -- 45
48 it("should work in conditional compilation", function() -- 56
49 local result = "debug mode" -- 62
50 return assert.same(result, "debug mode") -- 63
51 end) -- 56
52 it("should work with class system", function() -- 65
53 local Thing -- 66
54 do -- 66
55 local _class_0 -- 66
56 local _base_0 = { -- 66
57 value = 100, -- 68
58 get_value = function(self) -- 68
59 return self.value -- 68
60 end -- 66
61 } -- 66
62 if _base_0.__index == nil then -- 66
63 _base_0.__index = _base_0 -- 66
64 end -- 66
65 _class_0 = setmetatable({ -- 66
66 __init = function() end, -- 66
67 __base = _base_0, -- 66
68 __name = "Thing" -- 66
69 }, { -- 66
70 __index = _base_0, -- 66
71 __call = function(cls, ...) -- 66
72 local _self_0 = setmetatable({ }, _base_0) -- 66
73 cls.__init(_self_0, ...) -- 66
74 return _self_0 -- 66
75 end -- 66
76 }) -- 66
77 _base_0.__class = _class_0 -- 66
78 Thing = _class_0 -- 66
79 end -- 66
80 local instance = Thing() -- 69
81 return assert.same(instance:get_value(), 100) -- 70
82 end) -- 65
83 it("should handle macro in switch expressions", function() -- 72
84 local result -- 74
85 do -- 74
86 local _exp_0 = "test" -- 74
87 if "test" == _exp_0 then -- 75
88 result = "matched" -- 76
89 else -- 78
90 result = "no match" -- 78
91 end -- 74
92 end -- 74
93 return assert.same(result, "matched") -- 79
94 end) -- 72
95 it("should support macro in expression context", function() -- 81
96 local result = 5 + (2 * 3) -- 83
97 return assert.same(result, 11) -- 84
98 end) -- 81
99 it("should handle $is_ast for type checking", function() -- 86
100 local result = 42 -- 91
101 return assert.same(result, 42) -- 92
102 end) -- 86
103 it("should work with string interpolation", function() -- 94
104 local result = { -- 96
105 ["test"] = 123 -- 96
106 } -- 96
107 return assert.same(result, "test: 123") -- 97
108 end) -- 94
109 it("should support function call syntax", function() -- 99
110 local result = (5 + 10) -- 101
111 return assert.same(result, 15) -- 102
112 end) -- 99
113 it("should handle empty macro return", function() -- 104
114 local a = 1 -- 106
115 a = 2 -- 108
116 return assert.same(a, 2) -- 109
117 end) -- 104
118 it("should work with table literals", function() -- 111
119 local point = { -- 113
120 x = 10, -- 113
121 y = 20 -- 113
122 } -- 113
123 assert.same(point.x, 10) -- 114
124 return assert.same(point.y, 20) -- 115
125 end) -- 111
126 it("should support conditional expressions in macro", function() -- 117
127 local result = (5 + 1) -- 119
128 return assert.same(result, 6) -- 120
129 end) -- 117
130 it("should work with comprehension", function() -- 122
131 local result -- 124
132 do -- 124
133 local _accum_0 = { } -- 124
134 local _len_0 = 1 -- 124
135 local _list_0 = { -- 124
136 1, -- 124
137 2, -- 124
138 3 -- 124
139 } -- 124
140 for _index_0 = 1, #_list_0 do -- 124
141 local _ = _list_0[_index_0] -- 124
142 _accum_0[_len_0] = _ * 2 -- 124
143 _len_0 = _len_0 + 1 -- 124
144 end -- 124
145 result = _accum_0 -- 124
146 end -- 124
147 return assert.same(result, { -- 125
148 2, -- 125
149 4, -- 125
150 6 -- 125
151 }) -- 125
152 end) -- 122
153 it("should support complex expression macros", function() -- 127
154 local result = (1 + 2 * 3) -- 129
155 return assert.same(result, 7) -- 130
156 end) -- 127
157 return it("should work with string literals", function() -- 132
158 local result = "Hello, " .. tostring(name) -- 134
159 return assert.same(result, "Hello, World") -- 135
160 end) -- 132
161end) -- 1
diff --git a/spec/outputs/5.1/test/metatable_spec.lua b/spec/outputs/5.1/test/metatable_spec.lua
deleted file mode 100644
index 8088b0c..0000000
--- a/spec/outputs/5.1/test/metatable_spec.lua
+++ /dev/null
@@ -1,141 +0,0 @@
1return describe("metatable", function() -- 1
2 it("should get metatable with <> syntax", function() -- 2
3 local obj = setmetatable({ -- 3
4 value = 42 -- 3
5 }, { -- 3
6 __index = { -- 3
7 extra = "data" -- 3
8 } -- 3
9 }) -- 3
10 local mt = getmetatable(obj) -- 4
11 return assert.is_true(mt ~= nil) -- 5
12 end) -- 2
13 it("should set metatable with <>", function() -- 7
14 local obj = { } -- 8
15 setmetatable(obj, { -- 9
16 __index = { -- 9
17 value = 100 -- 9
18 } -- 9
19 }) -- 9
20 return assert.same(obj.value, 100) -- 10
21 end) -- 7
22 it("should access metatable with <>", function() -- 12
23 local obj = setmetatable({ }, { -- 13
24 __index = { -- 13
25 value = 50 -- 13
26 } -- 13
27 }) -- 13
28 local result = getmetatable(obj).__index.value -- 14
29 return assert.same(result, 50) -- 15
30 end) -- 12
31 it("should work with <index> metamethod", function() -- 17
32 local obj = setmetatable({ }, { -- 19
33 __index = function(self, key) -- 19
34 if key == "computed" then -- 20
35 return "computed_value" -- 21
36 end -- 20
37 end -- 19
38 }) -- 18
39 return assert.same(obj.computed, "computed_value") -- 23
40 end) -- 17
41 it("should work with <newindex> metamethod", function() -- 25
42 local obj = setmetatable({ }, { -- 27
43 __newindex = function(self, key, value) -- 27
44 return rawset(self, "stored_" .. key, value) -- 28
45 end -- 27
46 }) -- 26
47 obj.test = 123 -- 30
48 return assert.same(obj.stored_test, 123) -- 31
49 end) -- 25
50 it("should work with <add> metamethod", function() -- 33
51 local obj = setmetatable({ -- 34
52 value = 10 -- 34
53 }, { -- 35
54 __add = function(a, b) -- 35
55 return a.value + b.value -- 35
56 end -- 35
57 }) -- 34
58 local obj2 = setmetatable({ -- 37
59 value = 20 -- 37
60 }, { -- 38
61 __add = function(a, b) -- 38
62 return a.value + b.value -- 38
63 end -- 38
64 }) -- 37
65 local result = obj + obj2 -- 40
66 return assert.same(result, 30) -- 41
67 end) -- 33
68 it("should work with <call> metamethod", function() -- 43
69 local obj = setmetatable({ }, { -- 45
70 __call = function(self, x) -- 45
71 return x * 2 -- 45
72 end -- 45
73 }) -- 44
74 local result = obj(5) -- 47
75 return assert.same(result, 10) -- 48
76 end) -- 43
77 it("should work with <tostring> metamethod", function() -- 50
78 local obj = setmetatable({ -- 51
79 value = 42 -- 51
80 }, { -- 52
81 __tostring = function(self) -- 52
82 return "Value: " .. tostring(self.value) -- 52
83 end -- 52
84 }) -- 51
85 local result = tostring(obj) -- 54
86 return assert.same(result, "Value: 42") -- 55
87 end) -- 50
88 it("should work with <eq> metamethod", function() -- 57
89 local obj1 = setmetatable({ -- 58
90 id = 1 -- 58
91 }, { -- 59
92 __eq = function(a, b) -- 59
93 return a.id == b.id -- 59
94 end -- 59
95 }) -- 58
96 local obj2 = setmetatable({ -- 61
97 id = 1 -- 61
98 }, { -- 62
99 __eq = function(a, b) -- 62
100 return a.id == b.id -- 62
101 end -- 62
102 }) -- 61
103 return assert.is_true(obj1 == obj2) -- 64
104 end) -- 57
105 it("should destructure metatable", function() -- 66
106 local obj = setmetatable({ }, { -- 68
107 new = function() -- 68
108 return "new result" -- 68
109 end, -- 68
110 update = function() -- 69
111 return "update result" -- 69
112 end -- 69
113 }) -- 67
114 local new, update -- 71
115 do -- 71
116 local _obj_0 = getmetatable(obj) -- 71
117 new, update = _obj_0.new, _obj_0.update -- 71
118 end -- 71
119 assert.is_true(type(new) == "function") -- 72
120 return assert.is_true(type(update) == "function") -- 73
121 end) -- 66
122 it("should check if two objects have same metatable", function() -- 75
123 local mt = { -- 76
124 value = 100 -- 76
125 } -- 76
126 local obj1 = setmetatable({ }, mt) -- 77
127 local obj2 = setmetatable({ }, mt) -- 78
128 return assert.is_true(getmetatable(obj1) == getmetatable(obj2)) -- 79
129 end) -- 75
130 return it("should work with <concat> metamethod", function() -- 81
131 local obj = setmetatable({ -- 82
132 value = "hello" -- 82
133 }, { -- 83
134 __concat = function(a, b) -- 83
135 return a.value .. b -- 83
136 end -- 83
137 }) -- 82
138 local result = obj .. " world" -- 85
139 return assert.same(result, "hello world") -- 86
140 end) -- 81
141end) -- 1
diff --git a/spec/outputs/5.1/test/operators_spec.lua b/spec/outputs/5.1/test/operators_spec.lua
deleted file mode 100644
index 661c422..0000000
--- a/spec/outputs/5.1/test/operators_spec.lua
+++ /dev/null
@@ -1,142 +0,0 @@
1return describe("operators", function() -- 1
2 it("should support addition", function() -- 2
3 return assert.same(1 + 2, 3) -- 3
4 end) -- 2
5 it("should support subtraction", function() -- 5
6 return assert.same(5 - 3, 2) -- 6
7 end) -- 5
8 it("should support multiplication", function() -- 8
9 return assert.same(4 * 3, 12) -- 9
10 end) -- 8
11 it("should support division", function() -- 11
12 return assert.same(10 / 2, 5) -- 12
13 end) -- 11
14 it("should support modulo", function() -- 14
15 return assert.same(10 % 3, 1) -- 15
16 end) -- 14
17 it("should support exponentiation", function() -- 17
18 return assert.same(2 ^ 3, 8) -- 18
19 end) -- 17
20 it("should support unary minus", function() -- 20
21 return assert.same(-5, -5) -- 21
22 end) -- 20
23 it("should support equality comparison", function() -- 23
24 assert.is_true(1 == 1) -- 24
25 return assert.is_false(1 == 2) -- 25
26 end) -- 23
27 it("should support inequality comparison", function() -- 27
28 assert.is_true(1 ~= 2) -- 28
29 return assert.is_false(1 ~= 1) -- 29
30 end) -- 27
31 it("should support less than", function() -- 31
32 assert.is_true(1 < 2) -- 32
33 return assert.is_false(2 < 1) -- 33
34 end) -- 31
35 it("should support greater than", function() -- 35
36 assert.is_true(2 > 1) -- 36
37 return assert.is_false(1 > 2) -- 37
38 end) -- 35
39 it("should support less than or equal", function() -- 39
40 assert.is_true(1 <= 2) -- 40
41 assert.is_true(2 <= 2) -- 41
42 return assert.is_false(3 <= 2) -- 42
43 end) -- 39
44 it("should support greater than or equal", function() -- 44
45 assert.is_true(2 >= 1) -- 45
46 assert.is_true(2 >= 2) -- 46
47 return assert.is_false(1 >= 2) -- 47
48 end) -- 44
49 it("should support logical and", function() -- 49
50 assert.same(true and false, false) -- 50
51 assert.same(true and true, true) -- 51
52 return assert.same(false and true, false) -- 52
53 end) -- 49
54 it("should support logical or", function() -- 54
55 assert.same(true or false, true) -- 55
56 assert.same(false or true, true) -- 56
57 return assert.same(false or false, false) -- 57
58 end) -- 54
59 it("should support logical not", function() -- 59
60 assert.same(not true, false) -- 60
61 assert.same(not false, true) -- 61
62 return assert.same(not nil, true) -- 62
63 end) -- 59
64 it("should support bitwise and", function() -- 64
65 return assert.same(5 & 3, 1) -- 65
66 end) -- 64
67 it("should support bitwise or", function() -- 67
68 return assert.same(5 | 3, 7) -- 68
69 end) -- 67
70 it("should support bitwise xor", function() -- 70
71 return assert.same(5 ~ 3, 6) -- 71
72 end) -- 70
73 it("should support left shift", function() -- 73
74 return assert.same(2 << 3, 16) -- 74
75 end) -- 73
76 it("should support right shift", function() -- 76
77 return assert.same(16 >> 2, 4) -- 77
78 end) -- 76
79 it("should support string concatenation", function() -- 79
80 return assert.same("hello" .. " world", "hello world") -- 80
81 end) -- 79
82 it("should support length operator", function() -- 82
83 assert.same(#"hello", 5) -- 83
84 return assert.same(#{ -- 84
85 1, -- 84
86 2, -- 84
87 3 -- 84
88 }, 3) -- 84
89 end) -- 82
90 it("should respect operator precedence", function() -- 86
91 assert.same(1 + 2 * 3, 7) -- 87
92 return assert.same((1 + 2) * 3, 9) -- 88
93 end) -- 86
94 it("should support compound assignment", function() -- 90
95 local x = 10 -- 91
96 x = x + 5 -- 92
97 return assert.same(x, 15) -- 93
98 end) -- 90
99 it("should support compound subtraction", function() -- 95
100 local x = 10 -- 96
101 x = x - 3 -- 97
102 return assert.same(x, 7) -- 98
103 end) -- 95
104 it("should support compound multiplication", function() -- 100
105 local x = 5 -- 101
106 x = x * 2 -- 102
107 return assert.same(x, 10) -- 103
108 end) -- 100
109 it("should support compound division", function() -- 105
110 local x = 20 -- 106
111 x = x / 4 -- 107
112 return assert.same(x, 5) -- 108
113 end) -- 105
114 it("should handle division by zero", function() -- 110
115 local result = pcall(function() -- 112
116 local x = 10 / 0 -- 113
117 end) -- 112
118 return assert.is_true(result) -- 115
119 end) -- 110
120 it("should handle very large numbers", function() -- 117
121 local big = 1e100 -- 118
122 return assert.is_true(big > 0) -- 119
123 end) -- 117
124 it("should handle very small numbers", function() -- 121
125 local small = 1e-100 -- 122
126 return assert.is_true(small > 0) -- 123
127 end) -- 121
128 it("should support negation", function() -- 125
129 assert.same(-10, -10) -- 126
130 return assert.same -- 127
131 end) -- 125
132 it("should work with complex expressions", function() -- 129
133 local result = (1 + 2) * (3 + 4) / 2 -- 130
134 return assert.same(result, 10.5) -- 131
135 end) -- 129
136 it("should support power with decimal", function() -- 133
137 return assert.same(4 ^ 0.5, 2) -- 134
138 end) -- 133
139 return it("should handle modulo with negative numbers", function() -- 136
140 return assert.same(-10 % 3, 2) -- 137
141 end) -- 136
142end) -- 1
diff --git a/spec/outputs/5.1/test/return_spec.lua b/spec/outputs/5.1/test/return_spec.lua
deleted file mode 100644
index 4e6580f..0000000
--- a/spec/outputs/5.1/test/return_spec.lua
+++ /dev/null
@@ -1,145 +0,0 @@
1return describe("return", function() -- 1
2 it("should return from comprehension", function() -- 2
3 local fn -- 3
4 fn = function() -- 3
5 local _accum_0 = { } -- 4
6 local _len_0 = 1 -- 4
7 for x = 1, 5 do -- 4
8 _accum_0[_len_0] = x * 2 -- 4
9 _len_0 = _len_0 + 1 -- 4
10 end -- 4
11 return _accum_0 -- 4
12 end -- 3
13 local result = fn() -- 5
14 return assert.same(result, { -- 6
15 2, -- 6
16 4, -- 6
17 6, -- 6
18 8, -- 6
19 10 -- 6
20 }) -- 6
21 end) -- 2
22 it("should return from table comprehension", function() -- 8
23 local fn -- 9
24 fn = function() -- 9
25 local _tbl_0 = { } -- 10
26 for k, v in pairs({ -- 10
27 a = 1, -- 10
28 b = 2 -- 10
29 }) do -- 10
30 _tbl_0[k] = v -- 10
31 end -- 10
32 return _tbl_0 -- 10
33 end -- 9
34 local result = fn() -- 11
35 return assert.same(type(result), "table") -- 12
36 end) -- 8
37 it("should return from nested if", function() -- 14
38 local fn -- 15
39 fn = function(a, b) -- 15
40 if a then -- 16
41 if b then -- 17
42 return "both" -- 18
43 else -- 20
44 return "only a" -- 20
45 end -- 17
46 else -- 22
47 return "neither" -- 22
48 end -- 16
49 end -- 15
50 assert.same(fn(true, true), "both") -- 23
51 assert.same(fn(true, false), "only a") -- 24
52 return assert.same(fn(false, false), "neither") -- 25
53 end) -- 14
54 it("should return from switch", function() -- 27
55 local fn -- 28
56 fn = function(value) -- 28
57 if 1 == value then -- 30
58 return "one" -- 30
59 elseif 2 == value then -- 31
60 return "two" -- 31
61 else -- 32
62 return "other" -- 32
63 end -- 29
64 end -- 28
65 assert.same(fn(1), "one") -- 33
66 assert.same(fn(2), "two") -- 34
67 return assert.same(fn(3), "other") -- 35
68 end) -- 27
69 it("should return table literal", function() -- 37
70 local fn -- 38
71 fn = function() -- 38
72 return { -- 40
73 value = 42, -- 40
74 name = "test" -- 41
75 } -- 39
76 end -- 38
77 local result = fn() -- 42
78 assert.same(result.value, 42) -- 43
79 return assert.same(result.name, "test") -- 44
80 end) -- 37
81 it("should return array literal", function() -- 46
82 local fn -- 47
83 fn = function() -- 47
84 return { -- 49
85 1, -- 49
86 2, -- 50
87 3 -- 51
88 } -- 48
89 end -- 47
90 local result = fn() -- 52
91 return assert.same(result, { -- 53
92 1, -- 53
93 2, -- 53
94 3 -- 53
95 }) -- 53
96 end) -- 46
97 it("should return from with statement", function() -- 55
98 local fn -- 56
99 fn = function(obj) -- 56
100 local result = obj.value -- 57
101 return result -- 58
102 end -- 56
103 return assert.same(fn({ -- 59
104 value = 100 -- 59
105 }), 100) -- 59
106 end) -- 55
107 it("should return nil implicitly", function() -- 61
108 fn(function() -- 62
109 return print("no return") -- 62
110 end) -- 62
111 return assert.same(fn(), nil) -- 63
112 end) -- 61
113 it("should return multiple values", function() -- 65
114 fn(function() -- 66
115 return 1, 2, 3 -- 66
116 end) -- 66
117 local a, b, c = fn() -- 67
118 assert.same(a, 1) -- 68
119 assert.same(b, 2) -- 69
120 return assert.same(c, 3) -- 70
121 end) -- 65
122 it("should return from function call", function() -- 72
123 local fn -- 73
124 fn = function() -- 73
125 local inner -- 74
126 inner = function() -- 74
127 return 42 -- 74
128 end -- 74
129 return inner() -- 75
130 end -- 73
131 return assert.same(fn(), 42) -- 76
132 end) -- 72
133 return it("should handle return in expression context", function() -- 78
134 local fn -- 79
135 fn = function(cond) -- 79
136 if cond then -- 80
137 return "yes" -- 81
138 else -- 83
139 return "no" -- 83
140 end -- 80
141 end -- 79
142 assert.same(fn(true), "yes") -- 84
143 return assert.same(fn(false), "no") -- 85
144 end) -- 78
145end) -- 1
diff --git a/spec/outputs/5.1/test/string_spec.lua b/spec/outputs/5.1/test/string_spec.lua
deleted file mode 100644
index 95eb470..0000000
--- a/spec/outputs/5.1/test/string_spec.lua
+++ /dev/null
@@ -1,138 +0,0 @@
1return describe("string", function() -- 1
2 it("should support single quote strings", function() -- 2
3 local s = 'hello' -- 3
4 return assert.same(s, "hello") -- 4
5 end) -- 2
6 it("should support double quote strings", function() -- 6
7 local s = "world" -- 7
8 return assert.same(s, "world") -- 8
9 end) -- 6
10 it("should support escape sequences", function() -- 10
11 local s = "hello\nworld" -- 11
12 return assert.is_true(s:match("\n") ~= nil) -- 12
13 end) -- 10
14 it("should support escaped quotes", function() -- 14
15 local s = "he said \"hello\"" -- 15
16 return assert.same(s, 'he said "hello"') -- 16
17 end) -- 14
18 it("should support backslash escape", function() -- 18
19 local s = "\\" -- 19
20 return assert.same(s, "\\") -- 20
21 end) -- 18
22 it("should support multi-line strings with [[ ]]", function() -- 22
23 local s = [[ hello
24 world
25 ]] -- 23
26 assert.is_true(s:match("hello") ~= nil) -- 27
27 return assert.is_true(s:match("world") ~= nil) -- 28
28 end) -- 22
29 it("should support multi-line strings with [=[ ]=]", function() -- 30
30 local s = [==[ hello
31 world
32 ]==] -- 31
33 assert.is_true(s:match("hello") ~= nil) -- 35
34 return assert.is_true(s:match("world") ~= nil) -- 36
35 end) -- 30
36 it("should support string interpolation with double quotes", function() -- 38
37 local name = "world" -- 39
38 local s = "hello " .. tostring(name) -- 40
39 return assert.same(s, "hello world") -- 41
40 end) -- 38
41 it("should support expression interpolation", function() -- 43
42 local a, b = 1, 2 -- 44
43 local s = tostring(a) .. " + " .. tostring(b) .. " = " .. tostring(a + b) -- 45
44 return assert.same(s, "1 + 2 = 3") -- 46
45 end) -- 43
46 it("should not interpolate in single quotes", function() -- 48
47 local name = "world" -- 49
48 local s = 'hello #{name}' -- 50
49 return assert.same(s, "hello " .. tostring(name)) -- 51
50 end) -- 48
51 it("should escape interpolation with \#", function() -- 53
52 local name = "world" -- 54
53 local s = "hello \\" .. tostring(name) -- 55
54 return assert.same(s, "hello " .. tostring(name)) -- 56
55 end) -- 53
56 it("should support method calls on string literals", function() -- 58
57 local result = ("hello"):upper() -- 59
58 return assert.same(result, "HELLO") -- 60
59 end) -- 58
60 it("should support chained method calls", function() -- 62
61 local result = ("hello world"):upper():match("HELLO") -- 63
62 return assert.same(result, "HELLO") -- 64
63 end) -- 62
64 it("should support YAML style strings", function() -- 66
65 local s = "hello\nworld" -- 67
66 assert.is_true(s:match("hello") ~= nil) -- 70
67 return assert.is_true(s:match("world") ~= nil) -- 71
68 end) -- 66
69 it("should support YAML style with interpolation", function() -- 73
70 local name = "test" -- 74
71 local s = "hello " .. tostring(name) -- 75
72 return assert.same(s, "hello test\n") -- 77
73 end) -- 73
74 it("should support string concatenation", function() -- 79
75 local s = "hello" .. " " .. "world" -- 80
76 return assert.same(s, "hello world") -- 81
77 end) -- 79
78 it("should handle empty strings", function() -- 83
79 local s = "" -- 84
80 return assert.same(s, "") -- 85
81 end) -- 83
82 it("should support Unicode characters", function() -- 87
83 local s = "hello 世界" -- 88
84 return assert.is_true(s:match("世界") ~= nil) -- 89
85 end) -- 87
86 it("should support string length", function() -- 91
87 local s = "hello" -- 92
88 return assert.same(#s, 5) -- 93
89 end) -- 91
90 it("should support multi-line YAML with complex content", function() -- 95
91 local config = "key1: value1\nkey2: value2\nkey3: value3" -- 96
92 return assert.is_true(config:match("key1") ~= nil) -- 100
93 end) -- 95
94 it("should support interpolation in YAML strings", function() -- 102
95 local x, y = 10, 20 -- 103
96 local s = "point:\n\tx: " .. tostring(x) .. "\n\ty: " .. tostring(y) -- 104
97 assert.is_true(s:match("x: 10") ~= nil) -- 108
98 return assert.is_true(s:match("y: 20") ~= nil) -- 109
99 end) -- 102
100 it("should support function call in interpolation", function() -- 111
101 local s = "result: " .. tostring(function() -- 112
102 return 42 -- 112
103 end) -- 112
104 return assert.same(s, "result: 42") -- 113
105 end) -- 111
106 it("should support table indexing in interpolation", function() -- 115
107 local t = { -- 116
108 value = 100 -- 116
109 } -- 116
110 local s = "value: " .. tostring(t.value) -- 117
111 return assert.same(s, "value: 100") -- 118
112 end) -- 115
113 it("should handle escaped characters correctly", function() -- 120
114 local s = "tab:\t, newline:\n, return:\r" -- 121
115 assert.is_true(s:match("\t") ~= nil) -- 122
116 return assert.is_true(s:match("\n") ~= nil) -- 123
117 end) -- 120
118 it("should support string methods with colon syntax", function() -- 125
119 local s = "hello" -- 126
120 return assert.same(s:sub(1, 2), "he") -- 127
121 end) -- 125
122 it("should work in expressions", function() -- 129
123 local result = "hello" .. " world" -- 130
124 return assert.same(result, "hello world") -- 131
125 end) -- 129
126 it("should support octal escape", function() -- 133
127 local s = "\65" -- 134
128 return assert.same(s, "A") -- 135
129 end) -- 133
130 it("should support hex escape", function() -- 137
131 local s = "\x41" -- 138
132 return assert.same(s, "A") -- 139
133 end) -- 137
134 return it("should support unicode escape", function() -- 141
135 local s = "\u{4e16}" -- 142
136 return assert.same(s, "世") -- 143
137 end) -- 141
138end) -- 1
diff --git a/spec/outputs/5.1/test/switch_spec.lua b/spec/outputs/5.1/test/switch_spec.lua
deleted file mode 100644
index 5b13970..0000000
--- a/spec/outputs/5.1/test/switch_spec.lua
+++ /dev/null
@@ -1,743 +0,0 @@
1return describe("switch", function() -- 1
2 it("should match single value", function() -- 2
3 local value = "cool" -- 3
4 local result -- 4
5 if "cool" == value then -- 5
6 result = "matched" -- 6
7 else -- 8
8 result = "not matched" -- 8
9 end -- 4
10 return assert.same(result, "matched") -- 9
11 end) -- 2
12 it("should match multiple values with or", function() -- 11
13 local hi = "world" -- 12
14 local matched = false -- 13
15 if "one" == hi or "two" == hi then -- 15
16 matched = true -- 16
17 end -- 14
18 assert.is_false(matched) -- 17
19 hi = "one" -- 19
20 if "one" == hi or "two" == hi then -- 21
21 matched = true -- 22
22 end -- 20
23 return assert.is_true(matched) -- 23
24 end) -- 11
25 it("should execute else branch when no match", function() -- 25
26 local value = "other" -- 26
27 local result -- 27
28 if "cool" == value then -- 28
29 result = "matched cool" -- 29
30 elseif "yeah" == value then -- 30
31 result = "matched yeah" -- 31
32 else -- 33
33 result = "else branch" -- 33
34 end -- 27
35 return assert.same(result, "else branch") -- 34
36 end) -- 25
37 it("should destructure table with single key", function() -- 36
38 local tb = { -- 37
39 x = 100 -- 37
40 } -- 37
41 local result -- 38
42 do -- 39
43 local _type_0 = type(tb) -- 39
44 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 39
45 local _match_0 = false -- 39
46 if _tab_0 then -- 39
47 local x = tb.x -- 39
48 if x ~= nil then -- 39
49 _match_0 = true -- 39
50 result = x -- 40
51 end -- 39
52 end -- 39
53 if not _match_0 then -- 39
54 result = "no match" -- 42
55 end -- 38
56 end -- 38
57 return assert.same(result, 100) -- 43
58 end) -- 36
59 it("should destructure table with multiple keys", function() -- 45
60 local tb = { -- 46
61 x = 100, -- 46
62 y = 200 -- 46
63 } -- 46
64 local result -- 47
65 do -- 48
66 local _type_0 = type(tb) -- 48
67 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 48
68 local _match_0 = false -- 48
69 if _tab_0 then -- 48
70 local x = tb.x -- 48
71 local y = tb.y -- 48
72 if x ~= nil and y ~= nil then -- 48
73 _match_0 = true -- 48
74 result = x + y -- 49
75 end -- 48
76 end -- 48
77 if not _match_0 then -- 48
78 result = "no match" -- 51
79 end -- 47
80 end -- 47
81 return assert.same(result, 300) -- 52
82 end) -- 45
83 it("should destructure table with default values", function() -- 54
84 local tb = { -- 55
85 a = 1 -- 55
86 } -- 55
87 local _type_0 = type(tb) -- 57
88 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 57
89 if _tab_0 then -- 57
90 local a = tb.a -- 57
91 local b = tb.b -- 57
92 if a == nil then -- 57
93 a = 1 -- 57
94 end -- 57
95 if b == nil then -- 57
96 b = 2 -- 57
97 end -- 57
98 assert.same(a, 1) -- 58
99 return assert.same(b, 2) -- 59
100 end -- 56
101 end) -- 54
102 it("should destructure nested tables", function() -- 61
103 local dict = { -- 63
104 { }, -- 63
105 { -- 64
106 1, -- 64
107 2, -- 64
108 3 -- 64
109 }, -- 64
110 a = { -- 65
111 b = { -- 65
112 c = 1 -- 65
113 } -- 65
114 }, -- 65
115 x = { -- 66
116 y = { -- 66
117 z = 1 -- 66
118 } -- 66
119 } -- 66
120 } -- 62
121 local matched = false -- 68
122 do -- 70
123 local _type_0 = type(dict) -- 70
124 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 70
125 if _tab_0 then -- 70
126 local first = dict[1] -- 70
127 local one -- 70
128 do -- 70
129 local _obj_0 = dict[2] -- 70
130 local _type_1 = type(_obj_0) -- 70
131 if "table" == _type_1 or "userdata" == _type_1 then -- 70
132 one = _obj_0[1] -- 70
133 end -- 70
134 end -- 70
135 local two -- 70
136 do -- 70
137 local _obj_0 = dict[2] -- 70
138 local _type_1 = type(_obj_0) -- 70
139 if "table" == _type_1 or "userdata" == _type_1 then -- 70
140 two = _obj_0[2] -- 70
141 end -- 70
142 end -- 70
143 local three -- 70
144 do -- 70
145 local _obj_0 = dict[2] -- 70
146 local _type_1 = type(_obj_0) -- 70
147 if "table" == _type_1 or "userdata" == _type_1 then -- 70
148 three = _obj_0[3] -- 70
149 end -- 70
150 end -- 70
151 local c -- 70
152 do -- 70
153 local _obj_0 = dict.a -- 70
154 local _type_1 = type(_obj_0) -- 70
155 if "table" == _type_1 or "userdata" == _type_1 then -- 70
156 do -- 70
157 local _obj_1 = _obj_0.b -- 70
158 local _type_2 = type(_obj_1) -- 70
159 if "table" == _type_2 or "userdata" == _type_2 then -- 70
160 c = _obj_1.c -- 70
161 end -- 70
162 end -- 70
163 end -- 70
164 end -- 70
165 local z -- 70
166 do -- 70
167 local _obj_0 = dict.x -- 70
168 local _type_1 = type(_obj_0) -- 70
169 if "table" == _type_1 or "userdata" == _type_1 then -- 70
170 do -- 70
171 local _obj_1 = _obj_0.y -- 70
172 local _type_2 = type(_obj_1) -- 70
173 if "table" == _type_2 or "userdata" == _type_2 then -- 70
174 z = _obj_1.z -- 70
175 end -- 70
176 end -- 70
177 end -- 70
178 end -- 70
179 if first ~= nil and one ~= nil and two ~= nil and three ~= nil and c ~= nil and z ~= nil then -- 70
180 matched = first == { } and one == 1 and two == 2 and three == 3 and c == 1 and z == 1 -- 76
181 end -- 70
182 end -- 69
183 end -- 69
184 return assert.is_true(matched) -- 77
185 end) -- 61
186 it("should destructure arrays with exact match", function() -- 79
187 local tb = { -- 80
188 1, -- 80
189 2, -- 80
190 3 -- 80
191 } -- 80
192 local result -- 81
193 do -- 82
194 local _type_0 = type(tb) -- 82
195 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 82
196 local _match_0 = false -- 82
197 if _tab_0 then -- 82
198 if 1 == tb[1] and 2 == tb[2] and 3 == tb[3] then -- 82
199 _match_0 = true -- 82
200 result = "exact match" -- 83
201 end -- 82
202 end -- 82
203 if not _match_0 then -- 82
204 result = "no match" -- 85
205 end -- 81
206 end -- 81
207 return assert.same(result, "exact match") -- 86
208 end) -- 79
209 it("should destructure arrays with variables", function() -- 88
210 local tb = { -- 89
211 1, -- 89
212 "b", -- 89
213 3 -- 89
214 } -- 89
215 local result -- 90
216 do -- 91
217 local _type_0 = type(tb) -- 91
218 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 91
219 local _match_0 = false -- 91
220 if _tab_0 then -- 91
221 local b = tb[2] -- 91
222 if 1 == tb[1] and b ~= nil and 3 == tb[3] then -- 91
223 _match_0 = true -- 91
224 result = b -- 92
225 end -- 91
226 end -- 91
227 if not _match_0 then -- 91
228 result = "no match" -- 94
229 end -- 90
230 end -- 90
231 return assert.same(result, "b") -- 95
232 end) -- 88
233 it("should destructure arrays with defaults", function() -- 97
234 local tb = { -- 98
235 1, -- 98
236 2 -- 98
237 } -- 98
238 local result -- 99
239 do -- 100
240 local _type_0 = type(tb) -- 100
241 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 100
242 local _match_0 = false -- 100
243 if _tab_0 then -- 100
244 local b = tb[3] -- 100
245 if b == nil then -- 100
246 b = 3 -- 100
247 end -- 100
248 if 1 == tb[1] and 2 == tb[2] then -- 100
249 _match_0 = true -- 100
250 result = b -- 101
251 end -- 100
252 end -- 100
253 if not _match_0 then -- 100
254 result = "no match" -- 103
255 end -- 99
256 end -- 99
257 return assert.same(result, 3) -- 104
258 end) -- 97
259 it("should match pattern with __class", function() -- 106
260 local ClassA -- 107
261 do -- 107
262 local _class_0 -- 107
263 local _base_0 = { } -- 107
264 if _base_0.__index == nil then -- 107
265 _base_0.__index = _base_0 -- 107
266 end -- 107
267 _class_0 = setmetatable({ -- 107
268 __init = function() end, -- 107
269 __base = _base_0, -- 107
270 __name = "ClassA" -- 107
271 }, { -- 107
272 __index = _base_0, -- 107
273 __call = function(cls, ...) -- 107
274 local _self_0 = setmetatable({ }, _base_0) -- 107
275 cls.__init(_self_0, ...) -- 107
276 return _self_0 -- 107
277 end -- 107
278 }) -- 107
279 _base_0.__class = _class_0 -- 107
280 ClassA = _class_0 -- 107
281 end -- 107
282 local ClassB -- 108
283 do -- 108
284 local _class_0 -- 108
285 local _base_0 = { } -- 108
286 if _base_0.__index == nil then -- 108
287 _base_0.__index = _base_0 -- 108
288 end -- 108
289 _class_0 = setmetatable({ -- 108
290 __init = function() end, -- 108
291 __base = _base_0, -- 108
292 __name = "ClassB" -- 108
293 }, { -- 108
294 __index = _base_0, -- 108
295 __call = function(cls, ...) -- 108
296 local _self_0 = setmetatable({ }, _base_0) -- 108
297 cls.__init(_self_0, ...) -- 108
298 return _self_0 -- 108
299 end -- 108
300 }) -- 108
301 _base_0.__class = _class_0 -- 108
302 ClassB = _class_0 -- 108
303 end -- 108
304 local item = ClassA() -- 109
305 local result -- 110
306 do -- 111
307 local _type_0 = type(item) -- 111
308 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 111
309 local _match_0 = false -- 111
310 if _tab_0 then -- 111
311 ClassA = item.__class -- 111
312 if ClassA ~= nil then -- 111
313 _match_0 = true -- 111
314 result = "Object A" -- 112
315 end -- 111
316 end -- 111
317 if not _match_0 then -- 111
318 local _match_1 = false -- 113
319 if _tab_0 then -- 113
320 ClassB = item.__class -- 113
321 if ClassB ~= nil then -- 113
322 _match_1 = true -- 113
323 result = "Object B" -- 114
324 end -- 113
325 end -- 113
326 if not _match_1 then -- 113
327 result = "unknown" -- 116
328 end -- 110
329 end -- 110
330 end -- 110
331 return assert.same(result, "Object A") -- 117
332 end) -- 106
333 it("should match pattern with metatable", function() -- 119
334 local tb = setmetatable({ }, { -- 120
335 __mode = "v" -- 120
336 }) -- 120
337 local metatable_matched = false -- 121
338 do -- 123
339 local _type_0 = type(tb) -- 123
340 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 123
341 if _tab_0 then -- 123
342 local mt = getmetatable(tb) -- 123
343 if mt ~= nil then -- 123
344 metatable_matched = mt ~= nil -- 124
345 end -- 123
346 end -- 122
347 end -- 122
348 return assert.is_true(metatable_matched) -- 125
349 end) -- 119
350 it("should use switch as expression in assignment", function() -- 127
351 local tb = { -- 128
352 x = "abc" -- 128
353 } -- 128
354 local matched -- 129
355 if 1 == tb then -- 130
356 matched = "1" -- 131
357 else -- 132
358 do -- 132
359 local _type_0 = type(tb) -- 132
360 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 132
361 local _match_0 = false -- 132
362 if _tab_0 then -- 132
363 local x = tb.x -- 132
364 if x ~= nil then -- 132
365 _match_0 = true -- 132
366 matched = x -- 133
367 end -- 132
368 end -- 132
369 if not _match_0 then -- 132
370 if false == tb then -- 134
371 matched = "false" -- 135
372 else -- 137
373 matched = nil -- 137
374 end -- 129
375 end -- 129
376 end -- 129
377 end -- 129
378 return assert.same(matched, "abc") -- 138
379 end) -- 127
380 it("should use switch in return statement", function() -- 140
381 local fn -- 141
382 fn = function(tb) -- 141
383 if nil == tb then -- 143
384 return "invalid" -- 144
385 else -- 145
386 local _type_0 = type(tb) -- 145
387 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 145
388 local _match_0 = false -- 145
389 if _tab_0 then -- 145
390 local a = tb.a -- 145
391 local b = tb.b -- 145
392 if a ~= nil and b ~= nil then -- 145
393 _match_0 = true -- 145
394 return tostring(a + b) -- 146
395 end -- 145
396 end -- 145
397 if not _match_0 then -- 145
398 if 1 == tb or 2 == tb or 3 == tb or 4 == tb or 5 == tb then -- 147
399 return "number 1 - 5" -- 148
400 else -- 150
401 return "should not reach here" -- 150
402 end -- 142
403 end -- 142
404 end -- 142
405 end -- 141
406 assert.same(fn({ -- 151
407 a = 1, -- 151
408 b = 2 -- 151
409 }), "3") -- 151
410 assert.same(fn(3), "number 1 - 5") -- 152
411 return assert.same(fn(nil), "invalid") -- 153
412 end) -- 140
413 it("should support pattern matching assignment with :=", function() -- 155
414 local v = "hello" -- 156
415 local matched = false -- 157
416 do -- 158
417 v = "hello" -- 158
418 if "hello" == v then -- 159
419 matched = true -- 160
420 else -- 162
421 matched = false -- 162
422 end -- 158
423 end -- 158
424 assert.is_true(matched) -- 163
425 return assert.same(v, "hello") -- 164
426 end) -- 155
427 it("should match with computed expressions", function() -- 166
428 local hi = 4 -- 167
429 local matched = false -- 168
430 if (3 + 1) == hi or (function() -- 170
431 return 4 -- 170
432 end)() == hi or (5 - 1) == hi then -- 170
433 matched = true -- 171
434 end -- 169
435 return assert.is_true(matched) -- 172
436 end) -- 166
437 it("should handle nested array destructuring", function() -- 174
438 local tb = { -- 176
439 { -- 176
440 a = 1, -- 176
441 b = 2 -- 176
442 }, -- 176
443 { -- 177
444 a = 3, -- 177
445 b = 4 -- 177
446 }, -- 177
447 { -- 178
448 a = 5, -- 178
449 b = 6 -- 178
450 }, -- 178
451 "fourth" -- 179
452 } -- 175
453 local result -- 181
454 do -- 182
455 local _type_0 = type(tb) -- 182
456 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 182
457 local _match_0 = false -- 182
458 if _tab_0 then -- 182
459 local fourth = tb[4] -- 182
460 local _val_0 -- 182
461 do -- 182
462 local _obj_0 = tb[1] -- 182
463 if _obj_0 ~= nil then -- 182
464 _val_0 = _obj_0.a -- 182
465 end -- 182
466 end -- 182
467 local _val_1 -- 182
468 do -- 182
469 local _obj_0 = tb[1] -- 182
470 if _obj_0 ~= nil then -- 182
471 _val_1 = _obj_0.b -- 182
472 end -- 182
473 end -- 182
474 local _val_2 -- 182
475 do -- 182
476 local _obj_0 = tb[2] -- 182
477 if _obj_0 ~= nil then -- 182
478 _val_2 = _obj_0.a -- 182
479 end -- 182
480 end -- 182
481 local _val_3 -- 182
482 do -- 182
483 local _obj_0 = tb[2] -- 182
484 if _obj_0 ~= nil then -- 182
485 _val_3 = _obj_0.b -- 182
486 end -- 182
487 end -- 182
488 local _val_4 -- 182
489 do -- 182
490 local _obj_0 = tb[3] -- 182
491 if _obj_0 ~= nil then -- 182
492 _val_4 = _obj_0.a -- 182
493 end -- 182
494 end -- 182
495 local _val_5 -- 182
496 do -- 182
497 local _obj_0 = tb[3] -- 182
498 if _obj_0 ~= nil then -- 182
499 _val_5 = _obj_0.b -- 182
500 end -- 182
501 end -- 182
502 if 1 == _val_0 and 2 == _val_1 and 3 == _val_2 and 4 == _val_3 and 5 == _val_4 and 6 == _val_5 and fourth ~= nil then -- 182
503 _match_0 = true -- 182
504 result = fourth -- 188
505 end -- 182
506 end -- 182
507 if not _match_0 then -- 182
508 result = "no match" -- 190
509 end -- 181
510 end -- 181
511 return assert.same(result, "fourth") -- 191
512 end) -- 174
513 it("should match combined patterns", function() -- 193
514 local tb = { -- 194
515 success = true, -- 194
516 result = "data" -- 194
517 } -- 194
518 local result -- 195
519 do -- 196
520 local _type_0 = type(tb) -- 196
521 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 196
522 local _match_0 = false -- 196
523 if _tab_0 then -- 196
524 result = tb.result -- 196
525 if true == tb.success and result ~= nil then -- 196
526 _match_0 = true -- 196
527 result = { -- 197
528 "success", -- 197
529 result -- 197
530 } -- 197
531 end -- 196
532 end -- 196
533 if not _match_0 then -- 196
534 local _match_1 = false -- 198
535 if _tab_0 then -- 198
536 if false == tb.success then -- 198
537 _match_1 = true -- 198
538 result = { -- 199
539 "failed", -- 199
540 result -- 199
541 } -- 199
542 end -- 198
543 end -- 198
544 if not _match_1 then -- 198
545 result = { -- 201
546 "invalid" -- 201
547 } -- 201
548 end -- 195
549 end -- 195
550 end -- 195
551 return assert.same(result, { -- 202
552 "success", -- 202
553 "data" -- 202
554 }) -- 202
555 end) -- 193
556 it("should match type discriminated patterns", function() -- 204
557 local tb = { -- 205
558 type = "success", -- 205
559 content = "data" -- 205
560 } -- 205
561 local result -- 206
562 do -- 207
563 local _type_0 = type(tb) -- 207
564 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 207
565 local _match_0 = false -- 207
566 if _tab_0 then -- 207
567 local content = tb.content -- 207
568 if "success" == tb.type and content ~= nil then -- 207
569 _match_0 = true -- 207
570 result = { -- 208
571 "success", -- 208
572 content -- 208
573 } -- 208
574 end -- 207
575 end -- 207
576 if not _match_0 then -- 207
577 local _match_1 = false -- 209
578 if _tab_0 then -- 209
579 local content = tb.content -- 209
580 if "error" == tb.type and content ~= nil then -- 209
581 _match_1 = true -- 209
582 result = { -- 210
583 "error", -- 210
584 content -- 210
585 } -- 210
586 end -- 209
587 end -- 209
588 if not _match_1 then -- 209
589 result = { -- 212
590 "invalid" -- 212
591 } -- 212
592 end -- 206
593 end -- 206
594 end -- 206
595 return assert.same(result, { -- 213
596 "success", -- 213
597 "data" -- 213
598 }) -- 213
599 end) -- 204
600 it("should match with wildcard array capture", function() -- 215
601 local clientData = { -- 216
602 "Meta", -- 216
603 "CUST_1001", -- 216
604 "CHK123" -- 216
605 } -- 216
606 local metadata = nil -- 217
607 local customerId = nil -- 218
608 local checksum = nil -- 219
609 do -- 221
610 local _type_0 = type(clientData) -- 221
611 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 221
612 if _tab_0 then -- 221
613 local capturedMetadata -- 221
614 do -- 221
615 local _accum_0 = { } -- 221
616 local _len_0 = 1 -- 221
617 local _max_0 = #clientData + -3 + 1 -- 221
618 for _index_0 = 1, _max_0 do -- 221
619 local _item_0 = clientData[_index_0] -- 221
620 _accum_0[_len_0] = _item_0 -- 221
621 _len_0 = _len_0 + 1 -- 221
622 end -- 221
623 capturedMetadata = _accum_0 -- 221
624 end -- 221
625 customerId = clientData[#clientData - 1] -- 221
626 checksum = clientData[#clientData] -- 221
627 if customerId ~= nil and checksum ~= nil then -- 221
628 metadata = capturedMetadata -- 222
629 end -- 221
630 end -- 220
631 end -- 220
632 assert.same(metadata, { -- 223
633 "Meta" -- 223
634 }) -- 223
635 assert.same(customerId, "CUST_1001") -- 224
636 return assert.same(checksum, "CHK123") -- 225
637 end) -- 215
638 it("should work with complex tuple patterns", function() -- 227
639 local handlePath -- 228
640 handlePath = function(segments) -- 228
641 local _type_0 = type(segments) -- 230
642 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 230
643 local _match_0 = false -- 230
644 if _tab_0 then -- 230
645 local resource = segments[#segments - 1] -- 230
646 local action = segments[#segments] -- 230
647 if resource ~= nil and action ~= nil then -- 230
648 _match_0 = true -- 230
649 return { -- 231
650 "Resource: " .. tostring(resource), -- 231
651 "Action: " .. tostring(action) -- 231
652 } -- 231
653 end -- 230
654 end -- 230
655 if not _match_0 then -- 230
656 return { -- 233
657 "no match" -- 233
658 } -- 233
659 end -- 229
660 end -- 228
661 local result = handlePath({ -- 234
662 "admin", -- 234
663 "logs", -- 234
664 "view" -- 234
665 }) -- 234
666 return assert.same(result, { -- 235
667 "Resource: logs", -- 235
668 "Action: view" -- 235
669 }) -- 235
670 end) -- 227
671 it("should match boolean false correctly", function() -- 237
672 local items = { -- 239
673 { -- 239
674 x = 100, -- 239
675 y = 200 -- 239
676 }, -- 239
677 { -- 240
678 width = 300, -- 240
679 height = 400 -- 240
680 }, -- 240
681 false -- 241
682 } -- 238
683 local results = { } -- 243
684 for _index_0 = 1, #items do -- 244
685 local item = items[_index_0] -- 244
686 local _type_0 = type(item) -- 246
687 local _tab_0 = "table" == _type_0 or "userdata" == _type_0 -- 246
688 local _match_0 = false -- 246
689 if _tab_0 then -- 246
690 local x = item.x -- 246
691 local y = item.y -- 246
692 if x ~= nil and y ~= nil then -- 246
693 _match_0 = true -- 246
694 table.insert(results, "Vec2") -- 247
695 end -- 246
696 end -- 246
697 if not _match_0 then -- 246
698 local _match_1 = false -- 248
699 if _tab_0 then -- 248
700 local width = item.width -- 248
701 local height = item.height -- 248
702 if width ~= nil and height ~= nil then -- 248
703 _match_1 = true -- 248
704 table.insert(results, "Size") -- 249
705 end -- 248
706 end -- 248
707 if not _match_1 then -- 248
708 if false == item then -- 250
709 table.insert(results, "None") -- 251
710 end -- 245
711 end -- 245
712 end -- 245
713 end -- 244
714 return assert.same(results, { -- 252
715 "Vec2", -- 252
716 "Size", -- 252
717 "None" -- 252
718 }) -- 252
719 end) -- 237
720 it("should handle switch with then syntax", function() -- 254
721 local value = "cool" -- 255
722 local result -- 256
723 if "cool" == value then -- 257
724 result = "matched cool" -- 257
725 else -- 258
726 result = "else branch" -- 258
727 end -- 256
728 return assert.same(result, "matched cool") -- 259
729 end) -- 254
730 return it("should handle switch in function call", function() -- 261
731 local getValue -- 262
732 getValue = function() -- 262
733 local _exp_0 = something -- 263
734 if 1 == _exp_0 then -- 264
735 return "yes" -- 264
736 else -- 265
737 return "no" -- 265
738 end -- 263
739 end -- 262
740 local something = 1 -- 266
741 return assert.same(getValue(), "yes") -- 267
742 end) -- 261
743end) -- 1
diff --git a/spec/outputs/5.1/test/try_catch_spec.lua b/spec/outputs/5.1/test/try_catch_spec.lua
new file mode 100644
index 0000000..90e656b
--- /dev/null
+++ b/spec/outputs/5.1/test/try_catch_spec.lua
@@ -0,0 +1,22 @@
1local _anon_func_0 = function(e, error)
2 return error("wrap:" .. e:match("^.-:%d+:%s*(.*)$"))
3end
4return describe("try/catch", function()
5 return it("catch and rethrow", function()
6 local pcall = pcall
7 local error = error
8 local xpcall = xpcall
9 local assert = assert
10 local ok, success, err = pcall(function()
11 return xpcall(function()
12 return error("boom")
13 end, function(e)
14 local _, result = pcall(_anon_func_0, e, error)
15 return result
16 end)
17 end)
18 assert.same(ok, true)
19 assert.same(success, false)
20 return assert.is_true(err:match("wrap:boom") ~= nil)
21 end)
22end)
diff --git a/spec/outputs/5.1/test/vararg_spec.lua b/spec/outputs/5.1/test/vararg_spec.lua
deleted file mode 100644
index a95e64e..0000000
--- a/spec/outputs/5.1/test/vararg_spec.lua
+++ /dev/null
@@ -1,164 +0,0 @@
1return describe("vararg", function() -- 1
2 it("should pass varargs to function", function() -- 2
3 local sum -- 3
4 sum = function(...) -- 3
5 local total = 0 -- 4
6 for i = 1, select("#", ...) do -- 5
7 if type(select(i, ...)) == "number" then -- 6
8 total = total + select(i, ...) -- 7
9 end -- 6
10 end -- 5
11 return total -- 8
12 end -- 3
13 local result = sum(1, 2, 3, 4, 5) -- 9
14 return assert.same(result, 15) -- 10
15 end) -- 2
16 it("should handle empty varargs", function() -- 12
17 local fn -- 13
18 fn = function(...) -- 13
19 return select("#", ...) -- 13
20 end -- 13
21 local result = fn() -- 14
22 return assert.same(result, 0) -- 15
23 end) -- 12
24 it("should spread varargs in function call", function() -- 17
25 local receiver -- 18
26 receiver = function(a, b, c) -- 18
27 return { -- 18
28 a, -- 18
29 b, -- 18
30 c -- 18
31 } -- 18
32 end -- 18
33 local source -- 19
34 source = function() -- 19
35 return 1, 2, 3 -- 19
36 end -- 19
37 local result = receiver(source()) -- 20
38 return assert.same(result, { -- 21
39 1, -- 21
40 2, -- 21
41 3 -- 21
42 }) -- 21
43 end) -- 17
44 it("should use varargs in table", function() -- 23
45 local fn -- 24
46 fn = function(...) -- 24
47 return { -- 24
48 ... -- 24
49 } -- 24
50 end -- 24
51 local result = fn(1, 2, 3) -- 25
52 return assert.same(result, { -- 26
53 1, -- 26
54 2, -- 26
55 3 -- 26
56 }) -- 26
57 end) -- 23
58 it("should forward varargs", function() -- 28
59 local middle -- 29
60 middle = function(fn, ...) -- 29
61 return fn(...) -- 29
62 end -- 29
63 local inner -- 30
64 inner = function(a, b, c) -- 30
65 return a + b + c -- 30
66 end -- 30
67 local result = middle(inner, 1, 2, 3) -- 31
68 return assert.same(result, 6) -- 32
69 end) -- 28
70 it("should count varargs with select", function() -- 34
71 local fn -- 35
72 fn = function(...) -- 35
73 return select("#", ...) -- 35
74 end -- 35
75 assert.same(fn(1, 2, 3), 3) -- 36
76 assert.same(fn("a", "b"), 2) -- 37
77 return assert.same(fn(), 0) -- 38
78 end) -- 34
79 it("should select from varargs", function() -- 40
80 local fn -- 41
81 fn = function(...) -- 41
82 return select(2, ...) -- 41
83 end -- 41
84 local result = fn(1, 2, 3) -- 42
85 return assert.same(result, 2) -- 43
86 end) -- 40
87 it("should work with named parameters and varargs", function() -- 45
88 local fn -- 46
89 fn = function(first, ...) -- 46
90 return { -- 47
91 first, -- 47
92 select("#", ...) -- 47
93 } -- 47
94 end -- 46
95 local result = fn("first", "second", "third") -- 48
96 return assert.same(result, { -- 49
97 "first", -- 49
98 2 -- 49
99 }) -- 49
100 end) -- 45
101 it("should handle nil in varargs", function() -- 51
102 local fn -- 52
103 fn = function(...) -- 52
104 local count = select("#", ...) -- 53
105 local has_nil = false -- 54
106 for i = 1, count do -- 55
107 if select(i, ...) == nil then -- 56
108 has_nil = true -- 56
109 end -- 56
110 end -- 55
111 return { -- 57
112 count, -- 57
113 has_nil -- 57
114 } -- 57
115 end -- 52
116 local result = fn(1, nil, 3) -- 58
117 return assert.same(result, { -- 59
118 3, -- 59
119 true -- 59
120 }) -- 59
121 end) -- 51
122 it("should work with table unpack", function() -- 61
123 local fn -- 62
124 fn = function(...) -- 62
125 return { -- 62
126 ... -- 62
127 } -- 62
128 end -- 62
129 local result = fn(table.unpack({ -- 63
130 1, -- 63
131 2, -- 63
132 3 -- 63
133 })) -- 63
134 return assert.same(result, { -- 64
135 1, -- 64
136 2, -- 64
137 3 -- 64
138 }) -- 64
139 end) -- 61
140 return it("should work with varargs in comprehension", function() -- 66
141 local fn -- 67
142 fn = function(...) -- 67
143 local _accum_0 = { } -- 67
144 local _len_0 = 1 -- 67
145 local _list_0 = { -- 67
146 ... -- 67
147 } -- 67
148 for _index_0 = 1, #_list_0 do -- 67
149 local x = _list_0[_index_0] -- 67
150 _accum_0[_len_0] = x * 2 -- 67
151 _len_0 = _len_0 + 1 -- 67
152 end -- 67
153 return _accum_0 -- 67
154 end -- 67
155 local result = fn(1, 2, 3, 4, 5) -- 68
156 return assert.same(result, { -- 69
157 2, -- 69
158 4, -- 69
159 6, -- 69
160 8, -- 69
161 10 -- 69
162 }) -- 69
163 end) -- 66
164end) -- 1
diff --git a/spec/outputs/5.1/test/with_spec.lua b/spec/outputs/5.1/test/with_spec.lua
deleted file mode 100644
index f3f10e3..0000000
--- a/spec/outputs/5.1/test/with_spec.lua
+++ /dev/null
@@ -1,170 +0,0 @@
1return describe("with", function() -- 1
2 it("should access property with . syntax", function() -- 2
3 local obj = { -- 3
4 value = 42 -- 3
5 } -- 3
6 do -- 4
7 local result = obj.value -- 5
8 end -- 4
9 return assert.same(result, 42) -- 6
10 end) -- 2
11 it("should call method with : syntax", function() -- 8
12 local obj = { -- 9
13 func = function() -- 9
14 return "result" -- 9
15 end -- 9
16 } -- 9
17 do -- 10
18 local result = obj:func() -- 11
19 end -- 10
20 return assert.same(result, "result") -- 12
21 end) -- 8
22 it("should work as statement", function() -- 14
23 local obj = { -- 15
24 x = 10, -- 15
25 y = 20 -- 15
26 } -- 15
27 obj.sum = obj.x + obj.y -- 17
28 return assert.same(obj.sum, 30) -- 18
29 end) -- 14
30 it("should support nested with", function() -- 20
31 local outer = { -- 21
32 inner = { -- 21
33 value = 100 -- 21
34 } -- 21
35 } -- 21
36 do -- 22
37 local _with_0 = outer.inner -- 22
38 local result = _with_0.value -- 23
39 end -- 22
40 return assert.same(result, 100) -- 24
41 end) -- 20
42 it("should work with? safely", function() -- 26
43 local obj = { -- 27
44 x = 5 -- 27
45 } -- 27
46 do -- 28
47 local result = obj.x -- 29
48 end -- 28
49 return assert.same(result, 5) -- 30
50 end) -- 26
51 it("should work with if inside with", function() -- 32
52 local obj = { -- 33
53 x = 10, -- 33
54 y = 20 -- 33
55 } -- 33
56 if obj.x > 5 then -- 35
57 local result = obj.x + obj.y -- 36
58 end -- 35
59 return assert.same(result, 30) -- 37
60 end) -- 32
61 it("should work with switch inside with", function() -- 39
62 local obj = { -- 40
63 type = "add", -- 40
64 a = 5, -- 40
65 b = 3 -- 40
66 } -- 40
67 do -- 41
68 local result -- 42
69 local _exp_0 = obj.type -- 42
70 if "add" == _exp_0 then -- 43
71 result = obj.a + obj.b -- 43
72 else -- 44
73 result = 0 -- 44
74 end -- 42
75 end -- 41
76 return assert.same(result, 8) -- 45
77 end) -- 39
78 it("should work with loop inside with", function() -- 47
79 local obj = { -- 48
80 items = { -- 48
81 1, -- 48
82 2, -- 48
83 3 -- 48
84 } -- 48
85 } -- 48
86 local sum = 0 -- 49
87 local _list_0 = obj.items -- 51
88 for _index_0 = 1, #_list_0 do -- 51
89 local item = _list_0[_index_0] -- 51
90 sum = sum + item -- 52
91 end -- 51
92 return assert.same(sum, 6) -- 53
93 end) -- 47
94 it("should work with destructure", function() -- 55
95 local obj = { -- 56
96 x = 1, -- 56
97 y = 2, -- 56
98 z = 3 -- 56
99 } -- 56
100 do -- 57
101 local x, y, z = obj[1], obj[2], obj[3] -- 58
102 end -- 57
103 assert.same(x, 1) -- 59
104 assert.same(y, 2) -- 60
105 return assert.same(z, 3) -- 61
106 end) -- 55
107 it("should handle simple with body", function() -- 63
108 local obj = { -- 64
109 value = 42 -- 64
110 } -- 64
111 obj.value2 = 100 -- 66
112 return assert.same(obj.value2, 100) -- 67
113 end) -- 63
114 it("should work with return inside", function() -- 69
115 local obj = { -- 70
116 value = 100 -- 70
117 } -- 70
118 local fn -- 71
119 fn = function() -- 71
120 return obj.value -- 73
121 end -- 71
122 return assert.same(fn(), 100) -- 74
123 end) -- 69
124 it("should work with break inside", function() -- 76
125 local sum = 0 -- 77
126 for i = 1, 5 do -- 78
127 local obj = { -- 79
128 value = i -- 79
129 } -- 79
130 if obj.value == 3 then -- 81
131 break -- 82
132 end -- 81
133 sum = sum + obj.value -- 83
134 end -- 78
135 return assert.same(sum, 3) -- 84
136 end) -- 76
137 it("should chain property access", function() -- 86
138 local obj = { -- 87
139 a = { -- 87
140 b = { -- 87
141 c = 42 -- 87
142 } -- 87
143 } -- 87
144 } -- 87
145 do -- 88
146 local _with_0 = obj.a.b -- 88
147 local result = _with_0.c -- 89
148 end -- 88
149 return assert.same(result, 42) -- 90
150 end) -- 86
151 it("should work with multiple statements", function() -- 92
152 local obj = { -- 93
153 x = 1, -- 93
154 y = 2 -- 93
155 } -- 93
156 local sum = 0 -- 94
157 do -- 95
158 sum = sum + obj.x -- 96
159 sum = sum + obj.y -- 97
160 end -- 95
161 return assert.same(sum, 3) -- 98
162 end) -- 92
163 return it("should preserve object reference", function() -- 100
164 local obj = { -- 101
165 value = 42 -- 101
166 } -- 101
167 obj.value = 100 -- 103
168 return assert.same(obj.value, 100) -- 104
169 end) -- 100
170end) -- 1
diff --git a/spec/outputs/test/attrib_spec.lua b/spec/outputs/test/attrib_spec.lua
new file mode 100644
index 0000000..d459bbb
--- /dev/null
+++ b/spec/outputs/test/attrib_spec.lua
@@ -0,0 +1,96 @@
1return describe("attrib", function()
2 it("should support const attribute", function()
3 do
4 local x <const> = 10
5 return assert.same(x, 10)
6 end
7 end)
8 it("should support const with multiple variables", function()
9 do
10 local a <const>, b <const>, c <const> = 1, 2, 3
11 assert.same(a, 1)
12 assert.same(b, 2)
13 return assert.same(c, 3)
14 end
15 end)
16 it("should support close attribute", function()
17 do
18 local x <close> = setmetatable({ }, {
19 __close = function() end
20 })
21 return assert.same("table", type(x))
22 end
23 end)
24 it("should work with destructuring", function()
25 do
26 local a, b
27 do
28 local _obj_0 = {
29 a = 1,
30 b = 2
31 }
32 a, b = _obj_0.a, _obj_0.b
33 end
34 assert.same(a, 1)
35 return assert.same(b, 2)
36 end
37 end)
38 it("should work in conditional", function()
39 do
40 local flag = true
41 local x
42 if flag then
43 x = 5
44 end
45 return assert.same(x, 5)
46 end
47 end)
48 it("should work with switch", function()
49 do
50 local y
51 do
52 local _exp_0 = 2
53 if 2 == _exp_0 then
54 y = 100
55 else
56 y = 0
57 end
58 end
59 return assert.same(y, 100)
60 end
61 end)
62 it("should work with table literals", function()
63 do
64 local a, b
65 do
66 local _obj_0 = {
67 1,
68 2
69 }
70 a, b = _obj_0[1], _obj_0[2]
71 end
72 assert.same(a, 1)
73 return assert.same(b, 2)
74 end
75 end)
76 return it("should support close in expressions", function()
77 do
78 local result
79 if true then
80 result = setmetatable({
81 value = 42,
82 }, {
83 __close = function() end
84 })
85 else
86 result = setmetatable({
87 value = 0,
88 }, {
89 __close = function() end
90 })
91 end
92 local _close_0 <close> = result
93 return assert.same(result.value, 42)
94 end
95 end)
96end)
diff --git a/spec/outputs/test/backcall_spec.lua b/spec/outputs/test/backcall_spec.lua
new file mode 100644
index 0000000..1eb9f02
--- /dev/null
+++ b/spec/outputs/test/backcall_spec.lua
@@ -0,0 +1,64 @@
1return describe("backcall", function()
2 it("should support basic backcall with <-", function()
3 local results = { }
4 local mock_map
5 mock_map = function(list, fn)
6 for _index_0 = 1, #list do
7 local item = list[_index_0]
8 table.insert(results, fn(item))
9 end
10 end
11 do
12 mock_map({
13 1,
14 2,
15 3
16 }, function(x)
17 return x * 2
18 end)
19 end
20 return assert.same(results, {
21 2,
22 4,
23 6
24 })
25 end)
26 it("should support nested backcalls", function()
27 local results = { }
28 local mock_map
29 mock_map = function(list, fn)
30 for _index_0 = 1, #list do
31 local item = list[_index_0]
32 fn(item)
33 end
34 end
35 mock_map({
36 1,
37 2,
38 3,
39 4
40 }, function(x)
41 if x > 2 then
42 return table.insert(results, x)
43 end
44 end)
45 return assert.same(results, {
46 3,
47 4
48 })
49 end)
50 return it("should work with method call backcall", function()
51 local results = { }
52 local obj = {
53 process = function(self, fn)
54 return fn(42)
55 end
56 }
57 return obj:process(function(value)
58 table.insert(results, value)
59 return assert.same(results, {
60 42
61 })
62 end)
63 end)
64end)
diff --git a/spec/outputs/test/cond_spec.lua b/spec/outputs/test/cond_spec.lua
new file mode 100644
index 0000000..838809a
--- /dev/null
+++ b/spec/outputs/test/cond_spec.lua
@@ -0,0 +1,237 @@
1local _anon_func_0 = function(flag)
2 if flag then
3 return 1
4 else
5 return 0
6 end
7end
8local _anon_func_1 = function()
9 if nil then
10 return true
11 else
12 return false
13 end
14end
15local _anon_func_2 = function()
16 if false then
17 return true
18 else
19 return false
20 end
21end
22local _anon_func_3 = function()
23 if 0 then
24 return true
25 else
26 return false
27 end
28end
29local _anon_func_4 = function()
30 if "" then
31 return true
32 else
33 return false
34 end
35end
36local _anon_func_5 = function()
37 if { } then
38 return true
39 else
40 return false
41 end
42end
43local _anon_func_6 = function()
44 if 1 then
45 return true
46 else
47 return false
48 end
49end
50return describe("cond", function()
51 it("should execute if branch when condition is true", function()
52 local result = nil
53 if true then
54 result = "yes"
55 end
56 return assert.same(result, "yes")
57 end)
58 it("should execute else branch when condition is false", function()
59 local result = nil
60 if false then
61 result = "yes"
62 else
63 result = "no"
64 end
65 return assert.same(result, "no")
66 end)
67 it("should support elseif chain", function()
68 local value = 2
69 local result
70 if 1 == value then
71 result = "one"
72 elseif 2 == value then
73 result = "two"
74 else
75 result = "other"
76 end
77 return assert.same(result, "two")
78 end)
79 it("should handle nested conditions", function()
80 local result = nil
81 if true then
82 if true then
83 result = "nested"
84 end
85 end
86 return assert.same(result, "nested")
87 end)
88 it("should work as expression", function()
89 local value
90 if true then
91 value = "yes"
92 else
93 value = "no"
94 end
95 return assert.same(value, "yes")
96 end)
97 it("should work in string interpolation", function()
98 local flag = true
99 local result = "value is " .. tostring(_anon_func_0(flag))
100 return assert.same(result, "value is 1")
101 end)
102 it("should support chained comparisons", function()
103 return assert.is_true(1 < 2 and 2 <= 2 and 2 < 3)
104 end)
105 it("should short-circuit and expression", function()
106 local count = 0
107 local inc
108 inc = function()
109 count = count + 1
110 return false
111 end
112 local result = inc() and inc()
113 return assert.same(count, 1)
114 end)
115 it("should short-circuit or expression", function()
116 local count = 0
117 local inc
118 inc = function()
119 count = count + 1
120 return true
121 end
122 local result = inc() or inc()
123 return assert.same(count, 1)
124 end)
125 it("should support unless keyword", function()
126 local result = nil
127 if not false then
128 result = "executed"
129 end
130 return assert.same(result, "executed")
131 end)
132 it("should support unless with else", function()
133 local result = nil
134 if not true then
135 result = "no"
136 else
137 result = "yes"
138 end
139 return assert.same(result, "yes")
140 end)
141 it("should handle postfix if", function()
142 local result = nil
143 if true then
144 result = "yes"
145 end
146 return assert.same(result, "yes")
147 end)
148 it("should handle postfix unless", function()
149 local result = nil
150 if not false then
151 result = "yes"
152 end
153 return assert.same(result, "yes")
154 end)
155 it("should evaluate truthiness correctly", function()
156 assert.is_false(_anon_func_1())
157 assert.is_false(_anon_func_2())
158 assert.is_true(_anon_func_3())
159 assert.is_true(_anon_func_4())
160 assert.is_true(_anon_func_5())
161 return assert.is_true(_anon_func_6())
162 end)
163 it("should support and/or operators", function()
164 assert.same(true and false, false)
165 assert.same(false or true, true)
166 assert.same(nil or "default", "default")
167 return assert.same("value" or "default", "value")
168 end)
169 it("should handle complex boolean expressions", function()
170 local a, b, c = true, false, true
171 local result = a and b or c
172 return assert.same(result, c)
173 end)
174 it("should support not operator", function()
175 assert.is_true(not false)
176 assert.is_true(not nil)
177 assert.is_false(not true)
178 return assert.is_false(not 1)
179 end)
180 it("should work with table as condition", function()
181 local result = nil
182 if { } then
183 result = "truthy"
184 end
185 return assert.same(result, "truthy")
186 end)
187 it("should work with string as condition", function()
188 local result = nil
189 if "" then
190 result = "truthy"
191 end
192 return assert.same(result, "truthy")
193 end)
194 it("should work with zero as condition", function()
195 local result = nil
196 if 0 then
197 result = "truthy"
198 end
199 return assert.same(result, "truthy")
200 end)
201 it("should support multiple elseif branches", function()
202 local value = 3
203 local result
204 if value == 1 then
205 result = "one"
206 elseif value == 2 then
207 result = "two"
208 elseif value == 3 then
209 result = "three"
210 else
211 result = "other"
212 end
213 return assert.same(result, "three")
214 end)
215 it("should handle then keyword syntax", function()
216 local result
217 if true then
218 result = "yes"
219 else
220 result = "no"
221 end
222 return assert.same(result, "yes")
223 end)
224 return it("should work with function call in condition", function()
225 local return_true
226 return_true = function()
227 return true
228 end
229 local result
230 if return_true() then
231 result = "yes"
232 else
233 result = "no"
234 end
235 return assert.same(result, "yes")
236 end)
237end)
diff --git a/spec/outputs/test/config_spec.lua b/spec/outputs/test/config_spec.lua
new file mode 100644
index 0000000..410bacc
--- /dev/null
+++ b/spec/outputs/test/config_spec.lua
@@ -0,0 +1,195 @@
1return describe("config", function()
2 it("should handle implicit return", function()
3 local fn
4 fn = function()
5 return 42
6 end
7 return assert.same(fn(), 42)
8 end)
9 it("should handle return in last position", function()
10 local fn
11 fn = function()
12 if true then
13 return 100
14 else
15 return 200
16 end
17 end
18 return assert.same(fn(), 100)
19 end)
20 it("should work with various code patterns", function()
21 local x = 1 + 2
22 local y
23 if x > 0 then
24 y = "positive"
25 else
26 y = "negative"
27 end
28 return assert.same(y, "positive")
29 end)
30 it("should handle class definitions", function()
31 local TestClass
32 do
33 local _class_0
34 local _base_0 = {
35 value = 100,
36 get_value = function(self)
37 return self.value
38 end
39 }
40 if _base_0.__index == nil then
41 _base_0.__index = _base_0
42 end
43 _class_0 = setmetatable({
44 __init = function() end,
45 __base = _base_0,
46 __name = "TestClass"
47 }, {
48 __index = _base_0,
49 __call = function(cls, ...)
50 local _self_0 = setmetatable({ }, _base_0)
51 cls.__init(_self_0, ...)
52 return _self_0
53 end
54 })
55 _base_0.__class = _class_0
56 TestClass = _class_0
57 end
58 local instance = TestClass()
59 return assert.same(instance:get_value(), 100)
60 end)
61 it("should handle macro definitions", function()
62 local result = (5 + 1)
63 return assert.same(result, 6)
64 end)
65 it("should handle import statements", function()
66 local format
67 do
68 local _obj_0 = require("string")
69 format = _obj_0.format
70 end
71 return assert.is_true(type(format) == "function")
72 end)
73 it("should handle string interpolation", function()
74 local name = "world"
75 local result = "hello " .. tostring(name)
76 return assert.same(result, "hello world")
77 end)
78 it("should handle comprehensions", function()
79 local result
80 do
81 local _accum_0 = { }
82 local _len_0 = 1
83 for x = 1, 5 do
84 _accum_0[_len_0] = x * 2
85 _len_0 = _len_0 + 1
86 end
87 result = _accum_0
88 end
89 return assert.same(result, {
90 2,
91 4,
92 6,
93 8,
94 10
95 })
96 end)
97 it("should handle switch expressions", function()
98 local result
99 do
100 local _exp_0 = 2
101 if 1 == _exp_0 then
102 result = "one"
103 elseif 2 == _exp_0 then
104 result = "two"
105 else
106 result = "other"
107 end
108 end
109 return assert.same(result, "two")
110 end)
111 it("should handle with statements", function()
112 local obj = {
113 x = 10,
114 y = 20
115 }
116 local result
117 do
118 local _accum_0
119 repeat
120 _accum_0 = obj.x + obj.y
121 break
122 until true
123 result = _accum_0
124 end
125 return assert.same(result, 30)
126 end)
127 it("should handle existential operators", function()
128 local obj = {
129 value = 100
130 }
131 local result
132 if obj ~= nil then
133 result = obj.value
134 end
135 return assert.same(result, 100)
136 end)
137 it("should handle pipe operator", function()
138 local result = table.concat({
139 1,
140 2,
141 3
142 })
143 return assert.same(result, "123")
144 end)
145 it("should handle loops", function()
146 local sum = 0
147 for i = 1, 5 do
148 sum = sum + i
149 end
150 return assert.same(sum, 15)
151 end)
152 it("should handle while loops", function()
153 local count = 0
154 while count < 3 do
155 count = count + 1
156 end
157 return assert.same(count, 3)
158 end)
159 it("should handle table literals", function()
160 local t = {
161 key1 = "value1",
162 key2 = "value2"
163 }
164 return assert.same(t.key1, "value1")
165 end)
166 it("should handle function definitions", function()
167 local fn
168 fn = function(a, b)
169 return a + b
170 end
171 return assert.same(fn(5, 3), 8)
172 end)
173 it("should handle nested functions", function()
174 local outer
175 outer = function()
176 local inner
177 inner = function(x)
178 return x * 2
179 end
180 return inner(10)
181 end
182 return assert.same(outer(), 20)
183 end)
184 return it("should handle destructure", function()
185 local t = {
186 x = 1,
187 y = 2,
188 z = 3
189 }
190 local x, y, z = t.x, t.y, t.z
191 assert.same(x, 1)
192 assert.same(y, 2)
193 return assert.same(z, 3)
194 end)
195end)
diff --git a/spec/outputs/test/existential_spec.lua b/spec/outputs/test/existential_spec.lua
new file mode 100644
index 0000000..9485c34
--- /dev/null
+++ b/spec/outputs/test/existential_spec.lua
@@ -0,0 +1,244 @@
1local _anon_func_0 = function(obj)
2 if obj ~= nil then
3 return obj.value
4 end
5 return nil
6end
7local _anon_func_1 = function(obj)
8 if obj ~= nil then
9 return obj.value
10 end
11 return nil
12end
13local _anon_func_2 = function(obj)
14 if obj ~= nil then
15 return obj.x
16 end
17 return nil
18end
19local _anon_func_3 = function(obj)
20 if obj ~= nil then
21 return obj.y
22 end
23 return nil
24end
25return describe("existential", function()
26 it("should handle ?. with existing object", function()
27 local obj = {
28 value = 42
29 }
30 local result
31 if obj ~= nil then
32 result = obj.value
33 end
34 return assert.same(result, 42)
35 end)
36 it("should handle ?. with nil object", function()
37 local obj = nil
38 local result
39 if obj ~= nil then
40 result = obj.value
41 end
42 return assert.same(result, nil)
43 end)
44 it("should chain ?. calls", function()
45 local obj = {
46 nested = {
47 value = 100
48 }
49 }
50 local result
51 if obj ~= nil then
52 do
53 local _obj_0 = obj.nested
54 if _obj_0 ~= nil then
55 result = _obj_0.value
56 end
57 end
58 end
59 return assert.same(result, 100)
60 end)
61 it("should return nil in chain with nil", function()
62 local obj = nil
63 local result
64 if obj ~= nil then
65 do
66 local _obj_0 = obj.nested
67 if _obj_0 ~= nil then
68 result = _obj_0.value
69 end
70 end
71 end
72 return assert.same(result, nil)
73 end)
74 it("should handle ?. with method call", function()
75 local obj = {
76 func = function()
77 return "result"
78 end
79 }
80 local result
81 if obj ~= nil then
82 result = obj.func()
83 end
84 return assert.same(result, "result")
85 end)
86 it("should handle ? on table index", function()
87 local tb = {
88 [1] = "first"
89 }
90 local result
91 if tb ~= nil then
92 result = tb[1]
93 end
94 return assert.same(result, "first")
95 end)
96 it("should return nil for missing index", function()
97 local tb = { }
98 local result
99 if tb ~= nil then
100 result = tb[99]
101 end
102 return assert.same(result, nil)
103 end)
104 it("should work with ? in if condition", function()
105 local obj = {
106 value = 5
107 }
108 local result
109 if _anon_func_0(obj) then
110 result = "exists"
111 end
112 return assert.same(result, "exists")
113 end)
114 it("should combine ?. with and/or", function()
115 local obj = {
116 value = 10
117 }
118 local result = _anon_func_1(obj) and 20 or 30
119 return assert.same(result, 20)
120 end)
121 it("should handle with? safely", function()
122 local obj = {
123 x = 1,
124 y = 2
125 }
126 local sum = _anon_func_2(obj) + _anon_func_3(obj)
127 return assert.same(sum, 3)
128 end)
129 it("should return nil with with? on nil", function()
130 local obj = nil
131 local result
132 if obj ~= nil then
133 result = obj.x
134 end
135 return assert.same(result, nil)
136 end)
137 it("should handle false value correctly", function()
138 local obj = {
139 value = false
140 }
141 local result
142 if obj ~= nil then
143 result = obj.value
144 end
145 return assert.same(result, false)
146 end)
147 it("should handle 0 value correctly", function()
148 local obj = {
149 value = 0
150 }
151 local result
152 if obj ~= nil then
153 result = obj.value
154 end
155 return assert.same(result, 0)
156 end)
157 it("should handle empty string correctly", function()
158 local obj = {
159 value = ""
160 }
161 local result
162 if obj ~= nil then
163 result = obj.value
164 end
165 return assert.same(result, "")
166 end)
167 it("should handle empty table correctly", function()
168 local obj = {
169 value = { }
170 }
171 local result
172 if obj ~= nil then
173 result = obj.value
174 end
175 return assert.same(type(result), "table")
176 end)
177 it("should work with deep chains", function()
178 local obj = {
179 a = {
180 b = {
181 c = {
182 d = "deep"
183 }
184 }
185 }
186 }
187 local result
188 if obj ~= nil then
189 do
190 local _obj_0 = obj.a
191 if _obj_0 ~= nil then
192 do
193 local _obj_1 = _obj_0.b
194 if _obj_1 ~= nil then
195 do
196 local _obj_2 = _obj_1.c
197 if _obj_2 ~= nil then
198 result = _obj_2.d
199 end
200 end
201 end
202 end
203 end
204 end
205 end
206 return assert.same(result, "deep")
207 end)
208 it("should break chain on first nil", function()
209 local obj = {
210 a = nil
211 }
212 local result
213 if obj ~= nil then
214 do
215 local _obj_0 = obj.a
216 if _obj_0 ~= nil then
217 do
218 local _obj_1 = _obj_0.b
219 if _obj_1 ~= nil then
220 result = _obj_1.c
221 end
222 end
223 end
224 end
225 end
226 return assert.same(result, nil)
227 end)
228 it("should handle ?. with string methods", function()
229 local s = "hello"
230 local result
231 if s ~= nil then
232 result = s:upper()
233 end
234 return assert.same(result, "HELLO")
235 end)
236 return it("should handle ?. with nil string", function()
237 local s = nil
238 local result
239 if s ~= nil then
240 result = s:upper()
241 end
242 return assert.same(result, nil)
243 end)
244end)
diff --git a/spec/outputs/test/export_spec.lua b/spec/outputs/test/export_spec.lua
new file mode 100644
index 0000000..92cb402
--- /dev/null
+++ b/spec/outputs/test/export_spec.lua
@@ -0,0 +1,153 @@
1return describe("export", function()
2 it("should export basic variables", function()
3 local a = 1
4 local b = 2
5 local c = 3
6 assert.same(a, 1)
7 assert.same(b, 2)
8 return assert.same(c, 3)
9 end)
10 it("should export multiple variables at once", function()
11 local x, y, z = 10, 20, 30
12 assert.same(x, 10)
13 assert.same(y, 20)
14 return assert.same(z, 30)
15 end)
16 it("should export class definitions", function()
17 local MyClass
18 do
19 local _class_0
20 local _base_0 = {
21 value = 100
22 }
23 if _base_0.__index == nil then
24 _base_0.__index = _base_0
25 end
26 _class_0 = setmetatable({
27 __init = function() end,
28 __base = _base_0,
29 __name = "MyClass"
30 }, {
31 __index = _base_0,
32 __call = function(cls, ...)
33 local _self_0 = setmetatable({ }, _base_0)
34 cls.__init(_self_0, ...)
35 return _self_0
36 end
37 })
38 _base_0.__class = _class_0
39 MyClass = _class_0
40 end
41 return assert.same(MyClass.value, 100)
42 end)
43 it("should export function expressions", function()
44 local my_func
45 my_func = function()
46 return 42
47 end
48 return assert.same(my_func(), 42)
49 end)
50 it("should export conditional expressions", function()
51 local result
52 if true then
53 result = "yes"
54 else
55 result = "no"
56 end
57 return assert.same(result, "yes")
58 end)
59 it("should export switch expressions", function()
60 local value
61 do
62 local _exp_0 = 5
63 if 5 == _exp_0 then
64 value = 100
65 else
66 value = 0
67 end
68 end
69 return assert.same(value, 100)
70 end)
71 it("should export with do block", function()
72 local result
73 do
74 local x = 5
75 result = x * 2
76 end
77 return assert.same(result, 10)
78 end)
79 it("should export comprehension", function()
80 local doubled
81 do
82 local _accum_0 = { }
83 local _len_0 = 1
84 for i = 1, 5 do
85 _accum_0[_len_0] = i * 2
86 _len_0 = _len_0 + 1
87 end
88 doubled = _accum_0
89 end
90 return assert.same(doubled, {
91 2,
92 4,
93 6,
94 8,
95 10
96 })
97 end)
98 it("should export with pipe operator", function()
99 local result = table.concat({
100 1,
101 2,
102 3
103 })
104 return assert.same(result, "123")
105 end)
106 it("should export nil values", function()
107 local empty = nil
108 return assert.same(empty, nil)
109 end)
110 it("should export tables", function()
111 local config = {
112 key1 = "value1",
113 key2 = "value2"
114 }
115 assert.same(config.key1, "value1")
116 return assert.same(config.key2, "value2")
117 end)
118 it("should export string values", function()
119 local message = "hello world"
120 return assert.same(message, "hello world")
121 end)
122 it("should export boolean values", function()
123 local flag_true = true
124 local flag_false = false
125 assert.is_true(flag_true)
126 return assert.is_false(flag_false)
127 end)
128 it("should export number values", function()
129 local count = 42
130 local price = 19.99
131 assert.same(count, 42)
132 return assert.same(price, 19.99)
133 end)
134 it("should export function with parameters", function()
135 local add
136 add = function(a, b)
137 return a + b
138 end
139 return assert.same(add(5, 3), 8)
140 end)
141 it("should maintain export order", function()
142 local first = 1
143 local second = 2
144 local third = 3
145 assert.same(first, 1)
146 assert.same(second, 2)
147 return assert.same(third, 3)
148 end)
149 return it("should work with complex expressions", function()
150 local calc = (10 + 20) * 2
151 return assert.same(calc, 60)
152 end)
153end)
diff --git a/spec/outputs/test/goto_spec.lua b/spec/outputs/test/goto_spec.lua
new file mode 100644
index 0000000..50974fa
--- /dev/null
+++ b/spec/outputs/test/goto_spec.lua
@@ -0,0 +1,103 @@
1return describe("goto", function()
2 it("should support basic goto and label", function()
3 local a = 0
4 ::start::
5 a = a + 1
6 if a < 5 then
7 goto start
8 end
9 return assert.same(a, 5)
10 end)
11 it("should support conditional goto", function()
12 local a = 0
13 ::loop::
14 a = a + 1
15 if a == 3 then
16 goto done
17 end
18 goto loop
19 ::done::
20 return assert.same(a, 3)
21 end)
22 it("should support goto in nested loops", function()
23 local count = 0
24 for x = 1, 3 do
25 for y = 1, 3 do
26 count = count + 1
27 if x == 2 and y == 2 then
28 goto found
29 end
30 end
31 end
32 ::found::
33 return assert.same(count, 5)
34 end)
35 it("should support multiple labels", function()
36 local a = 0
37 ::first::
38 a = a + 1
39 if a == 2 then
40 goto second
41 end
42 goto first
43 ::second::
44 return assert.same(a, 2)
45 end)
46 it("should work with for loops", function()
47 local sum = 0
48 for i = 1, 10 do
49 sum = sum + i
50 if i == 5 then
51 goto done
52 end
53 end
54 ::done::
55 return assert.same(sum, 15)
56 end)
57 it("should work with while loops", function()
58 local count = 0
59 while true do
60 count = count + 1
61 if count == 3 then
62 goto endwhile
63 end
64 end
65 ::endwhile::
66 return assert.same(count, 3)
67 end)
68 it("should skip rest of loop with goto", function()
69 local values = { }
70 for i = 1, 5 do
71 if i % 2 == 0 then
72 goto continue
73 end
74 table.insert(values, i)
75 ::continue::
76 end
77 return assert.same(values, {
78 1,
79 3,
80 5
81 })
82 end)
83 return it("should support goto with switch", function()
84 local result = "default"
85 local value = 2
86 if 1 == value then
87 goto case_one
88 elseif 2 == value then
89 goto case_two
90 end
91 goto default_label
92 ::case_one::
93 result = "one"
94 goto finish
95 ::case_two::
96 result = "two"
97 goto finish
98 ::default_label::
99 result = "default"
100 ::finish::
101 return assert.same(result, "two")
102 end)
103end)
diff --git a/spec/outputs/test/import_spec.lua b/spec/outputs/test/import_spec.lua
new file mode 100644
index 0000000..d1feafa
--- /dev/null
+++ b/spec/outputs/test/import_spec.lua
@@ -0,0 +1,196 @@
1return describe("import", function()
2 it("should import from table expression", function()
3 local source = {
4 hello = "world",
5 foo = "bar"
6 }
7 local hello, foo = source.hello, source.foo
8 assert.same(hello, "world")
9 return assert.same(foo, "bar")
10 end)
11 it("should import with backslash escaping", function()
12 local source = {
13 x = 1,
14 y = function(self) end,
15 z = 3
16 }
17 local x, y, z = source.x, (function()
18 local _base_0 = source
19 local _fn_0 = _base_0.y
20 return _fn_0 and function(...)
21 return _fn_0(_base_0, ...)
22 end
23 end)(), source.z
24 assert.same(x, 1)
25 assert.same("function", type(y))
26 return assert.same(z, 3)
27 end)
28 it("should import from string module", function()
29 local format
30 do
31 local _obj_0 = require("string")
32 format = _obj_0.format
33 end
34 return assert.is_true(type(format) == "function")
35 end)
36 it("should import from table with dot path", function()
37 local sub
38 do
39 local _obj_0 = require("string")
40 sub = _obj_0.sub
41 end
42 local result = sub("hello", 1, 2)
43 return assert.same(result, "he")
44 end)
45 it("should import multiple values with table destructuring", function()
46 local source = {
47 a = 1,
48 b = 2,
49 c = 3
50 }
51 local a, b, c = source.a, source.b, source.c
52 assert.same(a, 1)
53 assert.same(b, 2)
54 return assert.same(c, 3)
55 end)
56 it("should import with multi-line format", function()
57 local source = {
58 x = 1,
59 y = 2,
60 z = 3
61 }
62 local x, y, z = source.x, source.y, source.z
63 assert.same(x, 1)
64 assert.same(y, 2)
65 return assert.same(z, 3)
66 end)
67 it("should import using from syntax", function()
68 local source = {
69 foo = "bar",
70 baz = "qux"
71 }
72 local foo, baz = source.foo, source.baz
73 assert.same(foo, "bar")
74 return assert.same(baz, "qux")
75 end)
76 it("should handle import with computed expressions", function()
77 local source = {
78 first = 1,
79 second = 2
80 }
81 local target = source
82 local first, second = target.first, target.second
83 assert.same(first, 1)
84 return assert.same(second, 2)
85 end)
86 it("should import from nested table paths", function()
87 local deep = {
88 outer = {
89 inner = "value"
90 }
91 }
92 local outer = deep.outer
93 return assert.same(outer.inner, "value")
94 end)
95 it("should support importing Lua standard library functions", function()
96 local print, type
97 do
98 local _obj_0 = require("_G")
99 print, type = _obj_0.print, _obj_0.type
100 end
101 assert.is_true(type(print) == "function")
102 return assert.is_true(type(type) == "function")
103 end)
104 it("should handle empty import gracefully", function()
105 local source = { }
106 local dummy = source.dummy
107 return assert.same(dummy, nil)
108 end)
109 it("should work with table index expressions", function()
110 local source = {
111 normal = "ok"
112 }
113 local normal = source.normal
114 return assert.same(normal, "ok")
115 end)
116 it("should support chaining imports from same source", function()
117 local source = {
118 a = 1,
119 b = 2,
120 c = 3
121 }
122 local a, b = source.a, source.b
123 local c = source.c
124 assert.same(a, 1)
125 assert.same(b, 2)
126 return assert.same(c, 3)
127 end)
128 it("should handle importing from table returned by function", function()
129 local get_table
130 get_table = function()
131 return {
132 x = 100,
133 y = 200
134 }
135 end
136 local x, y
137 do
138 local _obj_0 = get_table()
139 x, y = _obj_0.x, _obj_0.y
140 end
141 assert.same(x, 100)
142 return assert.same(y, 200)
143 end)
144 it("should support from with multi-line import", function()
145 local source = {
146 item1 = 1,
147 item2 = 2,
148 item3 = 3
149 }
150 local item1, item2, item3 = source.item1, source.item2, source.item3
151 assert.same(item1, 1)
152 assert.same(item2, 2)
153 return assert.same(item3, 3)
154 end)
155 it("should work with import from string literal", function()
156 local char
157 do
158 local _obj_0 = require("string")
159 char = _obj_0.char
160 end
161 return assert.same(char(65), "A")
162 end)
163 it("should support import with table literal keys", function()
164 local source = {
165 normal_key = "value2"
166 }
167 local normal_key = source.normal_key
168 return assert.same(normal_key, "value2")
169 end)
170 it("should handle consecutive imports", function()
171 local source1 = {
172 a = 1
173 }
174 local source2 = {
175 b = 2
176 }
177 local a = source1.a
178 local b = source2.b
179 assert.same(a, 1)
180 return assert.same(b, 2)
181 end)
182 return it("should support importing from complex expressions", function()
183 local get_source
184 get_source = function()
185 return {
186 result = 42
187 }
188 end
189 local result
190 do
191 local _obj_0 = get_source()
192 result = _obj_0.result
193 end
194 return assert.same(result, 42)
195 end)
196end)
diff --git a/spec/outputs/test/literals_spec.lua b/spec/outputs/test/literals_spec.lua
new file mode 100644
index 0000000..3fa36eb
--- /dev/null
+++ b/spec/outputs/test/literals_spec.lua
@@ -0,0 +1,90 @@
1return describe("literals", function()
2 it("should support integer literals", function()
3 return assert.same(123, 123)
4 end)
5 it("should support float literals", function()
6 return assert.same(1.5, 1.5)
7 end)
8 it("should support scientific notation", function()
9 return assert.same(1.5e2, 150)
10 end)
11 it("should support negative numbers", function()
12 return assert.same(-42, -42)
13 end)
14 it("should support hexadecimal literals", function()
15 return assert.same(0xff, 255)
16 end)
17 it("should support hexadecimal with uppercase", function()
18 return assert.same(0XFF, 255)
19 end)
20 it("should support binary literals", function()
21 return assert.same(5, 5)
22 end)
23 it("should support binary with uppercase", function()
24 return assert.same(5, 5)
25 end)
26 it("should support number with underscores", function()
27 return assert.same(1000000, 1000000)
28 end)
29 it("should support hex with underscores", function()
30 return assert.same(0xDEADBEEF, 0xDEADBEEF)
31 end)
32 it("should support double quote strings", function()
33 return assert.same("hello", "hello")
34 end)
35 it("should support single quote strings", function()
36 return assert.same('world', 'world')
37 end)
38 it("should support multi-line strings with [[", function()
39 local s = [[ hello
40 world
41 ]]
42 return assert.is_true((s:match("hello") ~= nil))
43 end)
44 it("should support multi-line strings with [=[", function()
45 local s = [==[ test
46 ]==]
47 return assert.is_true((s:match("test") ~= nil))
48 end)
49 it("should support boolean true", function()
50 return assert.same(true, true)
51 end)
52 it("should support boolean false", function()
53 return assert.same(false, false)
54 end)
55 it("should support nil", function()
56 return assert.same(nil, nil)
57 end)
58 it("should support empty table", function()
59 local t = { }
60 return assert.same(#t, 0)
61 end)
62 it("should support table with keys", function()
63 local t = {
64 a = 1,
65 b = 2
66 }
67 assert.same(t.a, 1)
68 return assert.same(t.b, 2)
69 end)
70 it("should support array literal", function()
71 local t = {
72 1,
73 2,
74 3
75 }
76 assert.same(t[1], 1)
77 assert.same(t[2], 2)
78 return assert.same(t[3], 3)
79 end)
80 return it("should support mixed table", function()
81 local t = {
82 1,
83 2,
84 3,
85 key = "value"
86 }
87 assert.same(t[1], 1)
88 return assert.same(t.key, "value")
89 end)
90end)
diff --git a/spec/outputs/test/macro_spec.lua b/spec/outputs/test/macro_spec.lua
new file mode 100644
index 0000000..9c50548
--- /dev/null
+++ b/spec/outputs/test/macro_spec.lua
@@ -0,0 +1,166 @@
1return describe("macro", function()
2 it("should define and call basic macro", function()
3 local result = (5 * 2)
4 return assert.same(result, 10)
5 end)
6 it("should maintain hygiene in macros", function()
7 local a = 8
8 local result = 2
9 return assert.same(result, 2)
10 end)
11 it("should validate AST types", function()
12 local result = {
13 123,
14 'xyz'
15 }
16 return assert.same(result, {
17 123,
18 'xyz'
19 })
20 end)
21 it("should support simple code generation", function()
22 local result = (10 + 1)
23 return assert.same(result, 11)
24 end)
25 it("should support nested macro calls", function()
26 local result = 7
27 return assert.same(result, 7)
28 end)
29 it("should respect macro scope in do blocks", function()
30 do
31 local result = 'inner'
32 assert.same(result, "inner")
33 end
34 local result = 'outer'
35 return assert.same(result, "outer")
36 end)
37 it("should provide $LINE macro", function()
38 local line_num = 42
39 return assert.is_true(line_num > 0)
40 end)
41 it("should inject Lua code", function()
42 local x = 0
43 do
44local function f(a)
45 return a + 1
46 end
47 x = x + f(3)
48 end
49 return assert.same(x, 4)
50 end)
51 it("should work in conditional compilation", function()
52 local result = "debug mode"
53 return assert.same(result, "debug mode")
54 end)
55 it("should work with class system", function()
56 local Thing
57 do
58 local _class_0
59 local _base_0 = {
60 value = 100,
61 get_value = function(self)
62 return self.value
63 end
64 }
65 if _base_0.__index == nil then
66 _base_0.__index = _base_0
67 end
68 _class_0 = setmetatable({
69 __init = function() end,
70 __base = _base_0,
71 __name = "Thing"
72 }, {
73 __index = _base_0,
74 __call = function(cls, ...)
75 local _self_0 = setmetatable({ }, _base_0)
76 cls.__init(_self_0, ...)
77 return _self_0
78 end
79 })
80 _base_0.__class = _class_0
81 Thing = _class_0
82 end
83 local instance = Thing()
84 return assert.same(instance:get_value(), 100)
85 end)
86 it("should handle macro in switch expressions", function()
87 local result
88 do
89 local _exp_0 = "test"
90 if "test" == _exp_0 then
91 result = "matched"
92 else
93 result = "no match"
94 end
95 end
96 return assert.same(result, "matched")
97 end)
98 it("should support macro in expression context", function()
99 local result = 5 + (2 * 3)
100 return assert.same(result, 11)
101 end)
102 it("should handle $is_ast for type checking", function()
103 local result = 42
104 return assert.same(result, 42)
105 end)
106 it("should work with string interpolation", function()
107 local result = {
108 ["test"] = 123
109 }
110 return assert.same(result, {
111 test = 123
112 })
113 end)
114 it("should support function call syntax", function()
115 local result = (5 + 10)
116 return assert.same(result, 15)
117 end)
118 it("should handle empty macro return", function()
119 local a = 1
120 a = 2
121 return assert.same(a, 2)
122 end)
123 it("should work with table literals", function()
124 local point = {
125 x = 10,
126 y = 20
127 }
128 assert.same(point.x, 10)
129 return assert.same(point.y, 20)
130 end)
131 it("should support conditional expressions in macro", function()
132 local result = (5 + 1)
133 return assert.same(result, 6)
134 end)
135 it("should work with comprehension", function()
136 local result
137 do
138 local _accum_0 = { }
139 local _len_0 = 1
140 local _list_0 = {
141 1,
142 2,
143 3
144 }
145 for _index_0 = 1, #_list_0 do
146 local _ = _list_0[_index_0]
147 _accum_0[_len_0] = _ * 2
148 _len_0 = _len_0 + 1
149 end
150 result = _accum_0
151 end
152 return assert.same(result, {
153 2,
154 4,
155 6
156 })
157 end)
158 it("should support complex expression macros", function()
159 local result = (1 + 2 * 3)
160 return assert.same(result, 7)
161 end)
162 return it("should work with string literals", function()
163 local result = ('Hello, ' .. "World")
164 return assert.same(result, "Hello, World")
165 end)
166end)
diff --git a/spec/outputs/test/metatable_spec.lua b/spec/outputs/test/metatable_spec.lua
new file mode 100644
index 0000000..4d2a886
--- /dev/null
+++ b/spec/outputs/test/metatable_spec.lua
@@ -0,0 +1,141 @@
1return describe("metatable", function()
2 it("should get metatable with <> syntax", function()
3 local obj = setmetatable({
4 value = 42
5 }, {
6 __index = {
7 extra = "data"
8 }
9 })
10 local mt = getmetatable(obj)
11 return assert.is_true(mt ~= nil)
12 end)
13 it("should set metatable with <>", function()
14 local obj = { }
15 setmetatable(obj, {
16 __index = {
17 value = 100
18 }
19 })
20 return assert.same(obj.value, 100)
21 end)
22 it("should access metatable with <>", function()
23 local obj = setmetatable({ }, {
24 __index = {
25 value = 50
26 }
27 })
28 local result = getmetatable(obj).__index.value
29 return assert.same(result, 50)
30 end)
31 it("should work with <index> metamethod", function()
32 local obj = setmetatable({ }, {
33 __index = function(self, key)
34 if key == "computed" then
35 return "computed_value"
36 end
37 end
38 })
39 return assert.same(obj.computed, "computed_value")
40 end)
41 it("should work with <newindex> metamethod", function()
42 local obj = setmetatable({ }, {
43 __newindex = function(self, key, value)
44 return rawset(self, "stored_" .. key, value)
45 end
46 })
47 obj.test = 123
48 return assert.same(obj.stored_test, 123)
49 end)
50 it("should work with <add> metamethod", function()
51 local obj = setmetatable({
52 value = 10
53 }, {
54 __add = function(a, b)
55 return a.value + b.value
56 end
57 })
58 local obj2 = setmetatable({
59 value = 20
60 }, {
61 __add = function(a, b)
62 return a.value + b.value
63 end
64 })
65 local result = obj + obj2
66 return assert.same(result, 30)
67 end)
68 it("should work with <call> metamethod", function()
69 local obj = setmetatable({ }, {
70 __call = function(self, x)
71 return x * 2
72 end
73 })
74 local result = obj(5)
75 return assert.same(result, 10)
76 end)
77 it("should work with <tostring> metamethod", function()
78 local obj = setmetatable({
79 value = 42
80 }, {
81 __tostring = function(self)
82 return "Value: " .. tostring(self.value)
83 end
84 })
85 local result = tostring(obj)
86 return assert.same(result, "Value: 42")
87 end)
88 it("should work with <eq> metamethod", function()
89 local obj1 = setmetatable({
90 id = 1
91 }, {
92 __eq = function(a, b)
93 return a.id == b.id
94 end
95 })
96 local obj2 = setmetatable({
97 id = 1
98 }, {
99 __eq = function(a, b)
100 return a.id == b.id
101 end
102 })
103 return assert.is_true(obj1 == obj2)
104 end)
105 it("should destructure metatable", function()
106 local obj = setmetatable({ }, {
107 new = function()
108 return "new result"
109 end,
110 update = function()
111 return "update result"
112 end
113 })
114 local new, update
115 do
116 local _obj_0 = getmetatable(obj)
117 new, update = _obj_0.new, _obj_0.update
118 end
119 assert.is_true(type(new) == "function")
120 return assert.is_true(type(update) == "function")
121 end)
122 it("should check if two objects have same metatable", function()
123 local mt = {
124 value = 100
125 }
126 local obj1 = setmetatable({ }, mt)
127 local obj2 = setmetatable({ }, mt)
128 return assert.is_true(getmetatable(obj1) == getmetatable(obj2))
129 end)
130 return it("should work with <concat> metamethod", function()
131 local obj = setmetatable({
132 value = "hello"
133 }, {
134 __concat = function(a, b)
135 return a.value .. b
136 end
137 })
138 local result = obj .. " world"
139 return assert.same(result, "hello world")
140 end)
141end)
diff --git a/spec/outputs/test/operators_spec.lua b/spec/outputs/test/operators_spec.lua
new file mode 100644
index 0000000..a17ff03
--- /dev/null
+++ b/spec/outputs/test/operators_spec.lua
@@ -0,0 +1,142 @@
1return describe("operators", function()
2 it("should support addition", function()
3 return assert.same(1 + 2, 3)
4 end)
5 it("should support subtraction", function()
6 return assert.same(5 - 3, 2)
7 end)
8 it("should support multiplication", function()
9 return assert.same(4 * 3, 12)
10 end)
11 it("should support division", function()
12 return assert.same(10 / 2, 5)
13 end)
14 it("should support modulo", function()
15 return assert.same(10 % 3, 1)
16 end)
17 it("should support exponentiation", function()
18 return assert.same(2 ^ 3, 8)
19 end)
20 it("should support unary minus", function()
21 return assert.same(-5, -5)
22 end)
23 it("should support equality comparison", function()
24 assert.is_true(1 == 1)
25 return assert.is_false(1 == 2)
26 end)
27 it("should support inequality comparison", function()
28 assert.is_true(1 ~= 2)
29 return assert.is_false(1 ~= 1)
30 end)
31 it("should support less than", function()
32 assert.is_true(1 < 2)
33 return assert.is_false(2 < 1)
34 end)
35 it("should support greater than", function()
36 assert.is_true(2 > 1)
37 return assert.is_false(1 > 2)
38 end)
39 it("should support less than or equal", function()
40 assert.is_true(1 <= 2)
41 assert.is_true(2 <= 2)
42 return assert.is_false(3 <= 2)
43 end)
44 it("should support greater than or equal", function()
45 assert.is_true(2 >= 1)
46 assert.is_true(2 >= 2)
47 return assert.is_false(1 >= 2)
48 end)
49 it("should support logical and", function()
50 assert.same(true and false, false)
51 assert.same(true and true, true)
52 return assert.same(false and true, false)
53 end)
54 it("should support logical or", function()
55 assert.same(true or false, true)
56 assert.same(false or true, true)
57 return assert.same(false or false, false)
58 end)
59 it("should support logical not", function()
60 assert.same(not true, false)
61 assert.same(not false, true)
62 return assert.same(not nil, true)
63 end)
64 it("should support bitwise and", function()
65 return assert.same(5 & 3, 1)
66 end)
67 it("should support bitwise or", function()
68 return assert.same(5 | 3, 7)
69 end)
70 it("should support bitwise xor", function()
71 return assert.same(5 ~ 3, 6)
72 end)
73 it("should support left shift", function()
74 return assert.same(2 << 3, 16)
75 end)
76 it("should support right shift", function()
77 return assert.same(16 >> 2, 4)
78 end)
79 it("should support string concatenation", function()
80 return assert.same("hello" .. " world", "hello world")
81 end)
82 it("should support length operator", function()
83 assert.same(#"hello", 5)
84 return assert.same(#{
85 1,
86 2,
87 3
88 }, 3)
89 end)
90 it("should respect operator precedence", function()
91 assert.same(1 + 2 * 3, 7)
92 return assert.same((1 + 2) * 3, 9)
93 end)
94 it("should support compound assignment", function()
95 local x = 10
96 x = x + 5
97 return assert.same(x, 15)
98 end)
99 it("should support compound subtraction", function()
100 local x = 10
101 x = x - 3
102 return assert.same(x, 7)
103 end)
104 it("should support compound multiplication", function()
105 local x = 5
106 x = x * 2
107 return assert.same(x, 10)
108 end)
109 it("should support compound division", function()
110 local x = 20
111 x = x / 4
112 return assert.same(x, 5)
113 end)
114 it("should handle division by zero", function()
115 local result = pcall(function()
116 local x = 10 / 0
117 end)
118 return assert.is_true(result)
119 end)
120 it("should handle very large numbers", function()
121 local big = 1e100
122 return assert.is_true(big > 0)
123 end)
124 it("should handle very small numbers", function()
125 local small = 1e-100
126 return assert.is_true(small > 0)
127 end)
128 it("should support negation", function()
129 assert.same(-10, -10)
130 return assert.same
131 end)
132 it("should work with complex expressions", function()
133 local result = (1 + 2) * (3 + 4) / 2
134 return assert.same(result, 10.5)
135 end)
136 it("should support power with decimal", function()
137 return assert.same(4 ^ 0.5, 2)
138 end)
139 return it("should handle modulo with negative numbers", function()
140 return assert.same(-10 % 3, 2)
141 end)
142end)
diff --git a/spec/outputs/test/return_spec.lua b/spec/outputs/test/return_spec.lua
new file mode 100644
index 0000000..9479773
--- /dev/null
+++ b/spec/outputs/test/return_spec.lua
@@ -0,0 +1,147 @@
1return describe("return", function()
2 it("should return from comprehension", function()
3 local fn
4 fn = function()
5 local _accum_0 = { }
6 local _len_0 = 1
7 for x = 1, 5 do
8 _accum_0[_len_0] = x * 2
9 _len_0 = _len_0 + 1
10 end
11 return _accum_0
12 end
13 local result = fn()
14 return assert.same(result, {
15 2,
16 4,
17 6,
18 8,
19 10
20 })
21 end)
22 it("should return from table comprehension", function()
23 local fn
24 fn = function()
25 local _tbl_0 = { }
26 for k, v in pairs({
27 a = 1,
28 b = 2
29 }) do
30 _tbl_0[k] = v
31 end
32 return _tbl_0
33 end
34 local result = fn()
35 return assert.same(type(result), "table")
36 end)
37 it("should return from nested if", function()
38 local fn
39 fn = function(a, b)
40 if a then
41 if b then
42 return "both"
43 else
44 return "only a"
45 end
46 else
47 return "neither"
48 end
49 end
50 assert.same(fn(true, true), "both")
51 assert.same(fn(true, false), "only a")
52 return assert.same(fn(false, false), "neither")
53 end)
54 it("should return from switch", function()
55 local fn
56 fn = function(value)
57 if 1 == value then
58 return "one"
59 elseif 2 == value then
60 return "two"
61 else
62 return "other"
63 end
64 end
65 assert.same(fn(1), "one")
66 assert.same(fn(2), "two")
67 return assert.same(fn(3), "other")
68 end)
69 it("should return table literal", function()
70 local fn
71 fn = function()
72 return {
73 value = 42,
74 name = "test"
75 }
76 end
77 local result = fn()
78 assert.same(result.value, 42)
79 return assert.same(result.name, "test")
80 end)
81 it("should return array literal", function()
82 local fn
83 fn = function()
84 return {
85 1,
86 2,
87 3
88 }
89 end
90 local result = fn()
91 return assert.same(result, {
92 1,
93 2,
94 3
95 })
96 end)
97 it("should return from with statement", function()
98 local fn
99 fn = function(obj)
100 local result = obj.value
101 return result
102 end
103 return assert.same(fn({
104 value = 100
105 }), 100)
106 end)
107 it("should return nil implicitly", function()
108 local fn
109 fn = function()
110 local _ = "no return"
111 end
112 return assert.same(fn(), nil)
113 end)
114 it("should return multiple values", function()
115 local fn
116 fn = function()
117 return 1, 2, 3
118 end
119 local a, b, c = fn()
120 assert.same(a, 1)
121 assert.same(b, 2)
122 return assert.same(c, 3)
123 end)
124 it("should return from function call", function()
125 local fn
126 fn = function()
127 local inner
128 inner = function()
129 return 42
130 end
131 return inner()
132 end
133 return assert.same(fn(), 42)
134 end)
135 return it("should handle return in expression context", function()
136 local fn
137 fn = function(cond)
138 if cond then
139 return "yes"
140 else
141 return "no"
142 end
143 end
144 assert.same(fn(true), "yes")
145 return assert.same(fn(false), "no")
146 end)
147end)
diff --git a/spec/outputs/test/string_spec.lua b/spec/outputs/test/string_spec.lua
new file mode 100644
index 0000000..76d4ae6
--- /dev/null
+++ b/spec/outputs/test/string_spec.lua
@@ -0,0 +1,138 @@
1return describe("string", function()
2 it("should support single quote strings", function()
3 local s = 'hello'
4 return assert.same(s, "hello")
5 end)
6 it("should support double quote strings", function()
7 local s = "world"
8 return assert.same(s, "world")
9 end)
10 it("should support escape sequences", function()
11 local s = "hello\nworld"
12 return assert.is_true(s:match("\n") ~= nil)
13 end)
14 it("should support escaped quotes", function()
15 local s = "he said \"hello\""
16 return assert.same(s, 'he said "hello"')
17 end)
18 it("should support backslash escape", function()
19 local s = "\\"
20 return assert.same(s, "\\")
21 end)
22 it("should support multi-line strings with [[ ]]", function()
23 local s = [[ hello
24 world
25 ]]
26 assert.is_true(s:match("hello") ~= nil)
27 return assert.is_true(s:match("world") ~= nil)
28 end)
29 it("should support multi-line strings with [=[ ]=]", function()
30 local s = [==[ hello
31 world
32 ]==]
33 assert.is_true(s:match("hello") ~= nil)
34 return assert.is_true(s:match("world") ~= nil)
35 end)
36 it("should support string interpolation with double quotes", function()
37 local name = "world"
38 local s = "hello " .. tostring(name)
39 return assert.same(s, "hello world")
40 end)
41 it("should support expression interpolation", function()
42 local a, b = 1, 2
43 local s = tostring(a) .. " + " .. tostring(b) .. " = " .. tostring(a + b)
44 return assert.same(s, "1 + 2 = 3")
45 end)
46 it("should not interpolate in single quotes", function()
47 local name = "world"
48 local s = 'hello #{name}'
49 return assert.same(s, "hello #{name}")
50 end)
51 it("should escape interpolation with \\#", function()
52 local name = "world"
53 local s = "hello #{name}"
54 return assert.same(s, 'hello #{name}')
55 end)
56 it("should support method calls on string literals", function()
57 local result = ("hello"):upper()
58 return assert.same(result, "HELLO")
59 end)
60 it("should support chained method calls", function()
61 local result = ("hello world"):upper():match("HELLO")
62 return assert.same(result, "HELLO")
63 end)
64 it("should support YAML style strings", function()
65 local s = "hello\nworld"
66 assert.is_true(s:match("hello") ~= nil)
67 return assert.is_true(s:match("world") ~= nil)
68 end)
69 it("should support YAML style with interpolation", function()
70 local name = "test"
71 local s = "hello " .. tostring(name)
72 return assert.same(s, "hello test")
73 end)
74 it("should support string concatenation", function()
75 local s = "hello" .. " " .. "world"
76 return assert.same(s, "hello world")
77 end)
78 it("should handle empty strings", function()
79 local s = ""
80 return assert.same(s, "")
81 end)
82 it("should support Unicode characters", function()
83 local s = "hello 世界"
84 return assert.is_true(s:match("世界") ~= nil)
85 end)
86 it("should support string length", function()
87 local s = "hello"
88 return assert.same(#s, 5)
89 end)
90 it("should support multi-line YAML with complex content", function()
91 local config = "key1: value1\nkey2: value2\nkey3: value3"
92 return assert.is_true(config:match("key1") ~= nil)
93 end)
94 it("should support interpolation in YAML strings", function()
95 local x, y = 10, 20
96 local s = "point:\n\tx: " .. tostring(x) .. "\n\ty: " .. tostring(y)
97 assert.is_true(s:match("x: 10") ~= nil)
98 return assert.is_true(s:match("y: 20") ~= nil)
99 end)
100 it("should support function call in interpolation", function()
101 local s = "result: " .. tostring((function()
102 return 42
103 end)())
104 return assert.same(s, "result: 42")
105 end)
106 it("should support table indexing in interpolation", function()
107 local t = {
108 value = 100
109 }
110 local s = "value: " .. tostring(t.value)
111 return assert.same(s, "value: 100")
112 end)
113 it("should handle escaped characters correctly", function()
114 local s = "tab:\t, newline:\n, return:\r"
115 assert.is_true(s:match("\t") ~= nil)
116 return assert.is_true(s:match("\n") ~= nil)
117 end)
118 it("should support string methods with colon syntax", function()
119 local s = "hello"
120 return assert.same(s:sub(1, 2), "he")
121 end)
122 it("should work in expressions", function()
123 local result = "hello" .. " world"
124 return assert.same(result, "hello world")
125 end)
126 it("should support octal escape", function()
127 local s = "\65"
128 return assert.same(s, "A")
129 end)
130 it("should support hex escape", function()
131 local s = "\x41"
132 return assert.same(s, "A")
133 end)
134 return it("should support unicode escape", function()
135 local s = "\u{4e16}"
136 return assert.same(s, "世")
137 end)
138end)
diff --git a/spec/outputs/test/switch_spec.lua b/spec/outputs/test/switch_spec.lua
new file mode 100644
index 0000000..59ffca5
--- /dev/null
+++ b/spec/outputs/test/switch_spec.lua
@@ -0,0 +1,742 @@
1return describe("switch", function()
2 it("should match single value", function()
3 local value = "cool"
4 local result
5 if "cool" == value then
6 result = "matched"
7 else
8 result = "not matched"
9 end
10 return assert.same(result, "matched")
11 end)
12 it("should match multiple values with or", function()
13 local hi = "world"
14 local matched = false
15 if "one" == hi or "two" == hi then
16 matched = true
17 end
18 assert.is_false(matched)
19 hi = "one"
20 if "one" == hi or "two" == hi then
21 matched = true
22 end
23 return assert.is_true(matched)
24 end)
25 it("should execute else branch when no match", function()
26 local value = "other"
27 local result
28 if "cool" == value then
29 result = "matched cool"
30 elseif "yeah" == value then
31 result = "matched yeah"
32 else
33 result = "else branch"
34 end
35 return assert.same(result, "else branch")
36 end)
37 it("should destructure table with single key", function()
38 local tb = {
39 x = 100
40 }
41 local result
42 do
43 local _type_0 = type(tb)
44 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
45 local _match_0 = false
46 if _tab_0 then
47 local x = tb.x
48 if x ~= nil then
49 _match_0 = true
50 result = x
51 end
52 end
53 if not _match_0 then
54 result = "no match"
55 end
56 end
57 return assert.same(result, 100)
58 end)
59 it("should destructure table with multiple keys", function()
60 local tb = {
61 x = 100,
62 y = 200
63 }
64 local result
65 do
66 local _type_0 = type(tb)
67 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
68 local _match_0 = false
69 if _tab_0 then
70 local x = tb.x
71 local y = tb.y
72 if x ~= nil and y ~= nil then
73 _match_0 = true
74 result = x + y
75 end
76 end
77 if not _match_0 then
78 result = "no match"
79 end
80 end
81 return assert.same(result, 300)
82 end)
83 it("should destructure table with default values", function()
84 local tb = {
85 a = 1
86 }
87 local _type_0 = type(tb)
88 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
89 if _tab_0 then
90 local a = tb.a
91 local b = tb.b
92 if a == nil then
93 a = 1
94 end
95 if b == nil then
96 b = 2
97 end
98 assert.same(a, 1)
99 return assert.same(b, 2)
100 end
101 end)
102 it("should destructure nested tables", function()
103 local dict = {
104 { },
105 {
106 1,
107 2,
108 3
109 },
110 a = {
111 b = {
112 c = 1
113 }
114 },
115 x = {
116 y = {
117 z = 1
118 }
119 }
120 }
121 local matched = false
122 do
123 local _type_0 = type(dict)
124 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
125 if _tab_0 then
126 local first = dict[1]
127 local one
128 do
129 local _obj_0 = dict[2]
130 local _type_1 = type(_obj_0)
131 if "table" == _type_1 or "userdata" == _type_1 then
132 one = _obj_0[1]
133 end
134 end
135 local two
136 do
137 local _obj_0 = dict[2]
138 local _type_1 = type(_obj_0)
139 if "table" == _type_1 or "userdata" == _type_1 then
140 two = _obj_0[2]
141 end
142 end
143 local three
144 do
145 local _obj_0 = dict[2]
146 local _type_1 = type(_obj_0)
147 if "table" == _type_1 or "userdata" == _type_1 then
148 three = _obj_0[3]
149 end
150 end
151 local c
152 do
153 local _obj_0 = dict.a
154 local _type_1 = type(_obj_0)
155 if "table" == _type_1 or "userdata" == _type_1 then
156 do
157 local _obj_1 = _obj_0.b
158 local _type_2 = type(_obj_1)
159 if "table" == _type_2 or "userdata" == _type_2 then
160 c = _obj_1.c
161 end
162 end
163 end
164 end
165 local z
166 do
167 local _obj_0 = dict.x
168 local _type_1 = type(_obj_0)
169 if "table" == _type_1 or "userdata" == _type_1 then
170 do
171 local _obj_1 = _obj_0.y
172 local _type_2 = type(_obj_1)
173 if "table" == _type_2 or "userdata" == _type_2 then
174 z = _obj_1.z
175 end
176 end
177 end
178 end
179 if first ~= nil and one ~= nil and two ~= nil and three ~= nil and c ~= nil and z ~= nil then
180 matched = type(first) == 'table' and one == 1 and two == 2 and three == 3 and c == 1 and z == 1
181 end
182 end
183 end
184 return assert.is_true(matched)
185 end)
186 it("should destructure arrays with exact match", function()
187 local tb = {
188 1,
189 2,
190 3
191 }
192 local result
193 do
194 local _type_0 = type(tb)
195 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
196 local _match_0 = false
197 if _tab_0 then
198 if 1 == tb[1] and 2 == tb[2] and 3 == tb[3] then
199 _match_0 = true
200 result = "exact match"
201 end
202 end
203 if not _match_0 then
204 result = "no match"
205 end
206 end
207 return assert.same(result, "exact match")
208 end)
209 it("should destructure arrays with variables", function()
210 local tb = {
211 1,
212 "b",
213 3
214 }
215 local result
216 do
217 local _type_0 = type(tb)
218 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
219 local _match_0 = false
220 if _tab_0 then
221 local b = tb[2]
222 if 1 == tb[1] and b ~= nil and 3 == tb[3] then
223 _match_0 = true
224 result = b
225 end
226 end
227 if not _match_0 then
228 result = "no match"
229 end
230 end
231 return assert.same(result, "b")
232 end)
233 it("should destructure arrays with defaults", function()
234 local tb = {
235 1,
236 2
237 }
238 local result
239 do
240 local _type_0 = type(tb)
241 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
242 local _match_0 = false
243 if _tab_0 then
244 local b = tb[3]
245 if b == nil then
246 b = 3
247 end
248 if 1 == tb[1] and 2 == tb[2] then
249 _match_0 = true
250 result = b
251 end
252 end
253 if not _match_0 then
254 result = "no match"
255 end
256 end
257 return assert.same(result, 3)
258 end)
259 it("should match pattern with __class", function()
260 local ClassA
261 do
262 local _class_0
263 local _base_0 = { }
264 if _base_0.__index == nil then
265 _base_0.__index = _base_0
266 end
267 _class_0 = setmetatable({
268 __init = function() end,
269 __base = _base_0,
270 __name = "ClassA"
271 }, {
272 __index = _base_0,
273 __call = function(cls, ...)
274 local _self_0 = setmetatable({ }, _base_0)
275 cls.__init(_self_0, ...)
276 return _self_0
277 end
278 })
279 _base_0.__class = _class_0
280 ClassA = _class_0
281 end
282 local ClassB
283 do
284 local _class_0
285 local _base_0 = { }
286 if _base_0.__index == nil then
287 _base_0.__index = _base_0
288 end
289 _class_0 = setmetatable({
290 __init = function() end,
291 __base = _base_0,
292 __name = "ClassB"
293 }, {
294 __index = _base_0,
295 __call = function(cls, ...)
296 local _self_0 = setmetatable({ }, _base_0)
297 cls.__init(_self_0, ...)
298 return _self_0
299 end
300 })
301 _base_0.__class = _class_0
302 ClassB = _class_0
303 end
304 local item = ClassA()
305 local result
306 do
307 local _type_0 = type(item)
308 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
309 local _match_0 = false
310 if _tab_0 then
311 ClassA = item.__class
312 if ClassA ~= nil then
313 _match_0 = true
314 result = "Object A"
315 end
316 end
317 if not _match_0 then
318 local _match_1 = false
319 if _tab_0 then
320 ClassB = item.__class
321 if ClassB ~= nil then
322 _match_1 = true
323 result = "Object B"
324 end
325 end
326 if not _match_1 then
327 result = "unknown"
328 end
329 end
330 end
331 return assert.same(result, "Object A")
332 end)
333 it("should match pattern with metatable", function()
334 local tb = setmetatable({ }, {
335 __mode = "v"
336 })
337 local metatable_matched = false
338 do
339 local _type_0 = type(tb)
340 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
341 if _tab_0 then
342 local mt = getmetatable(tb)
343 if mt ~= nil then
344 metatable_matched = mt ~= nil
345 end
346 end
347 end
348 return assert.is_true(metatable_matched)
349 end)
350 it("should use switch as expression in assignment", function()
351 local tb = {
352 x = "abc"
353 }
354 local matched
355 if 1 == tb then
356 matched = "1"
357 else
358 do
359 local _type_0 = type(tb)
360 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
361 local _match_0 = false
362 if _tab_0 then
363 local x = tb.x
364 if x ~= nil then
365 _match_0 = true
366 matched = x
367 end
368 end
369 if not _match_0 then
370 if false == tb then
371 matched = "false"
372 else
373 matched = nil
374 end
375 end
376 end
377 end
378 return assert.same(matched, "abc")
379 end)
380 it("should use switch in return statement", function()
381 local fn
382 fn = function(tb)
383 if nil == tb then
384 return "invalid"
385 else
386 local _type_0 = type(tb)
387 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
388 local _match_0 = false
389 if _tab_0 then
390 local a = tb.a
391 local b = tb.b
392 if a ~= nil and b ~= nil then
393 _match_0 = true
394 return tostring(a + b)
395 end
396 end
397 if not _match_0 then
398 if 1 == tb or 2 == tb or 3 == tb or 4 == tb or 5 == tb then
399 return "number 1 - 5"
400 else
401 return "should not reach here"
402 end
403 end
404 end
405 end
406 assert.same(fn({
407 a = 1,
408 b = 2
409 }), "3")
410 assert.same(fn(3), "number 1 - 5")
411 return assert.same(fn(nil), "invalid")
412 end)
413 it("should support pattern matching assignment with :=", function()
414 local v = "hello"
415 local matched = false
416 do
417 v = "hello"
418 if "hello" == v then
419 matched = true
420 else
421 matched = false
422 end
423 end
424 assert.is_true(matched)
425 return assert.same(v, "hello")
426 end)
427 it("should match with computed expressions", function()
428 local hi = 4
429 local matched = false
430 if (3 + 1) == hi or (function()
431 return 4
432 end)() == hi or (5 - 1) == hi then
433 matched = true
434 end
435 return assert.is_true(matched)
436 end)
437 it("should handle nested array destructuring", function()
438 local tb = {
439 {
440 a = 1,
441 b = 2
442 },
443 {
444 a = 3,
445 b = 4
446 },
447 {
448 a = 5,
449 b = 6
450 },
451 "fourth"
452 }
453 local result
454 do
455 local _type_0 = type(tb)
456 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
457 local _match_0 = false
458 if _tab_0 then
459 local fourth = tb[4]
460 local _val_0
461 do
462 local _obj_0 = tb[1]
463 if _obj_0 ~= nil then
464 _val_0 = _obj_0.a
465 end
466 end
467 local _val_1
468 do
469 local _obj_0 = tb[1]
470 if _obj_0 ~= nil then
471 _val_1 = _obj_0.b
472 end
473 end
474 local _val_2
475 do
476 local _obj_0 = tb[2]
477 if _obj_0 ~= nil then
478 _val_2 = _obj_0.a
479 end
480 end
481 local _val_3
482 do
483 local _obj_0 = tb[2]
484 if _obj_0 ~= nil then
485 _val_3 = _obj_0.b
486 end
487 end
488 local _val_4
489 do
490 local _obj_0 = tb[3]
491 if _obj_0 ~= nil then
492 _val_4 = _obj_0.a
493 end
494 end
495 local _val_5
496 do
497 local _obj_0 = tb[3]
498 if _obj_0 ~= nil then
499 _val_5 = _obj_0.b
500 end
501 end
502 if 1 == _val_0 and 2 == _val_1 and 3 == _val_2 and 4 == _val_3 and 5 == _val_4 and 6 == _val_5 and fourth ~= nil then
503 _match_0 = true
504 result = fourth
505 end
506 end
507 if not _match_0 then
508 result = "no match"
509 end
510 end
511 return assert.same(result, "fourth")
512 end)
513 it("should match combined patterns", function()
514 local tb = {
515 success = true,
516 result = "data"
517 }
518 local result
519 do
520 local _type_0 = type(tb)
521 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
522 local _match_0 = false
523 if _tab_0 then
524 result = tb.result
525 if true == tb.success and result ~= nil then
526 _match_0 = true
527 result = {
528 "success",
529 result
530 }
531 end
532 end
533 if not _match_0 then
534 local _match_1 = false
535 if _tab_0 then
536 if false == tb.success then
537 _match_1 = true
538 result = {
539 "failed",
540 result
541 }
542 end
543 end
544 if not _match_1 then
545 result = {
546 "invalid"
547 }
548 end
549 end
550 end
551 return assert.same(result, {
552 "success",
553 "data"
554 })
555 end)
556 it("should match type discriminated patterns", function()
557 local tb = {
558 type = "success",
559 content = "data"
560 }
561 local result
562 do
563 local _type_0 = type(tb)
564 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
565 local _match_0 = false
566 if _tab_0 then
567 local content = tb.content
568 if "success" == tb.type and content ~= nil then
569 _match_0 = true
570 result = {
571 "success",
572 content
573 }
574 end
575 end
576 if not _match_0 then
577 local _match_1 = false
578 if _tab_0 then
579 local content = tb.content
580 if "error" == tb.type and content ~= nil then
581 _match_1 = true
582 result = {
583 "error",
584 content
585 }
586 end
587 end
588 if not _match_1 then
589 result = {
590 "invalid"
591 }
592 end
593 end
594 end
595 return assert.same(result, {
596 "success",
597 "data"
598 })
599 end)
600 it("should match with wildcard array capture", function()
601 local clientData = {
602 "Meta",
603 "CUST_1001",
604 "CHK123"
605 }
606 local metadata = nil
607 local customerId = nil
608 local checksum = nil
609 do
610 local _type_0 = type(clientData)
611 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
612 if _tab_0 then
613 local capturedMetadata
614 do
615 local _accum_0 = { }
616 local _len_0 = 1
617 local _max_0 = #clientData + -3 + 1
618 for _index_0 = 1, _max_0 do
619 local _item_0 = clientData[_index_0]
620 _accum_0[_len_0] = _item_0
621 _len_0 = _len_0 + 1
622 end
623 capturedMetadata = _accum_0
624 end
625 customerId = clientData[#clientData - 1]
626 checksum = clientData[#clientData]
627 if customerId ~= nil and checksum ~= nil then
628 metadata = capturedMetadata
629 end
630 end
631 end
632 assert.same(metadata, {
633 "Meta"
634 })
635 assert.same(customerId, "CUST_1001")
636 return assert.same(checksum, "CHK123")
637 end)
638 it("should work with complex tuple patterns", function()
639 local handlePath
640 handlePath = function(segments)
641 local _type_0 = type(segments)
642 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
643 local _match_0 = false
644 if _tab_0 then
645 local resource = segments[#segments - 1]
646 local action = segments[#segments]
647 if resource ~= nil and action ~= nil then
648 _match_0 = true
649 return {
650 "Resource: " .. tostring(resource),
651 "Action: " .. tostring(action)
652 }
653 end
654 end
655 if not _match_0 then
656 return {
657 "no match"
658 }
659 end
660 end
661 local result = handlePath({
662 "admin",
663 "logs",
664 "view"
665 })
666 return assert.same(result, {
667 "Resource: logs",
668 "Action: view"
669 })
670 end)
671 it("should match boolean false correctly", function()
672 local items = {
673 {
674 x = 100,
675 y = 200
676 },
677 {
678 width = 300,
679 height = 400
680 },
681 false
682 }
683 local results = { }
684 for _index_0 = 1, #items do
685 local item = items[_index_0]
686 local _type_0 = type(item)
687 local _tab_0 = "table" == _type_0 or "userdata" == _type_0
688 local _match_0 = false
689 if _tab_0 then
690 local x = item.x
691 local y = item.y
692 if x ~= nil and y ~= nil then
693 _match_0 = true
694 table.insert(results, "Vec2")
695 end
696 end
697 if not _match_0 then
698 local _match_1 = false
699 if _tab_0 then
700 local width = item.width
701 local height = item.height
702 if width ~= nil and height ~= nil then
703 _match_1 = true
704 table.insert(results, "Size")
705 end
706 end
707 if not _match_1 then
708 if false == item then
709 table.insert(results, "None")
710 end
711 end
712 end
713 end
714 return assert.same(results, {
715 "Vec2",
716 "Size",
717 "None"
718 })
719 end)
720 it("should handle switch with then syntax", function()
721 local value = "cool"
722 local result
723 if "cool" == value then
724 result = "matched cool"
725 else
726 result = "else branch"
727 end
728 return assert.same(result, "matched cool")
729 end)
730 return it("should handle switch in function call", function()
731 local something = 1
732 local getValue
733 getValue = function()
734 if 1 == something then
735 return "yes"
736 else
737 return "no"
738 end
739 end
740 return assert.same(getValue(), "yes")
741 end)
742end)
diff --git a/spec/outputs/test/try_catch_spec.lua b/spec/outputs/test/try_catch_spec.lua
index 2bcfc16..4183610 100644
--- a/spec/outputs/test/try_catch_spec.lua
+++ b/spec/outputs/test/try_catch_spec.lua
@@ -1,14 +1,20 @@
1local _anon_func_0 = function(error)
2 return error("boom")
3end
4local _anon_func_1 = function(e, error)
5 return error("wrap:" .. e:match("^.-:%d+:%s*(.*)$"))
6end
1return describe("try/catch", function() 7return describe("try/catch", function()
2 return it("catch and rethrow", function() 8 return it("catch and rethrow", function()
9 local pcall <const> = pcall
10 local error <const> = error
11 local xpcall <const> = xpcall
12 local assert <const> = assert
3 local ok, success, err = pcall(function() 13 local ok, success, err = pcall(function()
4 return xpcall(function() 14 return xpcall(_anon_func_0, function(e)
5 return error("boom") 15 local _, result = pcall(_anon_func_1, e, error)
6 end, function(e)
7 local _, result = pcall(function()
8 return error("wrap:" .. e:match("^.-:%d+:%s*(.*)$"))
9 end)
10 return result 16 return result
11 end) 17 end, error)
12 end) 18 end)
13 assert.same(ok, true) 19 assert.same(ok, true)
14 assert.same(success, false) 20 assert.same(success, false)
diff --git a/spec/outputs/test/vararg_spec.lua b/spec/outputs/test/vararg_spec.lua
new file mode 100644
index 0000000..67a272b
--- /dev/null
+++ b/spec/outputs/test/vararg_spec.lua
@@ -0,0 +1,164 @@
1return describe("vararg", function()
2 it("should pass varargs to function", function()
3 local sum
4 sum = function(...)
5 local total = 0
6 for i = 1, select("#", ...) do
7 if type(select(i, ...)) == "number" then
8 total = total + select(i, ...)
9 end
10 end
11 return total
12 end
13 local result = sum(1, 2, 3, 4, 5)
14 return assert.same(result, 15)
15 end)
16 it("should handle empty varargs", function()
17 local fn
18 fn = function(...)
19 return select("#", ...)
20 end
21 local result = fn()
22 return assert.same(result, 0)
23 end)
24 it("should spread varargs in function call", function()
25 local receiver
26 receiver = function(a, b, c)
27 return {
28 a,
29 b,
30 c
31 }
32 end
33 local source
34 source = function()
35 return 1, 2, 3
36 end
37 local result = receiver(source())
38 return assert.same(result, {
39 1,
40 2,
41 3
42 })
43 end)
44 it("should use varargs in table", function()
45 local fn
46 fn = function(...)
47 return {
48 ...
49 }
50 end
51 local result = fn(1, 2, 3)
52 return assert.same(result, {
53 1,
54 2,
55 3
56 })
57 end)
58 it("should forward varargs", function()
59 local middle
60 middle = function(fn, ...)
61 return fn(...)
62 end
63 local inner
64 inner = function(a, b, c)
65 return a + b + c
66 end
67 local result = middle(inner, 1, 2, 3)
68 return assert.same(result, 6)
69 end)
70 it("should count varargs with select", function()
71 local fn
72 fn = function(...)
73 return select("#", ...)
74 end
75 assert.same(fn(1, 2, 3), 3)
76 assert.same(fn("a", "b"), 2)
77 return assert.same(fn(), 0)
78 end)
79 it("should select from varargs", function()
80 local fn
81 fn = function(...)
82 return select(2, ...)
83 end
84 local result = fn(1, 2, 3)
85 return assert.same(result, 2)
86 end)
87 it("should work with named parameters and varargs", function()
88 local fn
89 fn = function(first, ...)
90 return {
91 first,
92 select("#", ...)
93 }
94 end
95 local result = fn("first", "second", "third")
96 return assert.same(result, {
97 "first",
98 2
99 })
100 end)
101 it("should handle nil in varargs", function()
102 local fn
103 fn = function(...)
104 local count = select("#", ...)
105 local has_nil = false
106 for i = 1, count do
107 if select(i, ...) == nil then
108 has_nil = true
109 end
110 end
111 return {
112 count,
113 has_nil
114 }
115 end
116 local result = fn(1, nil, 3)
117 return assert.same(result, {
118 3,
119 true
120 })
121 end)
122 it("should work with table unpack", function()
123 local fn
124 fn = function(...)
125 return {
126 ...
127 }
128 end
129 local result = fn(table.unpack({
130 1,
131 2,
132 3
133 }))
134 return assert.same(result, {
135 1,
136 2,
137 3
138 })
139 end)
140 return it("should work with varargs in comprehension", function()
141 local fn
142 fn = function(...)
143 local _accum_0 = { }
144 local _len_0 = 1
145 local _list_0 = {
146 ...
147 }
148 for _index_0 = 1, #_list_0 do
149 local x = _list_0[_index_0]
150 _accum_0[_len_0] = x * 2
151 _len_0 = _len_0 + 1
152 end
153 return _accum_0
154 end
155 local result = fn(1, 2, 3, 4, 5)
156 return assert.same(result, {
157 2,
158 4,
159 6,
160 8,
161 10
162 })
163 end)
164end)
diff --git a/spec/outputs/test/with_spec.lua b/spec/outputs/test/with_spec.lua
new file mode 100644
index 0000000..252fe7f
--- /dev/null
+++ b/spec/outputs/test/with_spec.lua
@@ -0,0 +1,166 @@
1return describe("with", function()
2 it("should access property with . syntax", function()
3 local obj = {
4 value = 42
5 }
6 local result = obj.value
7 assert.same(result, 42)
8 return obj
9 end)
10 it("should call method with : syntax", function()
11 local obj = {
12 func = function()
13 return "result"
14 end
15 }
16 local result = obj:func()
17 assert.same(result, "result")
18 return obj
19 end)
20 it("should work as statement", function()
21 local obj = {
22 x = 10,
23 y = 20
24 }
25 obj.sum = obj.x + obj.y
26 return assert.same(obj.sum, 30)
27 end)
28 it("should support nested with", function()
29 local outer = {
30 inner = {
31 value = 100
32 }
33 }
34 local _with_0 = outer.inner
35 local result = _with_0.value
36 assert.same(result, 100)
37 return _with_0
38 end)
39 it("should work with? safely", function()
40 local obj = {
41 x = 5
42 }
43 local result = obj.x
44 assert.same(result, 5)
45 return obj
46 end)
47 it("should work with if inside with", function()
48 local obj = {
49 x = 10,
50 y = 20
51 }
52 if obj.x > 5 then
53 local result = obj.x + obj.y
54 assert.same(result, 30)
55 end
56 return obj
57 end)
58 it("should work with switch inside with", function()
59 local obj = {
60 type = "add",
61 a = 5,
62 b = 3
63 }
64 local result
65 do
66 local _exp_0 = obj.type
67 if "add" == _exp_0 then
68 result = obj.a + obj.b
69 else
70 result = 0
71 end
72 end
73 assert.same(result, 8)
74 return obj
75 end)
76 it("should work with loop inside with", function()
77 local obj = {
78 items = {
79 1,
80 2,
81 3
82 }
83 }
84 local sum = 0
85 local _list_0 = obj.items
86 for _index_0 = 1, #_list_0 do
87 local item = _list_0[_index_0]
88 sum = sum + item
89 end
90 return assert.same(sum, 6)
91 end)
92 it("should work with destructure", function()
93 local obj = {
94 x = 1,
95 y = 2,
96 z = 3
97 }
98 local x, y, z = obj.x, obj.y, obj.z
99 assert.same(x, 1)
100 assert.same(y, 2)
101 assert.same(z, 3)
102 return obj
103 end)
104 it("should handle simple with body", function()
105 local obj = {
106 value = 42
107 }
108 obj.value2 = 100
109 return assert.same(obj.value2, 100)
110 end)
111 it("should work with return inside", function()
112 local obj = {
113 value = 100
114 }
115 local fn
116 fn = function()
117 return obj.value
118 end
119 return assert.same(fn(), 100)
120 end)
121 it("should work with break inside", function()
122 local sum = 0
123 for i = 1, 5 do
124 local obj = {
125 value = i
126 }
127 if obj.value == 3 then
128 break
129 end
130 sum = sum + obj.value
131 end
132 return assert.same(sum, 3)
133 end)
134 it("should chain property access", function()
135 local obj = {
136 a = {
137 b = {
138 c = 42
139 }
140 }
141 }
142 local _with_0 = obj.a.b
143 local result = _with_0.c
144 assert.same(result, 42)
145 return _with_0
146 end)
147 it("should work with multiple statements", function()
148 local obj = {
149 x = 1,
150 y = 2
151 }
152 local sum = 0
153 do
154 sum = sum + obj.x
155 sum = sum + obj.y
156 end
157 return assert.same(sum, 3)
158 end)
159 return it("should preserve object reference", function()
160 local obj = {
161 value = 42
162 }
163 obj.value = 100
164 return assert.same(obj.value, 100)
165 end)
166end)
diff --git a/spec/outputs/with.lua b/spec/outputs/with.lua
index 530915e..3cd8aab 100644
--- a/spec/outputs/with.lua
+++ b/spec/outputs/with.lua
@@ -190,6 +190,7 @@ end
190do 190do
191 f((function() 191 f((function()
192 local _with_0 = item 192 local _with_0 = item
193 local _val_0
193 do 194 do
194 local _accum_0 195 local _accum_0
195 repeat 196 repeat
@@ -198,9 +199,9 @@ do
198 break 199 break
199 end 200 end
200 until true 201 until true
201 _with_0 = _accum_0 202 _val_0 = _accum_0
202 end 203 end
203 return _with_0 204 return _val_0
204 end)()) 205 end)())
205 local a 206 local a
206 do 207 do
@@ -213,9 +214,8 @@ do
213 break 214 break
214 end 215 end
215 until true 216 until true
216 _with_0 = _accum_0 217 a = _accum_0
217 end 218 end
218 a = _with_0
219 end 219 end
220 local _accum_0 220 local _accum_0
221 while true do 221 while true do
@@ -227,8 +227,7 @@ do
227 break 227 break
228 end 228 end
229 until true 229 until true
230 _with_0 = _accum_1 230 _accum_0 = _accum_1
231 _accum_0 = _with_0
232 break 231 break
233 end 232 end
234 a = _accum_0 233 a = _accum_0
@@ -249,4 +248,17 @@ do
249 end 248 end
250 a = _accum_0 249 a = _accum_0
251end 250end
251do
252 local tb = {
253 x = 1,
254 y = 2
255 }
256 local a
257 local _accum_0
258 repeat
259 _accum_0 = tb.x + tb.y
260 break
261 until true
262 a = _accum_0
263end
252return nil 264return nil
diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp
index d20b94b..c5e4a78 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.32.4"sv; 81const std::string_view version = "0.32.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 {
@@ -10226,7 +10226,7 @@ private:
10226 } else if (auto expList = expListFrom(statement)) { 10226 } else if (auto expList = expListFrom(statement)) {
10227 if (auto value = singleValueFrom(expList)) { 10227 if (auto value = singleValueFrom(expList)) {
10228 clsDecl = value->get_by_path<SimpleValue_t, ClassDecl_t>(); 10228 clsDecl = value->get_by_path<SimpleValue_t, ClassDecl_t>();
10229 } 10229 }
10230 } 10230 }
10231 if (clsDecl) { 10231 if (clsDecl) {
10232 auto variable = clsDecl->name.as<Variable_t>(); 10232 auto variable = clsDecl->name.as<Variable_t>();
@@ -10244,10 +10244,18 @@ private:
10244 } 10244 }
10245 _withVars.push(withVar); 10245 _withVars.push(withVar);
10246 std::string breakWithVar; 10246 std::string breakWithVar;
10247 bool extraBreakVar = false;
10247 if (assignList || returnValue) { 10248 if (assignList || returnValue) {
10248 auto breakLoopType = getBreakLoopType(with->body, withVar); 10249 if (assignList) {
10249 if (hasBreakWithValue(breakLoopType)) { 10250 breakWithVar = singleVariableFrom(assignList, AccessType::None);
10250 breakWithVar = withVar; 10251 }
10252 if (breakWithVar.empty()) {
10253 breakWithVar = getUnusedName("_val_"sv);
10254 extraBreakVar = true;
10255 }
10256 auto breakLoopType = getBreakLoopType(with->body, breakWithVar);
10257 if (!hasBreakWithValue(breakLoopType)) {
10258 breakWithVar.clear();
10251 } 10259 }
10252 } 10260 }
10253 if (with->eop) { 10261 if (with->eop) {
@@ -10328,17 +10336,19 @@ private:
10328 } 10336 }
10329 _withVars.pop(); 10337 _withVars.pop();
10330 if (assignList) { 10338 if (assignList) {
10331 auto assignment = x->new_ptr<ExpListAssign_t>(); 10339 if (breakWithVar.empty() || extraBreakVar) {
10332 assignment->expList.set(assignList); 10340 auto assignment = x->new_ptr<ExpListAssign_t>();
10333 auto assign = x->new_ptr<Assign_t>(); 10341 assignment->expList.set(assignList);
10334 assign->values.push_back(toAst<Exp_t>(withVar, x)); 10342 auto assign = x->new_ptr<Assign_t>();
10335 assignment->action.set(assign); 10343 assign->values.push_back(toAst<Exp_t>(breakWithVar.empty() ? withVar : breakWithVar, x));
10336 transformAssignment(assignment, temp); 10344 assignment->action.set(assign);
10345 transformAssignment(assignment, temp);
10346 }
10337 } 10347 }
10338 if (returnValue) { 10348 if (returnValue) {
10339 auto last = lastStatementFrom(with->body); 10349 auto last = lastStatementFrom(with->body);
10340 if (last && !last->content.is<Return_t>()) { 10350 if (last && !last->content.is<Return_t>()) {
10341 temp.push_back(indent() + "return "s + withVar + nl(with)); 10351 temp.push_back(indent() + "return "s + (breakWithVar.empty() ? withVar : breakWithVar) + nl(with));
10342 } 10352 }
10343 } 10353 }
10344 if (extraScope) { 10354 if (extraScope) {