updated error names and Display

This commit is contained in:
Moritz Gmeiner 2024-09-01 23:53:04 +02:00
commit f9fe77f1e2
7 changed files with 164 additions and 81 deletions

View file

@ -9,6 +9,8 @@ use crate::{LoxError, ResolverError};
type ResolverScope = FxHashMap<Box<str>, ResolveStatus>;
type ResolverFrame = Vec<ResolverScope>;
type ResolverResult<T> = Result<T, ResolverError>;
/*====================================================================================================================*/
#[derive(Debug, Clone, Copy)]
@ -81,14 +83,21 @@ impl Resolver {
.expect("Tried to pop non-existant ResolverFrame");
}
fn declare(&mut self, name: impl Into<Box<str>>) {
fn declare(&mut self, name: impl Into<Box<str>>) -> ResolverResult<()> {
let name = name.into();
if let Some(local_scope) = self.local_scopes_mut().last_mut() {
if local_scope.get(&name).is_some() {
return Err(ResolverError::LocalMulipleDeclarations { name });
}
local_scope.insert(name, ResolveStatus::Declared);
} else {
// global variables can be declared multiple times
self.global_scope.insert(name, ResolveStatus::Declared);
}
Ok(())
}
fn define(&mut self, name: impl Into<Box<str>>) {
@ -109,7 +118,7 @@ impl Resolver {
}
}
fn resolve_var(&mut self, name: &str) -> Result<Expr, ResolverError> {
fn resolve_var(&mut self, name: &str) -> ResolverResult<Expr> {
let mut level = 0;
for scope in self.local_scopes().iter().rev() {
@ -152,7 +161,7 @@ impl Resolver {
}
}
fn resolve_stmt(&mut self, stmt: &mut Stmt) -> Result<(), ResolverError> {
fn resolve_stmt(&mut self, stmt: &mut Stmt) -> ResolverResult<()> {
match stmt {
Stmt::Print { expr } => self.resolve_expr(expr),
Stmt::IfStmt {
@ -161,29 +170,40 @@ impl Resolver {
else_branch,
} => {
self.resolve_expr(condition)?;
self.resolve_stmt(then_branch)?;
if let Some(else_branch) = else_branch {
self.resolve_stmt(else_branch)?;
}
Ok(())
}
Stmt::While { condition, body } => {
self.resolve_expr(condition)?;
self.resolve_stmt(body)?;
Ok(())
}
Stmt::VarDecl { name, initializer } => {
self.declare(name.clone());
self.declare(name.clone())?;
self.resolve_expr(initializer)?;
self.define(name.clone());
Ok(())
}
Stmt::Block { statements } => {
self.enter_scope();
for statement in statements.iter_mut() {
self.resolve_stmt(statement)?;
}
self.exit_scope();
Ok(())
}
Stmt::ExprStmt { expr } => self.resolve_expr(expr),
@ -192,18 +212,22 @@ impl Resolver {
}
}
fn resolve_expr(&mut self, expr: &mut Expr) -> Result<(), ResolverError> {
fn resolve_expr(&mut self, expr: &mut Expr) -> ResolverResult<()> {
match expr {
Expr::Literal { literal: _ } => Ok(()),
Expr::Unary { op: _, expr } => self.resolve_expr(expr),
Expr::Binary { left, op: _, right } => {
self.resolve_expr(left)?;
self.resolve_expr(right)?;
Ok(())
}
Expr::Logical { left, op: _, right } => {
self.resolve_expr(left)?;
self.resolve_expr(right)?;
Ok(())
}
Expr::Grouping { expr } => self.resolve_expr(expr),
@ -228,6 +252,7 @@ impl Resolver {
self.resolve_expr(value)?;
let target = target.as_mut();
if let Expr::Variable { name } = target {
*target = self.resolve_var(name)?;
} else {
@ -238,13 +263,16 @@ impl Resolver {
}
Expr::Call { callee, args } => {
self.resolve_expr(callee)?;
for arg in args.iter_mut() {
self.resolve_expr(arg)?;
}
Ok(())
}
Expr::Get { target, name: _ } => {
self.resolve_expr(target)?;
Ok(())
}
Expr::Set {
@ -253,7 +281,9 @@ impl Resolver {
value,
} => {
self.resolve_expr(target)?;
self.resolve_expr(value)?;
Ok(())
}
Expr::Function {
@ -266,11 +296,12 @@ impl Resolver {
self.push_frame();
self.declare(name.clone());
self.declare(name.clone())?;
self.define(name.clone());
for param_name in param_names.iter() {
self.declare(param_name.clone());
self.declare(param_name.clone())?;
self.define(param_name.clone());
}
@ -291,7 +322,7 @@ impl Resolver {
name,
methods,
} => {
self.declare(name.clone());
self.declare(name.clone())?;
if let Some(superclass) = superclass {
self.resolve_expr(superclass)?;
@ -301,10 +332,13 @@ impl Resolver {
// this is the scope "this" is defined in
self.enter_scope();
self.declare("this");
// this should never fail! we just made a new scope
self.declare("this").unwrap();
if superclass.is_some() {
self.declare("super");
// this should never fail either! same as `this`
self.declare("super").unwrap();
}
for method in methods.iter_mut() {
@ -325,6 +359,7 @@ impl Resolver {
method: _,
} => {
self.resolve_expr(super_var)?;
self.resolve_expr(this_var)
}
}