include :assert
add_results setup name: "parser tests" {
test "little_program_parse" {
{ a = new;a.! = {x| x + 1};a.? = {x| x + 1};a.\\ = {x| x + 1};a.- = {x| x + 1};a.* = {x| x + 1};a.+ = {x| x + 1};a.^ = {x| x + 1};a.@ = {x| x + 1};a.~ = {x| x + 1};a./ = {x| x + 1};a.> = {x| x + 1};a.< = {x| x + 1};a.$ = {x| x + 1};a._ = {x| x + 1};a.% = {x| x + 1};a.!= = {x| x + 1};a.>= = {x| x + 1};a.<= = {x| x + 1};a.|| = {x| x + 1};a.| = {x| x + 1};a.&& = {x| x + 1};a.& = {x| x + 1};a.== = {x| x + 1}}
}
test "simple_identifier_parse" {
{ a }
}
test "mixed_identifier_parse" {
{ h1h4h3 }
{ what?? }
{ HhH1?1! }
{ h-h!l2Al102913l??a }
{ a123_!?-*+^&@~#\\><$
}
}
test "method_parse" {
{ hello }
{ what.what? }
{ hello() }
{ p f test: 'hello' test2: 'there' }
}
test "chained_method_parse" {
{ what.what.what }
{ hello().something.what() }
{ hello.something() }
{ [1].test.test }
{ [a:1].test.test 3 }
{ "a".test.test(1).test }
{ a[1].test }
{ 1.test[3].test(1)[3][3].test }
{ "hi".test }
{ (a).test }
}
test "big_combo_parse" {
{ a[1].test(1,2,3)[1].o(a,b,c,3).b(a:1)[1][2][3].test }
{ a[1].test(1,2,3)[1].o(a,b,c,3).b(a:1)[1][2][3].test [1,2,3] }
}
test "array_parse" {
{ [1,2,3] }
{ [a,1,b] }
{ [1, a, b, b.m, c.d(1,2,3)] }
{ [[[1,a], [2,b], [3,c]]] }
{ [1][0][2] }
{ [1,2,3].test }
{ [1].test }
{ [a][b][c][d,2].test }
}
test "simple_args_parse" {
{ sup dawg }
{ sup 1, 2, 3 }
{ sup b, a, 3, sup }
}
test "simple_named_args_parse" {
{ sup I:1, bob:b1 }
}
test "weird_args_parse" {
{ sup dog.bark }
{ call_this wacky:method, then:this.one, 1, 2
,3, 4 }
}
test "operation_parse" {
{ a.@ = 1 }
{ a + b }
{ 1 + a.b }
{ 1 + 2 ! 3 @ b }
{ 1.a + b }
}
test "formal_parse" {
{ {x, y | } }
{ {x, y| z } }
{ {x, y = 1 | y } }
{ {*y | p y } }
{ {x, *y | p y } }
{ { x = 1, *y | } }
{ { x = 1, z = 3, *y | } }
{ { a,b, c, x = 1,z = 3,*y | } }
}
test "hash_parse" {
{ [a:1, b:2] }
{ [a : 1, b : 2] }
}
test "list_access_parse" {
{ a[1] }
{ a[x.y] }
}
test "list_set_parse" {
{ a[1] = 2 }
{ a[x] = m.m }
{ a[z] = {x, y| x } }
}
test "comment_parse" {
{ x = 1; #x = 6
x }
{ x = 1; #* x = 6 *#
x }
{ x = 1; #*
x = 6
*#
x }
{ #* # *#
}
{ #
}
{ #;+
}
{ #
"hi" }
assert 3 { x = { *args | p args.length }
x 1 2 #3
{ 4 }
}
assert 3 { x = { *args | p args.length }
x 1 2
#blah blah
{ 4 }
}
}
test "symbol_parse" {
{ x = :x }
{ x = :sdifhsd123123! }
{ x :a.hello(1, 2, 3) }
}
test "method_parens_parse" {
{ to_be?() }
{ sup(dawg) }
{ hi(man, girl, sister, brother, 1, 2, 3, 4, 5) }
{ monkey_butt(first:scratch, then:poke.it(1)) }
{ hi().hi.hi(1,2).hi(a,b,c).hi(a.a) }
}
test "method_access_parse" {
{ hi->there }
{ ->there }
{ a->->> }
}
test "paren_exp_parse" {
{ ( hi ) }
{ what().what() }
{ (( ((((((((a))) ))))))) }
{ (this.thing.is?( really ).driving.me.crazy) }
}
test "integer_parse" {
{ 1 }
{ 12312490 }
{ 001293213 }
}
test "float_parse" {
{ 1.1 }
}
test "digit_parse" {
{ 1 }
}
test "string_parse" {
{ "Hello, there" }
{ 'what is up' }
{ 'what\'s up?' }
{ 'stray double \"quote' }
}
test "double quotes string parse with line breaks" {
a = "
"
b = "\n "
assert_equal b, a
}
test "single quotes string parse with line breaks" {
a = '
'
b = "\n \n "
assert_equal b, a
}
test "assignment_parse" {
{ pi = 3.123123 }
}
test "method_definition_parse" {
{ { p hi } }
{ { x, y | p x, y } }
{ x = { p hi } }
{ x = { a, b | "a + b" } }
}
test "multiline_method_parse" {
{ b = {
a = 1
} }
}
test "variable length argument scope" {
f = { *x | x[0] }
y = f 1
z = f 2
assert_false { y == z }
}
test "method call on index call with known 'type'" {
a = object.new
a.x = 1
b = [a]
assert_equal 1 { b[0].x }
}
test "newlines as separators in index get" {
{
x[1
2
3]
}
}
test "escaped double quote in string" {
{
"\\"
}
}
}