diff options
author | Vincent Ambo <mail@tazj.in> | 2021-02-27T19·51+0200 |
---|---|---|
committer | tazjin <mail@tazj.in> | 2021-02-27T20·19+0000 |
commit | 56f6a6e9f20236cb97d2e6bc2a7819762ecb0fe7 (patch) | |
tree | 0eb60beb7fb0473a0afe95e989963b57f5330056 /users/tazjin | |
parent | 7778a58f8d80147a5b180e0a889c245b47d573a5 (diff) |
feat(tazjin/rlox): Implement parser precedence rules r/2242
Change-Id: Idcf3c84126603086bbf7e8d54773bccb3ae3b5ab Reviewed-on: https://cl.tvl.fyi/c/depot/+/2561 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
Diffstat (limited to 'users/tazjin')
-rw-r--r-- | users/tazjin/rlox/src/bytecode/compiler/mod.rs | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/users/tazjin/rlox/src/bytecode/compiler/mod.rs b/users/tazjin/rlox/src/bytecode/compiler/mod.rs index fab06fe39cf2..58a5c1b98a02 100644 --- a/users/tazjin/rlox/src/bytecode/compiler/mod.rs +++ b/users/tazjin/rlox/src/bytecode/compiler/mod.rs @@ -183,12 +183,26 @@ impl<T: Iterator<Item = Token>> Compiler<T> { fn parse_precedence(&mut self, precedence: Precedence) -> LoxResult<()> { self.advance(); let rule: ParseRule<T> = rule_for(&self.previous().kind); - - if let Some(func) = rule.prefix { - func(self)?; + let prefix_fn = match rule.prefix { + None => unimplemented!("expected expression or something, unclear"), + Some(func) => func, + }; + + prefix_fn(self)?; + + while precedence <= rule_for::<T>(&self.current().kind).precedence { + self.advance(); + match rule_for::<T>(&self.previous().kind).infix { + Some(func) => { + func(self)?; + } + None => { + unreachable!("invalid compiler state: error in parse rules") + } + } } - unimplemented!("expect expression?") + Ok(()) } fn consume( @@ -224,6 +238,12 @@ impl<T: Iterator<Item = Token>> Compiler<T> { .expect("invalid internal compiler state: missing previous token") } + fn current(&self) -> &Token { + self.current + .as_ref() + .expect("invalid internal compiler state: missing current token") + } + fn error_at(&mut self, token: &Token, kind: ErrorKind) { if self.panic { return; |