♻️ refactor: remove special types BogusArg and BogusEnv
This is a milestone towards actually implementing all of Lua.main
parent
062c6e6a2d
commit
5ab30ac5b4
39
src/state.rs
39
src/state.rs
|
@ -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;
|
||||
|
|
44
src/value.rs
44
src/value.rs
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue