♻️ refactor: remove special types BogusArg and BogusEnv

This is a milestone towards actually implementing all of Lua.
main
_ 2023-09-26 23:19:33 -05:00
parent 062c6e6a2d
commit 5ab30ac5b4
2 changed files with 51 additions and 32 deletions

View File

@ -1,7 +1,4 @@
use std::{
collections::HashMap,
rc::Rc,
};
use std::rc::Rc;
use crate::{
instruction::Instruction,
@ -71,15 +68,16 @@ impl Default for State {
impl State {
pub fn upvalues_from_args <I: Iterator <Item = String>> (args: I) -> Vec <Value>
{
let arg: Vec <_> = args.map (|s| s.to_string ()).collect ();
let arg = args.map (|s| Value::from (s)).enumerate ();
let arg = Value::from_iter (arg.map (|(i, v)| (Value::from (i), v)));
let env = HashMap::from_iter ([
("arg", Value::BogusArg (arg.into ())),
let env = [
("arg", arg),
("print", Value::BogusPrint),
].map (|(k, v)| (k.to_string (), v)));
].into_iter ().map (|(k, v)| (k.to_string (), v));
vec! [
Value::BogusEnv (env.into ()),
Value::from_iter (env.into_iter ()),
]
}
@ -272,30 +270,21 @@ impl State {
let b = usize::try_from (*b).unwrap ();
let c = usize::try_from (*c).unwrap ();
let env = match upvalues.get (b).unwrap () {
Value::BogusEnv (x) => x,
_ => panic! ("Only allowed upvalue is BogusEnv"),
};
let table = upvalues.get (b).unwrap ().as_table ().expect ("GetTabUp only works on tables").borrow ();
let key = match k.get (c).unwrap () {
Value::String (s) => s.as_ref (),
Value::String (s) => String::from (s.as_ref()),
_ => panic! ("GetTabUp only supports string keys"),
};
let value = env.get (key).unwrap ();
*self.reg_mut (*a) = value.clone ();
*self.reg_mut (*a) = table.get (key);
},
Instruction::GetI (a, b, c) => {
let key = usize::try_from (*c).unwrap ();
let key = i64::try_from (*c).unwrap ();
let table = self.reg (*b);
let value = match table {
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.borrow ().get (key)
},
_ => unimplemented! (),
let value = {
let table = self.reg (*b).as_table ().expect ("GetI only works on tables").borrow ();
table.get (key)
};
*self.reg_mut (*a) = value;

View File

@ -29,11 +29,9 @@ pub enum Value {
Table (Rc <RefCell <Table>>),
// These are all bogus, I haven't figured out how to implement
// tables and function pointers yet
// closures yet
BogusArg (Rc <Vec <String>>),
BogusClosure (Rc <BogusClosure>),
BogusEnv (Rc <HashMap <String, Value>>),
BogusPrint,
}
@ -54,9 +52,7 @@ impl fmt::Display for Value {
Value::String (s) => write! (f, "{}", s),
Value::Table (t) => write! (f, "table: {:?}", std::rc::Rc::as_ptr (t)),
Value::BogusArg (_) => write! (f, "BogusArg"),
Value::BogusClosure (_) => write! (f, "BogusClosure"),
Value::BogusEnv (_) => write! (f, "BogusEnv"),
Value::BogusPrint => write! (f, "BogusPrint"),
}
}
@ -98,12 +94,37 @@ impl From <f64> for Value {
}
}
impl From <usize> for Value {
fn from (x: usize) -> Self {
Self::Integer (i64::try_from (x).unwrap ())
}
}
impl From <Table> for Value {
fn from (x: Table) -> Self {
Self::Table (Rc::new (RefCell::new (x)))
}
}
impl FromIterator <(Value, Value)> for Value {
fn from_iter <I: IntoIterator <Item=(Value, Value)>> (i: I) -> Self {
let table = Table::from_iter (i);
Self::from (table)
}
}
impl FromIterator <(String, Value)> for Value {
fn from_iter <I: IntoIterator <Item=(String, Value)>> (i: I) -> Self {
Self::from_iter (i.into_iter ().map (|(s, v)| (Value::from (s), v)))
}
}
impl FromIterator <Value> for Value {
fn from_iter <I: IntoIterator <Item=Value>> (i: I) -> Self {
Self::from_iter ((1..).zip (i.into_iter ()).map (|(i, v)| (Value::from (i), v)))
}
}
impl Eq for Value {}
impl std::hash::Hash for Value {
@ -122,9 +143,7 @@ impl std::hash::Hash for Value {
Self::String (x) => x.hash (state),
Self::Table (x) => Rc::as_ptr (&x).hash (state),
Self::BogusArg (_) => panic! ("can't hash Bogus values"),
Self::BogusClosure (_) => panic! ("can't hash Bogus values"),
Self::BogusEnv (_) => panic! ("can't hash Bogus values"),
Self::BogusPrint => panic! ("can't hash Bogus values"),
}
}
@ -205,6 +224,17 @@ impl Table {
}
}
impl FromIterator <(Value, Value)> for Table {
fn from_iter<I: IntoIterator<Item = (Value, Value)>> (i: I) -> Self
{
let hash = i.into_iter ().collect ();
Self {
array: Default::default (),
hash,
}
}
}
#[cfg (test)]
mod tests {
use std::collections::HashMap;