mirror of
https://github.com/MorizzG/rlox.git
synced 2025-12-06 04:12:42 +00:00
updated error names and Display
This commit is contained in:
parent
b8741ea3cc
commit
f9fe77f1e2
7 changed files with 164 additions and 81 deletions
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue