mirror of
https://github.com/PaddiM8/kalker.git
synced 2025-01-22 04:58:35 +01:00
Implemented somewhat proper error handling for the interpreter. This involved removing the visitor.
This commit is contained in:
parent
1a56ddac45
commit
41a41629a5
@ -2,15 +2,15 @@ use std::mem;
|
||||
|
||||
use crate::lexer::TokenKind;
|
||||
use crate::parser::{Expr, Stmt, Unit};
|
||||
use crate::prelude::{self};
|
||||
use crate::{symbol_table::SymbolTable, visitor::Visitor};
|
||||
use crate::prelude;
|
||||
use crate::symbol_table::SymbolTable;
|
||||
|
||||
pub struct Interpreter<'a> {
|
||||
pub struct Context<'a> {
|
||||
symbol_table: &'a mut SymbolTable,
|
||||
angle_unit: Unit,
|
||||
}
|
||||
|
||||
impl<'a> Interpreter<'a> {
|
||||
impl<'a> Context<'a> {
|
||||
pub fn new(angle_unit: Unit, symbol_table: &'a mut SymbolTable) -> Self {
|
||||
for constant in prelude::CONSTANTS {
|
||||
symbol_table.insert(
|
||||
@ -22,33 +22,33 @@ impl<'a> Interpreter<'a> {
|
||||
);
|
||||
}
|
||||
|
||||
Interpreter {
|
||||
Context {
|
||||
angle_unit: angle_unit.clone(),
|
||||
symbol_table,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn interpret(&mut self, statements: Vec<Stmt>) -> Option<f64> {
|
||||
pub fn interpret(&mut self, statements: Vec<Stmt>) -> Result<Option<f64>, String> {
|
||||
for (i, stmt) in statements.iter().enumerate() {
|
||||
let value = self.visit_stmt(stmt);
|
||||
let value = eval_stmt(self, stmt);
|
||||
|
||||
if i == statements.len() - 1 {
|
||||
if let Stmt::Expr(_) = stmt {
|
||||
return Some(value);
|
||||
return Ok(Some(value?));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return None;
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
impl TokenKind {
|
||||
fn to_unit(&self) -> Unit {
|
||||
fn to_unit(&self) -> Result<Unit, String> {
|
||||
match self {
|
||||
TokenKind::Deg => Unit::Degrees,
|
||||
TokenKind::Rad => Unit::Radians,
|
||||
_ => panic!("Invalid unit."),
|
||||
TokenKind::Deg => Ok(Unit::Degrees),
|
||||
TokenKind::Rad => Ok(Unit::Radians),
|
||||
_ => Err(String::from("Invalid unit.")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -60,142 +60,145 @@ impl Unit {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Visitor<f64, f64> for Interpreter<'a> {
|
||||
fn visit_stmt(&mut self, stmt: &Stmt) -> f64 {
|
||||
match stmt {
|
||||
Stmt::VarDecl(identifier, _) => self.eval_var_decl_stmt(stmt, identifier),
|
||||
Stmt::FnDecl(_, _, _) => self.eval_fn_decl_stmt(),
|
||||
Stmt::Expr(expr) => self.eval_expr_stmt(&expr),
|
||||
}
|
||||
fn eval_stmt(context: &mut Context, stmt: &Stmt) -> Result<f64, String> {
|
||||
match stmt {
|
||||
Stmt::VarDecl(identifier, _) => eval_var_decl_stmt(context, stmt, identifier),
|
||||
Stmt::FnDecl(_, _, _) => eval_fn_decl_stmt(context),
|
||||
Stmt::Expr(expr) => eval_expr_stmt(context, &expr),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &Expr) -> f64 {
|
||||
match expr {
|
||||
Expr::Binary(left, op, right) => self.eval_binary_expr(&left, op, &right),
|
||||
Expr::Unary(_, expr) => self.eval_unary_expr(expr),
|
||||
Expr::Unit(expr, kind) => self.eval_unit_expr(expr, kind),
|
||||
Expr::Var(identifier) => self.eval_var_expr(identifier),
|
||||
Expr::Literal(value) => self.eval_literal_expr(value),
|
||||
Expr::Group(expr) => self.eval_group_expr(&expr),
|
||||
Expr::FnCall(identifier, expressions) => {
|
||||
self.eval_fn_call_expr(identifier, expressions)
|
||||
}
|
||||
fn eval_var_decl_stmt(context: &mut Context, stmt: &Stmt, identifier: &str) -> Result<f64, String> {
|
||||
context.symbol_table.insert(&identifier, stmt.clone());
|
||||
Ok(0f64)
|
||||
}
|
||||
|
||||
fn eval_fn_decl_stmt(_: &mut Context) -> Result<f64, String> {
|
||||
Ok(0f64) // Nothing needs to happen here, since the parser will already have added the FnDecl's to the symbol table.
|
||||
}
|
||||
|
||||
fn eval_expr_stmt(context: &mut Context, expr: &Expr) -> Result<f64, String> {
|
||||
eval_expr(context, &expr)
|
||||
}
|
||||
|
||||
fn eval_expr(context: &mut Context, expr: &Expr) -> Result<f64, String> {
|
||||
match expr {
|
||||
Expr::Binary(left, op, right) => eval_binary_expr(context, &left, op, &right),
|
||||
Expr::Unary(_, expr) => eval_unary_expr(context, expr),
|
||||
Expr::Unit(expr, kind) => eval_unit_expr(context, expr, kind),
|
||||
Expr::Var(identifier) => eval_var_expr(context, identifier),
|
||||
Expr::Literal(value) => eval_literal_expr(context, value),
|
||||
Expr::Group(expr) => eval_group_expr(context, &expr),
|
||||
Expr::FnCall(identifier, expressions) => {
|
||||
eval_fn_call_expr(context, identifier, expressions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Interpreter<'a> {
|
||||
fn eval_var_decl_stmt(&mut self, stmt: &Stmt, identifier: &str) -> f64 {
|
||||
self.symbol_table.insert(&identifier, stmt.clone());
|
||||
0f64
|
||||
fn eval_binary_expr(
|
||||
context: &mut Context,
|
||||
left: &Expr,
|
||||
op: &TokenKind,
|
||||
right: &Expr,
|
||||
) -> Result<f64, String> {
|
||||
let left = eval_expr(context, &left)?;
|
||||
let right = eval_expr(context, &right)?;
|
||||
|
||||
Ok(match op {
|
||||
TokenKind::Plus => left + right,
|
||||
TokenKind::Minus => left - right,
|
||||
TokenKind::Star => left * right,
|
||||
TokenKind::Slash => left / right,
|
||||
TokenKind::Power => left.powf(right),
|
||||
_ => 0f64,
|
||||
})
|
||||
}
|
||||
|
||||
fn eval_unary_expr(context: &mut Context, expr: &Expr) -> Result<f64, String> {
|
||||
eval_expr(context, &expr).clone()
|
||||
}
|
||||
|
||||
fn eval_unit_expr(context: &mut Context, expr: &Expr, kind: &TokenKind) -> Result<f64, String> {
|
||||
let x = eval_expr(context, &expr);
|
||||
let unit = kind.to_unit()?;
|
||||
|
||||
// Don't do any angle conversions if the defauly angle unit is the same as the unit kind
|
||||
match unit {
|
||||
Unit::Degrees | Unit::Radians => {
|
||||
if context.angle_unit.compare(&unit) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_fn_decl_stmt(&mut self) -> f64 {
|
||||
0f64 // Nothing needs to happen here, since the parser will already have added the FnDecl's to the symbol table.
|
||||
}
|
||||
|
||||
fn eval_expr_stmt(&mut self, expr: &Expr) -> f64 {
|
||||
self.visit_expr(&expr)
|
||||
match unit {
|
||||
Unit::Degrees => Ok(x?.to_radians()),
|
||||
Unit::Radians => Ok(x?.to_degrees()),
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Interpreter<'a> {
|
||||
fn eval_binary_expr(&mut self, left: &Expr, op: &TokenKind, right: &Expr) -> f64 {
|
||||
let left = self.visit_expr(&left);
|
||||
let right = self.visit_expr(&right);
|
||||
fn eval_var_expr(context: &mut Context, identifier: &str) -> Result<f64, String> {
|
||||
let var_decl = context.symbol_table.get(identifier).cloned();
|
||||
match var_decl {
|
||||
Some(Stmt::VarDecl(_, expr)) => eval_expr(context, &expr),
|
||||
_ => Err(String::from("Undefined variable.")),
|
||||
}
|
||||
}
|
||||
|
||||
match op {
|
||||
TokenKind::Plus => left + right,
|
||||
TokenKind::Minus => left - right,
|
||||
TokenKind::Star => left * right,
|
||||
TokenKind::Slash => left / right,
|
||||
TokenKind::Power => left.powf(right),
|
||||
_ => 0f64,
|
||||
fn eval_literal_expr(_: &mut Context, value: &str) -> Result<f64, String> {
|
||||
match value.parse() {
|
||||
Ok(parsed_value) => Ok(parsed_value),
|
||||
Err(_) => Err(String::from("Invalid number literal.")),
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_group_expr(context: &mut Context, expr: &Expr) -> Result<f64, String> {
|
||||
eval_expr(context, expr)
|
||||
}
|
||||
|
||||
fn eval_fn_call_expr(
|
||||
context: &mut Context,
|
||||
identifier: &str,
|
||||
expressions: &Vec<Expr>,
|
||||
) -> Result<f64, String> {
|
||||
let prelude_func = match expressions.len() {
|
||||
1 => {
|
||||
let x = eval_expr(context, &expressions[0])?;
|
||||
prelude::call_unary_func(identifier, x, &context.angle_unit)
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_unary_expr(&mut self, expr: &Expr) -> f64 {
|
||||
self.visit_expr(&expr).clone()
|
||||
}
|
||||
|
||||
fn eval_unit_expr(&mut self, expr: &Expr, kind: &TokenKind) -> f64 {
|
||||
let x = self.visit_expr(&expr);
|
||||
|
||||
// Don't do any angle conversions if the defauly angle unit is the same as the unit kind
|
||||
if (kind.compare(&TokenKind::Deg) || kind.compare(&TokenKind::Rad))
|
||||
&& self.angle_unit.compare(&kind.to_unit())
|
||||
{
|
||||
return x;
|
||||
2 => {
|
||||
let x = eval_expr(context, &expressions[0])?;
|
||||
let y = eval_expr(context, &expressions[1])?;
|
||||
prelude::call_binary_func(identifier, x, y, &context.angle_unit)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
match kind {
|
||||
TokenKind::Deg => x.to_radians(),
|
||||
TokenKind::Rad => x.to_degrees(),
|
||||
_ => panic!("Invalid unit."),
|
||||
}
|
||||
if let Some(result) = prelude_func {
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
fn eval_var_expr(&mut self, identifier: &str) -> f64 {
|
||||
let value = self
|
||||
.symbol_table
|
||||
.get(identifier)
|
||||
.expect("Undefined variable.")
|
||||
.clone();
|
||||
if let Stmt::VarDecl(_, expr) = value {
|
||||
return self.visit_expr(&expr);
|
||||
}
|
||||
let stmt_definition = context
|
||||
.symbol_table
|
||||
.get(&format!("{}()", identifier))
|
||||
.cloned();
|
||||
|
||||
panic!("Unknown error.");
|
||||
}
|
||||
|
||||
fn eval_literal_expr(&mut self, value: &str) -> f64 {
|
||||
value.parse().unwrap()
|
||||
}
|
||||
|
||||
fn eval_group_expr(&mut self, expr: &Expr) -> f64 {
|
||||
self.visit_expr(expr)
|
||||
}
|
||||
|
||||
fn eval_fn_call_expr(&mut self, identifier: &str, expressions: &Vec<Expr>) -> f64 {
|
||||
let prelude_func = match expressions.len() {
|
||||
1 => {
|
||||
let x = self.visit_expr(&expressions[0]);
|
||||
prelude::call_unary_func(identifier, x, &self.angle_unit)
|
||||
}
|
||||
2 => {
|
||||
let x = self.visit_expr(&expressions[0]);
|
||||
let y = self.visit_expr(&expressions[1]);
|
||||
prelude::call_binary_func(identifier, x, y, &self.angle_unit)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(result) = prelude_func {
|
||||
return result;
|
||||
}
|
||||
|
||||
let stmt = self
|
||||
.symbol_table
|
||||
.get(&format!("{}()", identifier))
|
||||
.expect("Undefined function")
|
||||
.clone();
|
||||
|
||||
if let Stmt::FnDecl(_, arguments, fn_body) = stmt {
|
||||
match stmt_definition {
|
||||
Some(Stmt::FnDecl(_, arguments, fn_body)) => {
|
||||
if arguments.len() != expressions.len() {
|
||||
panic!("Incorrect amount of arguments.");
|
||||
return Err(String::from("Incorrect amount of arguments."));
|
||||
}
|
||||
|
||||
// Initialise the arguments as their own variables.
|
||||
for (i, argument) in arguments.iter().enumerate() {
|
||||
self.visit_stmt(&Stmt::VarDecl(
|
||||
argument.clone(),
|
||||
Box::new(expressions[i].clone()),
|
||||
));
|
||||
eval_stmt(
|
||||
context,
|
||||
&Stmt::VarDecl(argument.clone(), Box::new(expressions[i].clone())),
|
||||
)?;
|
||||
}
|
||||
|
||||
return self.visit_expr(&*fn_body);
|
||||
return eval_expr(context, &*fn_body);
|
||||
}
|
||||
|
||||
panic!("Unexpected error.");
|
||||
_ => Err(String::from("Undefined function.")),
|
||||
}
|
||||
}
|
||||
|
14
src/main.rs
14
src/main.rs
@ -5,14 +5,13 @@ mod lexer;
|
||||
mod parser;
|
||||
mod prelude;
|
||||
mod symbol_table;
|
||||
mod visitor;
|
||||
use parser::{ParserContext, Unit};
|
||||
use parser::Unit;
|
||||
|
||||
use rustyline::error::ReadlineError;
|
||||
use rustyline::Editor;
|
||||
|
||||
fn main() {
|
||||
let mut parser = ParserContext::new();
|
||||
let mut parser = parser::Context::new();
|
||||
|
||||
// Command line argument input, execute it and exit.
|
||||
if let Some(expr) = env::args().skip(1).next() {
|
||||
@ -37,7 +36,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
fn eval_repl(parser: &mut ParserContext, input: &str) {
|
||||
fn eval_repl(parser: &mut parser::Context, input: &str) {
|
||||
match input {
|
||||
"" => eprint!(""),
|
||||
"clear" => print!("\x1B[2J"),
|
||||
@ -46,10 +45,11 @@ fn eval_repl(parser: &mut ParserContext, input: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
fn eval(parser: &mut ParserContext, input: &str) {
|
||||
fn eval(parser: &mut parser::Context, input: &str) {
|
||||
match parser::parse(parser, input, get_angle_unit()) {
|
||||
Ok(result) => println!("{}", result),
|
||||
Err(_) => println!("Invalid expression"),
|
||||
Ok(Some(result)) => println!("{}", result),
|
||||
Ok(None) => print!(""),
|
||||
Err(err) => println!("{}", err),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::mem;
|
||||
|
||||
use crate::{
|
||||
interpreter::Interpreter,
|
||||
interpreter,
|
||||
lexer::{Lexer, Token, TokenKind},
|
||||
symbol_table::SymbolTable,
|
||||
};
|
||||
@ -30,7 +30,7 @@ pub enum Unit {
|
||||
Degrees,
|
||||
}
|
||||
|
||||
pub struct ParserContext {
|
||||
pub struct Context {
|
||||
//angle_unit: Unit,
|
||||
tokens: Vec<Token>,
|
||||
pos: usize,
|
||||
@ -50,9 +50,9 @@ impl TokenKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl ParserContext {
|
||||
impl Context {
|
||||
pub fn new() -> Self {
|
||||
ParserContext {
|
||||
Context {
|
||||
tokens: Vec::new(),
|
||||
pos: 0,
|
||||
symbol_table: SymbolTable::new(),
|
||||
@ -60,19 +60,20 @@ impl ParserContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(context: &mut ParserContext, input: &str, angle_unit: Unit) -> Result<f64, String> {
|
||||
pub fn parse(context: &mut Context, input: &str, angle_unit: Unit) -> Result<Option<f64>, String> {
|
||||
context.tokens = Lexer::lex(input);
|
||||
context.pos = 0;
|
||||
|
||||
let mut statements: Vec<Stmt> = Vec::new();
|
||||
while !is_at_end(context) {
|
||||
statements.push(parse_stmt(context)?);
|
||||
}
|
||||
|
||||
let mut interpreter = Interpreter::new(angle_unit, &mut context.symbol_table);
|
||||
Ok(interpreter.interpret(statements).unwrap())
|
||||
let mut interpreter = interpreter::Context::new(angle_unit, &mut context.symbol_table);
|
||||
interpreter.interpret(statements)
|
||||
}
|
||||
|
||||
fn parse_stmt(context: &mut ParserContext) -> Result<Stmt, String> {
|
||||
fn parse_stmt(context: &mut Context) -> Result<Stmt, String> {
|
||||
if match_token(context, TokenKind::Identifier) {
|
||||
return Ok(match peek_next(context).kind {
|
||||
TokenKind::Equals => parse_var_decl_stmt(context)?,
|
||||
@ -84,7 +85,7 @@ fn parse_stmt(context: &mut ParserContext) -> Result<Stmt, String> {
|
||||
Ok(Stmt::Expr(Box::new(parse_expr(context)?)))
|
||||
}
|
||||
|
||||
fn parse_identifier_stmt(context: &mut ParserContext) -> Result<Stmt, String> {
|
||||
fn parse_identifier_stmt(context: &mut Context) -> Result<Stmt, String> {
|
||||
let began_at = context.pos;
|
||||
let primary = parse_primary(context)?; // Since function declarations and function calls look the same at first, simply parse a "function call", and re-use the data.
|
||||
|
||||
@ -126,7 +127,7 @@ fn parse_identifier_stmt(context: &mut ParserContext) -> Result<Stmt, String> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_var_decl_stmt(context: &mut ParserContext) -> Result<Stmt, String> {
|
||||
fn parse_var_decl_stmt(context: &mut Context) -> Result<Stmt, String> {
|
||||
let identifier = advance(context).clone();
|
||||
advance(context); // Equal sign
|
||||
let expr = parse_expr(context)?;
|
||||
@ -134,11 +135,11 @@ fn parse_var_decl_stmt(context: &mut ParserContext) -> Result<Stmt, String> {
|
||||
Ok(Stmt::VarDecl(identifier.value, Box::new(expr)))
|
||||
}
|
||||
|
||||
fn parse_expr(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
fn parse_expr(context: &mut Context) -> Result<Expr, String> {
|
||||
Ok(parse_sum(context)?)
|
||||
}
|
||||
|
||||
fn parse_sum(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
fn parse_sum(context: &mut Context) -> Result<Expr, String> {
|
||||
let mut left = parse_factor(context)?;
|
||||
|
||||
while match_token(context, TokenKind::Plus) || match_token(context, TokenKind::Minus) {
|
||||
@ -152,7 +153,7 @@ fn parse_sum(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_factor(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
fn parse_factor(context: &mut Context) -> Result<Expr, String> {
|
||||
let mut left = parse_unary(context)?;
|
||||
|
||||
while match_token(context, TokenKind::Star)
|
||||
@ -175,7 +176,7 @@ fn parse_factor(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_unary(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
fn parse_unary(context: &mut Context) -> Result<Expr, String> {
|
||||
if match_token(context, TokenKind::Minus) {
|
||||
let op = advance(context).kind.clone();
|
||||
let expr = Box::new(parse_unary(context)?);
|
||||
@ -185,7 +186,7 @@ fn parse_unary(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
Ok(parse_exponent(context)?)
|
||||
}
|
||||
|
||||
fn parse_exponent(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
fn parse_exponent(context: &mut Context) -> Result<Expr, String> {
|
||||
let left = parse_primary(context)?;
|
||||
|
||||
if match_token(context, TokenKind::Power) {
|
||||
@ -197,7 +198,7 @@ fn parse_exponent(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
Ok(left)
|
||||
}
|
||||
|
||||
fn parse_primary(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
fn parse_primary(context: &mut Context) -> Result<Expr, String> {
|
||||
let expr = match peek(context).kind {
|
||||
TokenKind::OpenParenthesis => parse_group(context)?,
|
||||
TokenKind::Pipe => parse_abs(context)?,
|
||||
@ -212,7 +213,7 @@ fn parse_primary(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_group(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
fn parse_group(context: &mut Context) -> Result<Expr, String> {
|
||||
advance(context);
|
||||
let group_expr = Expr::Group(Box::new(parse_expr(context)?));
|
||||
consume(context, TokenKind::ClosedParenthesis)?;
|
||||
@ -220,7 +221,7 @@ fn parse_group(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
Ok(group_expr)
|
||||
}
|
||||
|
||||
fn parse_abs(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
fn parse_abs(context: &mut Context) -> Result<Expr, String> {
|
||||
advance(context);
|
||||
let group_expr = Expr::Group(Box::new(parse_expr(context)?));
|
||||
consume(context, TokenKind::Pipe)?;
|
||||
@ -228,7 +229,7 @@ fn parse_abs(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
Ok(Expr::FnCall(String::from("abs"), vec![group_expr]))
|
||||
}
|
||||
|
||||
fn parse_identifier(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
fn parse_identifier(context: &mut Context) -> Result<Expr, String> {
|
||||
let identifier = advance(context).clone();
|
||||
|
||||
// Eg. sqrt64
|
||||
@ -261,19 +262,19 @@ fn parse_identifier(context: &mut ParserContext) -> Result<Expr, String> {
|
||||
Ok(Expr::Var(identifier.value))
|
||||
}
|
||||
|
||||
fn peek<'a>(context: &'a mut ParserContext) -> &'a Token {
|
||||
fn peek<'a>(context: &'a mut Context) -> &'a Token {
|
||||
&context.tokens[context.pos]
|
||||
}
|
||||
|
||||
fn peek_next<'a>(context: &'a mut ParserContext) -> &'a Token {
|
||||
fn peek_next<'a>(context: &'a mut Context) -> &'a Token {
|
||||
&context.tokens[context.pos + 1]
|
||||
}
|
||||
|
||||
fn previous<'a>(context: &'a mut ParserContext) -> &'a Token {
|
||||
fn previous<'a>(context: &'a mut Context) -> &'a Token {
|
||||
&context.tokens[context.pos - 1]
|
||||
}
|
||||
|
||||
fn match_token(context: &mut ParserContext, kind: TokenKind) -> bool {
|
||||
fn match_token(context: &mut Context, kind: TokenKind) -> bool {
|
||||
if is_at_end(context) {
|
||||
return false;
|
||||
}
|
||||
@ -281,12 +282,12 @@ fn match_token(context: &mut ParserContext, kind: TokenKind) -> bool {
|
||||
peek(context).kind.compare(&kind)
|
||||
}
|
||||
|
||||
fn advance<'a>(context: &'a mut ParserContext) -> &'a Token {
|
||||
fn advance<'a>(context: &'a mut Context) -> &'a Token {
|
||||
context.pos += 1;
|
||||
previous(context)
|
||||
}
|
||||
|
||||
fn consume<'a>(context: &'a mut ParserContext, kind: TokenKind) -> Result<&'a Token, String> {
|
||||
fn consume<'a>(context: &'a mut Context, kind: TokenKind) -> Result<&'a Token, String> {
|
||||
if match_token(context, kind) {
|
||||
return Ok(advance(context));
|
||||
}
|
||||
@ -294,6 +295,6 @@ fn consume<'a>(context: &'a mut ParserContext, kind: TokenKind) -> Result<&'a To
|
||||
Err("Unexpected token".into())
|
||||
}
|
||||
|
||||
fn is_at_end(context: &mut ParserContext) -> bool {
|
||||
fn is_at_end(context: &mut Context) -> bool {
|
||||
context.pos >= context.tokens.len() || peek(context).kind.compare(&TokenKind::EOF)
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
use crate::parser::{Expr, Stmt};
|
||||
|
||||
pub trait Visitor<T, U> {
|
||||
fn visit_stmt(&mut self, stmt: &Stmt) -> T;
|
||||
fn visit_expr(&mut self, expr: &Expr) -> U;
|
||||
}
|
Loading…
Reference in New Issue
Block a user