🐛 bug: switch to RefCell so some more of the tables tests will pass

main
_ 2023-09-26 21:43:02 -05:00
parent 0d5e1098bc
commit fcfd9397ff
4 changed files with 77 additions and 24 deletions

View File

@ -7,7 +7,6 @@ use crate::{
instruction::Instruction,
value::{
BogusClosure,
Table,
Value,
},
};
@ -226,7 +225,9 @@ impl State {
_ => panic! ("K[C] must be a string"),
};
*self.reg_mut (*a) = t.get (Value::String (Rc::clone (key)));
let val = t.borrow ().get (Value::String (Rc::clone (key)));
*self.reg_mut (*a) = val;
},
Instruction::GetTable (a, b, c) => {
let t = match self.reg (*b) {
@ -236,7 +237,7 @@ impl State {
let key = self.reg (*c);
let val = t.get (key.clone ());
let val = t.borrow ().get (key.clone ());
*self.reg_mut (*a) = val;
},
@ -265,7 +266,7 @@ impl State {
Value::BogusArg (arg) => arg.get (key).map (|x| x.as_str().into ()).unwrap_or_default(),
Value::Table (t) => {
let key = Value::from (i64::try_from (key).unwrap ());
t.get (key)
t.borrow ().get (key)
},
_ => unimplemented! (),
};
@ -419,10 +420,10 @@ impl State {
_ => panic! ("GetTabUp only supports string keys"),
};
let dst = self.reg_mut (*a).as_table_mut ()
.expect ("SetField only works on tables");
let mut dst = self.reg (*a).as_table ()
.expect ("SetField only works on tables").borrow_mut ();
Rc::get_mut (dst).expect ("shrug").insert (Value::from (key.as_str ()), value);
dst.insert (Value::from (key.as_str ()), value);
},
Instruction::SetI (a, b, c, k_flag) => {
let value = if *k_flag {
@ -433,10 +434,9 @@ impl State {
}
.clone ();
let dst = self.reg_mut (*a).as_table_mut ()
.expect ("SetI only works on tables");
let mut dst = self.reg_mut (*a).as_table ().expect ("SetI only works on tables").borrow_mut ();
Rc::get_mut (dst).expect ("shrug").insert (i64::from (*b), value);
dst.insert (i64::from (*b), value);
},
Instruction::SetList (a, b, c, k) => {
if *b == 0 {
@ -446,18 +446,12 @@ impl State {
panic! ("SetList with k = true not implemented");
}
// Temporarily move the table out
let mut dst = Rc::into_inner (std::mem::replace (self.reg_mut (*a).as_table_mut ().expect ("SetList only works on tables"), Default::default ())).unwrap ();
let mut dst = self.reg (*a).as_table ().expect ("SetList only works on tables").borrow_mut ();
for i in 1..=*b {
let src = self.reg (*a + i);
dst.insert (Value::from (i64::from (*c + i)), src.clone ());
}
// Put the table back and pretend it's all okay
*self.reg_mut (*a) = Value::Table (dst.into ());
},
Instruction::SetTabUp (_a, _b, _c) => unimplemented! (),
Instruction::TailCall (_a, _b, _c, _k) => unimplemented! (),

View File

@ -214,6 +214,64 @@ fn fma () {
}
}
#[test]
fn heap () {
use std::{
cell::RefCell,
collections::HashMap,
rc::Rc,
};
use crate::value::Table;
{
let mut allocations = HashMap::new ();
let mut ctr = 0;
let c = ctr;
allocations.insert (ctr, Table::default ());
ctr += 1;
let a = ctr;
allocations.insert (ctr, Table::default ());
ctr += 1;
allocations.get_mut (&a).unwrap ().insert (1, c);
allocations.get_mut (&c).unwrap ().insert (2, "eee");
}
if true {
#[derive (Clone, Debug, PartialEq)]
enum Value {
S (Rc <String>),
T (Rc <RefCell <HashMap <i64, Value>>>),
}
let c = Value::T (Default::default ());
let a = Value::T (Default::default ());
match &a {
Value::T (t) => t.borrow_mut ().insert (1, c.clone ()),
_ => panic! ("impossible"),
};
match &c {
Value::T (t) => t.borrow_mut ().insert (2, Value::S (Rc::new (String::from ("eee")))),
_ =>panic! ("impossible"),
};
let actual = match &a {
Value::T (t) => match t.borrow ().get (&1) {
Some (Value::T (t)) => t.borrow ().get (&2).unwrap ().clone (),
_ => panic! ("impossible"),
},
_ => panic! ("impossible"),
};
assert_eq! (actual, Value::S (Rc::new ("eee".into ())));
}
}
#[test]
fn is_93 () {
assert_eq! (Value::from ("93"), Value::from ("93"));

View File

@ -1,4 +1,5 @@
use std::{
cell::RefCell,
cmp::{
Eq,
PartialEq,
@ -25,7 +26,7 @@ pub enum Value {
Integer (i64),
String (Rc <String>),
Table (Rc <Table>),
Table (Rc <RefCell <Table>>),
// These are all bogus, I haven't figured out how to implement
// tables and function pointers yet
@ -99,7 +100,7 @@ impl From <f64> for Value {
impl From <Table> for Value {
fn from (x: Table) -> Self {
Self::Table (x.into ())
Self::Table (Rc::new (RefCell::new (x)))
}
}
@ -145,7 +146,7 @@ impl Value {
}
}
pub fn as_table_mut (&mut self) -> Option <&mut Rc <Table>> {
pub fn as_table (&self) -> Option <&Rc <RefCell <Table>>> {
match self {
Self::Table (t) => Some (t),
_ => None,

View File

@ -28,10 +28,10 @@ c [1] = "ddd"
local a = { c }
local b = { c }
print (a [1])
print (b [1])
print (a [1][2])
print (b [1][2])
c [2] = "eee"
print (a [2])
print (b [2])
print (a [1][2])
print (b [1][2])