aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-04-12 13:09:31 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-04-12 13:09:31 -0400
commit6c01eef851439549018267fdc439e4884af0c624 (patch)
tree0599dd071b8a5effb67e6a87ed1c34777eb8d8c7 /test
parent17cb6ffd88c4464c513b045f4b06c4e6e46e8f22 (diff)
Introducing the main() function
Diffstat (limited to 'test')
-rw-r--r--test/arrays.tm189
-rw-r--r--test/corecursive_func.tm5
-rw-r--r--test/enums.tm63
-rw-r--r--test/extern.tm6
-rw-r--r--test/for.tm37
-rw-r--r--test/functions.tm15
-rw-r--r--test/integers.tm84
-rw-r--r--test/lambdas.tm47
-rw-r--r--test/lang.tm27
-rw-r--r--test/minmax.tm33
-rw-r--r--test/nums.tm73
-rw-r--r--test/reductions.tm28
-rw-r--r--test/structs.tm26
-rw-r--r--test/tables.tm116
-rw-r--r--test/text.tm99
15 files changed, 431 insertions, 417 deletions
diff --git a/test/arrays.tm b/test/arrays.tm
index 17aeee53..c8e34af4 100644
--- a/test/arrays.tm
+++ b/test/arrays.tm
@@ -1,96 +1,97 @@
-if yes
- >> [:Num32]
- = [] : [Num32]
-
-if yes
- >> arr := [10, 20, 30]
- = [10, 20, 30]
-
- >> arr[1]
- = 10
- >> arr[-1]
- = 30
-
- >> #arr
- = 3
-
- sum := 0
- for x in arr
- sum += x
- >> sum
- = 60
-
- str := ""
- for i,x in arr
- str ++= "({i},{x})"
- >> str
- = "(1,10)(2,20)(3,30)"
-
-if yes
- >> arr := [10, 20] ++ [30, 40]
- = [10, 20, 30, 40]
-
- >> arr ++= [50, 60]
- >> arr
- = [10, 20, 30, 40, 50, 60]
-
- >> arr ++= 70
- >> arr
- = [10, 20, 30, 40, 50, 60, 70]
-
-if yes
- >> arr := [10, 20]
- >> copy := arr
- >> arr ++= 30
- >> arr
- = [10, 20, 30]
- >> copy
- = [10, 20]
-
-if yes
- >> [10*i for i in 5]
+func main()
+ if yes
+ >> [:Num32]
+ = [] : [Num32]
+
+ if yes
+ >> arr := [10, 20, 30]
+ = [10, 20, 30]
+
+ >> arr[1]
+ = 10
+ >> arr[-1]
+ = 30
+
+ >> #arr
+ = 3
+
+ sum := 0
+ for x in arr
+ sum += x
+ >> sum
+ = 60
+
+ str := ""
+ for i,x in arr
+ str ++= "({i},{x})"
+ >> str
+ = "(1,10)(2,20)(3,30)"
+
+ if yes
+ >> arr := [10, 20] ++ [30, 40]
+ = [10, 20, 30, 40]
+
+ >> arr ++= [50, 60]
+ >> arr
+ = [10, 20, 30, 40, 50, 60]
+
+ >> arr ++= 70
+ >> arr
+ = [10, 20, 30, 40, 50, 60, 70]
+
+ if yes
+ >> arr := [10, 20]
+ >> copy := arr
+ >> arr ++= 30
+ >> arr
+ = [10, 20, 30]
+ >> copy
+ = [10, 20]
+
+ if yes
+ >> [10*i for i in 5]
+ = [10, 20, 30, 40, 50]
+
+ >> [i*10 for i in 5]
= [10, 20, 30, 40, 50]
->> [i*10 for i in 5]
-= [10, 20, 30, 40, 50]
-
->> [i*10 for i in 5 if i mod 2 != 0]
-= [10, 30, 50]
-
->> [x for x in y if x > 1 for y in [3, 4, 5] if y < 5]
-= [2, 3, 2, 3, 4]
-
-if yes
- >> arr := @[10, 20]
- >> copy := arr[]
- >> arr:insert(30)
- >> arr
- = @[10, 20, 30]
- >> copy
- = [10, 20]
-
-if yes
- >> arr := [10, 20, 30]
- >> arr:reversed()
- = [30, 20, 10]
-
-if yes
- >> nums := [10, -20, 30]
- // Sorted function doesn't mutate original:
- >> nums:sorted()
- = [-20, 10, 30]
- >> nums
- = [10, -20, 30]
- // Sort function does mutate in place:
- >> nums:sort()
- >> nums
- = [-20, 10, 30]
- // Custom sort functions:
- >> nums:sort(func(x:&%Int,y:&%Int) x:abs() <> y:abs())
- >> nums
- = [10, -20, 30]
- >> nums:sort(func(x:&%Int,y:&%Int) y[] <> x[])
- >> nums
- = [30, 10, -20]
-
->> ["A", "B", "C"]:sample(10, [1.0, 0.5, 0.0])
+ >> [i*10 for i in 5 if i mod 2 != 0]
+ = [10, 30, 50]
+
+ >> [x for x in y if x > 1 for y in [3, 4, 5] if y < 5]
+ = [2, 3, 2, 3, 4]
+
+ if yes
+ >> arr := @[10, 20]
+ >> copy := arr[]
+ >> arr:insert(30)
+ >> arr
+ = @[10, 20, 30]
+ >> copy
+ = [10, 20]
+
+ if yes
+ >> arr := [10, 20, 30]
+ >> arr:reversed()
+ = [30, 20, 10]
+
+ if yes
+ >> nums := [10, -20, 30]
+ // Sorted function doesn't mutate original:
+ >> nums:sorted()
+ = [-20, 10, 30]
+ >> nums
+ = [10, -20, 30]
+ // Sort function does mutate in place:
+ >> nums:sort()
+ >> nums
+ = [-20, 10, 30]
+ // Custom sort functions:
+ >> nums:sort(func(x:&%Int,y:&%Int) x:abs() <> y:abs())
+ >> nums
+ = [10, -20, 30]
+ >> nums:sort(func(x:&%Int,y:&%Int) y[] <> x[])
+ >> nums
+ = [30, 10, -20]
+
+ >> ["A", "B", "C"]:sample(10, [1.0, 0.5, 0.0])
diff --git a/test/corecursive_func.tm b/test/corecursive_func.tm
index 0ff92e53..22ffd627 100644
--- a/test/corecursive_func.tm
+++ b/test/corecursive_func.tm
@@ -10,5 +10,6 @@ func pong(x:Int)->[Text]
else
return ["pong: {x}"]
->> ping(3)
-= ["ping: 3", "pong: 2", "ping: 1", "pong: 0"]
+func main()
+ >> ping(3)
+ = ["ping: 3", "pong: 2", "ping: 1", "pong: 0"]
diff --git a/test/enums.tm b/test/enums.tm
index aea18948..f321af8c 100644
--- a/test/enums.tm
+++ b/test/enums.tm
@@ -1,34 +1,35 @@
enum Foo(Zero, One(x:Int), Two(x,y:Int))
->> Foo.Zero
-= Foo.Zero
->> Foo.One(123)
-= Foo.One(x=123)
->> Foo.Two(123, 456)
-= Foo.Two(x=123, y=456)
-
->> Foo.One(10) == Foo.One(10)
-= yes
-
->> Foo.One(10) == Foo.Zero
-= no
-
->> Foo.One(10) == Foo.One(-1)
-= no
-
->> Foo.One(10) < Foo.Two(1, 2)
-= yes
-
->> x := Foo.One(123)
->> t := {x=>"found"; default="missing"}
->> t[x]
-= "found"
->> t[Foo.Zero]
-= "missing"
-
-when x is o:One
- >> o.x
- = 123
-else
- fail("Oops")
+func main()
+ >> Foo.Zero
+ = Foo.Zero
+ >> Foo.One(123)
+ = Foo.One(x=123)
+ >> Foo.Two(123, 456)
+ = Foo.Two(x=123, y=456)
+
+ >> Foo.One(10) == Foo.One(10)
+ = yes
+
+ >> Foo.One(10) == Foo.Zero
+ = no
+
+ >> Foo.One(10) == Foo.One(-1)
+ = no
+
+ >> Foo.One(10) < Foo.Two(1, 2)
+ = yes
+
+ >> x := Foo.One(123)
+ >> t := {x=>"found"; default="missing"}
+ >> t[x]
+ = "found"
+ >> t[Foo.Zero]
+ = "missing"
+
+ when x is o:One
+ >> o.x
+ = 123
+ else
+ fail("Oops")
diff --git a/test/extern.tm b/test/extern.tm
index a02a6a85..896c5730 100644
--- a/test/extern.tm
+++ b/test/extern.tm
@@ -1,3 +1,5 @@
extern CORD_cat:func(a:Text, b:Text)->Text
->> CORD_cat("hello ", "world")
-= "hello world"
+
+func main()
+ >> CORD_cat("hello ", "world")
+ = "hello world"
diff --git a/test/for.tm b/test/for.tm
index 05990d37..51940973 100644
--- a/test/for.tm
+++ b/test/for.tm
@@ -7,11 +7,6 @@ func all_nums(nums:[Int])->Text
return "EMPTY"
return result
->> all_nums([10,20,30])
-= "10,20,30,"
->> all_nums([:Int])
-= "EMPTY"
-
func labeled_nums(nums:[Int])->Text
result := ""
for i,num in nums
@@ -20,11 +15,6 @@ func labeled_nums(nums:[Int])->Text
return "EMPTY"
return result
->> labeled_nums([10,20,30])
-= "1:10,2:20,3:30,"
->> labeled_nums([:Int])
-= "EMPTY"
-
func table_str(t:{Text=>Text})->Text
str := ""
for k,v in t
@@ -32,12 +22,6 @@ func table_str(t:{Text=>Text})->Text
else return "EMPTY"
return str
->> t := {"key1"=>"value1", "key2"=>"value2"}
->> table_str(t)
-= "key1=>value1,key2=>value2,"
->> table_str({:Text=>Text})
-= "EMPTY"
-
func table_key_str(t:{Text=>Text})->Text
str := ""
for k in t
@@ -45,5 +29,22 @@ func table_key_str(t:{Text=>Text})->Text
else return "EMPTY"
return str
->> table_key_str(t)
-= "key1,key2,"
+func main()
+ >> all_nums([10,20,30])
+ = "10,20,30,"
+ >> all_nums([:Int])
+ = "EMPTY"
+
+ >> labeled_nums([10,20,30])
+ = "1:10,2:20,3:30,"
+ >> labeled_nums([:Int])
+ = "EMPTY"
+
+ >> t := {"key1"=>"value1", "key2"=>"value2"}
+ >> table_str(t)
+ = "key1=>value1,key2=>value2,"
+ >> table_str({:Text=>Text})
+ = "EMPTY"
+
+ >> table_key_str(t)
+ = "key1,key2,"
diff --git a/test/functions.tm b/test/functions.tm
index 487e9467..13cdee55 100644
--- a/test/functions.tm
+++ b/test/functions.tm
@@ -1,14 +1,15 @@
func add(x:Int, y:Int)->Int
return x + y
->> add(3, 5)
-= 8
-
func cached_heap(x:Int; cached)->@Int
return @x
->> cached_heap(1) == cached_heap(1)
-= yes
->> cached_heap(1) == cached_heap(2)
-= no
+func main()
+ >> add(3, 5)
+ = 8
+
+ >> cached_heap(1) == cached_heap(1)
+ = yes
+ >> cached_heap(1) == cached_heap(2)
+ = no
diff --git a/test/integers.tm b/test/integers.tm
index a3ec7fe2..376e0319 100644
--- a/test/integers.tm
+++ b/test/integers.tm
@@ -1,55 +1,55 @@
+func main()
+ >> 2 + 3
+ = 5
->> 2 + 3
-= 5
+ >> 2 * 3
+ = 6
->> 2 * 3
-= 6
+ >> 2 + 3 * 4
+ = 14
->> 2 + 3 * 4
-= 14
+ >> 2 * 3 + 4
+ = 10
->> 2 * 3 + 4
-= 10
+ >> 1i8 + 2i16
+ = 3_i16
->> 1i8 + 2i16
-= 3_i16
+ >> 2 ^ 10
+ = 1024 : Num
->> 2 ^ 10
-= 1024 : Num
+ >> 3 and 2
+ = 2
->> 3 and 2
-= 2
+ >> 3 or 4
+ = 7
->> 3 or 4
-= 7
+ >> 3 xor 2
+ = 1
->> 3 xor 2
-= 1
+ nums := ""
+ for x in 5
+ nums ++= "{x},"
+ >> nums
+ = "1,2,3,4,5,"
-nums := ""
-for x in 5
- nums ++= "{x},"
->> nums
-= "1,2,3,4,5,"
+ >> x := 123
+ >> x:format(digits=5)
+ = "00123"
+ >> x:hex()
+ = "0x7B"
+ >> x:octal()
+ = "0o173"
->> x := 123
->> x:format(digits=5)
-= "00123"
->> x:hex()
-= "0x7B"
->> x:octal()
-= "0o173"
+ >> Int.random()
+ >> Int.min
+ = -9223372036854775808
+ >> Int.max
+ = 9223372036854775807
->> Int.random()
->> Int.min
-= -9223372036854775808
->> Int.max
-= 9223372036854775807
-
->> 123_i32:hex()
-= "0x7B"
->> 123_i16:hex()
-= "0x7B"
->> 123_i8:hex()
-= "0x7B"
+ >> 123_i32:hex()
+ = "0x7B"
+ >> 123_i16:hex()
+ = "0x7B"
+ >> 123_i8:hex()
+ = "0x7B"
diff --git a/test/lambdas.tm b/test/lambdas.tm
index ca2acb5d..a445540b 100644
--- a/test/lambdas.tm
+++ b/test/lambdas.tm
@@ -1,33 +1,32 @@
->> add_one := func(x:Int) x + 1
->> add_one(10)
-= 11
-
->> shout := func(msg:Text) say("{msg:upper()}!")
->> shout("hello")
-
->> asdf := add_one
->> asdf(99)
-= 100
-
-
func make_adder(x:Int)-> func(y:Int)->Int
return func(y:Int) x + y
->> add_100 := make_adder(100)
->> add_100(5)
-= 105
-
-
func suffix_fn(fn:func(t:Text)->Text, suffix:Text)->func(t:Text)->Text
return func(t:Text) fn(t)++suffix
->> shout2 := suffix_fn(Text.upper, "!")
->> shout2("hello")
-= "HELLO!"
-
func mul_func(n:Int, fn:func(x:Int)->Int)-> func(x:Int)->Int
return func(x:Int) n*fn(x)
->> abs100 := mul_func(100, Int.abs)
->> abs100(-5)
-= 500
+func main()
+ >> add_one := func(x:Int) x + 1
+ >> add_one(10)
+ = 11
+
+ >> shout := func(msg:Text) say("{msg:upper()}!")
+ >> shout("hello")
+
+ >> asdf := add_one
+ >> asdf(99)
+ = 100
+
+ >> add_100 := make_adder(100)
+ >> add_100(5)
+ = 105
+
+ >> shout2 := suffix_fn(Text.upper, "!")
+ >> shout2("hello")
+ = "HELLO!"
+
+ >> abs100 := mul_func(100, Int.abs)
+ >> abs100(-5)
+ = 500
diff --git a/test/lang.tm b/test/lang.tm
index 509a4ec6..ad09b605 100644
--- a/test/lang.tm
+++ b/test/lang.tm
@@ -14,20 +14,21 @@ lang HTML
func paragraph(content:HTML)->HTML
return $HTML{}"<p>{content}</p>"
->> HTML.HEADER
-= $HTML"<!DOCTYPE HTML>"
+func main()
+ >> HTML.HEADER
+ = $HTML"<!DOCTYPE HTML>"
->> user := "I <3 hax"
->> html := $HTML{}"Hello {user}!"
-= $HTML"Hello I &lt;3 hax!"
->> html ++ $HTML{}"<br>"
-= $HTML"Hello I &lt;3 hax!<br>"
+ >> user := "I <3 hax"
+ >> html := $HTML{}"Hello {user}!"
+ = $HTML"Hello I &lt;3 hax!"
+ >> html ++ $HTML{}"<br>"
+ = $HTML"Hello I &lt;3 hax!<br>"
->> $HTML{}"{1 + 2}"
-= $HTML"3"
+ >> $HTML{}"{1 + 2}"
+ = $HTML"3"
->> $HTML{}"{3_i8}"
-= $HTML"3"
+ >> $HTML{}"{3_i8}"
+ = $HTML"3"
->> html:paragraph()
-= $HTML"<p>Hello I &lt;3 hax!</p>"
+ >> html:paragraph()
+ = $HTML"<p>Hello I &lt;3 hax!</p>"
diff --git a/test/minmax.tm b/test/minmax.tm
index 58d9661d..c3af68d6 100644
--- a/test/minmax.tm
+++ b/test/minmax.tm
@@ -1,26 +1,27 @@
->> 3 _min_ 5
-= 3
->> 5 _min_ 3
-= 3
-
struct Foo(x:Int, y:Int)
func len(f:Foo)->Num
return Num.sqrt(f.x*f.x + f.y*f.y)
->> Foo(5, 1) _min_ Foo(5, 999)
-= Foo(x=5, y=1)
+func main()
+ >> 3 _min_ 5
+ = 3
+ >> 5 _min_ 3
+ = 3
+
+ >> Foo(5, 1) _min_ Foo(5, 999)
+ = Foo(x=5, y=1)
->> Foo(5, 999) _min_.x Foo(5, 1)
-= Foo(x=5, y=999)
+ >> Foo(5, 999) _min_.x Foo(5, 1)
+ = Foo(x=5, y=999)
->> Foo(999, 1) _min_.y Foo(1, 10)
-= Foo(x=999, y=1)
+ >> Foo(999, 1) _min_.y Foo(1, 10)
+ = Foo(x=999, y=1)
->> Foo(-999, -999) _max_:len() Foo(10, 10)
-= Foo(x=-999, y=-999)
+ >> Foo(-999, -999) _max_:len() Foo(10, 10)
+ = Foo(x=-999, y=-999)
->> foos := [Foo(5, 1), Foo(5, 99), Foo(-999, -999)]
->> (_max_) foos
-= Foo(x=5, y=99)
+ >> foos := [Foo(5, 1), Foo(5, 99), Foo(-999, -999)]
+ >> (_max_) foos
+ = Foo(x=5, y=99)
diff --git a/test/nums.tm b/test/nums.tm
index 14926aa0..766cfb48 100644
--- a/test/nums.tm
+++ b/test/nums.tm
@@ -1,49 +1,50 @@
->> n := 1.5
-= 1.5
+func main()
+ >> n := 1.5
+ = 1.5
->> n + n
-= 3
+ >> n + n
+ = 3
->> n * 2
-= 3
+ >> n * 2
+ = 3
->> n - n
-= 0
+ >> n - n
+ = 0
->> Num.PI
-= 3.14159
+ >> Num.PI
+ = 3.14159
->> Num.PI:format(precision=10)
-= "3.1415926536"
+ >> Num.PI:format(precision=10)
+ = "3.1415926536"
->> Num.random()
+ >> Num.random()
->> Num.INF
-= inf
->> Num.INF:isinf()
-= yes
+ >> Num.INF
+ = inf
+ >> Num.INF:isinf()
+ = yes
->> Num.nan()
-= nan
->> nan := Num.nan()
->> nan:isnan()
-= yes
->> nan == nan
-= no
+ >> Num.nan()
+ = nan
+ >> nan := Num.nan()
+ >> nan:isnan()
+ = yes
+ >> nan == nan
+ = no
->> Num.PI:cos():near(-1)
-= yes
->> Num.PI:sin():near(0)
-= yes
+ >> Num.PI:cos():near(-1)
+ = yes
+ >> Num.PI:sin():near(0)
+ = yes
->> 10.0:pow(3)
-= 1000
+ >> 10.0:pow(3)
+ = 1000
->> Num.nan():near(Num.nan())
-= no
+ >> Num.nan():near(Num.nan())
+ = no
->> Num.INF:near(-Num.INF)
-= no
+ >> Num.INF:near(-Num.INF)
+ = no
->> Num32.sqrt(16f32)
-= 4_f32
+ >> Num32.sqrt(16f32)
+ = 4_f32
diff --git a/test/reductions.tm b/test/reductions.tm
index e6b78539..6ed7823f 100644
--- a/test/reductions.tm
+++ b/test/reductions.tm
@@ -1,16 +1,18 @@
->> (+) [10, 20, 30]
-= 60
+struct Foo(x,y:Int)
->> (_max_) [3, 5, 2, 1, 4]
-= 5
+func main()
+ >> (+) [10, 20, 30]
+ = 60
->> (_max_:abs()) [1, -10, 5]
-= -10
+ >> (_max_) [3, 5, 2, 1, 4]
+ = 5
-struct Foo(x,y:Int)
->> (_max_) [Foo(0, 0), Foo(1, 0), Foo(0, 10)]
-= Foo(x=1, y=0)
->> (_max_.y) [Foo(0, 0), Foo(1, 0), Foo(0, 10)]
-= Foo(x=0, y=10)
->> (_max_.y:abs()) [Foo(0, 0), Foo(1, 0), Foo(0, 10), Foo(0, -999)]
-= Foo(x=0, y=-999)
+ >> (_max_:abs()) [1, -10, 5]
+ = -10
+
+ >> (_max_) [Foo(0, 0), Foo(1, 0), Foo(0, 10)]
+ = Foo(x=1, y=0)
+ >> (_max_.y) [Foo(0, 0), Foo(1, 0), Foo(0, 10)]
+ = Foo(x=0, y=10)
+ >> (_max_.y:abs()) [Foo(0, 0), Foo(1, 0), Foo(0, 10), Foo(0, -999)]
+ = Foo(x=0, y=-999)
diff --git a/test/structs.tm b/test/structs.tm
index c038bd07..1d9de8d0 100644
--- a/test/structs.tm
+++ b/test/structs.tm
@@ -1,6 +1,8 @@
struct Pair(x,y:Int)
struct Mixed(x:Int, text:Text)
+struct LinkedList(x:Int, next=!LinkedList)
+struct Password(text:Text; secret)
func test_literals()
>> x := Pair(10, 20)
@@ -11,7 +13,6 @@ func test_literals()
= yes
>> x == Pair(-1, -2)
= no
-test_literals()
func test_metamethods()
>> x := Pair(10, 20)
@@ -30,7 +31,6 @@ func test_metamethods()
= "found"
>> t2[y]
= "missing"
-test_metamethods()
func test_mixed()
>> x := Mixed(10, "Hello")
@@ -48,16 +48,18 @@ func test_mixed()
= "found"
>> t[y]
= "missing"
-test_mixed()
-struct LinkedList(x:Int, next=!LinkedList)
->> @LinkedList(10, @LinkedList(20))
+func main()
+ test_literals()
+ test_metamethods()
+ test_mixed()
-struct Password(text:Text; secret)
->> my_pass := Password("Swordfish")
-= Password(...)
->> users_by_password := {my_pass=> "User1", Password("xxx")=>"User2"}
-= {Password(...)=>"User1", Password(...)=>"User2"}
->> users_by_password[my_pass]
-= "User1"
+ >> @LinkedList(10, @LinkedList(20))
+
+ >> my_pass := Password("Swordfish")
+ = Password(...)
+ >> users_by_password := {my_pass=> "User1", Password("xxx")=>"User2"}
+ = {Password(...)=>"User1", Password(...)=>"User2"}
+ >> users_by_password[my_pass]
+ = "User1"
diff --git a/test/tables.tm b/test/tables.tm
index 74123f88..a55e4238 100644
--- a/test/tables.tm
+++ b/test/tables.tm
@@ -1,58 +1,58 @@
-
->> t := {"one"=>1, "two"=>2; default=999}
-= {"one"=>1, "two"=>2; default=999}
-
->> t["one"]
-= 1
->> t["two"]
-= 2
->> t["???"]
-= 999
-
-t_str := ""
-for k,v in t
- t_str ++= "({k}=>{v})"
->> t_str
-= "(one=>1)(two=>2)"
-
->> #t
-= 2
->> t.default
-= ?%999
->> t.fallback
-= !{Text=>Int}
-
->> t.keys
-= ["one", "two"]
->> t.values
-= [1, 2]
-
->> t2 := {"three"=>3; fallback=t}
-= {"three"=>3; fallback={"one"=>1, "two"=>2; default=999}}
-
->> t2["one"]
-= 1
->> t2["three"]
-= 3
->> t2["???"]
-= 999
-
->> #t2
-= 1
->> t2.default
-= !Int
->> t2.fallback
-= ?%{"one"=>1, "two"=>2; default=999}
-
-t2_str := ""
-for k,v in t2
- t2_str ++= "({k}=>{v})"
->> t2_str
-= "(three=>3)"
-
->> {i=>10*i for i in 5}
-= {1=>10, 2=>20, 3=>30, 4=>40, 5=>50}
->> {i=>10*i for i in 5 if i mod 2 != 0}
-= {1=>10, 3=>30, 5=>50}
->> {x=>10*x for x in y if x > 1 for y in [3, 4, 5] if y < 5}
-= {2=>20, 3=>30, 4=>40}
+func main()
+ >> t := {"one"=>1, "two"=>2; default=999}
+ = {"one"=>1, "two"=>2; default=999}
+
+ >> t["one"]
+ = 1
+ >> t["two"]
+ = 2
+ >> t["???"]
+ = 999
+
+ t_str := ""
+ for k,v in t
+ t_str ++= "({k}=>{v})"
+ >> t_str
+ = "(one=>1)(two=>2)"
+
+ >> #t
+ = 2
+ >> t.default
+ = ?%999
+ >> t.fallback
+ = !{Text=>Int}
+
+ >> t.keys
+ = ["one", "two"]
+ >> t.values
+ = [1, 2]
+
+ >> t2 := {"three"=>3; fallback=t}
+ = {"three"=>3; fallback={"one"=>1, "two"=>2; default=999}}
+
+ >> t2["one"]
+ = 1
+ >> t2["three"]
+ = 3
+ >> t2["???"]
+ = 999
+
+ >> #t2
+ = 1
+ >> t2.default
+ = !Int
+ >> t2.fallback
+ = ?%{"one"=>1, "two"=>2; default=999}
+
+ t2_str := ""
+ for k,v in t2
+ t2_str ++= "({k}=>{v})"
+ >> t2_str
+ = "(three=>3)"
+
+ >> {i=>10*i for i in 5}
+ = {1=>10, 2=>20, 3=>30, 4=>40, 5=>50}
+ >> {i=>10*i for i in 5 if i mod 2 != 0}
+ = {1=>10, 3=>30, 5=>50}
+ >> {x=>10*x for x in y if x > 1 for y in [3, 4, 5] if y < 5}
+ = {2=>20, 3=>30, 4=>40}
diff --git a/test/text.tm b/test/text.tm
index fee7e563..bb2cc14a 100644
--- a/test/text.tm
+++ b/test/text.tm
@@ -1,56 +1,57 @@
->> str := "Hello Amélie!"
->> str:upper()
-= "HELLO AMÉLIE!"
->> str:lower()
-= "hello amélie!"
->> str:lower():title()
-= "Hello Amélie!"
+func main()
+ >> str := "Hello Amélie!"
+ >> str:upper()
+ = "HELLO AMÉLIE!"
+ >> str:lower()
+ = "hello amélie!"
+ >> str:lower():title()
+ = "Hello Amélie!"
->> \UE9
-= "é"
+ >> \UE9
+ = "é"
->> \U65\U301
-= "é"
+ >> \U65\U301
+ = "é"
->> \UE9 == \U65\U301
-= yes
+ >> \UE9 == \U65\U301
+ = yes
->> amelie := "Am{\UE9}lie"
->> amelie:clusters()
-= ["A", "m", "é", "l", "i", "e"] : [Text]
->> amelie:codepoints()
-= [65_i32, 109_i32, 101_i32, 769_i32, 108_i32, 105_i32, 101_i32] : [Int32]
->> amelie:bytes()
-= [65_i8, 109_i8, 101_i8, -52_i8, -127_i8, 108_i8, 105_i8, 101_i8] : [Int8]
->> #amelie
-= 6
->> amelie:num_clusters()
-= 6
->> amelie:num_codepoints()
-= 7
->> amelie:num_bytes()
-= 8
+ >> amelie := "Am{\UE9}lie"
+ >> amelie:clusters()
+ = ["A", "m", "é", "l", "i", "e"] : [Text]
+ >> amelie:codepoints()
+ = [65_i32, 109_i32, 101_i32, 769_i32, 108_i32, 105_i32, 101_i32] : [Int32]
+ >> amelie:bytes()
+ = [65_i8, 109_i8, 101_i8, -52_i8, -127_i8, 108_i8, 105_i8, 101_i8] : [Int8]
+ >> #amelie
+ = 6
+ >> amelie:num_clusters()
+ = 6
+ >> amelie:num_codepoints()
+ = 7
+ >> amelie:num_bytes()
+ = 8
->> amelie2 := "Am{\U65\U301}lie"
->> amelie2:clusters()
-= ["A", "m", "é", "l", "i", "e"] : [Text]
->> amelie2:codepoints()
-= [65_i32, 109_i32, 101_i32, 769_i32, 108_i32, 105_i32, 101_i32] : [Int32]
->> amelie2:bytes()
-= [65_i8, 109_i8, 101_i8, -52_i8, -127_i8, 108_i8, 105_i8, 101_i8] : [Int8]
->> #amelie
-= 6
->> amelie2:num_clusters()
-= 6
->> amelie2:num_codepoints()
-= 7
->> amelie2:num_bytes()
-= 8
+ >> amelie2 := "Am{\U65\U301}lie"
+ >> amelie2:clusters()
+ = ["A", "m", "é", "l", "i", "e"] : [Text]
+ >> amelie2:codepoints()
+ = [65_i32, 109_i32, 101_i32, 769_i32, 108_i32, 105_i32, 101_i32] : [Int32]
+ >> amelie2:bytes()
+ = [65_i8, 109_i8, 101_i8, -52_i8, -127_i8, 108_i8, 105_i8, 101_i8] : [Int8]
+ >> #amelie
+ = 6
+ >> amelie2:num_clusters()
+ = 6
+ >> amelie2:num_codepoints()
+ = 7
+ >> amelie2:num_bytes()
+ = 8
->> amelie:character_names()
-= ["LATIN CAPITAL LETTER A", "LATIN SMALL LETTER M", "LATIN SMALL LETTER E", "COMBINING ACUTE ACCENT", "LATIN SMALL LETTER L", "LATIN SMALL LETTER I", "LATIN SMALL LETTER E"]
->> amelie2:character_names()
-= ["LATIN CAPITAL LETTER A", "LATIN SMALL LETTER M", "LATIN SMALL LETTER E", "COMBINING ACUTE ACCENT", "LATIN SMALL LETTER L", "LATIN SMALL LETTER I", "LATIN SMALL LETTER E"]
+ >> amelie:character_names()
+ = ["LATIN CAPITAL LETTER A", "LATIN SMALL LETTER M", "LATIN SMALL LETTER E", "COMBINING ACUTE ACCENT", "LATIN SMALL LETTER L", "LATIN SMALL LETTER I", "LATIN SMALL LETTER E"]
+ >> amelie2:character_names()
+ = ["LATIN CAPITAL LETTER A", "LATIN SMALL LETTER M", "LATIN SMALL LETTER E", "COMBINING ACUTE ACCENT", "LATIN SMALL LETTER L", "LATIN SMALL LETTER I", "LATIN SMALL LETTER E"]
->> "Hello":replace("e", "X")
-= "HXllo"
+ >> "Hello":replace("e", "X")
+ = "HXllo"