diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 173 |
1 files changed, 98 insertions, 75 deletions
diff --git a/src/main.rs b/src/main.rs index 5018b43..660a835 100644 --- a/src/main.rs +++ b/src/main.rs @@ -120,12 +120,12 @@ type Identifier = String; struct Binding { name: Identifier, - arg_type: Option<Box<TypeDeclaration>>, + arg_type: Option<Box<TypeDeclaration>>, // TODO: Gradual typing! } -struct TypeDeclaration { - base_type: Option<Identifier>, - arrow: Option<Box<(TypeDeclaration, TypeDeclaration)>>, +enum TypeDeclaration { + BaseType(Identifier), + Arrow(Box<(TypeDeclaration, TypeDeclaration)>), } struct Assignment { @@ -133,34 +133,26 @@ struct Assignment { computation: Computation, } -struct Arguments { - args_list: Vec<Identifier>, -} - struct Abstraction { - arguments: Arguments, + arguments: Vec<Binding>, body: Box<Computation>, } struct Application { - apply: Option<(Box<Computation>, Box<Computation>)>, -} - -struct Computation { - application: Option<Application>, - abstraction: Option<Abstraction>, - identifier: Option<Identifier>, + apply: Box<(Computation, Computation)>, } -struct LetStatement { - assignments: Vec<Assignment>, +enum Computation { + Application(Application), + Abstraction(Abstraction), + Identifier(Identifier), + LetStatement(LetStatement), // TODO: I think we can flatten these to just a long Abstraction } enum ASTNode { Binding(Binding), TypeDeclaration(TypeDeclaration), Assignment(Assignment), - Arguments(Arguments), Abstraction(Abstraction), Application(Application), Computation(Computation), @@ -179,8 +171,11 @@ enum ParsingFailure { } impl Parser { - fn peek(&mut self) -> Option<&Token> { - return self.tokens.get(self.position + 1); + fn peek(&mut self) -> Result<&Token, ParsingFailure> { + return self + .tokens + .get(self.position + 1) + .ok_or(ParsingFailure::PastTokens); } fn consume_if_and_map<T>( @@ -194,7 +189,7 @@ impl Parser { let val = f(&self.tokens[self.position]); if val.is_some() { self.position += 1; - return Result::Ok(val.unwrap()); //&self.tokens[self.position - 1]); + return Result::Ok(val.unwrap()); } return Result::Err(ParsingFailure::Blame(self.tokens[self.position].blame, msg)); } @@ -221,71 +216,100 @@ impl Parser { fn parse_type_declaration(&mut self) -> Result<TypeDeclaration, ParsingFailure> {} fn parse_binding(&mut self) -> Result<Binding, ParsingFailure> { - return self - .consume_if_and_map( - |it| match ((*it).token).clone() { - // unfortunately, gotta clone to make the borrow checker happy. maybe i'll come back to this :3 - TokenType::Identifier(name) => Some(name), - _ => None, - }, - String::from("Expected identifier"), - ) - .and_then(|name| { - let val = self.consume_if_match_nomsg(|it| (*it).token == TokenType::Colon); - if val.is_ok() { - let blame = val.unwrap().blame; - if let Ok(type_decl) = self.parse_type_declaration() { - return Ok(Binding { - name, - arg_type: Some(Box::new(type_decl)), - }); - } - return Err(ParsingFailure::Blame( - blame, - String::from("Expected type declaration"), - )); - } + let name = self.consume_if_and_map( + |it| match ((*it).token).clone() { + // unfortunately, gotta clone to make the borrow checker happy. maybe i'll come back to this :3 + TokenType::Identifier(name) => Some(name), + _ => None, + }, + String::from("Expected identifier"), + )?; + + let val = self.consume_if_match_nomsg(|it| (*it).token == TokenType::Colon); + if val.is_ok() { + let blame = val.unwrap().blame; + if let Ok(type_decl) = self.parse_type_declaration() { return Ok(Binding { name, - arg_type: None, + arg_type: Some(Box::new(type_decl)), }); - }); + } + return Err(ParsingFailure::Blame( + blame, + String::from("Expected type declaration"), + )); + } + return Ok(Binding { + name, + arg_type: None, + }); } fn parse_assignment(&mut self) -> Result<Assignment, ParsingFailure> { - let binding = self.parse_binding(); - if binding.is_ok() - && let Ok(ok) = self.consume_if_match( - |it| (*it).token == TokenType::Equals, - String::from("Expected equals after binding"), - ) - { - return Ok(Assignment { - binding: binding.unwrap(), - computation: self.parse_computation(), - }); - } - return Err(); - // - // if (self.consume_if_matches(|it| (*it).token == TokenType::Colon)) { - // type_declaration = self.parse_type_declaration(); - // } - // self.consume_if_matches(|it| (*it)) - // //return self.consume_if_matches(|it| match (*it) + let binding = self.parse_binding()?; + let _ = self.consume_if_match( + |it| (*it).token == TokenType::Equals, + String::from("Expected equals after binding"), + )?; + + return Ok(Assignment { + binding, + computation: self.parse_computation()?, + }); } - fn parse_let_statement(&mut self) -> Result<&LetStatement, ParsingFailure> { + fn parse_let_statement(&mut self) -> Result<LetStatement, ParsingFailure> { self.consume_if_match_nomsg(|it| (*it).token == TokenType::Identifier(String::from("let"))); + let mut assignments: Vec<Assignment> = Vec::new(); + loop { + if let Ok(_done) = self.consume_if_match_nomsg(|it| { + (*it).token == TokenType::Identifier(String::from("in")) + }) { + let body = self.parse_computation()?; + + return Ok(LetStatement { assignments }); + } + let assignment = self.parse_assignment()?; + self.consume_if_match_nomsg(|it| (*it).token == TokenType::Semicolon)?; + assignments.push(assignment); + } + } - let assignments: Vec<&Assignment> = Vec::new(); - let assignment = self.parse_assignment(); - self.consume_if_match_nomsg(|it| (*it).token == TokenType::Semicolon); + fn parse_abstraction(&mut self) -> Result<Abstraction, ParsingFailure> { + self.consume_if_match_nomsg(|it| (*it).token == TokenType::Lbracket)?; + let mut arguments: Vec<Binding> = Vec::new(); + loop { + if let Ok(_done) = self.consume_if_match_nomsg(|it| (*it).token == TokenType::Rbracket) + { + return Ok(Abstraction { + arguments, + body: Box::new(self.parse_computation()?), + }); + } + arguments.push(self.parse_binding()?); + self.consume_if_match_nomsg(|it| (*it).token == TokenType::Comma); + } } - fn parse(&mut self) -> Result<ASTNode, ParsingFailure> { - let consume = |args| {}; + fn parse_application(&mut self) -> Result<Application, ParsingFailure> { + self.consume_if_match_nomsg(|it| (*it).token == TokenType::Lparen)?; + let left = self.parse_computation()?; + let right = self.parse_computation()?; + self.consume_if_match_nomsg(|it| (*it).token == TokenType::Rparen)?; + return Ok(Application { + apply: Box::new((left, right)), + }); + } - // let program: LetStatement = self.parseLetStatement(); + fn parse_computation(&mut self) -> Result<Computation, ParsingFailure> { + let next = *(self.peek()?); + match next.token { + TokenType::Identifier(identifier) => { + Computation::LetStatement(self.parse_let_statement()?) + } + TokenType::Lbrace => Computation::Abstraction(self.parse_abstraction()?), + TokenType::Lparen => Computation::Application(self.parse_application()?), + }; } fn new(tokens: Vec<Token>) -> Parser { @@ -293,7 +317,6 @@ impl Parser { position: 0, tokens, }; - } // fn new() -> Parser {} } |
