diff --git a/rust/src/main.rs b/rust/src/main.rs index c43f07d..fc44eea 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -19,7 +19,7 @@ fn script(filename: &str) { let mut prgm = String::new(); file.read_to_string(&mut prgm).unwrap(); let tree = parser::parse(&prgm); - println!("{:?}", tree); + println!("{:#?}", tree); } fn main() { diff --git a/rust/src/parser.rs b/rust/src/parser.rs index 15d3e20..838a839 100644 --- a/rust/src/parser.rs +++ b/rust/src/parser.rs @@ -8,6 +8,7 @@ pub enum Stmt { #[derive(Debug,PartialEq,Clone)] pub enum Expr { Id(String), + String(String), Num(f64), Funcall(String, Vec), Funcdef(Option, Box), @@ -17,6 +18,7 @@ pub enum Expr { Div(Box, Box), Block(Vec), GuardedBlock(Box), + Object(Vec), } #[derive(Debug,PartialEq,Clone)] @@ -30,7 +32,7 @@ peg::parser! { pub rule program() -> Vec = __* s:stmt()* { s } pub rule stmt() -> Stmt - = i:id() "<-" _ e:expr() stop() { Stmt::Assignment(i, e) } / + = a:assignment() { a } / f:funcall() stop() { Stmt::Funcall(f) } / c:conditional() { c } rule expr() -> Expr = precedence! { @@ -41,14 +43,19 @@ peg::parser! { e1:(@) "/" _ e2:@ { Expr::Div(Box::new(e1), Box::new(e2)) } -- "(" _ e:expr() ")" _ { e } + ['"'] s:$((!['"'] [_] / r#"\""#)*) ['"'] { Expr::String(s.to_string()) } f:funcall() { f } - f:funcdef() { f } + f:funcdef() { f } + o:object() { o } i:id() _ { Expr::Id(i) } n:num() _ { Expr::Num(n) } + } rule id() -> String = i:$(letter() (letter() / digit() / ['?'|'.'|'-'])*) _ { i.to_string() } + rule assignment() -> Stmt + = i:id() "<-" _ e:expr() stop() { Stmt::Assignment(i, e) } rule num() -> f64 = n:$(digit()+ "."? digit()* / "." digit()+) _ { n.parse().unwrap() } rule funcall() -> Expr @@ -57,6 +64,9 @@ peg::parser! { = i:id()? "->" _ e:(expr() / block()) { Expr::Funcdef(i, Box::new(e)) } rule conditional() -> Stmt = i:_if() __* ei:elif()* __* e:_else()? __* { Stmt::Conditional([vec![i], ei].concat(), e) } + rule object() -> Expr + = "{" _ stop() indent() __* a:assignment()+ dedent() __* "}" _ { Expr::Object(a) } + rule _if() -> Expr = "if" _ g:expr() b:indented_block() { Expr::GuardedBlock(Box::new(GuardedBlock { @@ -305,6 +315,22 @@ else )]; assert_eq!(deelang_parser::program(prgm).unwrap(), expected); } + #[test] + fn test_object() { + let prgm = r"fruit <- { +>>>apple <- 1 +pear <- 2 +<<< +}"; + let expected = vec![Stmt::Assignment( + "fruit".to_string(), + Expr::Object(vec![ + Stmt::Assignment("apple".to_string(), Expr::Num(1.0)), + Stmt::Assignment("pear".to_string(), Expr::Num(2.0)), + ]), + )]; + assert_eq!(deelang_parser::program(prgm).unwrap(), expected); + } #[test] fn test_preprocess() {