diff options
| -rw-r--r-- | src/main.rs | 167 |
1 files changed, 131 insertions, 36 deletions
diff --git a/src/main.rs b/src/main.rs index 660a835..7736a08 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +use std::fmt; + #[derive(Debug, Clone, PartialEq, Eq)] enum TokenType { Lparen, @@ -21,7 +23,7 @@ struct Blame { char: usize, } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Clone)] struct Token { token: TokenType, blame: Blame, @@ -112,7 +114,7 @@ enum Atomic { } enum SimpleType { - Arrow((Box<SimpleType>, Box<SimpleType>)), + Arrow(Box<(SimpleType, SimpleType)>), Atom(Atomic), } @@ -120,7 +122,7 @@ type Identifier = String; struct Binding { name: Identifier, - arg_type: Option<Box<TypeDeclaration>>, // TODO: Gradual typing! + arg_type: Option<TypeDeclaration>, // TODO: Gradual typing! } enum TypeDeclaration { @@ -133,8 +135,10 @@ struct Assignment { computation: Computation, } +struct Arguments(Vec<Binding>); + struct Abstraction { - arguments: Vec<Binding>, + arguments: Arguments, body: Box<Computation>, } @@ -142,6 +146,13 @@ struct Application { apply: Box<(Computation, Computation)>, } +struct Assignments(Vec<Assignment>); + +struct LetStatement { + assignments: Assignments, + body: Box<Computation>, +} + enum Computation { Application(Application), Abstraction(Abstraction), @@ -149,14 +160,70 @@ enum Computation { LetStatement(LetStatement), // TODO: I think we can flatten these to just a long Abstraction } -enum ASTNode { - Binding(Binding), - TypeDeclaration(TypeDeclaration), - Assignment(Assignment), - Abstraction(Abstraction), - Application(Application), - Computation(Computation), - LetStatement(LetStatement), +impl fmt::Display for Arguments { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Arguments(")?; + for v in &self.0 { + write!(f, "\t{}", v)?; + } + write!(f, ")") + } +} + +impl fmt::Display for Assignment { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Assignment({}, {})", self.binding, self.computation) + } +} + +impl fmt::Display for Assignments { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Assignments(")?; + for v in &self.0 { + write!(f, "\t{}", v)?; + } + write!(f, ")") + } +} + +impl fmt::Display for Binding { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Binding({}, {})", self.name, "TYPE TODO") + } +} + +impl fmt::Display for TypeDeclaration { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + TypeDeclaration::BaseType(name) => write!(f, "BaseType({})", name), + TypeDeclaration::Arrow(arrow) => write!(f, "Arrow({}, {})", (**arrow).0, (**arrow).1), + } + } +} + +impl fmt::Display for Computation { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Computation::Identifier(name) => write!(f, "Identifier({})", name), + Computation::Application(application) => write!( + f, + "Application({}, {})", + (*application.apply).0, + (*application.apply).1 + ), + Computation::Abstraction(abstraction) => write!( + f, + "Abstraction({}, {})", + (abstraction.arguments), + (*abstraction.body) + ), + Computation::LetStatement(let_statement) => write!( + f, + "LetStatement({}, {})", + let_statement.assignments, let_statement.body + ), + } + } } struct Parser { @@ -174,7 +241,7 @@ impl Parser { fn peek(&mut self) -> Result<&Token, ParsingFailure> { return self .tokens - .get(self.position + 1) + .get(self.position) .ok_or(ParsingFailure::PastTokens); } @@ -213,7 +280,24 @@ impl Parser { return self.consume_if_match(f, String::from("Unexpected error")); } - fn parse_type_declaration(&mut self) -> Result<TypeDeclaration, ParsingFailure> {} + fn parse_type_declaration(&mut self) -> Result<TypeDeclaration, ParsingFailure> { + self.consume_if_match_nomsg(|it| (*it).token == TokenType::Lparen)?; + let my_type = 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.clone()), + _ => None, + }, + String::from("BWA"), + ); + if let Ok(name) = my_type { + return Ok(TypeDeclaration::BaseType(name as Identifier)); + } + let left = self.parse_type_declaration()?; + self.consume_if_match_nomsg(|it| (*it).token == TokenType::Arrow)?; + let right = self.parse_type_declaration()?; + return Ok(TypeDeclaration::Arrow(Box::new((left, right)))); + } fn parse_binding(&mut self) -> Result<Binding, ParsingFailure> { let name = self.consume_if_and_map( @@ -231,7 +315,7 @@ impl Parser { if let Ok(type_decl) = self.parse_type_declaration() { return Ok(Binding { name, - arg_type: Some(Box::new(type_decl)), + arg_type: Some(type_decl), }); } return Err(ParsingFailure::Blame( @@ -259,15 +343,19 @@ impl Parser { } fn parse_let_statement(&mut self) -> Result<LetStatement, ParsingFailure> { - self.consume_if_match_nomsg(|it| (*it).token == TokenType::Identifier(String::from("let"))); + 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 body = Box::new(self.parse_computation()?); + return Ok(LetStatement { + assignments: Assignments(assignments), + body, + }); } let assignment = self.parse_assignment()?; self.consume_if_match_nomsg(|it| (*it).token == TokenType::Semicolon)?; @@ -279,16 +367,16 @@ impl Parser { 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); + if let Err(_) = self.consume_if_match_nomsg(|it| (*it).token == TokenType::Comma) { + break; + } } + self.consume_if_match_nomsg(|it| (*it).token == TokenType::Rbracket)?; + return Ok(Abstraction { + arguments: Arguments(arguments), + body: Box::new(self.parse_computation()?), + }); } fn parse_application(&mut self) -> Result<Application, ParsingFailure> { @@ -302,13 +390,21 @@ impl Parser { } fn parse_computation(&mut self) -> Result<Computation, ParsingFailure> { - let next = *(self.peek()?); - match next.token { + let next = self.peek()?.clone(); + return match next.token { TokenType::Identifier(identifier) => { - Computation::LetStatement(self.parse_let_statement()?) + if identifier == String::from("let") { + Ok(Computation::LetStatement(self.parse_let_statement()?)) + } else { + Ok(Computation::Identifier(identifier)) + } } - TokenType::Lbrace => Computation::Abstraction(self.parse_abstraction()?), - TokenType::Lparen => Computation::Application(self.parse_application()?), + TokenType::Lbrace => Ok(Computation::Abstraction(self.parse_abstraction()?)), + TokenType::Lparen => Ok(Computation::Application(self.parse_application()?)), + _ => Err(ParsingFailure::Blame( + next.blame, + String::from("Expected application, abstraction, or let statement"), + )), }; } @@ -318,7 +414,6 @@ impl Parser { tokens, }; } - // fn new() -> Parser {} } pub enum StepResult<T> { @@ -429,10 +524,10 @@ mod tests { #[test] fn test_parse() { - let prog = "let Identity: ((Int) -> (Int)) = [a] { a };"; + let prog = "let Identity: ((Int) -> (Int)) = [a] { a }; in Identity"; let tokens = Lexer::analyze(prog); let mut parser = Parser::new(tokens); - let ast = parser.parse().ok(); - ast.unwrap(); + let ast = parser.parse_computation().ok(); + println!("{}", ast.unwrap()); } } |
