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 crate::ast::literal::Literal;
|
||||
|
||||
grammar;
|
||||
|
||||
pub Atom: f64 = {
|
||||
<n:Int> => n as f64,
|
||||
Float,
|
||||
"(" <Atom> ")",
|
||||
pub Atom: Literal = {
|
||||
<n:Int> => Literal::Int(n),
|
||||
<f: Float> => Literal::Float(f),
|
||||
"(" <f: Atom> ")" => f,
|
||||
};
|
||||
|
||||
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 StringLiteral: &'input str = <s:"\"[^\"]\""> => s;
|
||||
//pub StringLiteral: &'input str = <s:"\"[^\"]\""> => s;
|
||||
@@ -1,5 +1,11 @@
|
||||
use lalrpop_util::lalrpop_mod;
|
||||
|
||||
mod ast;
|
||||
mod optimising;
|
||||
mod tests;
|
||||
|
||||
lalrpop_mod!(pub literals);
|
||||
lalrpop_mod!(pub expressions);
|
||||
|
||||
fn main() {
|
||||
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 test {
|
||||
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());
|
||||
}
|
||||
}
|
||||
mod literals;
|
||||
mod expressions;
|
||||
|
||||
Reference in New Issue
Block a user