🐛 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
	
	 _
						_