feat(tazjin/rlox): Add initial Pratt parser table lookup
Change-Id: I1b894d2f84d23ddddcd1bb8794f771512b7d677e Reviewed-on: https://cl.tvl.fyi/c/depot/+/2560 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
This commit is contained in:
parent
d2f24c925d
commit
7778a58f8d
1 changed files with 67 additions and 9 deletions
|
@ -33,6 +33,28 @@ enum Precedence {
|
|||
Primary,
|
||||
}
|
||||
|
||||
type ParseFn<T> = fn(&mut Compiler<T>) -> LoxResult<()>;
|
||||
|
||||
struct ParseRule<T: Iterator<Item = Token>> {
|
||||
prefix: Option<ParseFn<T>>,
|
||||
infix: Option<ParseFn<T>>,
|
||||
precedence: Precedence,
|
||||
}
|
||||
|
||||
impl<T: Iterator<Item = Token>> ParseRule<T> {
|
||||
fn new(
|
||||
prefix: Option<ParseFn<T>>,
|
||||
infix: Option<ParseFn<T>>,
|
||||
precedence: Precedence,
|
||||
) -> Self {
|
||||
ParseRule {
|
||||
prefix,
|
||||
infix,
|
||||
precedence,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Precedence {
|
||||
// Return the next highest precedence, if there is one.
|
||||
fn next(&self) -> Self {
|
||||
|
@ -54,6 +76,38 @@ impl Precedence {
|
|||
}
|
||||
}
|
||||
|
||||
fn rule_for<T: Iterator<Item = Token>>(token: &TokenKind) -> ParseRule<T> {
|
||||
match token {
|
||||
TokenKind::LeftParen => {
|
||||
ParseRule::new(Some(Compiler::grouping), None, Precedence::None)
|
||||
}
|
||||
|
||||
TokenKind::Minus => ParseRule::new(
|
||||
Some(Compiler::unary),
|
||||
Some(Compiler::binary),
|
||||
Precedence::Term,
|
||||
),
|
||||
|
||||
TokenKind::Plus => {
|
||||
ParseRule::new(None, Some(Compiler::binary), Precedence::Term)
|
||||
}
|
||||
|
||||
TokenKind::Slash => {
|
||||
ParseRule::new(None, Some(Compiler::binary), Precedence::Factor)
|
||||
}
|
||||
|
||||
TokenKind::Star => {
|
||||
ParseRule::new(None, Some(Compiler::binary), Precedence::Factor)
|
||||
}
|
||||
|
||||
TokenKind::Number(_) => {
|
||||
ParseRule::new(Some(Compiler::number), None, Precedence::None)
|
||||
}
|
||||
|
||||
_ => ParseRule::new(None, None, Precedence::None),
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Iterator<Item = Token>> Compiler<T> {
|
||||
fn compile(&mut self) -> LoxResult<()> {
|
||||
self.advance();
|
||||
|
@ -77,11 +131,12 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
|||
|
||||
// TODO(tazjin): Assumption is that we have access to the previous
|
||||
// token wherever this ends up invoked. True?
|
||||
fn number(&mut self, num: f64) {
|
||||
fn number(&mut self) -> LoxResult<()> {
|
||||
let num = unimplemented!("get out of previous()");
|
||||
self.emit_constant(num);
|
||||
}
|
||||
|
||||
fn grouping(&mut self, num: f64) -> LoxResult<()> {
|
||||
fn grouping(&mut self) -> LoxResult<()> {
|
||||
self.expression()?;
|
||||
self.consume(
|
||||
&TokenKind::RightParen,
|
||||
|
@ -110,8 +165,8 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
|||
let operator = self.previous().kind.clone();
|
||||
|
||||
// Compile the right operand
|
||||
let rule = self.get_rule(&operator);
|
||||
self.parse_precedence(unimplemented!("rule.precendece.next()"))?;
|
||||
let rule: ParseRule<T> = rule_for(&operator);
|
||||
self.parse_precedence(rule.precedence)?;
|
||||
|
||||
// Emit operator instruction
|
||||
match operator {
|
||||
|
@ -125,12 +180,15 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
fn get_rule(&mut self, op: &TokenKind) -> usize {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn parse_precedence(&mut self, precedence: Precedence) -> LoxResult<()> {
|
||||
unimplemented!("what goes here?")
|
||||
self.advance();
|
||||
let rule: ParseRule<T> = rule_for(&self.previous().kind);
|
||||
|
||||
if let Some(func) = rule.prefix {
|
||||
func(self)?;
|
||||
}
|
||||
|
||||
unimplemented!("expect expression?")
|
||||
}
|
||||
|
||||
fn consume(
|
||||
|
|
Loading…
Reference in a new issue