Code:
// impl compiler
pub fn get_rule(&mut self, ttype: TokenType) -> ParseRule {
macro_rules! rule {
($prefix:expr, $infix:expr, $prec:expr) => {
ParseRule {
prefix: $prefix,
infix: $infix,
precedence: $prec,
}
};
}
let rules: [ParseRule; 40] = [
rule!(Some(Compiler::grouping), None, Precedence::None), // TOKEN_LEFT_PAREN
rule!(None, None, Precedence::None), // TOKEN_RIGHT_PAREN
rule!(None, None, Precedence::None), // TOKEN_LEFT_BRACE
rule!(None, None, Precedence::None), // TOKEN_RIGHT_BRACE
rule!(None, None, Precedence::None), // TOKEN_COMMA
rule!(None, None, Precedence::None), // TOKEN_DOT
rule!(Some(Compiler::unary), Some(Compiler::binary), Precedence::Term), // TOKEN_MINUS
rule!(None, Some(Compiler::binary), Precedence::Term), // TOKEN_PLUS
rule!(None, None, Precedence::None), // TOKEN_SEMICOLON
rule!(None, Some(Compiler::binary), Precedence::Factor), // TOKEN_SLASH
rule!(None, Some(Compiler::binary), Precedence::Factor), // TOKEN_STAR
rule!(Some(Compiler::number), None, Precedence::None), // TOKEN_NUMBER
// continues
];
if let Some(rule) = rules.get(ttype as usize) {
return *rule;
} else {
return rule!(None, None, Precedence::None);
}
}
// the structs:
struct ParseRule {
prefix: Option<ParseFn>,
infix: Option<ParseFn>,
precedence: Precedence,
}
pub struct Compiler {
current: Option<Token>,
previous: Option<Token>,
compiling_chunk: Option<Chunk>,
had_error: bool,
panic_mode: bool,
scanner: Scanner,
}