diff --git a/src/ast.rs b/src/ast.rs index 1aa3453f..d599c860 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -63,6 +63,11 @@ pub enum StmtKind { args: Vec, body: Block, }, + BfFunctio { + iden: Iden, + tape_len: Option, + code: String, + }, Call { iden: Iden, args: Vec, diff --git a/src/interpret.rs b/src/interpret.rs index 3ae0e9d9..5775f738 100644 --- a/src/interpret.rs +++ b/src/interpret.rs @@ -208,6 +208,7 @@ impl ExecEnv { args: _, body: _, } => todo!(), + StmtKind::BfFunctio { .. } => todo!(), // This is missing from StmtKind after the interpreter // rewrite; presumably, parsing is not yet implemented for // it. ~~Alex diff --git a/src/parser.rs b/src/parser.rs index 19294c33..15190dfe 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -62,6 +62,7 @@ impl<'source> Parser<'source> { self.functio_flow()?, start..self.lexer.span().end, )), + Token::Bff => Ok(Stmt::new(self.bff_flow()?, start..self.lexer.span().end)), Token::Var => Ok(Stmt::new(self.var_flow()?, start..self.lexer.span().end)), Token::Melo => Ok(Stmt::new(self.melo_flow()?, start..self.lexer.span().end)), Token::Loop => Ok(Stmt::new(self.loop_flow()?, start..self.lexer.span().end)), @@ -381,6 +382,55 @@ impl<'source> Parser<'source> { Ok(StmtKind::Functio { iden, args, body }) } + /// Parse BF function declaration + /// + /// `bff $iden $((tapelen))? { ... }` + fn bff_flow(&mut self) -> Result { + let iden = self.get_iden()?; + + let tape_len = match self + .lexer + .next() + .ok_or(Error::unexpected_eof(self.lexer.span().start))? + { + Token::LeftParen => { + let len = Some(self.expr_flow(Token::RightParen)?); + self.require(Token::LeftCurly)?; + len + } + Token::LeftCurly => None, + _ => todo!(), + }; + + let mut code = String::new(); + loop { + code.push_str( + match self + .lexer + .next() + .ok_or(Error::unexpected_eof(self.lexer.span().start))? + { + Token::Plus + | Token::Minus + | Token::Dot + | Token::Comma + | Token::LeftBracket + | Token::RightBracket + | Token::LessThan + | Token::GreaterThan => self.lexer.slice(), + Token::RightCurly => break, + _ => "", + }, + ); + } + + Ok(StmtKind::BfFunctio { + iden, + tape_len, + code, + }) + } + /// Parse functio call flow fn functio_call_flow(&mut self, iden: Iden) -> Result { let mut args = vec![];