Compare commits

...

2 Commits

Author SHA1 Message Date
_ 51b04be1ab 🐛 bug: PUC Lua says divides always make floats, even int / int 2023-10-01 15:03:37 -05:00
_ eb024eed3e 🚧 wip: only 5.8x slower than PUC, but brittle 2023-10-01 02:46:10 -05:00
2 changed files with 45 additions and 16 deletions

View File

@ -391,19 +391,11 @@ impl <'a> State <'a> {
let v_b = self.reg (*b); let v_b = self.reg (*b);
let v_c = self.reg (*c); let v_c = self.reg (*c);
let x = if let (Some (v_b), Some (v_c)) = (v_b.as_int (), v_c.as_int ()) let v_b = v_b.as_float ().unwrap_or_else (|| panic! ("{v_b}"));
{
Value::from (v_b / v_c)
}
else {
let v_b = v_b.as_float ().unwrap_or_else (|| panic! ("{v_b}"));
let v_c = v_c.as_float ().ok_or_else (|| make_step_error ("C must be a number"))?;
Value::from (v_b / v_c)
};
*self.reg_mut (*a) = x; let v_c = v_c.as_float ().ok_or_else (|| make_step_error ("C must be a number"))?;
*self.reg_mut (*a) = Value::from (v_b / v_c);
}, },
Instruction::EqI (a, sb, k_flag) => { Instruction::EqI (a, sb, k_flag) => {
if (self.reg (*a).as_int ().unwrap () == *sb as i64) != *k_flag if (self.reg (*a).as_int ().unwrap () == *sb as i64) != *k_flag
@ -457,7 +449,7 @@ impl <'a> State <'a> {
_ => panic! ("K[C] must be a string"), _ => panic! ("K[C] must be a string"),
}; };
let val = t.borrow ().get (Value::String (Rc::clone (key))); let val = t.borrow ().get_str (key.as_str ()).clone ();
*self.reg_mut (*a) = val; *self.reg_mut (*a) = val;
}, },
@ -733,13 +725,13 @@ impl <'a> State <'a> {
let key = match k.get (b).unwrap () { let key = match k.get (b).unwrap () {
Value::String (s) => s.as_ref (), Value::String (s) => s.as_ref (),
_ => panic! ("GetTabUp only supports string keys"), _ => panic! ("SetField only supports string keys"),
}; };
let mut dst = self.reg (*a).as_table () let mut dst = self.reg (*a).as_table ()
.expect ("SetField only works on tables").borrow_mut (); .expect ("SetField only works on tables").borrow_mut ();
dst.insert (Value::from (key.as_str ()), value); dst.insert_str (key.as_str (), value);
}, },
Instruction::SetI (a, b, c, k_flag) => { Instruction::SetI (a, b, c, k_flag) => {
let value = if *k_flag { let value = if *k_flag {

View File

@ -36,6 +36,8 @@ pub enum Value {
BogusClosure (Rc <RefCell <BogusClosure>>), BogusClosure (Rc <RefCell <BogusClosure>>),
} }
const NIL: Value = Value::Nil;
impl fmt::Debug for Value { impl fmt::Debug for Value {
fn fmt (&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt (&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
@ -254,7 +256,14 @@ impl fmt::Debug for Table {
impl Table { impl Table {
fn get_inner (&self, key: &Value) -> Value { fn get_inner (&self, key: &Value) -> Value {
self.hash.get (key).cloned ().unwrap_or_default () // self.hash.get (key).cloned ().unwrap_or_default ()
for (hay, value) in &self.hash {
if key == hay {
return value.clone ();
}
}
Value::Nil
} }
pub fn get <A: Into <Value>> (&self, key: A) -> Value { pub fn get <A: Into <Value>> (&self, key: A) -> Value {
@ -265,7 +274,24 @@ impl Table {
self.get_inner (&(key.into ())) self.get_inner (&(key.into ()))
} }
pub fn get_str (&self, key: &str) -> &Value {
for (hay, value) in &self.hash {
if Some (key) == hay.as_str () {
return value;
}
}
&NIL
}
fn insert_inner (&mut self, a: Value, b: Value) { fn insert_inner (&mut self, a: Value, b: Value) {
for (hay, value) in &mut self.hash {
if &a == hay {
*value = b;
return;
}
}
self.hash.insert (a, b); self.hash.insert (a, b);
} }
@ -286,6 +312,17 @@ impl Table {
self.insert_inner (k.into (), v.into ()) self.insert_inner (k.into (), v.into ())
} }
pub fn insert_str (&mut self, key: &str, v: Value) {
for (hay, value) in &mut self.hash {
if Some (key) == hay.as_str () {
*value = v;
return;
}
}
self.hash.insert (key.into (), v);
}
pub fn length (&self) -> i64 { pub fn length (&self) -> i64 {
for i in 1..i64::MAX { for i in 1..i64::MAX {
if self.get (i) == Value::Nil { if self.get (i) == Value::Nil {