Make environment a true table
This commit is contained in:
parent
56943d612a
commit
f12f3b629b
@ -5,7 +5,7 @@ use std::{cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc};
|
||||
use crate::{
|
||||
CompilationUnit,
|
||||
ast::{BinaryOperator, UnaryOperator},
|
||||
vm::value::{Constant, IndexableValue, LuaInteger, Value},
|
||||
vm::value::{Constant, IndexableValue, LuaInteger, Table, Value},
|
||||
};
|
||||
|
||||
pub mod value;
|
||||
@ -143,36 +143,6 @@ pub enum RuntimeError {
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub(crate) struct Environment {
|
||||
pub globals: HashMap<Constant, Rc<RefCell<Value>>>,
|
||||
}
|
||||
|
||||
impl Environment {
|
||||
fn get_global(&mut self, key: &Constant) -> Option<StackValue> {
|
||||
let value = self.globals.get_mut(key)?;
|
||||
Some(match &*value.borrow() {
|
||||
_ => StackValue::Value(value.borrow().clone()),
|
||||
})
|
||||
}
|
||||
|
||||
fn set_global(&mut self, key: Constant, value: StackValue) {
|
||||
if let Some(existing) = self.globals.get_mut(&key) {
|
||||
match value {
|
||||
StackValue::Value(value) => {
|
||||
*existing.borrow_mut() = value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match value {
|
||||
StackValue::Value(value) => {
|
||||
self.globals.insert(key, Rc::new(RefCell::new(value)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Prototype {
|
||||
pub instructions: Vec<Instruction>,
|
||||
@ -181,7 +151,7 @@ pub struct Prototype {
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct VirtualMachine {
|
||||
pub(super) environment: Rc<RefCell<Environment>>,
|
||||
pub(super) environment: Table,
|
||||
pub(super) constants: Vec<Constant>,
|
||||
pub(super) prototypes: HashMap<u32, Prototype>,
|
||||
pub(super) proto_counter: u32,
|
||||
@ -206,16 +176,17 @@ impl VirtualMachine {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_global(&mut self, key: Constant, value: Value) {
|
||||
pub fn set_global(&mut self, key: Value, value: Value) -> Result<(), RuntimeError> {
|
||||
self.environment
|
||||
.borrow_mut()
|
||||
.set_global(key, StackValue::Value(value));
|
||||
.insert(key.as_indexable()?, value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_globals(&self) -> HashMap<Constant, Value> {
|
||||
pub fn get_globals(&self) -> HashMap<IndexableValue, Value> {
|
||||
let mut values = HashMap::new();
|
||||
for (key, value) in &self.environment.borrow().globals {
|
||||
values.insert(key.clone(), value.borrow().clone());
|
||||
for (key, value) in self.environment.borrow().iter() {
|
||||
values.insert(key.clone(), value.clone());
|
||||
}
|
||||
|
||||
values
|
||||
@ -226,7 +197,7 @@ impl VirtualMachine {
|
||||
pub struct Closure {
|
||||
vm: VirtualMachine,
|
||||
pub(crate) prototype: u32,
|
||||
environment: Rc<RefCell<Environment>>,
|
||||
environment: Table,
|
||||
upvalues: HashMap<u16, Rc<RefCell<Value>>>,
|
||||
}
|
||||
|
||||
@ -424,19 +395,26 @@ impl ClosureRunner {
|
||||
}
|
||||
Instruction::SetGlobal(reg, global) => {
|
||||
let value = self.get_stack(*reg);
|
||||
self.closure
|
||||
.environment
|
||||
.borrow_mut()
|
||||
.set_global(constants.get(*global as usize).unwrap().clone(), value);
|
||||
self.closure.environment.borrow_mut().insert(
|
||||
constants
|
||||
.get(*global as usize)
|
||||
.unwrap()
|
||||
.clone()
|
||||
.as_value()
|
||||
.as_indexable()?,
|
||||
match value {
|
||||
StackValue::Value(value) => value,
|
||||
},
|
||||
);
|
||||
}
|
||||
Instruction::GetGlobal(reg, global) => {
|
||||
let glob = self
|
||||
.closure
|
||||
.environment
|
||||
.borrow_mut()
|
||||
.get_global(constants.get(*global as usize).unwrap());
|
||||
let constant = constants.get(*global as usize).unwrap().clone();
|
||||
let environment = self.closure.environment.borrow_mut().clone();
|
||||
let glob = environment
|
||||
.get(&constant.as_value().as_indexable()?)
|
||||
.cloned();
|
||||
if let Some(global) = glob {
|
||||
self.set_stack(*reg, global);
|
||||
self.set_stack(*reg, StackValue::Value(global));
|
||||
} else {
|
||||
return Err(RuntimeError::GlobalNotFound(
|
||||
constants.get(*global as usize).cloned(),
|
||||
|
||||
@ -96,9 +96,15 @@ pub enum Constant {
|
||||
Nil,
|
||||
}
|
||||
|
||||
impl From<&str> for Constant {
|
||||
fn from(value: &str) -> Self {
|
||||
Constant::String(value.to_owned())
|
||||
impl Constant {
|
||||
pub fn as_value(self) -> Value {
|
||||
match self {
|
||||
Constant::String(value) => Value::String(value),
|
||||
Constant::Float(vmfloat) => Value::Float(vmfloat),
|
||||
Constant::Integer(lua_integer) => Value::Integer(lua_integer),
|
||||
Constant::Bool(lua_bool) => Value::Boolean(lua_bool),
|
||||
Constant::Nil => Value::Nil,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,6 +120,8 @@ impl Debug for Constant {
|
||||
}
|
||||
}
|
||||
|
||||
pub type Table = Rc<RefCell<HashMap<IndexableValue, Value>>>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Value {
|
||||
String(String),
|
||||
@ -123,7 +131,7 @@ pub enum Value {
|
||||
RustFunction(Rc<RefCell<dyn RustFunction>>),
|
||||
Function(Closure),
|
||||
Nil,
|
||||
Table(Rc<RefCell<HashMap<IndexableValue, Value>>>),
|
||||
Table(Table),
|
||||
}
|
||||
|
||||
impl Value {
|
||||
@ -160,14 +168,10 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Ord, PartialOrd)]
|
||||
pub enum IndexableValue {
|
||||
String(String),
|
||||
Float(VMFloat),
|
||||
Integer(LuaInteger),
|
||||
Bool(LuaBool),
|
||||
RustFunction(String),
|
||||
Function(u32),
|
||||
impl From<&str> for Value {
|
||||
fn from(value: &str) -> Self {
|
||||
Value::String(value.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl Value {
|
||||
@ -357,3 +361,13 @@ impl Debug for Value {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Ord, PartialOrd)]
|
||||
pub enum IndexableValue {
|
||||
String(String),
|
||||
Float(VMFloat),
|
||||
Integer(LuaInteger),
|
||||
Bool(LuaBool),
|
||||
RustFunction(String),
|
||||
Function(u32),
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user