🐛 bug: switch to RefCell so some more of the tables tests will pass
parent
0d5e1098bc
commit
fcfd9397ff
28
src/state.rs
28
src/state.rs
|
@ -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! (),
|
||||
|
|
58
src/tests.rs
58
src/tests.rs
|
@ -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"));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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])
|
||||
|
|
Loading…
Reference in New Issue