diff --git a/src/compiler/ast.rs b/src/compiler/ast.rs index 4919a28..890ec87 100644 --- a/src/compiler/ast.rs +++ b/src/compiler/ast.rs @@ -3,6 +3,7 @@ pub enum Expression<'source> { IntLiteral(u32), BoolLiteral(bool), Identifier(&'source str), + UnaryOp(&'source str, Box>), BinaryOp( Box>, &'source str, diff --git a/src/compiler/parser/tests.rs b/src/compiler/parser/tests.rs index e675a5f..42d24c9 100644 --- a/src/compiler/parser/tests.rs +++ b/src/compiler/parser/tests.rs @@ -13,6 +13,12 @@ macro_rules! id_ast { }; } +macro_rules! un_ast { + ($x:expr, $y:expr) => { + Box::new(UnaryOp($x, $y)) + }; +} + macro_rules! bin_ast { ($x:expr, $y:expr, $z:expr) => { Box::new(BinaryOp($x, $y, $z)) @@ -122,6 +128,31 @@ fn test_binary_op_precedence() { ); } +#[test] +fn test_assignment() { + let result = parse(&tokenize("a = b = 1 + 2")); + assert_eq!( + result, + BinaryOp( + id_ast!("a"), + "=", + bin_ast!(id_ast!("b"), "=", bin_ast!(int_ast!(1), "+", int_ast!(2))) + ) + ); +} + +#[test] +fn test_unary() { + let result = parse(&tokenize("not not x")); + assert_eq!(result, UnaryOp("not", un_ast!("not", id_ast!("x")))); + + let result = parse(&tokenize("--x")); + assert_eq!(result, UnaryOp("-", un_ast!("-", id_ast!("x")))); + + let result = parse(&tokenize("--1")); + assert_eq!(result, UnaryOp("-", un_ast!("-", int_ast!(1)))); +} + #[test] fn test_parenthesized() { let result = parse(&tokenize("(1+2)*3"));