Rename "Local" to "Name" when referring to variables during compilation

* Variables were previously named "Local"s because they described a
  local variable - however, this is kind of a misnomer because it
  handles globals as well. This has been changed pretty much everywhere
  when appropriate (hopefully).
* Renamed obj/names.rs to obj/reserved.rs, freeing up the "names" module
  for the new Names handle
* Renamed obj/locals.rs to obj/names.rs, see above

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-09-18 13:57:51 -07:00
parent 7228732128
commit 0d6f68216b
14 changed files with 114 additions and 111 deletions

View File

@@ -9,7 +9,7 @@ pub struct CollectLocals<'c> {
} }
// - Python's LEGB methodology seems to be good. Look up variables in this order: // - Python's LEGB methodology seems to be good. Look up variables in this order:
// - Local // - Name
// - Enclosing functions (i.e. inner functions) // - Enclosing functions (i.e. inner functions)
// - Global // - Global
// - Builtin // - Builtin
@@ -35,7 +35,7 @@ impl Visit for CollectLocals<'_> {
fn visit_assign_stmt(&mut self, assign: &AssignStmt) -> Self::Out { DefaultAccept::default_accept(assign, self); } fn visit_assign_stmt(&mut self, assign: &AssignStmt) -> Self::Out { DefaultAccept::default_accept(assign, self); }
fn visit_lhs_expr(&mut self, lhs_expr: &LhsExpr) -> Self::Out { fn visit_lhs_expr(&mut self, lhs_expr: &LhsExpr) -> Self::Out {
match lhs_expr { match lhs_expr {
LhsExpr::Local(name) => { LhsExpr::Name(name) => {
let sym = global_sym(name.to_string()); let sym = global_sym(name.to_string());
self.compile.create_local(sym); self.compile.create_local(sym);
} }

View File

@@ -9,10 +9,10 @@ use std::collections::{BTreeMap, HashMap};
#[derive(Default)] #[derive(Default)]
pub struct Compile { pub struct Compile {
const_data: ConstData, const_data: ConstData,
globals: BTreeMap<Sym, Local>, globals: BTreeMap<Sym, Name>,
locals: Vec<BTreeMap<Sym, Local>>, scope: Vec<BTreeMap<Sym, Name>>,
names: Vec<Sym>, names: Vec<Sym>,
next_local: Local, next_local: Name,
} }
impl Compile { impl Compile {
@@ -54,8 +54,8 @@ impl Compile {
/// ///
/// This will search up the locals stack until the given name is found, ultimately ending with /// This will search up the locals stack until the given name is found, ultimately ending with
/// a global name lookup. /// a global name lookup.
pub fn lookup_scope(&mut self, sym: Sym) -> Option<Local> { pub fn lookup_scope(&mut self, sym: Sym) -> Option<Name> {
self.locals self.scope
.iter() .iter()
.rev() .rev()
.filter_map(|locals| locals.get(&sym)) .filter_map(|locals| locals.get(&sym))
@@ -65,7 +65,7 @@ impl Compile {
} }
/// Looks up a variable name, or creates a global name if it doesn't exist. /// Looks up a variable name, or creates a global name if it doesn't exist.
pub fn lookup_scope_or_create_global(&mut self, sym: Sym) -> Local { pub fn lookup_scope_or_create_global(&mut self, sym: Sym) -> Name {
if let Some(local) = self.lookup_scope(sym) { if let Some(local) = self.lookup_scope(sym) {
local local
} else { } else {
@@ -74,8 +74,8 @@ impl Compile {
} }
/// Creates a new local variable if it does not exist in the current local scope. /// Creates a new local variable if it does not exist in the current local scope.
pub(crate) fn create_local(&mut self, sym: Sym) -> Local { pub(crate) fn create_local(&mut self, sym: Sym) -> Name {
let locals = self.locals.last_mut().expect("scope"); let locals = self.scope.last_mut().expect("scope");
if let Some(local) = locals.get(&sym) { if let Some(local) = locals.get(&sym) {
*local *local
} else { } else {
@@ -90,7 +90,7 @@ impl Compile {
} }
/// Creates a new global variable if it does not exist in the current global scope. /// Creates a new global variable if it does not exist in the current global scope.
pub fn create_global(&mut self, sym: Sym) -> Local { pub fn create_global(&mut self, sym: Sym) -> Name {
if let Some(global) = self.globals.get(&sym) { if let Some(global) = self.globals.get(&sym) {
*global *global
} else { } else {
@@ -105,12 +105,12 @@ impl Compile {
/// Pushes an empty scope layer of local variables. /// Pushes an empty scope layer of local variables.
pub(crate) fn push_scope_layer(&mut self) { pub(crate) fn push_scope_layer(&mut self) {
self.locals.push(Default::default()); self.scope.push(Default::default());
} }
/// Pops a scope layer of local variables, if any are available. /// Pops a scope layer of local variables, if any are available.
pub(crate) fn pop_scope_layer(&mut self) -> Option<BTreeMap<Sym, Local>> { pub(crate) fn pop_scope_layer(&mut self) -> Option<BTreeMap<Sym, Name>> {
self.locals.pop() self.scope.pop()
} }
/// Collects local variables for the given AST body non-recursively. /// Collects local variables for the given AST body non-recursively.

View File

@@ -264,7 +264,7 @@ impl Visit for CompileBody<'_> {
let attr = global_sym(expr.access.to_string()); let attr = global_sym(expr.access.to_string());
thunk.push(Inst::SetAttr(attr)); thunk.push(Inst::SetAttr(attr));
} }
LhsExpr::Local(local_name) => { LhsExpr::Name(local_name) => {
let sym = global_sym(local_name.to_string()); let sym = global_sym(local_name.to_string());
let local = self.compile.lookup_scope_or_create_global(sym); let local = self.compile.lookup_scope_or_create_global(sym);
thunk = Inst::Pop(Some(local)).into(); thunk = Inst::Pop(Some(local)).into();
@@ -349,9 +349,9 @@ impl Visit for CompileBody<'_> {
let thunk = match atom { let thunk = match atom {
Atom::Ident(ident) => { Atom::Ident(ident) => {
let sym = global_sym(ident.to_string()); let sym = global_sym(ident.to_string());
let local = self.compile.lookup_scope_or_create_global(sym); let name = self.compile.lookup_scope_or_create_global(sym);
// get local // get local
Inst::PushLocal(local).into() Inst::LoadName(name).into()
} }
Atom::Sym(sym) => { Atom::Sym(sym) => {
// push symbol // push symbol

View File

@@ -1,4 +1,4 @@
use crate::{obj::{names::*, prelude::*}, vm::{inst::Inst, Vm}}; use crate::{obj::{reserved::*, prelude::*}, vm::{inst::Inst, Vm}};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use shredder::{GcSafeWrapper, Scan}; use shredder::{GcSafeWrapper, Scan};
use std::fmt::{Debug, Formatter, self}; use std::fmt::{Debug, Formatter, self};
@@ -44,7 +44,7 @@ pub struct UserFun {
code: Vec<Inst>, code: Vec<Inst>,
// Safe because this is just an interner that points to symbols, which aren't GC'd // Safe because this is just an interner that points to symbols, which aren't GC'd
#[shredder(unsafe_skip)] #[shredder(unsafe_skip)]
locals: Locals, locals: Names,
} }
impl UserFun { impl UserFun {
@@ -52,7 +52,7 @@ impl UserFun {
&self.code &self.code
} }
pub fn locals(&self) -> &Locals { pub fn locals(&self) -> &Names {
&self.locals &self.locals
} }
} }

View File

@@ -1,6 +0,0 @@
use crate::obj::ObjRef;
use std::collections::BTreeMap;
handle_type!(Local);
pub type Locals = BTreeMap<Local, ObjRef>;

View File

@@ -5,15 +5,15 @@ pub mod attrs;
pub mod fun; pub mod fun;
pub mod int; pub mod int;
pub mod intern; pub mod intern;
pub mod locals;
pub mod names; pub mod names;
pub mod reserved;
pub mod str; pub mod str;
pub mod sym; pub mod sym;
pub mod ty; pub mod ty;
pub mod prelude { pub mod prelude {
pub use crate::obj::{ pub use crate::obj::{
attrs::*, fun::*, int::*, intern::*, locals::*, str::*, sym::*, ty::*, Obj, ObjRef, attrs::*, fun::*, int::*, intern::*, names::*, str::*, sym::*, ty::*, Obj, ObjRef,
}; };
} }

View File

@@ -1,71 +1,6 @@
use crate::obj::sym::{Sym, SymRef, global_sym, global_sym_ref}; use crate::obj::ObjRef;
use once_cell::sync::Lazy; use std::collections::BTreeMap;
macro_rules! name { handle_type!(Name);
($name:ident, $text:expr $(,)?) => {
pub static $name: Lazy<NameInfo> = Lazy::new(|| {
let name = $text;
let sym = global_sym(name.to_string());
NameInfo { name, sym, }
});
}
}
pub struct NameInfo { pub type Names = BTreeMap<Name, ObjRef>;
pub name: &'static str,
pub sym: Sym,
}
impl NameInfo {
pub fn sym_ref(&self) -> SymRef {
global_sym_ref(self.sym)
}
}
//
// Types
//
name!(INT_NAME, "Int");
name!(TY_NAME, "Type");
name!(SYM_NAME, "Sym");
//
// Members
//
name!(TY_MEMBER_NAME, "__type__");
name!(CALL_MEMBER_NAME, "__call__");
name!(NAME_MEMBER_NAME, "__name__");
name!(GET_ATTR_MEMBER_NAME, "__get_attr__");
name!(SET_ATTR_MEMBER_NAME, "__set_attr__");
name!(SELF_MEMBER_NAME, "__self__");
name!(FUNC_MEMBER_NAME, "__func__");
//
// Predefined VM-aware symbols
//
name!(SCOPE_NAME, "__scope__");
//
// Builtin functions
//
//name!(REPR_FUN_NAME, REPR_FUN_SYM, "repr");
//name!(GET_LOCAL_FUN_NAME, GET_LOCAL_FUN_SYM, "get_local");
//name!(SET_LOCAL_FUN_NAME, SET_LOCAL_FUN_SYM, "set_local");
//
// Builtin constants
//
name!(TRUE_NAME, "true");
name!(FALSE_NAME, "false");
name!(NIL_NAME, "nil");
// Operator function names
name!(EQ_EQ_OP_NAME, "__eq__");
name!(LT_OP_NAME, "__lt__");
name!(GT_OP_NAME, "__gt__");
name!(LT_EQ_OP_NAME, "__le__");
name!(GT_EQ_OP_NAME, "__ge__");
name!(PLUS_OP_NAME, "__add__");
name!(MINUS_OP_NAME, "__sub__");
name!(TIMES_OP_NAME, "__mul__");
name!(DIV_OP_NAME, "__div__");

74
src/obj/reserved.rs Normal file
View File

@@ -0,0 +1,74 @@
//! Reserved names for object members.
use crate::obj::sym::{Sym, SymRef, global_sym, global_sym_ref};
use once_cell::sync::Lazy;
macro_rules! name {
($name:ident, $text:expr $(,)?) => {
pub static $name: Lazy<NameInfo> = Lazy::new(|| {
let name = $text;
let sym = global_sym(name.to_string());
NameInfo { name, sym, }
});
}
}
pub struct NameInfo {
pub name: &'static str,
pub sym: Sym,
}
impl NameInfo {
pub fn sym_ref(&self) -> SymRef {
global_sym_ref(self.sym)
}
}
//
// Types
//
name!(INT_NAME, "Int");
name!(TY_NAME, "Type");
name!(SYM_NAME, "Sym");
//
// Members
//
name!(TY_MEMBER_NAME, "__type__");
name!(CALL_MEMBER_NAME, "__call__");
name!(NAME_MEMBER_NAME, "__name__");
name!(GET_ATTR_MEMBER_NAME, "__get_attr__");
name!(SET_ATTR_MEMBER_NAME, "__set_attr__");
name!(SELF_MEMBER_NAME, "__self__");
name!(FUNC_MEMBER_NAME, "__func__");
//
// Predefined VM-aware symbols
//
name!(SCOPE_NAME, "__scope__");
//
// Builtin functions
//
//name!(REPR_FUN_NAME, REPR_FUN_SYM, "repr");
//name!(GET_LOCAL_FUN_NAME, GET_LOCAL_FUN_SYM, "get_local");
//name!(SET_LOCAL_FUN_NAME, SET_LOCAL_FUN_SYM, "set_local");
//
// Builtin constants
//
name!(TRUE_NAME, "true");
name!(FALSE_NAME, "false");
name!(NIL_NAME, "nil");
// Operator function names
name!(EQ_EQ_OP_NAME, "__eq__");
name!(LT_OP_NAME, "__lt__");
name!(GT_OP_NAME, "__gt__");
name!(LT_EQ_OP_NAME, "__le__");
name!(GT_EQ_OP_NAME, "__ge__");
name!(PLUS_OP_NAME, "__add__");
name!(MINUS_OP_NAME, "__sub__");
name!(TIMES_OP_NAME, "__mul__");
name!(DIV_OP_NAME, "__div__");

View File

@@ -1,4 +1,4 @@
use crate::obj::{intern::Interner, names::*, prelude::*}; use crate::obj::{intern::Interner, reserved::*, prelude::*};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::{collections::BTreeMap, sync::{Arc, Mutex}}; use std::{collections::BTreeMap, sync::{Arc, Mutex}};

View File

@@ -1,4 +1,4 @@
use crate::obj::{names::*, prelude::*}; use crate::obj::{reserved::*, prelude::*};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use shredder::Scan; use shredder::Scan;

View File

@@ -75,7 +75,7 @@ impl<V: Visit<Out=()>> DefaultAccept<V> for AssignStmt {
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum LhsExpr { pub enum LhsExpr {
SetAttr(AccessExpr), SetAttr(AccessExpr),
Local(String), Name(String),
} }
// //
@@ -94,7 +94,7 @@ impl<V: Visit<Out=()>> DefaultAccept<V> for LhsExpr {
fn default_accept(&self, visitor: &mut V) -> V::Out { fn default_accept(&self, visitor: &mut V) -> V::Out {
match self { match self {
LhsExpr::SetAttr(a) => a.accept(visitor), LhsExpr::SetAttr(a) => a.accept(visitor),
LhsExpr::Local(_) => {}, LhsExpr::Name(_) => {},
} }
} }
} }

View File

@@ -26,20 +26,20 @@ unsafe impl GcSafe for FrameKind {}
#[derive(Scan, Debug, Clone)] #[derive(Scan, Debug, Clone)]
pub struct Frame { pub struct Frame {
locals: Locals, locals: Names,
kind: FrameKind, kind: FrameKind,
} }
impl Frame { impl Frame {
pub fn new(locals: Locals, kind: FrameKind) -> Self { pub fn new(locals: Names, kind: FrameKind) -> Self {
Self { locals, kind, } Self { locals, kind, }
} }
pub fn locals(&self) -> &Locals { pub fn locals(&self) -> &Names {
&self.locals &self.locals
} }
pub fn locals_mut(&mut self) -> &mut Locals { pub fn locals_mut(&mut self) -> &mut Names {
&mut self.locals &mut self.locals
} }

View File

@@ -10,10 +10,10 @@ pub enum Inst {
PushConst(ConstHandle), PushConst(ConstHandle),
/// Looks up and pushes a local value. /// Looks up and pushes a local value.
PushLocal(Local), LoadName(Name),
/// Pop a value from the stack, possibly into a local symbol. /// Pop a value from the stack, possibly into a local symbol.
Pop(Option<Local>), Pop(Option<Name>),
/// Pops a symbol value and an object reference. /// Pops a symbol value and an object reference.
/// ///
@@ -119,7 +119,7 @@ impl Inst {
match self { match self {
Inst::PushSym(_) => "PUSH_SYM", Inst::PushSym(_) => "PUSH_SYM",
Inst::PushConst(_) => "PUSH_CONST", Inst::PushConst(_) => "PUSH_CONST",
Inst::PushLocal(_) => "PUSH_LOCAL", Inst::LoadName(_) => "LOAD_NAME",
Inst::Pop(_) => "POP", Inst::Pop(_) => "POP",
Inst::GetAttr(_) => "GET_ATTR", Inst::GetAttr(_) => "GET_ATTR",
Inst::SetAttr(_) => "SET_ATTR", Inst::SetAttr(_) => "SET_ATTR",
@@ -189,7 +189,7 @@ impl Display for InstFormatter<'_, '_> {
format!("{:?}", obj) format!("{:?}", obj)
}, },
), ),
Inst::PushLocal(local) => ( Inst::LoadName(local) => (
local.index().to_string(), local.index().to_string(),
"TODO: local name".to_string(), "TODO: local name".to_string(),
), ),

View File

@@ -4,7 +4,7 @@ pub mod frame;
pub mod inst; pub mod inst;
use crate::{ use crate::{
obj::{names::*, prelude::*}, obj::{reserved::*, prelude::*},
vm::{consts::*, error::*, frame::*, inst::*}, vm::{consts::*, error::*, frame::*, inst::*},
}; };
use shredder::{GcSafe, Scanner, Scan}; use shredder::{GcSafe, Scanner, Scan};
@@ -129,7 +129,7 @@ impl<'c> Vm<'c> {
let obj_ref = self.const_pool.get(hdl).clone(); let obj_ref = self.const_pool.get(hdl).clone();
self.push(obj_ref); self.push(obj_ref);
} }
Inst::PushLocal(_sym) => todo!(), Inst::LoadName(_sym) => todo!(),
Inst::Pop(Some(_sym)) => todo!(), Inst::Pop(Some(_sym)) => todo!(),
Inst::Pop(None) => todo!(), Inst::Pop(None) => todo!(),
Inst::GetAttr(sym) => { Inst::GetAttr(sym) => {