diff --git a/src/ast/ast.rs b/src/ast/ast.rs index 50417318082330ea12b8623d3d2fb7ee57daa764..6cdec503367e5f0f3ad9249e208e1734f1a14137 100644 --- a/src/ast/ast.rs +++ b/src/ast/ast.rs @@ -3,7 +3,7 @@ use std::fmt; // ast // println!("{:?}", ..) -#[derive(Debug)] +#[derive(Debug)] pub enum NumOrId { Num(usize), Id(String), @@ -11,7 +11,6 @@ pub enum NumOrId { // println!("{}", ..) impl fmt::Display for NumOrId { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { NumOrId::Num(i) => write!(f, "{}", i)?, @@ -19,4 +18,4 @@ impl fmt::Display for NumOrId { }; Ok(()) } -} \ No newline at end of file +} diff --git a/src/ast/main.rs b/src/ast/main.rs index 998eed7d08991ba6c56c49d8c78aa26c190709c8..68f38969dca28eb986b37d9dab2d9a3c51543af4 100644 --- a/src/ast/main.rs +++ b/src/ast/main.rs @@ -17,6 +17,12 @@ fn main() { #[test] fn parse_num_or_id() { - assert_eq!(format!("{}", NumOrIdParser::new().parse("123").unwrap()), "123"); - assert_eq!(format!("{}", NumOrIdParser::new().parse("a1_a").unwrap()), "a1_a"); + assert_eq!( + format!("{}", NumOrIdParser::new().parse("123").unwrap()), + "123" + ); + assert_eq!( + format!("{}", NumOrIdParser::new().parse("a1_a").unwrap()), + "a1_a" + ); } diff --git a/src/main.rs b/src/main.rs index a7b0dbd15c51b37b79693a8c9d75647a16ac45e0..0f5481ee507b46513c5fdf73a3f7d68a84cbb156 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,8 +8,7 @@ fn main() { println!("Parse an Id {:?}", IdParser::new().parse("abcd")); } -#[test] +#[test] fn hello() { println!("Parse an Id {:?}", IdParser::new().parse("abcd")); } - diff --git a/tests/w1_2.rs b/tests/w1_2.rs new file mode 100644 index 0000000000000000000000000000000000000000..c29830ac008ffb76eb8a6d7cf61ba2400aa108a5 --- /dev/null +++ b/tests/w1_2.rs @@ -0,0 +1,72 @@ +// A set of small examples that your parser should accept and parse into an ast +// you should also be able to print the ast (debug ":?" or even prettier using display "{}") +// +// Notice that a sequence of statements may have an optional trailing ";" + +fn _let_and_return() { + // a function taking no arguments returning the unit type + fn a() -> () { + let _a: i32 = 5; // this returns a unit type + } + + // a function taking two i32 arguments returning the i32 type + fn b(_x: i32, _y: i32) -> i32 { + 3 // this returns 3 (as i32) + } + + // a function taking two i32 arguments returning the i32 type + // with some let statements + fn c(x: i32, y: i32) -> i32 { + let a: i32 = 5; + let b: i32 = x + y; // this will be an infix operator "+"" + -a - (-b) * y // here we have prefix operator "-" + } +} + +// More advanced statements +fn _if_then_else_and_while() { + // a function taking two bool arguments returning the bool type + // with some let statements and function calls + fn a(x: bool, y: bool) -> bool { + if x && y { + let a: bool = true; + y || a + } else { + x && false + } + } + + // a function taking two bool arguments returning the i32 type + // with some let statements and function calls + fn b(x: bool, y: bool) -> i32 { + let a: bool = a(x, y || false); + let mut b: i32 = 0; + if a && y { + let a: bool = true; // shadowing + if y || a { + b = b + 1; + }; + } else { + if !(x && false) { + b = b - 1; + } + }; + b + 3 + } + + // a function taking two bool arguments returning the i32 type + // while + fn c(x: bool, y: bool) -> i32 { + let mut b: i32 = 0; + let mut c: i32 = 1; + while (b < 10) { + c = c * 2; + } + c + } +} + +// optionally you may support other integer types, such as u8, u16, u32, u64, i8, i16, i64 and usize +// you may also support explicit local scopes +// +// later we will introduce references and user defined data types