Skip to content

Commit

Permalink
Add some parsing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vhiribarren committed Mar 17, 2023
1 parent 29ecfc1 commit cec8bbd
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 8 deletions.
16 changes: 8 additions & 8 deletions src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub enum TopAST {
Function(FunctionAST),
Prototype(PrototypeAST),
}

#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub enum ExprAST {
NumberExpr(NumberExprAST),
VariableExpr(VariableExprAST),
BinaryExpr(BinaryExprAST),
CallExpr(CallExprAST),
}

#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct NumberExprAST {
pub val: f64,
}

#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct VariableExprAST {
pub name: String,
}

#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct BinaryExprAST {
pub op: char,
pub lhs: Box<ExprAST>,
pub rhs: Box<ExprAST>,
}

#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct CallExprAST {
pub callee: String,
pub args: Vec<ExprAST>,
}

#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct PrototypeAST {
pub name: String,
pub args: Vec<String>,
}

#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct FunctionAST {
pub proto: PrototypeAST,
pub body: ExprAST,
Expand Down
93 changes: 93 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,96 @@ pub fn generate_ast(input: &str) -> Result<Vec<TopAST>> {
let lexer = Lexer::new(input.chars());
Parser::parse(lexer)
}

#[cfg(test)]
mod tests {

use super::*;

#[test]
fn scan_input_1() {
let input = r#"
extern sin(a);
"#;
let ast = generate_ast(input).unwrap();
let result = vec![TopAST::Prototype(PrototypeAST {
name: String::from("sin"),
args: vec![String::from("a")],
})];
assert_eq!(ast, result);
}

#[test]
fn scan_input_2() {
let input = r#"
def foo(x y) x+foo(y, 4.0);
"#;
let ast = generate_ast(input).unwrap();
let result = vec![TopAST::Function(FunctionAST {
proto: PrototypeAST {
name: "foo".to_string(),
args: vec!["x".to_string(), "y".to_string()],
},
body: ExprAST::BinaryExpr(BinaryExprAST {
op: '+',
lhs: Box::new(ExprAST::VariableExpr(VariableExprAST {
name: "x".to_string(),
})),
rhs: Box::new(ExprAST::CallExpr(CallExprAST {
callee: "foo".to_string(),
args: vec![
ExprAST::VariableExpr(VariableExprAST {
name: "y".to_string(),
}),
ExprAST::NumberExpr(NumberExprAST { val: 4.0 }),
],
})),
}),
})];
assert_eq!(ast, result);
}

#[test]
fn scan_input_3() {
let input = r#"
def foo(x y) x+y y;
"#;
let ast = generate_ast(input).unwrap();
let result = vec![
TopAST::Function(FunctionAST {
proto: PrototypeAST {
name: "foo".to_string(),
args: vec!["x".to_string(), "y".to_string()],
},
body: ExprAST::BinaryExpr(BinaryExprAST {
op: '+',
lhs: Box::new(ExprAST::VariableExpr(VariableExprAST {
name: "x".to_string(),
})),
rhs: Box::new(ExprAST::VariableExpr(VariableExprAST {
name: "y".to_string(),
})),
}),
}),
TopAST::Function(FunctionAST {
proto: PrototypeAST {
name: "".to_string(),
args: vec![],
},
body: ExprAST::VariableExpr(VariableExprAST {
name: "y".to_string(),
}),
}),
];
assert_eq!(ast, result);
}

#[test]
fn scan_bad_input_1() {
let input = r#"
def foo(x y) x+y );
"#;
let ast = generate_ast(input);
assert!(ast.is_err());
}
}

0 comments on commit cec8bbd

Please sign in to comment.