2025-01-29 16:46:28 +02:00
use super ::* ;
2025-01-31 19:49:46 +02:00
use crate ::compiler ::{ token ::CodeLocation , tokenizer ::tokenize } ;
macro_rules ! bool_ast {
( $x :expr ) = > {
BoolLiteral ( CodeLocation ::new ( usize ::MAX , usize ::MAX ) , $x )
} ;
}
macro_rules ! bool_ast_b {
( $x :expr ) = > {
Box ::new ( bool_ast! ( $x ) )
} ;
}
2025-01-29 16:46:28 +02:00
macro_rules ! int_ast {
( $x :expr ) = > {
2025-01-31 19:49:46 +02:00
IntLiteral ( CodeLocation ::new ( usize ::MAX , usize ::MAX ) , $x )
} ;
}
macro_rules ! int_ast_b {
( $x :expr ) = > {
Box ::new ( int_ast! ( $x ) )
2025-01-29 16:46:28 +02:00
} ;
}
macro_rules ! id_ast {
( $x :expr ) = > {
2025-01-31 19:49:46 +02:00
Identifier ( CodeLocation ::new ( usize ::MAX , usize ::MAX ) , $x )
} ;
}
macro_rules ! id_ast_b {
( $x :expr ) = > {
Box ::new ( id_ast! ( $x ) )
2025-01-29 16:46:28 +02:00
} ;
}
2025-01-31 13:30:05 +02:00
macro_rules ! un_ast {
( $x :expr , $y :expr ) = > {
2025-01-31 19:49:46 +02:00
UnaryOp ( CodeLocation ::new ( usize ::MAX , usize ::MAX ) , $x , $y )
} ;
}
macro_rules ! un_ast_b {
( $x :expr , $y :expr ) = > {
Box ::new ( un_ast! ( $x , $y ) )
2025-01-31 13:30:05 +02:00
} ;
}
2025-01-29 16:46:28 +02:00
macro_rules ! bin_ast {
( $x :expr , $y :expr , $z :expr ) = > {
2025-01-31 19:49:46 +02:00
BinaryOp ( CodeLocation ::new ( usize ::MAX , usize ::MAX ) , $x , $y , $z )
2025-01-29 16:46:28 +02:00
} ;
}
2025-01-31 19:49:46 +02:00
macro_rules ! bin_ast_b {
( $x :expr , $y :expr , $z :expr ) = > {
Box ::new ( bin_ast! ( $x , $y , $z ) )
} ;
}
macro_rules ! con_ast {
( $x :expr , $y :expr , $z :expr ) = > {
Conditional ( CodeLocation ::new ( usize ::MAX , usize ::MAX ) , $x , $y , $z )
} ;
}
macro_rules ! con_ast_b {
( $x :expr , $y :expr , $z :expr ) = > {
Box ::new ( con_ast! ( $x , $y , $z ) )
} ;
}
macro_rules ! fun_ast {
( $x :expr , $y :expr ) = > {
FunCall ( CodeLocation ::new ( usize ::MAX , usize ::MAX ) , $x , $y )
} ;
}
macro_rules ! fun_ast_b {
( $x :expr , $y :expr ) = > {
Box ::new ( fun_ast! ( $x , $y ) )
} ;
}
macro_rules ! block_ast {
( $x :expr ) = > {
Block ( CodeLocation ::new ( usize ::MAX , usize ::MAX ) , $x )
} ;
}
macro_rules ! block_ast_b {
2025-01-29 16:46:28 +02:00
( $x :expr ) = > {
2025-01-31 19:49:46 +02:00
Box ::new ( block_ast! ( $x ) )
} ;
}
macro_rules ! empty_ast {
( ) = > {
EmptyLiteral ( CodeLocation ::new ( usize ::MAX , usize ::MAX ) )
} ;
}
macro_rules ! var_ast {
( $x :expr , $y :expr ) = > {
VarDeclaration ( CodeLocation ::new ( usize ::MAX , usize ::MAX ) , $x , $y )
2025-01-29 16:46:28 +02:00
} ;
}
2025-01-29 16:51:33 +02:00
#[ test ]
#[ should_panic ]
fn test_empty ( ) {
parse ( & vec! [ ] ) ;
}
#[ test ]
#[ should_panic ]
fn test_invalid_start ( ) {
2025-01-31 13:03:38 +02:00
parse ( & tokenize ( " 1 2 + 3 " ) ) ;
2025-01-29 16:51:33 +02:00
}
#[ test ]
#[ should_panic ]
fn test_invalid_middle ( ) {
2025-01-31 13:03:38 +02:00
parse ( & tokenize ( " 1 + 2 2 + 3 " ) ) ;
2025-01-29 16:51:33 +02:00
}
#[ test ]
#[ should_panic ]
fn test_invalid_end ( ) {
2025-01-31 13:03:38 +02:00
parse ( & tokenize ( " 1 + 2 3 " ) ) ;
2025-01-29 16:51:33 +02:00
}
2025-01-29 16:46:28 +02:00
#[ test ]
fn test_binary_op_basic ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " 1 + 23 " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , bin_ast! ( int_ast_b! ( 1 ) , " + " , int_ast_b! ( 23 ) ) ) ;
2025-01-29 16:46:28 +02:00
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " 4 - 56 " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , bin_ast! ( int_ast_b! ( 4 ) , " - " , int_ast_b! ( 56 ) ) ) ;
2025-01-29 16:46:28 +02:00
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " 1 * 2 " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , bin_ast! ( int_ast_b! ( 1 ) , " * " , int_ast_b! ( 2 ) ) ) ;
2025-01-29 16:46:28 +02:00
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " 1 / 2 " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , bin_ast! ( int_ast_b! ( 1 ) , " / " , int_ast_b! ( 2 ) ) ) ;
2025-01-29 16:46:28 +02:00
}
2025-01-31 13:19:40 +02:00
#[ test ]
fn test_binary_op_all_levels ( ) {
let result = parse ( & tokenize ( " 1 * 2 + 3 < 4 == 5 and 6 or 7 " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
bin_ast_b! (
bin_ast_b! (
bin_ast_b! (
bin_ast_b! (
bin_ast_b! ( int_ast_b! ( 1 ) , " * " , int_ast_b! ( 2 ) ) ,
" + " ,
int_ast_b! ( 3 )
) ,
2025-01-31 13:19:40 +02:00
" < " ,
2025-01-31 19:49:46 +02:00
int_ast_b! ( 4 )
2025-01-31 13:19:40 +02:00
) ,
" == " ,
2025-01-31 19:49:46 +02:00
int_ast_b! ( 5 )
2025-01-31 13:19:40 +02:00
) ,
" and " ,
2025-01-31 19:49:46 +02:00
int_ast_b! ( 6 )
2025-01-31 13:19:40 +02:00
) ,
" or " ,
2025-01-31 19:49:46 +02:00
int_ast_b! ( 7 )
2025-01-31 13:19:40 +02:00
)
) ;
}
2025-01-29 16:46:28 +02:00
#[ test ]
fn test_binary_op_identifier ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " a + 1 " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , bin_ast! ( id_ast_b! ( " a " ) , " + " , int_ast_b! ( 1 ) ) ) ;
2025-01-29 16:46:28 +02:00
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " 1 - a " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , bin_ast! ( int_ast_b! ( 1 ) , " - " , id_ast_b! ( " a " ) ) ) ;
2025-01-29 16:46:28 +02:00
}
#[ test ]
fn test_binary_op_multiple ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " 1 + 2 - 3 " ) ) ;
2025-01-29 16:46:28 +02:00
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
bin_ast_b! ( int_ast_b! ( 1 ) , " + " , int_ast_b! ( 2 ) ) ,
" - " ,
int_ast_b! ( 3 )
)
2025-01-29 16:46:28 +02:00
) ;
}
#[ test ]
fn test_binary_op_precedence ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " 1 + 2 * 3 " ) ) ;
2025-01-29 16:46:28 +02:00
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
int_ast_b! ( 1 ) ,
" + " ,
bin_ast_b! ( int_ast_b! ( 2 ) , " * " , int_ast_b! ( 3 ) )
)
2025-01-29 16:46:28 +02:00
) ;
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " 1 - 2 / 3 " ) ) ;
2025-01-29 16:46:28 +02:00
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
int_ast_b! ( 1 ) ,
" - " ,
bin_ast_b! ( int_ast_b! ( 2 ) , " / " , int_ast_b! ( 3 ) )
)
2025-01-29 16:46:28 +02:00
) ;
}
2025-01-31 13:30:05 +02:00
#[ test ]
2025-01-31 13:58:04 +02:00
fn test_assignment_basic ( ) {
let result = parse ( & tokenize ( " a = 1 + 2 " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
id_ast_b! ( " a " ) ,
" = " ,
bin_ast_b! ( int_ast_b! ( 1 ) , " + " , int_ast_b! ( 2 ) )
)
2025-01-31 13:58:04 +02:00
) ;
}
#[ test ]
fn test_assignment_chain ( ) {
2025-01-31 13:30:05 +02:00
let result = parse ( & tokenize ( " a = b = 1 + 2 " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
id_ast_b! ( " a " ) ,
2025-01-31 13:30:05 +02:00
" = " ,
2025-01-31 19:49:46 +02:00
bin_ast_b! (
id_ast_b! ( " b " ) ,
" = " ,
bin_ast_b! ( int_ast_b! ( 1 ) , " + " , int_ast_b! ( 2 ) )
)
2025-01-31 13:30:05 +02:00
)
) ;
}
2025-01-31 14:19:01 +02:00
#[ test ]
#[ should_panic ]
fn test_assignment_invalid ( ) {
parse ( & tokenize ( " a = " ) ) ;
}
2025-01-31 13:30:05 +02:00
#[ test ]
2025-01-31 13:58:04 +02:00
fn test_unary_basic ( ) {
let result = parse ( & tokenize ( " not x " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , un_ast! ( " not " , id_ast_b! ( " x " ) ) ) ;
2025-01-31 13:58:04 +02:00
let result = parse ( & tokenize ( " -x " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , un_ast! ( " - " , id_ast_b! ( " x " ) ) ) ;
2025-01-31 13:58:04 +02:00
let result = parse ( & tokenize ( " -1 " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , un_ast! ( " - " , int_ast_b! ( 1 ) ) ) ;
2025-01-31 14:03:20 +02:00
let result = parse ( & tokenize ( " -1 + 2 " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! ( un_ast_b! ( " - " , int_ast_b! ( 1 ) ) , " + " , int_ast_b! ( 2 ) )
2025-01-31 14:03:20 +02:00
) ;
2025-01-31 13:58:04 +02:00
}
#[ test ]
fn test_unary_chain ( ) {
2025-01-31 13:30:05 +02:00
let result = parse ( & tokenize ( " not not x " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , un_ast! ( " not " , un_ast_b! ( " not " , id_ast_b! ( " x " ) ) ) ) ;
2025-01-31 13:30:05 +02:00
let result = parse ( & tokenize ( " --x " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , un_ast! ( " - " , un_ast_b! ( " - " , id_ast_b! ( " x " ) ) ) ) ;
2025-01-31 13:30:05 +02:00
let result = parse ( & tokenize ( " --1 " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , un_ast! ( " - " , un_ast_b! ( " - " , int_ast_b! ( 1 ) ) ) ) ;
2025-01-31 14:03:20 +02:00
let result = parse ( & tokenize ( " --1 + 2 " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
un_ast_b! ( " - " , un_ast_b! ( " - " , int_ast_b! ( 1 ) ) ) ,
" + " ,
int_ast_b! ( 2 )
)
2025-01-31 14:03:20 +02:00
) ;
2025-01-31 13:30:05 +02:00
}
2025-01-29 16:46:28 +02:00
#[ test ]
fn test_parenthesized ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " (1+2)*3 " ) ) ;
2025-01-29 16:46:28 +02:00
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
bin_ast_b! ( int_ast_b! ( 1 ) , " + " , int_ast_b! ( 2 ) ) ,
" * " ,
int_ast_b! ( 3 )
)
2025-01-29 16:46:28 +02:00
) ;
2025-01-29 16:51:33 +02:00
}
2025-01-29 16:46:28 +02:00
2025-01-29 16:51:33 +02:00
#[ test ]
fn test_parenthesized_nested ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " ((1 - 2))/3 " ) ) ;
2025-01-29 16:46:28 +02:00
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
bin_ast_b! ( int_ast_b! ( 1 ) , " - " , int_ast_b! ( 2 ) ) ,
" / " ,
int_ast_b! ( 3 )
)
2025-01-29 16:46:28 +02:00
) ;
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " ((1 + 2)*3) / 4 " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
bin_ast_b! (
bin_ast_b! ( int_ast_b! ( 1 ) , " + " , int_ast_b! ( 2 ) ) ,
" * " ,
int_ast_b! ( 3 )
) ,
2025-01-31 13:03:38 +02:00
" / " ,
2025-01-31 19:49:46 +02:00
int_ast_b! ( 4 )
2025-01-31 13:03:38 +02:00
)
) ;
2025-01-29 16:46:28 +02:00
}
2025-01-29 16:51:33 +02:00
#[ test ]
#[ should_panic ]
fn test_parenthesized_mismatched ( ) {
2025-01-31 13:03:38 +02:00
parse ( & tokenize ( " (1+2*3 " ) ) ;
2025-01-29 16:51:33 +02:00
}
2025-01-29 16:46:28 +02:00
#[ test ]
fn test_if_then ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " if 1 + 2 then 3 " ) ) ;
2025-01-29 16:46:28 +02:00
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
con_ast! (
bin_ast_b! ( int_ast_b! ( 1 ) , " + " , int_ast_b! ( 2 ) ) ,
int_ast_b! ( 3 ) ,
None
)
2025-01-29 16:46:28 +02:00
) ;
}
#[ test ]
fn test_if_then_else ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " if a then b + c else 1 * 2 " ) ) ;
2025-01-29 16:46:28 +02:00
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
con_ast! (
id_ast_b! ( " a " ) ,
bin_ast_b! ( id_ast_b! ( " b " ) , " + " , id_ast_b! ( " c " ) ) ,
Some ( bin_ast_b! ( int_ast_b! ( 1 ) , " * " , int_ast_b! ( 2 ) ) )
2025-01-29 16:46:28 +02:00
)
) ;
}
#[ test ]
2025-01-29 16:51:33 +02:00
fn test_if_then_else_embedded ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " 1 + if true then 2 else 3 " ) ) ;
2025-01-29 16:46:28 +02:00
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
int_ast_b! ( 1 ) ,
2025-01-29 16:46:28 +02:00
" + " ,
2025-01-31 19:49:46 +02:00
con_ast_b! ( bool_ast_b! ( true ) , int_ast_b! ( 2 ) , Some ( int_ast_b! ( 3 ) ) )
2025-01-29 16:46:28 +02:00
)
) ;
}
#[ test ]
2025-01-29 16:51:33 +02:00
fn test_if_then_else_nested ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " if true then if false then 1 else 2 else 3 " ) ) ;
2025-01-29 16:46:28 +02:00
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
con_ast! (
bool_ast_b! ( true ) ,
con_ast_b! ( bool_ast_b! ( false ) , int_ast_b! ( 1 ) , Some ( int_ast_b! ( 2 ) ) ) ,
Some ( int_ast_b! ( 3 ) )
2025-01-29 16:46:28 +02:00
)
) ;
}
2025-01-29 16:51:33 +02:00
#[ test ]
#[ should_panic ]
fn test_if_no_then ( ) {
2025-01-31 13:03:38 +02:00
parse ( & tokenize ( " if true " ) ) ;
2025-01-29 16:51:33 +02:00
}
2025-01-29 16:46:28 +02:00
#[ test ]
fn test_func_basic ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " f(a, b) " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , fun_ast! ( " f " , vec! [ id_ast! ( " a " ) , id_ast! ( " b " ) , ] ) ) ;
2025-01-29 16:46:28 +02:00
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " f(a, 1 + 2) " ) ) ;
2025-01-29 16:46:28 +02:00
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
fun_ast! (
2025-01-29 16:46:28 +02:00
" f " ,
2025-01-31 19:49:46 +02:00
vec! [ id_ast! ( " a " ) , bin_ast! ( int_ast_b! ( 1 ) , " + " , int_ast_b! ( 2 ) ) , ]
2025-01-29 16:46:28 +02:00
)
) ;
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " f() " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , fun_ast! ( " f " , vec! [ ] ) ) ;
2025-01-29 16:46:28 +02:00
}
#[ test ]
2025-01-29 16:51:33 +02:00
fn test_func_embedded ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " 1 + f(a) " ) ) ;
2025-01-29 16:46:28 +02:00
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! ( int_ast_b! ( 1 ) , " + " , fun_ast_b! ( " f " , vec! [ id_ast! ( " a " ) ] ) )
2025-01-29 16:46:28 +02:00
) ;
}
#[ test ]
2025-01-29 16:51:33 +02:00
fn test_func_nested ( ) {
2025-01-31 13:03:38 +02:00
let result = parse ( & tokenize ( " f(a, g(b)) " ) ) ;
2025-01-29 16:46:28 +02:00
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
fun_ast! ( " f " , vec! [ id_ast! ( " a " ) , fun_ast! ( " g " , vec! [ id_ast! ( " b " ) ] ) , ] )
2025-01-29 16:46:28 +02:00
) ;
}
#[ test ]
#[ should_panic ]
fn test_func_missing_comma ( ) {
2025-01-31 13:03:38 +02:00
parse ( & tokenize ( " f(a b) " ) ) ;
2025-01-29 16:46:28 +02:00
}
#[ test ]
#[ should_panic ]
fn test_func_missing_close ( ) {
2025-01-31 13:03:38 +02:00
parse ( & tokenize ( " f(a " ) ) ;
2025-01-29 16:46:28 +02:00
}
2025-01-31 16:09:47 +02:00
#[ test ]
fn test_block_basic ( ) {
let result = parse ( & tokenize ( " { a = 1; b; } " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
block_ast! ( vec! [
bin_ast! ( id_ast_b! ( " a " ) , " = " , int_ast_b! ( 1 ) ) ,
id_ast! ( " b " ) ,
empty_ast! ( )
2025-01-31 16:09:47 +02:00
] )
) ;
let result = parse ( & tokenize ( " { a = 1; b } " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
block_ast! ( vec! [
bin_ast! ( id_ast_b! ( " a " ) , " = " , int_ast_b! ( 1 ) ) ,
id_ast! ( " b " ) ,
2025-01-31 16:09:47 +02:00
] )
) ;
}
#[ test ]
fn test_block_embedded ( ) {
let result = parse ( & tokenize ( " { 1 + 2 } * 3 " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
block_ast_b! ( vec! [ bin_ast! ( int_ast_b! ( 1 ) , " + " , int_ast_b! ( 2 ) ) ] ) ,
2025-01-31 16:09:47 +02:00
" * " ,
2025-01-31 19:49:46 +02:00
int_ast_b! ( 3 )
2025-01-31 16:09:47 +02:00
)
) ;
}
#[ test ]
fn test_block_nested ( ) {
let result = parse ( & tokenize ( " { a = { 1 + 2}} " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
block_ast! ( vec! [ bin_ast! (
id_ast_b! ( " a " ) ,
2025-01-31 16:09:47 +02:00
" = " ,
2025-01-31 19:49:46 +02:00
block_ast_b! ( vec! [ bin_ast! ( int_ast_b! ( 1 ) , " + " , int_ast_b! ( 2 ) ) ] )
2025-01-31 16:09:47 +02:00
) ] )
) ;
}
#[ test ]
#[ should_panic ]
fn test_block_unmatched ( ) {
parse ( & tokenize ( " { a = 1 " ) ) ;
}
#[ test ]
#[ should_panic ]
fn test_block_missing_semicolon ( ) {
parse ( & tokenize ( " { a = 1 \n b } " ) ) ;
}
2025-01-31 16:50:51 +02:00
#[ test ]
fn test_var_basic ( ) {
let result = parse ( & tokenize ( " var x = 1 " ) ) ;
2025-01-31 19:49:46 +02:00
assert_eq! ( result , var_ast! ( " x " , int_ast_b! ( 1 ) ) ) ;
2025-01-31 16:50:51 +02:00
let result = parse ( & tokenize ( " { var x = 1; x = 2; } " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
block_ast! ( vec! [
var_ast! ( " x " , int_ast_b! ( 1 ) ) ,
bin_ast! ( id_ast_b! ( " x " ) , " = " , int_ast_b! ( 2 ) ) ,
empty_ast! ( )
2025-01-31 16:50:51 +02:00
] )
) ;
}
#[ test ]
#[ should_panic ]
fn test_var_chain ( ) {
parse ( & tokenize ( " var x = var y = 1 " ) ) ;
}
#[ test ]
#[ should_panic ]
fn test_var_embedded ( ) {
parse ( & tokenize ( " if true then var x = 3 " ) ) ;
}
2025-01-31 18:28:03 +02:00
#[ test ]
fn test_omitting_semicolons ( ) {
let result = parse ( & tokenize ( " { { a } { b } } " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
block_ast! ( vec! [
block_ast! ( vec! [ id_ast! ( " a " ) ] ) ,
block_ast! ( vec! [ id_ast! ( " b " ) ] )
2025-01-31 18:28:03 +02:00
] )
) ;
let result = parse ( & tokenize ( " { if true then { a } b } " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
block_ast! ( vec! [
con_ast! ( bool_ast_b! ( true ) , block_ast_b! ( vec! [ id_ast! ( " a " ) ] ) , None ) ,
id_ast! ( " b " ) ,
2025-01-31 18:28:03 +02:00
] )
) ;
let result = parse ( & tokenize ( " { if true then { a }; b } " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
block_ast! ( vec! [
con_ast! ( bool_ast_b! ( true ) , block_ast_b! ( vec! [ id_ast! ( " a " ) ] ) , None ) ,
id_ast! ( " b " ) ,
2025-01-31 18:28:03 +02:00
] )
) ;
let result = parse ( & tokenize ( " { if true then { a } else { b } c } " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
block_ast! ( vec! [
con_ast! (
bool_ast_b! ( true ) ,
block_ast_b! ( vec! [ id_ast! ( " a " ) ] ) ,
Some ( block_ast_b! ( vec! [ id_ast! ( " b " ) ] ) )
2025-01-31 18:28:03 +02:00
) ,
2025-01-31 19:49:46 +02:00
id_ast! ( " c " ) ,
2025-01-31 18:28:03 +02:00
] )
) ;
let result = parse ( & tokenize ( " x = { { f(a) } { b } } " ) ) ;
assert_eq! (
result ,
2025-01-31 19:49:46 +02:00
bin_ast! (
id_ast_b! ( " x " ) ,
2025-01-31 18:28:03 +02:00
" = " ,
2025-01-31 19:49:46 +02:00
block_ast_b! ( vec! [
block_ast! ( vec! [ fun_ast! ( " f " , vec! [ id_ast! ( " a " ) ] ) ] ) ,
block_ast! ( vec! [ id_ast! ( " b " ) ] ) ,
] )
2025-01-31 18:28:03 +02:00
)
) ;
}
#[ test ]
#[ should_panic ]
fn test_omitting_semicolons_invalid ( ) {
parse ( & tokenize ( " { if true then { a } b c } " ) ) ;
}