aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJohannes Stoelp <johannes.stoelp@gmail.com>2021-09-10 23:50:48 +0200
committerJohannes Stoelp <johannes.stoelp@gmail.com>2021-09-10 23:50:48 +0200
commit96e9dd5f4ae46b5705b8063a43bb8576e1e5b7b0 (patch)
treeb2cf7b460717fa281d3757af8fd8456e944a57d3
parent92d71da8e55422a4f008510d5bb6f7e09d25d5f8 (diff)
downloadllvm-kaleidoscope-rs-chapter2.tar.gz
llvm-kaleidoscope-rs-chapter2.zip
parser: fix parsing of multi argument prototypeschapter2
-rw-r--r--src/parser.rs42
1 files changed, 39 insertions, 3 deletions
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<String>);
/// 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<std::str::Chars> {
@@ -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));
+ }
}