about summary refs log tree commit diff
path: root/users/tazjin/rlox/src
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2020-12-06T14·28+0100
committertazjin <mail@tazj.in>2020-12-06T14·30+0000
commit4812fc2ee64536502093da04ea8a0efe616ffb26 (patch)
treef3ab8b51912b47c59398e66e485afcf7788e22f2 /users/tazjin/rlox/src
parent28002fcea50c028bcd136f321d3bbad6f141b212 (diff)
feat(tazjin/rlox): Implement parsing of parenthesised expressions r/1989
Change-Id: I0e6bd71fd787b719104ef93fc52df4090dc415b9
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2234
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
Diffstat (limited to 'users/tazjin/rlox/src')
-rw-r--r--users/tazjin/rlox/src/errors.rs1
-rw-r--r--users/tazjin/rlox/src/parser.rs16
2 files changed, 16 insertions, 1 deletions
diff --git a/users/tazjin/rlox/src/errors.rs b/users/tazjin/rlox/src/errors.rs
index bab3f4667a74..6bd922bc6c5e 100644
--- a/users/tazjin/rlox/src/errors.rs
+++ b/users/tazjin/rlox/src/errors.rs
@@ -2,6 +2,7 @@
 pub enum ErrorKind {
     UnexpectedChar(char),
     UnterminatedString,
+    UnmatchedParens,
 }
 
 #[derive(Debug)]
diff --git a/users/tazjin/rlox/src/parser.rs b/users/tazjin/rlox/src/parser.rs
index 62a8b5fe4d47..e7266c2352b4 100644
--- a/users/tazjin/rlox/src/parser.rs
+++ b/users/tazjin/rlox/src/parser.rs
@@ -118,7 +118,9 @@ impl<'a> Parser<'a> {
             TokenKind::String(string) => Literal::String(string),
 
             TokenKind::LeftParen => {
-                unimplemented!("need error handling to deal with unbalanced parens");
+                let expr = self.expression()?;
+                self.consume(&TokenKind::RightParen, ErrorKind::UnmatchedParens)?;
+                return Ok(Expr::Grouping(Grouping(Box::new(expr))));
             }
 
             // This branch indicates a parser bug, not invalid input.
@@ -168,6 +170,18 @@ impl<'a> Parser<'a> {
         self.tokens[self.current - 1].clone()
     }
 
+    fn consume(&mut self, kind: &TokenKind, err: ErrorKind) -> Result<(), Error> {
+        if self.check_token(kind) {
+            self.advance();
+            return Ok(());
+        }
+
+        Err(Error {
+            line: self.peek().line,
+            kind: err,
+        })
+    }
+
     fn binary_operator(
         &mut self,
         oneof: &[TokenKind],