mirror of
https://github.com/MorizzG/rlox.git
synced 2025-12-06 04:12:42 +00:00
updated a bunch of stuff
This commit is contained in:
parent
660464638f
commit
67bb5fe8fd
24 changed files with 683 additions and 702 deletions
|
|
@ -6,7 +6,7 @@ use crate::{LoxError, ResolverError};
|
|||
|
||||
/*====================================================================================================================*/
|
||||
|
||||
type ResolverScope = FxHashMap<String, ResolveStatus>;
|
||||
type ResolverScope = FxHashMap<Box<str>, ResolveStatus>;
|
||||
type ResolverFrame = Vec<ResolverScope>;
|
||||
|
||||
/*====================================================================================================================*/
|
||||
|
|
@ -35,11 +35,11 @@ struct Resolver {
|
|||
// local_scopes: Vec<ResolverScope>,
|
||||
frames: Vec<ResolverFrame>,
|
||||
|
||||
closure_vars: FxHashMap<String, usize>,
|
||||
closure_vars: FxHashMap<Box<str>, usize>,
|
||||
}
|
||||
|
||||
impl Resolver {
|
||||
fn new(global_names: impl Iterator<Item = String>) -> Self {
|
||||
fn new(global_names: impl Iterator<Item = Box<str>>) -> Self {
|
||||
let mut global_scope = ResolverScope::default();
|
||||
|
||||
for name in global_names {
|
||||
|
|
@ -76,11 +76,14 @@ impl Resolver {
|
|||
}
|
||||
|
||||
fn pop_frame(&mut self) {
|
||||
self.frames.pop().expect("Tried to pop non-existant ResolverFrame");
|
||||
self.frames
|
||||
.pop()
|
||||
.expect("Tried to pop non-existant ResolverFrame");
|
||||
}
|
||||
|
||||
fn declare(&mut self, name: &str) {
|
||||
let name = name.to_owned();
|
||||
fn declare(&mut self, name: impl Into<Box<str>>) {
|
||||
let name = name.into();
|
||||
|
||||
if let Some(local_scope) = self.local_scopes_mut().last_mut() {
|
||||
local_scope.insert(name, ResolveStatus::Declared);
|
||||
} else {
|
||||
|
|
@ -88,8 +91,9 @@ impl Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
fn define(&mut self, name: &str) {
|
||||
let name = name.to_owned();
|
||||
fn define(&mut self, name: impl Into<Box<str>>) {
|
||||
let name = name.into();
|
||||
|
||||
if let Some(local_scope) = self.local_scopes_mut().last_mut() {
|
||||
local_scope.insert(name, ResolveStatus::Defined);
|
||||
} else {
|
||||
|
|
@ -106,38 +110,36 @@ impl Resolver {
|
|||
}
|
||||
|
||||
fn resolve_var(&mut self, name: &str) -> Result<Expr, ResolverError> {
|
||||
let name = name.to_owned();
|
||||
|
||||
let mut level = 0;
|
||||
|
||||
for scope in self.local_scopes().iter().rev() {
|
||||
if scope.contains_key(&name) {
|
||||
return Ok(Expr::LocalVariable { name, level });
|
||||
if scope.contains_key(name) {
|
||||
return Ok(Expr::local_variable(name, level));
|
||||
}
|
||||
level += 1;
|
||||
}
|
||||
|
||||
for frame in self.frames.iter().rev().skip(1) {
|
||||
for scope in frame.iter().rev() {
|
||||
if scope.contains_key(&name) {
|
||||
if !self.closure_vars.contains_key(&name) {
|
||||
if scope.contains_key(name) {
|
||||
if !self.closure_vars.contains_key(name) {
|
||||
// the level at which the closed-over variable will be collected from
|
||||
// from the perspective of the parameter/closure scope i.e. the outmost of the function
|
||||
self.closure_vars
|
||||
.insert(name.clone(), level - self.local_scopes().len());
|
||||
.insert(name.into(), level - self.local_scopes().len());
|
||||
}
|
||||
return Ok(Expr::LocalVariable {
|
||||
name,
|
||||
// distance from actual variable refernce to parameter/closure scope
|
||||
level: self.local_scopes().len() - 1,
|
||||
});
|
||||
|
||||
// distance from actual variable refernce to parameter/closure scope
|
||||
let level = self.local_scopes().len() - 1;
|
||||
|
||||
return Ok(Expr::local_variable(name, level));
|
||||
}
|
||||
level += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if self.global_scope.contains_key(&name) {
|
||||
return Ok(Expr::GlobalVariable { name });
|
||||
if self.global_scope.contains_key(name) {
|
||||
return Ok(Expr::global_variable(name));
|
||||
}
|
||||
|
||||
if name == "this" {
|
||||
|
|
@ -145,6 +147,7 @@ impl Resolver {
|
|||
} else if name == "super" {
|
||||
Err(ResolverError::SuperOutsideMethod)
|
||||
} else {
|
||||
let name = name.into();
|
||||
Err(ResolverError::UnresolvableVariable { name })
|
||||
}
|
||||
}
|
||||
|
|
@ -170,9 +173,9 @@ impl Resolver {
|
|||
Ok(())
|
||||
}
|
||||
Stmt::VarDecl { name, initializer } => {
|
||||
self.declare(name);
|
||||
self.declare(name.clone());
|
||||
self.resolve_expr(initializer)?;
|
||||
self.define(name);
|
||||
self.define(name.clone());
|
||||
Ok(())
|
||||
}
|
||||
Stmt::Block { statements } => {
|
||||
|
|
@ -244,7 +247,11 @@ impl Resolver {
|
|||
self.resolve_expr(target)?;
|
||||
Ok(())
|
||||
}
|
||||
Expr::Set { target, name: _, value } => {
|
||||
Expr::Set {
|
||||
target,
|
||||
name: _,
|
||||
value,
|
||||
} => {
|
||||
self.resolve_expr(target)?;
|
||||
self.resolve_expr(value)?;
|
||||
Ok(())
|
||||
|
|
@ -259,12 +266,12 @@ impl Resolver {
|
|||
|
||||
self.push_frame();
|
||||
|
||||
self.declare(name);
|
||||
self.define(name);
|
||||
self.declare(name.clone());
|
||||
self.define(name.clone());
|
||||
|
||||
for param_name in param_names.iter() {
|
||||
self.declare(param_name);
|
||||
self.define(param_name);
|
||||
self.declare(param_name.clone());
|
||||
self.define(param_name.clone());
|
||||
}
|
||||
|
||||
self.resolve_stmt(body)?;
|
||||
|
|
@ -284,13 +291,13 @@ impl Resolver {
|
|||
name,
|
||||
methods,
|
||||
} => {
|
||||
self.declare(name);
|
||||
self.declare(name.clone());
|
||||
|
||||
if let Some(superclass) = superclass {
|
||||
self.resolve_expr(superclass)?;
|
||||
}
|
||||
|
||||
self.define(name);
|
||||
self.define(name.clone());
|
||||
|
||||
// this is the scope "this" is defined in
|
||||
self.enter_scope();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue