Renames, eof and comment fixes
This commit is contained in:
		| @@ -1,42 +1,44 @@ | |||||||
| #[derive(Debug,PartialEq)] | #[derive(Debug,PartialEq)] | ||||||
| pub enum Statement<'a> { | pub enum Stmt<'a> { | ||||||
|     Assignment(&'a str, Expression<'a>), |     Assignment(&'a str, Expr<'a>), | ||||||
|     Funcall(Funcall<'a>), |     Funcall(Funcall<'a>), | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug,PartialEq)] | #[derive(Debug,PartialEq)] | ||||||
| pub enum Expression<'a> { | pub enum Expr<'a> { | ||||||
|     Id(&'a str), |     Id(&'a str), | ||||||
|     Num(f64), |     Num(f64), | ||||||
|     Funcall(Funcall<'a>), |     Funcall(Funcall<'a>), | ||||||
|     Plus(Box<Expression<'a>>, Box<Expression<'a>>), |     Plus(Box<Expr<'a>>, Box<Expr<'a>>), | ||||||
|     Minus(Box<Expression<'a>>, Box<Expression<'a>>), |     Minus(Box<Expr<'a>>, Box<Expr<'a>>), | ||||||
|     Mult(Box<Expression<'a>>, Box<Expression<'a>>), |     Mult(Box<Expr<'a>>, Box<Expr<'a>>), | ||||||
|  |     Div(Box<Expr<'a>>, Box<Expr<'a>>), | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug,PartialEq)] | #[derive(Debug,PartialEq)] | ||||||
| pub struct Funcall<'a> { | pub struct Funcall<'a> { | ||||||
|     id: &'a str, |     id: &'a str, | ||||||
|     args: Vec<Expression<'a>>, |     args: Vec<Expr<'a>>, | ||||||
| } | } | ||||||
|  |  | ||||||
| peg::parser! { | peg::parser! { | ||||||
|     grammar deelang_parser() for str { |     grammar deelang_parser() for str { | ||||||
| 	pub rule program() -> Vec<Statement<'input>> | 	pub rule program() -> Vec<Stmt<'input>> | ||||||
| 	    = __* s:statement()* eof() { s } | 	    = __* s:stmt()* { s } | ||||||
| 	pub rule statement() -> Statement<'input> | 	pub rule stmt() -> Stmt<'input> | ||||||
| 	    = i:id() "<-" _ e:expr() __* { Statement::Assignment(i, e) } / | 	    = i:id() "<-" _ e:expr() stop() { Stmt::Assignment(i, e) } / | ||||||
| 	    f:funcall() __* { Statement::Funcall(f)} | 	    f:funcall() stop() { Stmt::Funcall(f) } | ||||||
| 	rule expr() -> Expression<'input> = precedence!{ | 	rule expr() -> Expr<'input> = precedence!{ | ||||||
| 	    e1:(@) "+" _ e2:@ { Expression::Plus(Box::new(e1), Box::new(e2)) } | 	    e1:(@) "+" _ e2:@ { Expr::Plus(Box::new(e1), Box::new(e2)) } | ||||||
| 	    e1:(@) "-" _ e2:@ { Expression::Minus(Box::new(e1), Box::new(e2)) } | 	    e1:(@) "-" _ e2:@ { Expr::Minus(Box::new(e1), Box::new(e2)) } | ||||||
| 	    -- | 	    -- | ||||||
|             e1:(@) "*" _ e2:@ { Expression::Mult(Box::new(e1), Box::new(e2)) } |             e1:(@) "*" _ e2:@ { Expr::Mult(Box::new(e1), Box::new(e2)) } | ||||||
|  | 	    e1:(@) "/" _ e2:@ { Expr::Div(Box::new(e1), Box::new(e2)) } | ||||||
| 	    -- | 	    -- | ||||||
|             "(" _ e:expr() ")" _ { e }  |             "(" _ e:expr() ")" _ { e }  | ||||||
| 	    f:funcall() _ { Expression::Funcall(f) } | 	    f:funcall() _ { Expr::Funcall(f) } | ||||||
| 	    i:id() _ { Expression::Id(i) } | 	    i:id() _ { Expr::Id(i) } | ||||||
| 	    n:num() _ { Expression::Num(n) } | 	    n:num() _ { Expr::Num(n) } | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	rule id() -> &'input str | 	rule id() -> &'input str | ||||||
| @@ -50,10 +52,12 @@ peg::parser! { | |||||||
| 	    = ['A'..='Z'] / ['a'..='z'] | 	    = ['A'..='Z'] / ['a'..='z'] | ||||||
| 	rule digit() | 	rule digit() | ||||||
| 	    = ['0'..='9'] | 	    = ['0'..='9'] | ||||||
|  | 	rule stop() | ||||||
|  | 	    = __+ / eof() | ||||||
| 	rule _ // Non-meaningful whitespace | 	rule _ // Non-meaningful whitespace | ||||||
| 	    = ['\t'|' ']* | 	    = ['\t'|' ']* | ||||||
| 	rule __ // Blank lines and lines containing only comments | 	rule __ // End Of Statement (comment, newline, eof, TODO semicolon) | ||||||
| 	    = comment() &eof() / comment() newline() / newline() | 	    = comment()? newline() / comment() &eof() | ||||||
| 	rule comment() | 	rule comment() | ||||||
| 	    = "#" (!newline() [_])* &(newline() / eof()) | 	    = "#" (!newline() [_])* &(newline() / eof()) | ||||||
| 	rule newline() | 	rule newline() | ||||||
| @@ -70,18 +74,20 @@ mod test { | |||||||
|      |      | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_comments() { |     fn test_comments() { | ||||||
| 	let expected = vec![]; | 	let prgm = "## This is a comment | ||||||
| 	let prgm = "## This is a comment"; | apple <- 1 ## This is too | ||||||
|  | ## This comment ends the file"; | ||||||
|  | 	let expected = vec![Stmt::Assignment("apple", Expr::Num(1.0))]; | ||||||
| 	assert_eq!(deelang_parser::program(prgm).unwrap(), expected); | 	assert_eq!(deelang_parser::program(prgm).unwrap(), expected); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_funcall() { |     fn test_funcall() { | ||||||
| 	let expected = vec![ | 	let expected = vec![ | ||||||
| 	    Statement::Funcall(Funcall{id: "pear", args: vec![]}), | 	    Stmt::Funcall(Funcall{id: "pear", args: vec![]}), | ||||||
|  	    Statement::Funcall(Funcall { |  	    Stmt::Funcall(Funcall { | ||||||
|  		id: "pear", |  		id: "pear", | ||||||
|  		args: vec![Expression::Id("x"), Expression::Id("y")], |  		args: vec![Expr::Id("x"), Expr::Id("y")], | ||||||
|  	    }) |  	    }) | ||||||
| 	]; | 	]; | ||||||
| 	let prgm = r"pear() | 	let prgm = r"pear() | ||||||
| @@ -94,14 +100,14 @@ pear(x, y)"; | |||||||
| 	let prgm = r"apple <- 1 | 	let prgm = r"apple <- 1 | ||||||
| apple <- pear(x, y)"; | apple <- pear(x, y)"; | ||||||
| 	let expected = vec![ | 	let expected = vec![ | ||||||
| 	    Statement::Assignment("apple", | 	    Stmt::Assignment("apple", | ||||||
| 				  Expression::Num(1.0)), | 				  Expr::Num(1.0)), | ||||||
| 	    Statement::Assignment("apple", | 	    Stmt::Assignment("apple", | ||||||
| 				  Expression::Funcall(Funcall { | 				  Expr::Funcall(Funcall { | ||||||
| 				      id: "pear", | 				      id: "pear", | ||||||
| 				      args: vec![ | 				      args: vec![ | ||||||
| 					  Expression::Id("x"), | 					  Expr::Id("x"), | ||||||
| 					  Expression::Id("y"), | 					  Expr::Id("y"), | ||||||
| 				      ]})), | 				      ]})), | ||||||
| 	]; | 	]; | ||||||
| 	assert_eq!(deelang_parser::program(prgm).unwrap(), expected); | 	assert_eq!(deelang_parser::program(prgm).unwrap(), expected); | ||||||
| @@ -113,23 +119,23 @@ apple <- pear(x, y)"; | |||||||
| one <- 3 - 2 | one <- 3 - 2 | ||||||
| four <- (3 - 1) * 2"; | four <- (3 - 1) * 2"; | ||||||
| 	let expected = vec![ | 	let expected = vec![ | ||||||
| 	    Statement::Assignment("three", | 	    Stmt::Assignment("three", | ||||||
| 				  Expression::Plus( | 				  Expr::Plus( | ||||||
| 				      Box::new(Expression::Num(1.0)), | 				      Box::new(Expr::Num(1.0)), | ||||||
| 				      Box::new(Expression::Num(2.0)) | 				      Box::new(Expr::Num(2.0)) | ||||||
| 				  )), | 				  )), | ||||||
| 	    Statement::Assignment("one", | 	    Stmt::Assignment("one", | ||||||
| 				  Expression::Minus( | 				  Expr::Minus( | ||||||
| 				      Box::new(Expression::Num(3.0)), | 				      Box::new(Expr::Num(3.0)), | ||||||
| 				      Box::new(Expression::Num(2.0)) | 				      Box::new(Expr::Num(2.0)) | ||||||
| 				  )), | 				  )), | ||||||
| 	    Statement::Assignment("four", | 	    Stmt::Assignment("four", | ||||||
| 				  Expression::Mult( | 				  Expr::Mult( | ||||||
| 				      Box::new(Expression::Minus( | 				      Box::new(Expr::Minus( | ||||||
| 					  Box::new(Expression::Num(3.0)), | 					  Box::new(Expr::Num(3.0)), | ||||||
| 					  Box::new(Expression::Num(1.0)), | 					  Box::new(Expr::Num(1.0)), | ||||||
| 				      )), | 				      )), | ||||||
| 				      Box::new(Expression::Num(2.0)), | 				      Box::new(Expr::Num(2.0)), | ||||||
| 				  )) | 				  )) | ||||||
| 	]; | 	]; | ||||||
| 	assert_eq!(deelang_parser::program(prgm).unwrap(), expected); | 	assert_eq!(deelang_parser::program(prgm).unwrap(), expected); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user