Write a test for parsing a simple list expression -- it fails right now
This commit is contained in:
parent
a780ef4ae2
commit
8e25c7e521
1 changed files with 39 additions and 7 deletions
|
@ -4,12 +4,22 @@
|
||||||
|
|
||||||
mod nodes;
|
mod nodes;
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use lexer::lex;
|
||||||
use lexer::Lex;
|
use lexer::Lex;
|
||||||
use lexer::Lexer;
|
use lexer::Lexer;
|
||||||
use lexer::Token;
|
use lexer::Token;
|
||||||
use self::nodes::Program;
|
use self::nodes::Program;
|
||||||
use self::nodes::Expression;
|
use self::nodes::Expression;
|
||||||
|
|
||||||
|
type ParseResult = Result<Program, Error>;
|
||||||
|
|
||||||
|
pub fn parse(input: &str) -> ParseResult {
|
||||||
|
let mut parser = Parser::new(lex(input));
|
||||||
|
parser.parse()
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Parser {
|
pub struct Parser {
|
||||||
lexer: Lexer,
|
lexer: Lexer,
|
||||||
}
|
}
|
||||||
|
@ -19,13 +29,13 @@ impl Parser {
|
||||||
Parser { lexer: lexer }
|
Parser { lexer: lexer }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(&mut self) -> Result<Program, Error> {
|
pub fn parse(&mut self) -> ParseResult {
|
||||||
self.parse_program()
|
self.parse_program()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parser {
|
impl Parser {
|
||||||
fn parse_program(&mut self) -> Result<Program, Error> {
|
fn parse_program(&mut self) -> ParseResult {
|
||||||
let mut forms: Vec<Expression> = Vec::new();
|
let mut forms: Vec<Expression> = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
match self.parse_expression() {
|
match self.parse_expression() {
|
||||||
|
@ -36,7 +46,7 @@ impl Parser {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(error) => panic!("PARSE ERROR: error = {}, lex = {:?}", error.desc, error.lex)
|
Err(error) => return Err(error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Program::new(forms))
|
Ok(Program::new(forms))
|
||||||
|
@ -61,22 +71,44 @@ pub struct Error {
|
||||||
desc: String,
|
desc: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "PARSE ERROR: {}\n token = {:?}", self.desc, self.lex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::nodes::*;
|
use super::nodes::*;
|
||||||
use lexer::Lexer;
|
use lexer::Lexer;
|
||||||
|
use lexer::Token;
|
||||||
use types::Boolean;
|
use types::Boolean;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parses_empty_input() {
|
fn parses_empty_input() {
|
||||||
let mut parser = Parser::new(Lexer::new(""));
|
let r = parse("");
|
||||||
assert_eq!(parser.parse().ok().unwrap(), Program::new(vec![Expression::EOF]));
|
assert_eq!(r.unwrap(), Program::new(vec![Expression::EOF]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parses_single_boolean() {
|
fn parses_single_boolean() {
|
||||||
let mut parser = Parser::new(Lexer::new("#t"));
|
let r = parse("#t");
|
||||||
assert_eq!(parser.parse().ok().unwrap(), Program::new(vec![Expression::Atom(Box::new(Boolean::new(true))), Expression::EOF]));
|
assert_eq!(r.unwrap(), Program::new(vec![Expression::Literal(Box::new(Boolean::new(true))), Expression::EOF]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parses_single_expression() {
|
||||||
|
let r = parse("(a)");
|
||||||
|
let list = list("(", vec![Box::new(Expression::Identifier("a".to_string()))], ")");
|
||||||
|
assert_eq!(r.unwrap(), Program::new(vec![list, Expression::EOF]));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn list(left: &str, expr: Vec<Box<Expression>>, right: &str) -> Expression {
|
||||||
|
Expression::List {
|
||||||
|
left: Token::LeftParen(left.to_string()),
|
||||||
|
expr: expr,
|
||||||
|
right: Token::RightParen(right.to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue