added grammar files
This commit is contained in:
		| @@ -0,0 +1 @@ | |||||||
|  | use crate::ast::expression::Expression; | ||||||
|   | |||||||
| @@ -0,0 +1,4 @@ | |||||||
|  | /// A node that is evaluable to type `T` | ||||||
|  | pub trait Evaluable<T> { | ||||||
|  |     fn evaluate(&self) -> T; | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | use crate::ast::literal::Literal; | ||||||
|  |  | ||||||
|  | pub enum Expression { | ||||||
|  |     Identifier(String), | ||||||
|  |     Literal(Literal), | ||||||
|  |  | ||||||
|  |     Addition(Box<Expression>, Box<Expression>), | ||||||
|  |     Subtraction(Box<Expression>, Box<Expression>), | ||||||
|  |     Multiplication(Box<Expression>, Box<Expression>), | ||||||
|  |     Division(Box<Expression>, Box<Expression>), | ||||||
|  |     Remainder(Box<Expression>, Box<Expression>), | ||||||
|  |     Negation(Box<Expression>), | ||||||
|  |  | ||||||
|  |     And(Box<Expression>, Box<Expression>), | ||||||
|  |     Or(Box<Expression>, Box<Expression>), | ||||||
|  |  | ||||||
|  |     Equal(Box<Expression>, Box<Expression>), | ||||||
|  |     NotEqual(Box<Expression>, Box<Expression>), | ||||||
|  |     Less(Box<Expression>, Box<Expression>), | ||||||
|  |     LessEqual(Box<Expression>, Box<Expression>), | ||||||
|  |     Greater(Box<Expression>, Box<Expression>), | ||||||
|  |     GreaterEqual(Box<Expression>, Box<Expression>), | ||||||
|  | } | ||||||
|   | |||||||
| @@ -0,0 +1,5 @@ | |||||||
|  | pub enum Literal { | ||||||
|  |     Int(i64), | ||||||
|  |     Float(f64), | ||||||
|  |     Bool(bool), | ||||||
|  | } | ||||||
|   | |||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | mod evaluable; | ||||||
|  | pub mod literal; | ||||||
|  | pub mod expression; | ||||||
|  | pub mod logical; | ||||||
|  | mod comparison; | ||||||
|  | mod operators; | ||||||
| @@ -0,0 +1,30 @@ | |||||||
|  | use crate::ast::expression::Expression; | ||||||
|  |  | ||||||
|  | pub enum Operator { | ||||||
|  |     Unary(UnaryOperator), | ||||||
|  |     Binary(BinaryOperator), | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub enum UnaryOperator { | ||||||
|  |     Minus, | ||||||
|  |     Not, | ||||||
|  |     Reference, | ||||||
|  |     Dereference, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub enum BinaryOperator { | ||||||
|  |     Plus, | ||||||
|  |     Minus, | ||||||
|  |     Multiply, | ||||||
|  |     Divide, | ||||||
|  |     Modulo, | ||||||
|  |     And, | ||||||
|  |     Or, | ||||||
|  |     Xor, | ||||||
|  |     Equal, | ||||||
|  |     NotEqual, | ||||||
|  |     Greater, | ||||||
|  |     GreaterEqual, | ||||||
|  |     Less, | ||||||
|  |     LessEqual, | ||||||
|  | } | ||||||
|   | |||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | use crate::ast::expression::Expression; | ||||||
|  |  | ||||||
|  | grammar; | ||||||
|  |  | ||||||
|  | pub ASTExpression: Expression = { | ||||||
|  |     <s: Identifier> => Expression::Identifier(String::from(s)), | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | pub Identifier: &'input str = <s:r"[_a-zA-Z][_a-zA-Z0-9]*"> => s; | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | Expr := Identifier | ||||||
|  | |       Expr Expr | ||||||
|  | |       "&" Identifier "." Expr | ||||||
|  | |       "(" Expr ")" | ||||||
|  |  | ||||||
|  | Declaration := Identifier ":=" Expr ";" | ||||||
|  |  | ||||||
|  | Abstraction := "&" Identifier "." Expr ";" | ||||||
|  |  | ||||||
|  | Application := Identifier "<|" Expr | ||||||
| @@ -1,13 +1,14 @@ | |||||||
| use std::str::FromStr; | use std::str::FromStr; | ||||||
|  | use crate::ast::literal::Literal; | ||||||
|  |  | ||||||
| grammar; | grammar; | ||||||
|  |  | ||||||
| pub Atom: f64 = { | pub Atom: Literal = { | ||||||
|     <n:Int> => n as f64, |     <n:Int> => Literal::Int(n), | ||||||
|     Float, |     <f: Float> => Literal::Float(f), | ||||||
|     "(" <Atom> ")", |     "(" <f: Atom> ")" => f, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| pub Int: i64 = <s:r"[0-9]|[1-9][0-9]*"> => i64::from_str(s).unwrap(); | pub Int: i64 = <s:r"[0-9]|[1-9][0-9]*"> => i64::from_str(s).unwrap(); | ||||||
| pub Float: f64 = <s:r"[+-]?([0-9]*[.][0-9]+|[0-9]*([.][0-9]+)?[Ee][+-]?[1-9][0-9]*)"> => f64::from_str(s).unwrap(); | pub Float: f64 = <s:r"[+-]?([0-9]*[.][0-9]+|[0-9]*([.][0-9]+)?[Ee][+-]?[1-9][0-9]*)"> => f64::from_str(s).unwrap(); | ||||||
| pub StringLiteral: &'input str = <s:"\"[^\"]\""> => s; | //pub StringLiteral: &'input str = <s:"\"[^\"]\""> => s; | ||||||
| @@ -1,5 +1,11 @@ | |||||||
|  | use lalrpop_util::lalrpop_mod; | ||||||
|  |  | ||||||
| mod ast; | mod ast; | ||||||
| mod optimising; | mod optimising; | ||||||
|  | mod tests; | ||||||
|  |  | ||||||
|  | lalrpop_mod!(pub literals); | ||||||
|  | lalrpop_mod!(pub expressions); | ||||||
|  |  | ||||||
| fn main() { | fn main() { | ||||||
|     println!("Hello, world!"); |     println!("Hello, world!"); | ||||||
|   | |||||||
| @@ -0,0 +1 @@ | |||||||
|  | mod constfolding; | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn identifiers() { | ||||||
|  |     use crate::expressions::IdentifierParser as IdentParser; | ||||||
|  |     assert!(IdentParser::new().parse("a").is_ok()); | ||||||
|  |     assert!(IdentParser::new().parse("_").is_ok()); | ||||||
|  |     assert!(IdentParser::new().parse("a_a_a_").is_ok()); | ||||||
|  |     assert!(IdentParser::new().parse("_0").is_ok()); | ||||||
|  |     assert!(IdentParser::new().parse("_a").is_ok()); | ||||||
|  |     assert!(IdentParser::new().parse("__").is_ok()); | ||||||
|  |  | ||||||
|  |     assert!(IdentParser::new().parse("0").is_err()); | ||||||
|  |     assert!(IdentParser::new().parse("0123456").is_err()); | ||||||
|  |     assert!(IdentParser::new().parse("0aaaa").is_err()); | ||||||
|  | } | ||||||
| @@ -0,0 +1,49 @@ | |||||||
|  | use crate::literals::AtomParser as Parser; | ||||||
|  | use std::any::type_name_of_val; | ||||||
|  | use std::convert::identity; | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn int_literals() { | ||||||
|  |     let parser = Parser::new(); | ||||||
|  |     let valid_ints = vec!["1234567890", "(1234567890)", "((((1))))"]; | ||||||
|  |     let invalid_ints = vec!["01", "(1", "6543)", "((987652345)"]; | ||||||
|  |  | ||||||
|  |     assert!(valid_ints.into_iter().all(|s| parser.parse(s).is_ok())); | ||||||
|  |     assert!(invalid_ints.into_iter().all(|s| parser.parse(s).is_err())); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn test_float_dots() { | ||||||
|  |     let valid_floats = vec![ | ||||||
|  |         "0.0", | ||||||
|  |         "-0.0", | ||||||
|  |         "3.141592653589793", | ||||||
|  |         "-1.123456765432123456789", | ||||||
|  |     ]; | ||||||
|  |     assert!(Parser::new().parse("1.1").is_ok()); | ||||||
|  |     assert!(Parser::new().parse("-1.1").is_ok()); | ||||||
|  |     assert!(Parser::new().parse(".1").is_ok()); | ||||||
|  |     assert!(Parser::new().parse("-.1").is_ok()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn test_float_exps() { | ||||||
|  |     let parser = crate::literals::FloatParser::new(); | ||||||
|  |  | ||||||
|  |     let valid_float_exps: Vec<&str> = vec![ | ||||||
|  |         "1e1", "-1e1", "1e-1", "-1e-1", "1.1e1", "1.1e-1", "-1.1e1", "-1.1e-1", ".1e1", "-.1e1", | ||||||
|  |         "-.1e-1", "1E1", "-1E1", "1E-1", "-1E-1", "1.1E1", "1.1E-1", "-1.1E1", "-1.1E-1", ".1E1", | ||||||
|  |         "-.1E1", "-.1E-1", | ||||||
|  |     ]; | ||||||
|  |  | ||||||
|  |     let invalid_float_exps: Vec<&str> = vec!["AAAAAAAAAAAAAAA", "1.e1", "1e1.1", "1.1e1.1", "-1e1.1", "1e-1.1"]; | ||||||
|  |  | ||||||
|  |     assert!( | ||||||
|  |         valid_float_exps | ||||||
|  |             .into_iter() | ||||||
|  |             .all(|s| parser.parse(s).is_ok()) | ||||||
|  |     ); | ||||||
|  |     assert!(invalid_float_exps | ||||||
|  |         .into_iter() | ||||||
|  |         .all(|s| parser.parse(s).is_err())); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,57 +1,2 @@ | |||||||
| #[cfg(test)] | mod literals; | ||||||
| mod test { | mod expressions; | ||||||
|     use crate::grammar; |  | ||||||
|     use grammar::AtomParser as Parser; |  | ||||||
|     #[test] |  | ||||||
|     fn int_literals() { |  | ||||||
|         assert!(Parser::new().parse("22").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(22)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("((22))").is_ok()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn test_float_dots() { |  | ||||||
|         assert!(Parser::new().parse("1.1").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("-1.1").is_ok()); |  | ||||||
|         assert!(Parser::new().parse(".1").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("-.1").is_ok()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     #[test] |  | ||||||
|     fn test_float_exps() { |  | ||||||
|         assert!(Parser::new().parse("(1e1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1e1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1e-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1e-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1E1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1E1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1E-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1E-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1.1e1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1.1e1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1.1e-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1.1e-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1.1E1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1.1E1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1.1E-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1.1E-1)").is_ok()); |  | ||||||
|  |  | ||||||
|         assert!(Parser::new().parse("(1.0e1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-0.1e1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1.0e-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1.0e-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1.E1)").is_err()); |  | ||||||
|         assert!(Parser::new().parse("(-1E1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1E-10)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1E-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1.1e1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1.1e1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1.1e-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1.1e-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1.1E1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1.1E1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(1.1E-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("(-1.1E-1)").is_ok()); |  | ||||||
|         assert!(Parser::new().parse("FOOBAR").is_err()); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user