diff --git a/compiler/src/parser.rs b/compiler/src/parser.rs index e21e049..7784e09 100644 --- a/compiler/src/parser.rs +++ b/compiler/src/parser.rs @@ -1,4 +1,4 @@ -use crate::expect_type; +use crate::expect_tt; use crate::lexer::Token; pub struct Parser { @@ -10,7 +10,7 @@ pub struct Parser { impl Parser { pub fn new(tokens: Vec) -> Self { Self { - ast: Node::Scope { + ast: Node::Block { children: Vec::new(), }, idx: 0, @@ -19,13 +19,17 @@ impl Parser { } pub fn parse(&mut self) -> Result { + self.parse_block() + } + + fn parse_block(&mut self) -> Result { let mut statements = Vec::new(); - while let Some(_) = self.peek_next() { + while self.peek_next().is_ok() { statements.push(self.parse_statement()?); } - Ok(Node::Scope { + Ok(Node::Block { children: statements, }) } @@ -35,11 +39,11 @@ impl Parser { let left = if let Ok(typed_var) = self.parse_typed_var() { Box::new(typed_var) } else { - let tok = expect_type!(self.next()?, Identifier)?; + let tok = expect_tt!(self.next()?, Identifier)?; Box::new(Node::Terminal { value: tok }) }; - let _ = expect_type!(self.next()?, Assign)?; + let _ = expect_tt!(self.next()?, Assign)?; let right = Box::new(self.parse_expression()?); @@ -47,17 +51,144 @@ impl Parser { } fn parse_typed_var(&mut self) -> Result { - let name = expect_type!(self.next()?, Identifier)?; - let _ = expect_type!(self.next()?, Colon)?; - let type_ = expect_type!(self.next()?, Identifier)?; + let name = expect_tt!(self.next()?, Identifier)?; + let _ = expect_tt!(self.next()?, Colon)?; + let type_ = expect_tt!(self.next()?, Identifier)?; Ok(Node::TypedVar { name, type_ }) } fn parse_expression(&mut self) -> Result { + if expect_tt!(self.peek_next()?, Pipe).is_ok() { + return self.parse_func(); + } + + if expect_tt!(self.peek_next()?, If).is_ok() { + return self.parse_if(); + } + + if expect_tt!(self.peek_next()?, Loop).is_ok() { + return self.parse_loop(); + } + + if expect_tt!(self.peek_next()?, Identifier, String, Number).is_ok() { + let left = Node::Terminal { + value: self.next()?, + }; + + if expect_tt!( + self.next()?, + Plus, + Minus, + Star, + Slash, + EqualEqual, + BangEqual, + Less, + LessEqual, + Greater, + GreaterEqual + ) + .is_err() + { + return Ok(left); + } + + let operator = self.next()?; + let right = Box::new(self.parse_expression()?); + + return Ok(Node::BinaryOp { + left: Box::new(left), + op: operator, + right, + }); + } + Err(CompileError::Generic) } + fn parse_func(&mut self) -> Result { + // left arg delimiter + let _ = expect_tt!(self.next()?, Pipe)?; + + // parse args + let mut args = Vec::new(); + + while expect_tt!(self.peek_next()?, Identifier).is_ok() { + // add a typed var + let arg = self.parse_typed_var()?; + args.push(arg); + } + + // right arg delimiter + let _ = expect_tt!(self.next()?, Pipe)?; + + // ensure we have an open brace + let _ = expect_tt!(self.next()?, LeftBrace)?; + + // parse the body + let body = Box::new(self.parse_block()?); + + // ensure we have a close brace + let _ = expect_tt!(self.next()?, RightBrace)?; + + Ok(Node::FunctionDef { params: args, body }) + } + + fn parse_loop(&mut self) -> Result { + let _ = expect_tt!(self.next()?, Loop)?; + + // ensure we have an open brace + let _ = expect_tt!(self.next()?, LeftBrace)?; + + // parse the body + let body = Box::new(self.parse_block()?); + + // ensure we have a close brace + let _ = expect_tt!(self.next()?, RightBrace)?; + + Ok(Node::Loop { body }) + } + + fn parse_if(&mut self) -> Result { + let _ = expect_tt!(self.next()?, If)?; + + // parse condition (expr) + let condition = Box::new(self.parse_expression()?); + + // ensure we have an open brace + let _ = expect_tt!(self.next()?, LeftBrace)?; + + // parse the "then" branch (expr/statement) + let then_branch = Box::new(self.parse_expression()?); + + // ensure we have a close brace + let _ = expect_tt!(self.next()?, RightBrace)?; + + // if there is an else branch, we include it in the statement + let else_branch = self.parse_else()?.map(Box::new); + + Ok(Node::If { + condition, + then_branch, + else_branch, + }) + } + + fn parse_else(&mut self) -> Result, CompileError> { + // if there is no else branch, return None. + if expect_tt!(self.peek_next()?, Else).is_err() { + return Ok(None); + } + let _ = self.next()?; + + if expect_tt!(self.peek_next()?, If).is_ok() { + Ok(Some(self.parse_if()?)) + } else { + Ok(Some(self.parse_expression()?)) + } + } + fn next(&mut self) -> Result { if self.idx >= self.tokens.len() { return Err(CompileError::UnexpectedEOF); @@ -69,53 +200,54 @@ impl Parser { Ok(token) } - fn peek_next(&mut self) -> Option { + fn peek_next(&mut self) -> Result { if self.idx >= self.tokens.len() { - return None; + return Err(CompileError::UnexpectedEOF); } - Some(self.tokens[self.idx].clone()) + Ok(self.tokens[self.idx].clone()) } } - #[derive(Debug, Clone, PartialEq)] pub enum Node { - Scope { - children: Vec, - }, - Terminal { - value: Token, - }, - UnaryOp { - op: Token, - right: Box, - }, + /// A scope, which is a list of child nodes that are evaluated in order. + Block { children: Vec }, + + /// A leaf node with a value. + Terminal { value: Token }, + + /// A unary operator with a right operand. + UnaryOp { op: Token, right: Box }, + + /// A binary operator with a left and right operand. BinaryOp { left: Box, op: Token, right: Box, }, - Statement { - left: Box, - right: Box, - }, + + /// A statement, consisting of a value to assign to, and an expression. + Statement { left: Box, right: Box }, + + /// An if expression, which evaluates to either the then branch or the else branch. If { condition: Box, then_branch: Box, else_branch: Option>, }, - FunctionDef { - params: Vec, - body: Box, - }, - TypedVar { - name: Token, - type_: Token, - }, - TypeDef { - name: Token, - fields: Vec, - }, + + /// A loop expression, which evaluates to the last value of the loop. + /// a loop can be exited with the break keyword. + Loop { body: Box }, + + /// A function definition. ``` | param: type .. | -> ret_type { body }``` + FunctionDef { params: Vec, body: Box }, + + /// A typed variable definition: ```val: Type``` + TypedVar { name: Token, type_: Token }, + + /// A type definition, which is a list of fields. ```type MyType { field: Type }``` + TypeDef { name: Token, fields: Vec }, } #[derive(Debug)] @@ -126,16 +258,44 @@ pub enum CompileError { } #[macro_export] -macro_rules! expect_type { +macro_rules! expect_tt { ($token:expr, $($variant:ident),+) => {{ - match $token.tt() { + let tt = $token.tt().to_string(); + + println!("CASE"); + println!("TOK {:?}", $token); + println!("TT {}", tt); + + let mut vs = String::new(); + $( + let s = stringify!($variant); + vs.push_str(s); + vs.push_str("|"); + )+ + + match tt.as_str() { $( stringify!($variant) => Ok($token.clone()), )+ _ => { - // return an expected token error + println!("EXPECTED!! {} [{}]", tt, vs); let expected = format!("[{}]", vec![$(stringify!($variant)),+].join(" | ")); - + Err(CompileError::ExpectedToken { + expected, + found: $token.clone(), + }) + } + } + }}; +} + +#[macro_export] +macro_rules! expect_value { + ($token:expr, $variant:expr) => {{ + match $token { + $variant(x) => Ok(x), + _ => { + let expected = format!("[{}]") Err(CompileError::ExpectedToken { expected, found: $token.clone(),