From 96e9dd5f4ae46b5705b8063a43bb8576e1e5b7b0 Mon Sep 17 00:00:00 2001 From: Johannes Stoelp Date: Fri, 10 Sep 2021 23:50:48 +0200 Subject: parser: fix parsing of multi argument prototypes --- src/parser.rs | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/parser.rs b/src/parser.rs index 76f31e4..63f5a77 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -18,11 +18,11 @@ pub enum ExprAST { /// PrototypeAST - This class represents the "prototype" for a function, /// which captures its name, and its argument names (thus implicitly the number /// of arguments the function takes). -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct PrototypeAST(String, Vec); /// FunctionAST - This class represents a function definition itself. -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct FunctionAST(PrototypeAST, ExprAST); /// Parse result with String as Error type (to be compliant with tutorial). @@ -258,6 +258,7 @@ where match self.cur_tok.take() { Some(Token::Identifier(arg)) => args.push(arg), + Some(Token::Char(',')) => {} other => { self.cur_tok = other; break; @@ -325,7 +326,7 @@ fn get_tok_precedence(tok: &Token) -> isize { #[cfg(test)] mod test { - use super::{ExprAST, Parser}; + use super::{ExprAST, FunctionAST, Parser, PrototypeAST}; use crate::lexer::Lexer; fn parser(input: &str) -> Parser { @@ -420,4 +421,39 @@ mod test { assert_eq!(p.parse_expression(), Ok(binexpr_abc)); } + + #[test] + fn parse_prototype() { + let mut p = parser("foo(a,b)"); + + let proto = PrototypeAST("foo".into(), vec!["a".into(), "b".into()]); + + assert_eq!(p.parse_prototype(), Ok(proto)); + } + + #[test] + fn parse_definition() { + let mut p = parser("def bar( arg0 , arg1 ) arg0 + arg1"); + + let proto = PrototypeAST("bar".into(), vec!["arg0".into(), "arg1".into()]); + + let body = ExprAST::Binary( + '+', + Box::new(ExprAST::Variable("arg0".into())), + Box::new(ExprAST::Variable("arg1".into())), + ); + + let func = FunctionAST(proto, body); + + assert_eq!(p.parse_definition(), Ok(func)); + } + + #[test] + fn parse_extern() { + let mut p = parser("extern baz()"); + + let proto = PrototypeAST("baz".into(), vec![]); + + assert_eq!(p.parse_extern(), Ok(proto)); + } } -- cgit v1.2.3