aboutsummaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2026-01-26 06:38:38 +0000
committerLi Jin <dragon-fly@qq.com>2026-01-26 06:38:38 +0000
commit5d5b657f606b5939062983b1f90c3359d542672e (patch)
tree32132fd8908d6a8920d59362c572815a949f1a1f /spec
parentf5006f449a7be1a2f655f1b178ecf1d2f0569dd5 (diff)
downloadyuescript-5d5b657f606b5939062983b1f90c3359d542672e.tar.gz
yuescript-5d5b657f606b5939062983b1f90c3359d542672e.tar.bz2
yuescript-5d5b657f606b5939062983b1f90c3359d542672e.zip
Fixed compiler improvements and added comprehensive test suite
- Fixed makefile preprocessor macro definitions (removed spaces in -D flags) - Added null pointer check in compiler class declaration handling - Added comprehensive test specifications for various language features: - attrib, backcall, cond, config, existential, export, goto - import, literals, macro, metatable, operators, return - string, switch, vararg, with Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'spec')
-rw-r--r--spec/inputs/test/attrib_spec.yue51
-rw-r--r--spec/inputs/test/backcall_spec.yue29
-rw-r--r--spec/inputs/test/cond_spec.yue148
-rw-r--r--spec/inputs/test/config_spec.yue106
-rw-r--r--spec/inputs/test/existential_spec.yue100
-rw-r--r--spec/inputs/test/export_spec.yue99
-rw-r--r--spec/inputs/test/goto_spec.yue80
-rw-r--r--spec/inputs/test/import_spec.yue115
-rw-r--r--spec/inputs/test/literals_spec.yue81
-rw-r--r--spec/inputs/test/macro_spec.yue135
-rw-r--r--spec/inputs/test/metatable_spec.yue86
-rw-r--r--spec/inputs/test/operators_spec.yue137
-rw-r--r--spec/inputs/test/return_spec.yue85
-rw-r--r--spec/inputs/test/string_spec.yue143
-rw-r--r--spec/inputs/test/switch_spec.yue267
-rw-r--r--spec/inputs/test/vararg_spec.yue69
-rw-r--r--spec/inputs/test/with_spec.yue104
-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/vararg_spec.lua164
-rw-r--r--spec/outputs/5.1/test/with_spec.lua170
32 files changed, 4753 insertions, 0 deletions
diff --git a/spec/inputs/test/attrib_spec.yue b/spec/inputs/test/attrib_spec.yue
new file mode 100644
index 0000000..4a1fcab
--- /dev/null
+++ b/spec/inputs/test/attrib_spec.yue
@@ -0,0 +1,51 @@
1describe "attrib", ->
2 it "should support const attribute", ->
3 do
4 const x = 10
5 assert.same x, 10
6
7 it "should support const with multiple variables", ->
8 do
9 const a, b, c = 1, 2, 3
10 assert.same a, 1
11 assert.same b, 2
12 assert.same c, 3
13
14 it "should support close attribute", ->
15 -- close attribute for to-be-closed variables
16 do
17 close x = 1
18 assert.same x, 1
19
20 it "should work with destructuring", ->
21 do
22 const {a, b} = {a: 1, b: 2}
23 assert.same a, 1
24 assert.same b, 2
25
26 it "should work in conditional", ->
27 do
28 flag = true
29 const x = 5 if flag
30 assert.same x, 5
31
32 it "should work with switch", ->
33 do
34 const y = switch 2
35 when 2 then 100
36 else 0
37 assert.same y, 100
38
39 it "should work with table literals", ->
40 do
41 const [a, b] = [1, 2]
42 assert.same a, 1
43 assert.same b, 2
44
45 it "should support close in expressions", ->
46 do
47 close result = if true
48 42
49 else
50 0
51 assert.same result, 42
diff --git a/spec/inputs/test/backcall_spec.yue b/spec/inputs/test/backcall_spec.yue
new file mode 100644
index 0000000..9534e7c
--- /dev/null
+++ b/spec/inputs/test/backcall_spec.yue
@@ -0,0 +1,29 @@
1describe "backcall", ->
2 it "should support basic backcall with <-", ->
3 results = {}
4 mock_map = (list, fn) ->
5 for item in *list
6 table.insert results, fn(item)
7 (x) <- mock_map {1, 2, 3}
8 x * 2
9 assert.same results, {2, 4, 6}
10
11 it "should support nested backcalls", ->
12 results = {}
13 mock_map = (list, fn) ->
14 for item in *list
15 fn(item)
16 mock_map {1, 2, 3, 4}, (x) ->
17 if x > 2
18 table.insert results, x
19 assert.same results, {3, 4}
20
21 it "should work with method call backcall", ->
22 results = {}
23 obj = {
24 process: (self, fn) ->
25 fn 42
26 }
27 (value) <- obj\process
28 table.insert results, value
29 assert.same results, {42}
diff --git a/spec/inputs/test/cond_spec.yue b/spec/inputs/test/cond_spec.yue
new file mode 100644
index 0000000..9c7cac7
--- /dev/null
+++ b/spec/inputs/test/cond_spec.yue
@@ -0,0 +1,148 @@
1describe "cond", ->
2 it "should execute if branch when condition is true", ->
3 result = nil
4 if true
5 result = "yes"
6 assert.same result, "yes"
7
8 it "should execute else branch when condition is false", ->
9 result = nil
10 if false
11 result = "yes"
12 else
13 result = "no"
14 assert.same result, "no"
15
16 it "should support elseif chain", ->
17 value = 2
18 result = switch value
19 when 1 then "one"
20 when 2 then "two"
21 else "other"
22 assert.same result, "two"
23
24 it "should handle nested conditions", ->
25 result = nil
26 if true
27 if true
28 result = "nested"
29 assert.same result, "nested"
30
31 it "should work as expression", ->
32 value = if true then "yes" else "no"
33 assert.same value, "yes"
34
35 it "should work in string interpolation", ->
36 flag = true
37 result = "value is #{if flag then 1 else 0}"
38 assert.same result, "value is 1"
39
40 it "should support chained comparisons", ->
41 assert.is_true 1 < 2 <= 2 < 3
42
43 it "should short-circuit and expression", ->
44 count = 0
45 inc = ->
46 count += 1
47 false
48 result = inc! and inc!
49 assert.same count, 1
50
51 it "should short-circuit or expression", ->
52 count = 0
53 inc = ->
54 count += 1
55 true
56 result = inc! or inc!
57 assert.same count, 1
58
59 it "should support unless keyword", ->
60 result = nil
61 unless false
62 result = "executed"
63 assert.same result, "executed"
64
65 it "should support unless with else", ->
66 result = nil
67 unless true
68 result = "no"
69 else
70 result = "yes"
71 assert.same result, "yes"
72
73 it "should handle postfix if", ->
74 result = nil
75 result = "yes" if true
76 assert.same result, "yes"
77
78 it "should handle postfix unless", ->
79 result = nil
80 result = "yes" unless false
81 assert.same result, "yes"
82
83 it "should evaluate truthiness correctly", ->
84 -- nil and false are falsy
85 assert.is_false if nil then true else false
86 assert.is_false if false then true else false
87
88 -- Everything else is truthy
89 assert.is_true if 0 then true else false
90 assert.is_true if "" then true else false
91 assert.is_true if {} then true else false
92 assert.is_true if 1 then true else false
93
94 it "should support and/or operators", ->
95 assert.same true and false, false
96 assert.same false or true, true
97 assert.same nil or "default", "default"
98 assert.same "value" or "default", "value"
99
100 it "should handle complex boolean expressions", ->
101 a, b, c = true, false, true
102 result = a and b or c
103 assert.same result, c
104
105 it "should support not operator", ->
106 assert.is_true not false
107 assert.is_true not nil
108 assert.is_false not true
109 assert.is_false not 1
110
111 it "should work with table as condition", ->
112 result = nil
113 if {}
114 result = "truthy"
115 assert.same result, "truthy"
116
117 it "should work with string as condition", ->
118 result = nil
119 if ""
120 result = "truthy"
121 assert.same result, "truthy"
122
123 it "should work with zero as condition", ->
124 result = nil
125 if 0
126 result = "truthy"
127 assert.same result, "truthy"
128
129 it "should support multiple elseif branches", ->
130 value = 3
131 result = if value == 1
132 "one"
133 elseif value == 2
134 "two"
135 elseif value == 3
136 "three"
137 else
138 "other"
139 assert.same result, "three"
140
141 it "should handle then keyword syntax", ->
142 result = if true then "yes" else "no"
143 assert.same result, "yes"
144
145 it "should work with function call in condition", ->
146 return_true = -> true
147 result = if return_true! then "yes" else "no"
148 assert.same result, "yes"
diff --git a/spec/inputs/test/config_spec.yue b/spec/inputs/test/config_spec.yue
new file mode 100644
index 0000000..2df8ef3
--- /dev/null
+++ b/spec/inputs/test/config_spec.yue
@@ -0,0 +1,106 @@
1describe "config", ->
2 -- Note: These tests verify that various compiler configs don't cause errors
3 -- Actual compiler config testing would require the compiler itself
4
5 it "should handle implicit return", ->
6 -- implicitReturnRoot is the default
7 fn = ->
8 42
9 assert.same fn!, 42
10
11 it "should handle return in last position", ->
12 fn = ->
13 if true
14 100
15 else
16 200
17 assert.same fn!, 100
18
19 it "should work with various code patterns", ->
20 -- Test that code compiles without explicit config
21 x = 1 + 2
22 y = if x > 0 then "positive" else "negative"
23 assert.same y, "positive"
24
25 it "should handle class definitions", ->
26 class TestClass
27 value: 100
28 get_value: => @value
29 instance = TestClass!
30 assert.same instance\get_value!, 100
31
32 it "should handle macro definitions", ->
33 macro test_macro = (x) -> "#{x} + 1"
34 result = $test_macro 5
35 assert.same result, 6
36
37 it "should handle import statements", ->
38 import format from "string"
39 assert.is_true type(format) == "function"
40
41 it "should handle string interpolation", ->
42 name = "world"
43 result = "hello #{name}"
44 assert.same result, "hello world"
45
46 it "should handle comprehensions", ->
47 result = [x * 2 for x = 1, 5]
48 assert.same result, {2, 4, 6, 8, 10}
49
50 it "should handle switch expressions", ->
51 result = switch 2
52 when 1 then "one"
53 when 2 then "two"
54 else "other"
55 assert.same result, "two"
56
57 it "should handle with statements", ->
58 obj = {x: 10, y: 20}
59 result = with obj
60 .x + .y
61 assert.same result, 30
62
63 it "should handle existential operators", ->
64 obj = {value: 100}
65 result = obj?.value
66 assert.same result, 100
67
68 it "should handle pipe operator", ->
69 result = {1, 2, 3} |> table.concat
70 assert.same result, "123"
71
72 it "should handle loops", ->
73 sum = 0
74 for i = 1, 5
75 sum += i
76 assert.same sum, 15
77
78 it "should handle while loops", ->
79 count = 0
80 while count < 3
81 count += 1
82 assert.same count, 3
83
84 it "should handle table literals", ->
85 t = {
86 key1: "value1"
87 key2: "value2"
88 }
89 assert.same t.key1, "value1"
90
91 it "should handle function definitions", ->
92 fn = (a, b) -> a + b
93 assert.same fn(5, 3), 8
94
95 it "should handle nested functions", ->
96 outer = ->
97 inner = (x) -> x * 2
98 inner 10
99 assert.same outer!, 20
100
101 it "should handle destructure", ->
102 t = {x: 1, y: 2, z: 3}
103 {:x, :y, :z} = t
104 assert.same x, 1
105 assert.same y, 2
106 assert.same z, 3
diff --git a/spec/inputs/test/existential_spec.yue b/spec/inputs/test/existential_spec.yue
new file mode 100644
index 0000000..f63967a
--- /dev/null
+++ b/spec/inputs/test/existential_spec.yue
@@ -0,0 +1,100 @@
1describe "existential", ->
2 it "should handle ?. with existing object", ->
3 obj = {value: 42}
4 result = obj?.value
5 assert.same result, 42
6
7 it "should handle ?. with nil object", ->
8 obj = nil
9 result = obj?.value
10 assert.same result, nil
11
12 it "should chain ?. calls", ->
13 obj = {nested: {value: 100}}
14 result = obj?.nested?.value
15 assert.same result, 100
16
17 it "should return nil in chain with nil", ->
18 obj = nil
19 result = obj?.nested?.value
20 assert.same result, nil
21
22 it "should handle ?. with method call", ->
23 obj = {func: -> "result"}
24 result = obj?.func!
25 assert.same result, "result"
26
27 it "should handle ? on table index", ->
28 tb = {[1]: "first"}
29 result = tb?[1]
30 assert.same result, "first"
31
32 it "should return nil for missing index", ->
33 tb = {}
34 result = tb?[99]
35 assert.same result, nil
36
37 it "should work with ? in if condition", ->
38 obj = {value: 5}
39 if obj?.value
40 result = "exists"
41 assert.same result, "exists"
42
43 it "should combine ?. with and/or", ->
44 obj = {value: 10}
45 result = obj?.value and 20 or 30
46 assert.same result, 20
47
48 it "should handle with? safely", ->
49 obj = {x: 1, y: 2}
50 sum = obj?.x + obj?.y
51 assert.same sum, 3
52
53 it "should return nil with with? on nil", ->
54 obj = nil
55 result = obj?.x
56 assert.same result, nil
57
58 it "should handle false value correctly", ->
59 -- false is a valid value, not nil
60 obj = {value: false}
61 result = obj?.value
62 assert.same result, false
63
64 it "should handle 0 value correctly", ->
65 -- 0 is a valid value, not nil
66 obj = {value: 0}
67 result = obj?.value
68 assert.same result, 0
69
70 it "should handle empty string correctly", ->
71 -- "" is a valid value, not nil
72 obj = {value: ""}
73 result = obj?.value
74 assert.same result, ""
75
76 it "should handle empty table correctly", ->
77 -- {} is a valid value, not nil
78 obj = {value: {}}
79 result = obj?.value
80 assert.same type(result), "table"
81
82 it "should work with deep chains", ->
83 obj = {a: {b: {c: {d: "deep"}}}}
84 result = obj?.a?.b?.c?.d
85 assert.same result, "deep"
86
87 it "should break chain on first nil", ->
88 obj = {a: nil}
89 result = obj?.a?.b?.c
90 assert.same result, nil
91
92 it "should handle ?. with string methods", ->
93 s = "hello"
94 result = s?\upper!
95 assert.same result, "HELLO"
96
97 it "should handle ?. with nil string", ->
98 s = nil
99 result = s?\upper!
100 assert.same result, nil
diff --git a/spec/inputs/test/export_spec.yue b/spec/inputs/test/export_spec.yue
new file mode 100644
index 0000000..c6ea99b
--- /dev/null
+++ b/spec/inputs/test/export_spec.yue
@@ -0,0 +1,99 @@
1describe "export", ->
2 it "should export basic variables", ->
3 a = 1
4 b = 2
5 c = 3
6 assert.same a, 1
7 assert.same b, 2
8 assert.same c, 3
9
10 it "should export multiple variables at once", ->
11 x, y, z = 10, 20, 30
12 assert.same x, 10
13 assert.same y, 20
14 assert.same z, 30
15
16 it "should export class definitions", ->
17 MyClass = class
18 value: 100
19 assert.same MyClass.value, 100
20
21 it "should export function expressions", ->
22 my_func = -> 42
23 assert.same my_func!, 42
24
25 it "should export conditional expressions", ->
26 result = if true
27 "yes"
28 else
29 "no"
30 assert.same result, "yes"
31
32 it "should export switch expressions", ->
33 value = switch 5
34 when 5 then 100
35 else 0
36 assert.same value, 100
37
38 it "should export with do block", ->
39 result = do
40 x = 5
41 x * 2
42 assert.same result, 10
43
44 it "should export comprehension", ->
45 doubled = [i * 2 for i = 1, 5]
46 assert.same doubled, {2, 4, 6, 8, 10}
47
48 it "should export with pipe operator", ->
49 result = {1, 2, 3} |> table.concat
50 assert.same result, "123"
51
52 it "should export nil values", ->
53 empty = nil
54 assert.same empty, nil
55
56 it "should export tables", ->
57 config = {
58 key1: "value1"
59 key2: "value2"
60 }
61 assert.same config.key1, "value1"
62 assert.same config.key2, "value2"
63
64 it "should export string values", ->
65 message = "hello world"
66 assert.same message, "hello world"
67
68 it "should export boolean values", ->
69 flag_true = true
70 flag_false = false
71 assert.is_true flag_true
72 assert.is_false flag_false
73
74 it "should export number values", ->
75 count = 42
76 price = 19.99
77 assert.same count, 42
78 assert.same price, 19.99
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", ->
86 add = (a, b) -> a + b
87 assert.same add(5, 3), 8
88
89 it "should maintain export order", ->
90 first = 1
91 second = 2
92 third = 3
93 assert.same first, 1
94 assert.same second, 2
95 assert.same third, 3
96
97 it "should work with complex expressions", ->
98 calc = (10 + 20) * 2
99 assert.same calc, 60
diff --git a/spec/inputs/test/goto_spec.yue b/spec/inputs/test/goto_spec.yue
new file mode 100644
index 0000000..fd2f401
--- /dev/null
+++ b/spec/inputs/test/goto_spec.yue
@@ -0,0 +1,80 @@
1describe "goto", ->
2 it "should support basic goto and label", ->
3 a = 0
4 ::start::
5 a += 1
6 if a < 5
7 goto start
8 assert.same a, 5
9
10 it "should support conditional goto", ->
11 a = 0
12 ::loop::
13 a += 1
14 goto done if a == 3
15 goto loop
16 ::done::
17 assert.same a, 3
18
19 it "should support goto in nested loops", ->
20 count = 0
21 for x = 1, 3
22 for y = 1, 3
23 count += 1
24 if x == 2 and y == 2
25 goto found
26 ::found::
27 assert.same count, 4 -- (1,1), (1,2), (1,3), (2,1), (2,2)
28
29 it "should support multiple labels", ->
30 a = 0
31 ::first::
32 a += 1
33 goto second if a == 2
34 goto first
35 ::second::
36 assert.same a, 2
37
38 it "should work with for loops", ->
39 sum = 0
40 for i = 1, 10
41 sum += i
42 goto done if i == 5
43 ::done::
44 assert.same sum, 15 -- 1+2+3+4+5
45
46 it "should work with while loops", ->
47 count = 0
48 while true
49 count += 1
50 goto endwhile if count == 3
51 ::endwhile::
52 assert.same count, 3
53
54 it "should skip rest of loop with goto", ->
55 values = {}
56 for i = 1, 5
57 goto continue if i % 2 == 0
58 table.insert values, i
59 ::continue::
60 assert.same values, {1, 3, 5}
61
62 it "should support goto with switch", ->
63 result = "default"
64 value = 2
65 switch value
66 when 1
67 goto case_one
68 when 2
69 goto case_two
70 goto default_label
71 ::case_one::
72 result = "one"
73 goto finish
74 ::case_two::
75 result = "two"
76 goto finish
77 ::default_label::
78 result = "default"
79 ::finish::
80 assert.same result, "two"
diff --git a/spec/inputs/test/import_spec.yue b/spec/inputs/test/import_spec.yue
new file mode 100644
index 0000000..deeb4a0
--- /dev/null
+++ b/spec/inputs/test/import_spec.yue
@@ -0,0 +1,115 @@
1describe "import", ->
2 it "should import from table expression", ->
3 source = {hello: "world", foo: "bar"}
4 import hello, foo from source
5 assert.same hello, "world"
6 assert.same foo, "bar"
7
8 it "should import with backslash escaping", ->
9 source = {x: 1, y: 2, z: 3}
10 import x, \y, z from source
11 assert.same x, 1
12 assert.same y, 2
13 assert.same z, 3
14
15 it "should import from string module", ->
16 -- Test with string library
17 import format from "string"
18 assert.is_true type(format) == "function"
19
20 it "should import from table with dot path", ->
21 -- Using string.sub as an example
22 import sub from "string"
23 result = sub "hello", 1, 2
24 assert.same result, "he"
25
26 it "should import multiple values with table destructuring", ->
27 source = {a: 1, b: 2, c: 3}
28 import a, b, c from source
29 assert.same a, 1
30 assert.same b, 2
31 assert.same c, 3
32
33 it "should import with multi-line format", ->
34 source = {x: 1, y: 2, z: 3}
35 import x, y, z from source
36 assert.same x, 1
37 assert.same y, 2
38 assert.same z, 3
39
40 it "should import using from syntax", ->
41 source = {foo: "bar", baz: "qux"}
42 from source import foo, baz
43 assert.same foo, "bar"
44 assert.same baz, "qux"
45
46 it "should handle import with computed expressions", ->
47 source = {first: 1, second: 2}
48 target = source
49 import first, second from target
50 assert.same first, 1
51 assert.same second, 2
52
53 it "should import from nested table paths", ->
54 deep = {outer: {inner: "value"}}
55 import outer from deep
56 assert.same outer.inner, "value"
57
58 it "should support importing Lua standard library functions", ->
59 import print, type from "_G"
60 assert.is_true type(print) == "function"
61 assert.is_true type(type) == "function"
62
63 it "should handle empty import gracefully", ->
64 -- Empty module shouldn't cause errors
65 source = {}
66 import dummy from source
67 assert.same dummy, nil
68
69 it "should work with table index expressions", ->
70 source = {normal: "ok"}
71 import normal from source
72 assert.same normal, "ok"
73
74 it "should support chaining imports from same source", ->
75 source = {a: 1, b: 2, c: 3}
76 import a, b from source
77 import c from source
78 assert.same a, 1
79 assert.same b, 2
80 assert.same c, 3
81
82 it "should handle importing from table returned by function", ->
83 get_table = -> {x: 100, y: 200}
84 import x, y from get_table!
85 assert.same x, 100
86 assert.same y, 200
87
88 it "should support from with multi-line import", ->
89 source = {item1: 1, item2: 2, item3: 3}
90 from source import item1, item2, item3
91 assert.same item1, 1
92 assert.same item2, 2
93 assert.same item3, 3
94
95 it "should work with import from string literal", ->
96 import char from "string"
97 assert.same char(65), "A"
98
99 it "should support import with table literal keys", ->
100 source = {normal_key: "value2"}
101 import normal_key from source
102 assert.same normal_key, "value2"
103
104 it "should handle consecutive imports", ->
105 source1 = {a: 1}
106 source2 = {b: 2}
107 import a from source1
108 import b from source2
109 assert.same a, 1
110 assert.same b, 2
111
112 it "should support importing from complex expressions", ->
113 get_source = -> {result: 42}
114 import result from get_source!
115 assert.same result, 42
diff --git a/spec/inputs/test/literals_spec.yue b/spec/inputs/test/literals_spec.yue
new file mode 100644
index 0000000..10bd6b3
--- /dev/null
+++ b/spec/inputs/test/literals_spec.yue
@@ -0,0 +1,81 @@
1describe "literals", ->
2 it "should support integer literals", ->
3 assert.same 123, 123
4
5 it "should support float literals", ->
6 assert.same 1.5, 1.5
7
8 it "should support scientific notation", ->
9 assert.same 1.5e2, 150
10
11 it "should support negative numbers", ->
12 assert.same -42, -42
13
14 it "should support hexadecimal literals", ->
15 assert.same 0xff, 255
16
17 it "should support hexadecimal with uppercase", ->
18 assert.same 0XFF, 255
19
20 it "should support binary literals", ->
21 assert.same 0b101, 5
22
23 it "should support binary with uppercase", ->
24 assert.same 0B101, 5
25
26 it "should support number with underscores", ->
27 assert.same 1_000_000, 1000000
28
29 it "should support hex with underscores", ->
30 assert.same 0xDE_AD_BE_EF, 0xDEADBEEF
31
32 it "should support double quote strings", ->
33 assert.same "hello", "hello"
34
35 it "should support single quote strings", ->
36 assert.same 'world', 'world'
37
38 it "should support multi-line strings with [[", ->
39 s = [[
40 hello
41 world
42 ]]
43 assert.is_true s\match "hello"
44
45 it "should support multi-line strings with [=[", ->
46 s = [==[
47 test
48 ]==]
49 assert.is_true s\match "test"
50
51 it "should support boolean true", ->
52 assert.same true, true
53
54 it "should support boolean false", ->
55 assert.same false, false
56
57 it "should support nil", ->
58 assert.same nil, nil
59
60 it "should support empty table", ->
61 t = {}
62 assert.same #t, 0
63
64 it "should support table with keys", ->
65 t = {a: 1, b: 2}
66 assert.same t.a, 1
67 assert.same t.b, 2
68
69 it "should support array literal", ->
70 t = {1, 2, 3}
71 assert.same t[1], 1
72 assert.same t[2], 2
73 assert.same t[3], 3
74
75 it "should support mixed table", ->
76 t = {
77 1, 2, 3
78 key: "value"
79 }
80 assert.same t[1], 1
81 assert.same t.key, "value"
diff --git a/spec/inputs/test/macro_spec.yue b/spec/inputs/test/macro_spec.yue
new file mode 100644
index 0000000..a4a170b
--- /dev/null
+++ b/spec/inputs/test/macro_spec.yue
@@ -0,0 +1,135 @@
1describe "macro", ->
2 it "should define and call basic macro", ->
3 macro double = (x) -> "#{x} * 2"
4 result = $double 5
5 assert.same result, 10
6
7 it "should maintain hygiene in macros", ->
8 macro get_value_hygienic = ->
9 (->
10 local a = 1
11 a + 1)!
12 a = 8
13 result = $get_value_hygienic!
14 assert.same result, 2
15
16 it "should validate AST types", ->
17 macro NumAndStr = (num`Num, str`SingleString) -> "[#{num}, #{str}]"
18 result = $NumAndStr 123, 'xyz'
19 assert.same result, "[123, xyz]"
20
21 it "should support simple code generation", ->
22 macro add_one = (x) -> "#{x} + 1"
23 result = $add_one 10
24 assert.same result, 11
25
26 it "should support nested macro calls", ->
27 macro inc = (x) -> "#{x} + 1"
28 macro double_inc = (x) -> $inc($inc(x))
29 result = $double_inc 5
30 assert.same result, 7
31
32 it "should respect macro scope in do blocks", ->
33 macro outer = -> "outer"
34 do
35 macro inner = -> "inner"
36 result = $inner!
37 assert.same result, "inner"
38 result = $outer!
39 assert.same result, "outer"
40
41 it "should provide $LINE macro", ->
42 line_num = $LINE
43 assert.is_true line_num > 0
44
45 it "should inject Lua code", ->
46 macro lua_code = (code) -> {:code, type: "lua"}
47 x = 0
48 $lua_code [[
49 local function f(a)
50 return a + 1
51 end
52 x = x + f(3)
53 ]]
54 assert.same x, 4
55
56 it "should work in conditional compilation", ->
57 macro if_debug = (debug_code) ->
58 if $LINE > 0
59 debug_code
60 else
61 ""
62 result = $if_debug "debug mode"
63 assert.same result, "debug mode"
64
65 it "should work with class system", ->
66 class Thing
67 value: 100
68 get_value: => @value
69 instance = Thing!
70 assert.same instance\get_value!, 100
71
72 it "should handle macro in switch expressions", ->
73 macro to_value = (x) -> x
74 result = switch $to_value "test"
75 when "test"
76 "matched"
77 else
78 "no match"
79 assert.same result, "matched"
80
81 it "should support macro in expression context", ->
82 macro triple = (x) -> "#{x} * 3"
83 result = 5 + $triple 2
84 assert.same result, 11
85
86 it "should handle $is_ast for type checking", ->
87 macro check_num = (x) ->
88 unless $is_ast(Num, x)
89 error "expected number"
90 x
91 result = $check_num 42
92 assert.same result, 42
93
94 it "should work with string interpolation", ->
95 macro format_result = (name, value) -> "#{name}: #{value}"
96 result = $format_result "test", 123
97 assert.same result, "test: 123"
98
99 it "should support function call syntax", ->
100 macro my_func = (x, y) -> "#{x} + #{y}"
101 result = $my_func(5, 10)
102 assert.same result, 15
103
104 it "should handle empty macro return", ->
105 macro skip = -> ""
106 a = 1
107 $skip
108 a = 2
109 assert.same a, 2
110
111 it "should work with table literals", ->
112 macro make_point = (x, y) -> "{x: #{x}, y: #{y}}"
113 point = $make_point 10, 20
114 assert.same point.x, 10
115 assert.same point.y, 20
116
117 it "should support conditional expressions in macro", ->
118 macro add_one = (x) -> "#{x} + 1"
119 result = $add_one 5
120 assert.same result, 6
121
122 it "should work with comprehension", ->
123 macro doubled_list = (items) -> "[_ * 2 for _ in *#{items}]"
124 result = $doubled_list {1, 2, 3}
125 assert.same result, {2, 4, 6}
126
127 it "should support complex expression macros", ->
128 macro calc = (a, b, c) -> "#{a} + #{b} * #{c}"
129 result = $calc 1, 2, 3
130 assert.same result, 7
131
132 it "should work with string literals", ->
133 macro greet = (name) -> '"Hello, #{name}"'
134 result = $greet "World"
135 assert.same result, "Hello, World"
diff --git a/spec/inputs/test/metatable_spec.yue b/spec/inputs/test/metatable_spec.yue
new file mode 100644
index 0000000..9a2ae6a
--- /dev/null
+++ b/spec/inputs/test/metatable_spec.yue
@@ -0,0 +1,86 @@
1describe "metatable", ->
2 it "should get metatable with <> syntax", ->
3 obj = setmetatable {value: 42}, {__index: {extra: "data"}}
4 mt = obj.<>
5 assert.is_true mt ~= nil
6
7 it "should set metatable with <>", ->
8 obj = {}
9 obj.<> = {__index: {value: 100}}
10 assert.same obj.value, 100
11
12 it "should access metatable with <>", ->
13 obj = setmetatable {}, {__index: {value: 50}}
14 result = obj.<>.__index.value
15 assert.same result, 50
16
17 it "should work with <index> metamethod", ->
18 obj = setmetatable {}, {
19 __index: (self, key) ->
20 if key == "computed"
21 return "computed_value"
22 }
23 assert.same obj.computed, "computed_value"
24
25 it "should work with <newindex> metamethod", ->
26 obj = setmetatable {}, {
27 __newindex: (self, key, value) ->
28 rawset self, "stored_" .. key, value
29 }
30 obj.test = 123
31 assert.same obj.stored_test, 123
32
33 it "should work with <add> metamethod", ->
34 obj = setmetatable({value: 10}, {
35 __add: (a, b) -> a.value + b.value
36 })
37 obj2 = setmetatable({value: 20}, {
38 __add: (a, b) -> a.value + b.value
39 })
40 result = obj + obj2
41 assert.same result, 30
42
43 it "should work with <call> metamethod", ->
44 obj = setmetatable {}, {
45 __call: (self, x) -> x * 2
46 }
47 result = obj 5
48 assert.same result, 10
49
50 it "should work with <tostring> metamethod", ->
51 obj = setmetatable {value: 42}, {
52 __tostring: (self) -> "Value: #{self.value}"
53 }
54 result = tostring obj
55 assert.same result, "Value: 42"
56
57 it "should work with <eq> metamethod", ->
58 obj1 = setmetatable({id: 1}, {
59 __eq: (a, b) -> a.id == b.id
60 })
61 obj2 = setmetatable({id: 1}, {
62 __eq: (a, b) -> a.id == b.id
63 })
64 assert.is_true obj1 == obj2
65
66 it "should destructure metatable", ->
67 obj = setmetatable {}, {
68 new: -> "new result"
69 update: -> "update result"
70 }
71 {:new, :update} = obj.<>
72 assert.is_true type(new) == "function"
73 assert.is_true type(update) == "function"
74
75 it "should check if two objects have same metatable", ->
76 mt = {value: 100}
77 obj1 = setmetatable {}, mt
78 obj2 = setmetatable {}, mt
79 assert.is_true obj1.<> == obj2.<>
80
81 it "should work with <concat> metamethod", ->
82 obj = setmetatable {value: "hello"}, {
83 __concat: (a, b) -> a.value .. b
84 }
85 result = obj .. " world"
86 assert.same result, "hello world"
diff --git a/spec/inputs/test/operators_spec.yue b/spec/inputs/test/operators_spec.yue
new file mode 100644
index 0000000..9b5585b
--- /dev/null
+++ b/spec/inputs/test/operators_spec.yue
@@ -0,0 +1,137 @@
1describe "operators", ->
2 it "should support addition", ->
3 assert.same 1 + 2, 3
4
5 it "should support subtraction", ->
6 assert.same 5 - 3, 2
7
8 it "should support multiplication", ->
9 assert.same 4 * 3, 12
10
11 it "should support division", ->
12 assert.same 10 / 2, 5
13
14 it "should support modulo", ->
15 assert.same 10 % 3, 1
16
17 it "should support exponentiation", ->
18 assert.same 2 ^ 3, 8
19
20 it "should support unary minus", ->
21 assert.same -5, -5
22
23 it "should support equality comparison", ->
24 assert.is_true 1 == 1
25 assert.is_false 1 == 2
26
27 it "should support inequality comparison", ->
28 assert.is_true 1 ~= 2
29 assert.is_false 1 ~= 1
30
31 it "should support less than", ->
32 assert.is_true 1 < 2
33 assert.is_false 2 < 1
34
35 it "should support greater than", ->
36 assert.is_true 2 > 1
37 assert.is_false 1 > 2
38
39 it "should support less than or equal", ->
40 assert.is_true 1 <= 2
41 assert.is_true 2 <= 2
42 assert.is_false 3 <= 2
43
44 it "should support greater than or equal", ->
45 assert.is_true 2 >= 1
46 assert.is_true 2 >= 2
47 assert.is_false 1 >= 2
48
49 it "should support logical and", ->
50 assert.same true and false, false
51 assert.same true and true, true
52 assert.same false and true, false
53
54 it "should support logical or", ->
55 assert.same true or false, true
56 assert.same false or true, true
57 assert.same false or false, false
58
59 it "should support logical not", ->
60 assert.same not true, false
61 assert.same not false, true
62 assert.same not nil, true
63
64 it "should support bitwise and", ->
65 assert.same 5 & 3, 1 -- 101 & 011 = 001
66
67 it "should support bitwise or", ->
68 assert.same 5 | 3, 7 -- 101 | 011 = 111
69
70 it "should support bitwise xor", ->
71 assert.same 5 ~ 3, 6 -- 101 ~ 011 = 110
72
73 it "should support left shift", ->
74 assert.same 2 << 3, 16
75
76 it "should support right shift", ->
77 assert.same 16 >> 2, 4
78
79 it "should support string concatenation", ->
80 assert.same "hello" .. " world", "hello world"
81
82 it "should support length operator", ->
83 assert.same #"hello", 5
84 assert.same #{1, 2, 3}, 3
85
86 it "should respect operator precedence", ->
87 assert.same 1 + 2 * 3, 7 -- multiplication before addition
88 assert.same (1 + 2) * 3, 9 -- parentheses first
89
90 it "should support compound assignment", ->
91 x = 10
92 x += 5
93 assert.same x, 15
94
95 it "should support compound subtraction", ->
96 x = 10
97 x -= 3
98 assert.same x, 7
99
100 it "should support compound multiplication", ->
101 x = 5
102 x *= 2
103 assert.same x, 10
104
105 it "should support compound division", ->
106 x = 20
107 x /= 4
108 assert.same x, 5
109
110 it "should handle division by zero", ->
111 -- Lua returns inf or nan
112 result = pcall(->
113 x = 10 / 0
114 )
115 assert.is_true result -- doesn't error in Lua
116
117 it "should handle very large numbers", ->
118 big = 1e100
119 assert.is_true big > 0
120
121 it "should handle very small numbers", ->
122 small = 1e-100
123 assert.is_true small > 0
124
125 it "should support negation", ->
126 assert.same -10, -10
127 assert.same --5, 5
128
129 it "should work with complex expressions", ->
130 result = (1 + 2) * (3 + 4) / 2
131 assert.same result, 10.5
132
133 it "should support power with decimal", ->
134 assert.same 4 ^ 0.5, 2
135
136 it "should handle modulo with negative numbers", ->
137 assert.same -10 % 3, 2 -- Lua's modulo behavior
diff --git a/spec/inputs/test/return_spec.yue b/spec/inputs/test/return_spec.yue
new file mode 100644
index 0000000..3bf0bed
--- /dev/null
+++ b/spec/inputs/test/return_spec.yue
@@ -0,0 +1,85 @@
1describe "return", ->
2 it "should return from comprehension", ->
3 fn = ->
4 return [x * 2 for x = 1, 5]
5 result = fn!
6 assert.same result, {2, 4, 6, 8, 10}
7
8 it "should return from table comprehension", ->
9 fn = ->
10 return {k, v for k, v in pairs {a: 1, b: 2}}
11 result = fn!
12 assert.same type(result), "table"
13
14 it "should return from nested if", ->
15 fn = (a, b) ->
16 if a
17 if b
18 return "both"
19 else
20 return "only a"
21 else
22 return "neither"
23 assert.same fn(true, true), "both"
24 assert.same fn(true, false), "only a"
25 assert.same fn(false, false), "neither"
26
27 it "should return from switch", ->
28 fn = (value) ->
29 return switch value
30 when 1 then "one"
31 when 2 then "two"
32 else "other"
33 assert.same fn(1), "one"
34 assert.same fn(2), "two"
35 assert.same fn(3), "other"
36
37 it "should return table literal", ->
38 fn = ->
39 return
40 value: 42
41 name: "test"
42 result = fn!
43 assert.same result.value, 42
44 assert.same result.name, "test"
45
46 it "should return array literal", ->
47 fn = ->
48 return
49 * 1
50 * 2
51 * 3
52 result = fn!
53 assert.same result, {1, 2, 3}
54
55 it "should return from with statement", ->
56 fn = (obj) ->
57 result = obj.value
58 return result
59 assert.same fn({value: 100}), 100
60
61 it "should return nil implicitly", ->
62 fn -> print "no return"
63 assert.same fn!, nil
64
65 it "should return multiple values", ->
66 fn -> 1, 2, 3
67 a, b, c = fn!
68 assert.same a, 1
69 assert.same b, 2
70 assert.same c, 3
71
72 it "should return from function call", ->
73 fn = ->
74 inner = -> 42
75 return inner!
76 assert.same fn!, 42
77
78 it "should handle return in expression context", ->
79 fn = (cond) ->
80 if cond
81 return "yes"
82 else
83 return "no"
84 assert.same fn(true), "yes"
85 assert.same fn(false), "no"
diff --git a/spec/inputs/test/string_spec.yue b/spec/inputs/test/string_spec.yue
new file mode 100644
index 0000000..b790518
--- /dev/null
+++ b/spec/inputs/test/string_spec.yue
@@ -0,0 +1,143 @@
1describe "string", ->
2 it "should support single quote strings", ->
3 s = 'hello'
4 assert.same s, "hello"
5
6 it "should support double quote strings", ->
7 s = "world"
8 assert.same s, "world"
9
10 it "should support escape sequences", ->
11 s = "hello\nworld"
12 assert.is_true s\match("\n") ~= nil
13
14 it "should support escaped quotes", ->
15 s = "he said \"hello\""
16 assert.same s, 'he said "hello"'
17
18 it "should support backslash escape", ->
19 s = "\\"
20 assert.same s, "\\"
21
22 it "should support multi-line strings with [[ ]]", ->
23 s = [[
24 hello
25 world
26 ]]
27 assert.is_true s\match("hello") ~= nil
28 assert.is_true s\match("world") ~= nil
29
30 it "should support multi-line strings with [=[ ]=]", ->
31 s = [==[
32 hello
33 world
34 ]==]
35 assert.is_true s\match("hello") ~= nil
36 assert.is_true s\match("world") ~= nil
37
38 it "should support string interpolation with double quotes", ->
39 name = "world"
40 s = "hello #{name}"
41 assert.same s, "hello world"
42
43 it "should support expression interpolation", ->
44 a, b = 1, 2
45 s = "#{a} + #{b} = #{a + b}"
46 assert.same s, "1 + 2 = 3"
47
48 it "should not interpolate in single quotes", ->
49 name = "world"
50 s = 'hello #{name}'
51 assert.same s, "hello #{name}"
52
53 it "should escape interpolation with \\#", ->
54 name = "world"
55 s = "hello \\#{name}"
56 assert.same s, "hello #{name}"
57
58 it "should support method calls on string literals", ->
59 result = "hello"\upper!
60 assert.same result, "HELLO"
61
62 it "should support chained method calls", ->
63 result = "hello world"\upper!\match "HELLO"
64 assert.same result, "HELLO"
65
66 it "should support YAML style strings", ->
67 s = |
68 hello
69 world
70 assert.is_true s\match("hello") ~= nil
71 assert.is_true s\match("world") ~= nil
72
73 it "should support YAML style with interpolation", ->
74 name = "test"
75 s = |
76 hello #{name}
77 assert.same s, "hello test\n"
78
79 it "should support string concatenation", ->
80 s = "hello" .. " " .. "world"
81 assert.same s, "hello world"
82
83 it "should handle empty strings", ->
84 s = ""
85 assert.same s, ""
86
87 it "should support Unicode characters", ->
88 s = "hello 世界"
89 assert.is_true s\match("世界") ~= nil
90
91 it "should support string length", ->
92 s = "hello"
93 assert.same #s, 5
94
95 it "should support multi-line YAML with complex content", ->
96 config = |
97 key1: value1
98 key2: value2
99 key3: value3
100 assert.is_true config\match("key1") ~= nil
101
102 it "should support interpolation in YAML strings", ->
103 x, y = 10, 20
104 s = |
105 point:
106 x: #{x}
107 y: #{y}
108 assert.is_true s\match("x: 10") ~= nil
109 assert.is_true s\match("y: 20") ~= nil
110
111 it "should support function call in interpolation", ->
112 s = "result: #{-> 42}"
113 assert.same s, "result: 42"
114
115 it "should support table indexing in interpolation", ->
116 t = {value: 100}
117 s = "value: #{t.value}"
118 assert.same s, "value: 100"
119
120 it "should handle escaped characters correctly", ->
121 s = "tab:\t, newline:\n, return:\r"
122 assert.is_true s\match("\t") ~= nil
123 assert.is_true s\match("\n") ~= nil
124
125 it "should support string methods with colon syntax", ->
126 s = "hello"
127 assert.same s\sub(1, 2), "he"
128
129 it "should work in expressions", ->
130 result = "hello" .. " world"
131 assert.same result, "hello world"
132
133 it "should support octal escape", ->
134 s = "\65"
135 assert.same s, "A"
136
137 it "should support hex escape", ->
138 s = "\x41"
139 assert.same s, "A"
140
141 it "should support unicode escape", ->
142 s = "\u{4e16}"
143 assert.same s, "世"
diff --git a/spec/inputs/test/switch_spec.yue b/spec/inputs/test/switch_spec.yue
new file mode 100644
index 0000000..3696cbe
--- /dev/null
+++ b/spec/inputs/test/switch_spec.yue
@@ -0,0 +1,267 @@
1describe "switch", ->
2 it "should match single value", ->
3 value = "cool"
4 result = switch value
5 when "cool"
6 "matched"
7 else
8 "not matched"
9 assert.same result, "matched"
10
11 it "should match multiple values with or", ->
12 hi = "world"
13 matched = false
14 switch hi
15 when "one", "two"
16 matched = true
17 assert.is_false matched
18
19 hi = "one"
20 switch hi
21 when "one", "two"
22 matched = true
23 assert.is_true matched
24
25 it "should execute else branch when no match", ->
26 value = "other"
27 result = switch value
28 when "cool"
29 "matched cool"
30 when "yeah"
31 "matched yeah"
32 else
33 "else branch"
34 assert.same result, "else branch"
35
36 it "should destructure table with single key", ->
37 tb = {x: 100}
38 result = switch tb
39 when :x
40 x
41 else
42 "no match"
43 assert.same result, 100
44
45 it "should destructure table with multiple keys", ->
46 tb = {x: 100, y: 200}
47 result = switch tb
48 when :x, :y
49 x + y
50 else
51 "no match"
52 assert.same result, 300
53
54 it "should destructure table with default values", ->
55 tb = {a: 1}
56 switch tb
57 when {:a = 1, :b = 2}
58 assert.same a, 1
59 assert.same b, 2
60
61 it "should destructure nested tables", ->
62 dict = {
63 {}
64 {1, 2, 3}
65 a: b: c: 1
66 x: y: z: 1
67 }
68 matched = false
69 switch dict
70 when {
71 first
72 {one, two, three}
73 a: b: :c
74 x: y: :z
75 }
76 matched = first == {} and one == 1 and two == 2 and three == 3 and c == 1 and z == 1
77 assert.is_true matched
78
79 it "should destructure arrays with exact match", ->
80 tb = {1, 2, 3}
81 result = switch tb
82 when [1, 2, 3]
83 "exact match"
84 else
85 "no match"
86 assert.same result, "exact match"
87
88 it "should destructure arrays with variables", ->
89 tb = {1, "b", 3}
90 result = switch tb
91 when [1, b, 3]
92 b
93 else
94 "no match"
95 assert.same result, "b"
96
97 it "should destructure arrays with defaults", ->
98 tb = {1, 2}
99 result = switch tb
100 when [1, 2, b = 3]
101 b
102 else
103 "no match"
104 assert.same result, 3
105
106 it "should match pattern with __class", ->
107 class ClassA
108 class ClassB
109 item = ClassA!
110 result = switch item
111 when __class: ClassA
112 "Object A"
113 when __class: ClassB
114 "Object B"
115 else
116 "unknown"
117 assert.same result, "Object A"
118
119 it "should match pattern with metatable", ->
120 tb = setmetatable {}, {__mode: "v"}
121 metatable_matched = false
122 switch tb
123 when <>: mt
124 metatable_matched = mt ~= nil
125 assert.is_true metatable_matched
126
127 it "should use switch as expression in assignment", ->
128 tb = {x: "abc"}
129 matched = switch tb
130 when 1
131 "1"
132 when :x
133 x
134 when false
135 "false"
136 else
137 nil
138 assert.same matched, "abc"
139
140 it "should use switch in return statement", ->
141 fn = (tb) ->
142 switch tb
143 when nil
144 "invalid"
145 when :a, :b
146 "#{a + b}"
147 when 1, 2, 3, 4, 5
148 "number 1 - 5"
149 else
150 "should not reach here"
151 assert.same fn({a: 1, b: 2}), "3"
152 assert.same fn(3), "number 1 - 5"
153 assert.same fn(nil), "invalid"
154
155 it "should support pattern matching assignment with :=", ->
156 v = "hello"
157 matched = false
158 switch v := "hello"
159 when "hello"
160 matched = true
161 else
162 matched = false
163 assert.is_true matched
164 assert.same v, "hello"
165
166 it "should match with computed expressions", ->
167 hi = 4
168 matched = false
169 switch hi
170 when 3+1, (-> 4)!, 5-1
171 matched = true
172 assert.is_true matched
173
174 it "should handle nested array destructuring", ->
175 tb = {
176 {a: 1, b: 2}
177 {a: 3, b: 4}
178 {a: 5, b: 6}
179 "fourth"
180 }
181 result = switch tb
182 when [
183 {a: 1, b: 2}
184 {a: 3, b: 4}
185 {a: 5, b: 6}
186 fourth
187 ]
188 fourth
189 else
190 "no match"
191 assert.same result, "fourth"
192
193 it "should match combined patterns", ->
194 tb = {success: true, result: "data"}
195 result = switch tb
196 when success: true, :result
197 {"success", result}
198 when success: false
199 {"failed", result}
200 else
201 {"invalid"}
202 assert.same result, {"success", "data"}
203
204 it "should match type discriminated patterns", ->
205 tb = {type: "success", content: "data"}
206 result = switch tb
207 when {type: "success", :content}
208 {"success", content}
209 when {type: "error", :content}
210 {"error", content}
211 else
212 {"invalid"}
213 assert.same result, {"success", "data"}
214
215 it "should match with wildcard array capture", ->
216 clientData = {"Meta", "CUST_1001", "CHK123"}
217 metadata = nil
218 customerId = nil
219 checksum = nil
220 switch clientData
221 when [...capturedMetadata, customerId, checksum]
222 metadata = capturedMetadata
223 assert.same metadata, {"Meta"}
224 assert.same customerId, "CUST_1001"
225 assert.same checksum, "CHK123"
226
227 it "should work with complex tuple patterns", ->
228 handlePath = (segments) ->
229 switch segments
230 when [..._, resource, action]
231 {"Resource: #{resource}", "Action: #{action}"}
232 else
233 {"no match"}
234 result = handlePath {"admin", "logs", "view"}
235 assert.same result, {"Resource: logs", "Action: view"}
236
237 it "should match boolean false correctly", ->
238 items = {
239 {x: 100, y: 200}
240 {width: 300, height: 400}
241 false
242 }
243 results = {}
244 for item in *items
245 switch item
246 when :x, :y
247 table.insert results, "Vec2"
248 when :width, :height
249 table.insert results, "Size"
250 when false
251 table.insert results, "None"
252 assert.same results, {"Vec2", "Size", "None"}
253
254 it "should handle switch with then syntax", ->
255 value = "cool"
256 result = switch value
257 when "cool" then "matched cool"
258 else "else branch"
259 assert.same result, "matched cool"
260
261 it "should handle switch in function call", ->
262 getValue = ->
263 switch something
264 when 1 then "yes"
265 else "no"
266 something = 1
267 assert.same getValue!, "yes"
diff --git a/spec/inputs/test/vararg_spec.yue b/spec/inputs/test/vararg_spec.yue
new file mode 100644
index 0000000..4d2557f
--- /dev/null
+++ b/spec/inputs/test/vararg_spec.yue
@@ -0,0 +1,69 @@
1describe "vararg", ->
2 it "should pass varargs to function", ->
3 sum = (...) ->
4 total = 0
5 for i = 1, select("#", ...)
6 if type(select(i, ...)) == "number"
7 total += select(i, ...)
8 total
9 result = sum 1, 2, 3, 4, 5
10 assert.same result, 15
11
12 it "should handle empty varargs", ->
13 fn = (...) -> select "#", ...
14 result = fn!
15 assert.same result, 0
16
17 it "should spread varargs in function call", ->
18 receiver = (a, b, c) -> {a, b, c}
19 source = -> 1, 2, 3
20 result = receiver source!
21 assert.same result, {1, 2, 3}
22
23 it "should use varargs in table", ->
24 fn = (...) -> {...}
25 result = fn 1, 2, 3
26 assert.same result, {1, 2, 3}
27
28 it "should forward varargs", ->
29 middle = (fn, ...) -> fn(...)
30 inner = (a, b, c) -> a + b + c
31 result = middle inner, 1, 2, 3
32 assert.same result, 6
33
34 it "should count varargs with select", ->
35 fn = (...) -> select "#", ...
36 assert.same fn(1, 2, 3), 3
37 assert.same fn("a", "b"), 2
38 assert.same fn!, 0
39
40 it "should select from varargs", ->
41 fn = (...) -> select 2, ...
42 result = fn 1, 2, 3
43 assert.same result, 2
44
45 it "should work with named parameters and varargs", ->
46 fn = (first, ...) ->
47 {first, select("#", ...)}
48 result = fn "first", "second", "third"
49 assert.same result, {"first", 2}
50
51 it "should handle nil in varargs", ->
52 fn = (...) ->
53 count = select "#", ...
54 has_nil = false
55 for i = 1, count
56 has_nil = true if select(i, ...) == nil
57 {count, has_nil}
58 result = fn 1, nil, 3
59 assert.same result, {3, true}
60
61 it "should work with table unpack", ->
62 fn = (...) -> {...}
63 result = fn table.unpack {1, 2, 3}
64 assert.same result, {1, 2, 3}
65
66 it "should work with varargs in comprehension", ->
67 fn = (...) -> [x * 2 for x in *{...}]
68 result = fn 1, 2, 3, 4, 5
69 assert.same result, {2, 4, 6, 8, 10}
diff --git a/spec/inputs/test/with_spec.yue b/spec/inputs/test/with_spec.yue
new file mode 100644
index 0000000..c3b8428
--- /dev/null
+++ b/spec/inputs/test/with_spec.yue
@@ -0,0 +1,104 @@
1describe "with", ->
2 it "should access property with . syntax", ->
3 obj = {value: 42}
4 with obj
5 result = .value
6 assert.same result, 42
7
8 it "should call method with : syntax", ->
9 obj = {func: -> "result"}
10 with obj
11 result = \func!
12 assert.same result, "result"
13
14 it "should work as statement", ->
15 obj = {x: 10, y: 20}
16 with obj
17 .sum = .x + .y
18 assert.same obj.sum, 30
19
20 it "should support nested with", ->
21 outer = {inner: {value: 100}}
22 with outer.inner
23 result = .value
24 assert.same result, 100
25
26 it "should work with? safely", ->
27 obj = {x: 5}
28 with obj
29 result = .x
30 assert.same result, 5
31
32 it "should work with if inside with", ->
33 obj = {x: 10, y: 20}
34 with obj
35 if .x > 5
36 result = .x + .y
37 assert.same result, 30
38
39 it "should work with switch inside with", ->
40 obj = {type: "add", a: 5, b: 3}
41 with obj
42 result = switch .type
43 when "add" then .a + .b
44 else 0
45 assert.same result, 8
46
47 it "should work with loop inside with", ->
48 obj = {items: {1, 2, 3}}
49 sum = 0
50 with obj
51 for item in *.items
52 sum += item
53 assert.same sum, 6
54
55 it "should work with destructure", ->
56 obj = {x: 1, y: 2, z: 3}
57 with obj
58 {x, y, z} = obj
59 assert.same x, 1
60 assert.same y, 2
61 assert.same z, 3
62
63 it "should handle simple with body", ->
64 obj = {value: 42}
65 with obj
66 .value2 = 100
67 assert.same obj.value2, 100
68
69 it "should work with return inside", ->
70 obj = {value: 100}
71 fn = ->
72 with obj
73 return .value
74 assert.same fn!, 100
75
76 it "should work with break inside", ->
77 sum = 0
78 for i = 1, 5
79 obj = {value: i}
80 with obj
81 if .value == 3
82 break
83 sum += .value
84 assert.same sum, 3 -- 1 + 2
85
86 it "should chain property access", ->
87 obj = {a: {b: {c: 42}}}
88 with obj.a.b
89 result = .c
90 assert.same result, 42
91
92 it "should work with multiple statements", ->
93 obj = {x: 1, y: 2}
94 sum = 0
95 with obj
96 sum += .x
97 sum += .y
98 assert.same sum, 3
99
100 it "should preserve object reference", ->
101 obj = {value: 42}
102 with obj
103 .value = 100
104 assert.same obj.value, 100
diff --git a/spec/outputs/5.1/test/attrib_spec.lua b/spec/outputs/5.1/test/attrib_spec.lua
new file mode 100644
index 0000000..6fd2287
--- /dev/null
+++ b/spec/outputs/5.1/test/attrib_spec.lua
@@ -0,0 +1,86 @@
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
new file mode 100644
index 0000000..c89a1cc
--- /dev/null
+++ b/spec/outputs/5.1/test/cond_spec.lua
@@ -0,0 +1,237 @@
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
new file mode 100644
index 0000000..8b8064a
--- /dev/null
+++ b/spec/outputs/5.1/test/existential_spec.lua
@@ -0,0 +1,243 @@
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
new file mode 100644
index 0000000..f40a298
--- /dev/null
+++ b/spec/outputs/5.1/test/export_spec.lua
@@ -0,0 +1,159 @@
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
new file mode 100644
index 0000000..e0921c8
--- /dev/null
+++ b/spec/outputs/5.1/test/goto_spec.lua
@@ -0,0 +1,103 @@
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
new file mode 100644
index 0000000..f77ef04
--- /dev/null
+++ b/spec/outputs/5.1/test/import_spec.lua
@@ -0,0 +1,196 @@
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
new file mode 100644
index 0000000..3bbfb37
--- /dev/null
+++ b/spec/outputs/5.1/test/literals_spec.lua
@@ -0,0 +1,90 @@
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
new file mode 100644
index 0000000..3d60580
--- /dev/null
+++ b/spec/outputs/5.1/test/macro_spec.lua
@@ -0,0 +1,161 @@
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
new file mode 100644
index 0000000..8088b0c
--- /dev/null
+++ b/spec/outputs/5.1/test/metatable_spec.lua
@@ -0,0 +1,141 @@
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
new file mode 100644
index 0000000..661c422
--- /dev/null
+++ b/spec/outputs/5.1/test/operators_spec.lua
@@ -0,0 +1,142 @@
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
new file mode 100644
index 0000000..4e6580f
--- /dev/null
+++ b/spec/outputs/5.1/test/return_spec.lua
@@ -0,0 +1,145 @@
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
new file mode 100644
index 0000000..95eb470
--- /dev/null
+++ b/spec/outputs/5.1/test/string_spec.lua
@@ -0,0 +1,138 @@
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
new file mode 100644
index 0000000..5b13970
--- /dev/null
+++ b/spec/outputs/5.1/test/switch_spec.lua
@@ -0,0 +1,743 @@
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/vararg_spec.lua b/spec/outputs/5.1/test/vararg_spec.lua
new file mode 100644
index 0000000..a95e64e
--- /dev/null
+++ b/spec/outputs/5.1/test/vararg_spec.lua
@@ -0,0 +1,164 @@
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
new file mode 100644
index 0000000..f3f10e3
--- /dev/null
+++ b/spec/outputs/5.1/test/with_spec.lua
@@ -0,0 +1,170 @@
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