Skip to content

Commit ecb86b7

Browse files
authored
Merge pull request #10 from rbartlensky/luatable-indexing
Luatable indexing
2 parents eac2a60 + 89af7b0 commit ecb86b7

File tree

6 files changed

+447
-68
lines changed

6 files changed

+447
-68
lines changed

luavm/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ name = "luavm"
88
path = "src/lib/mod.rs"
99

1010
[dependencies]
11-
gc = "0.3"
11+
gc = { git="https://github.com/rbartlensky/rust-gc", branch="ref-eq" }
1212
gc_derive = "0.3"
1313
luacompiler = { path="../luacompiler" }
1414
assert_float_eq = "1.1.3"

luavm/src/lib/errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ pub enum LuaError {
88
IntConversionErr,
99
/// Raised when a conversion to float fails.
1010
FloatConversionErr,
11+
/// Raised when a conversion to string fails.
12+
StringConversionErr,
1113
}

luavm/src/lib/instructions/loads.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ pub fn ldf(vm: &mut Vm, instr: u32) -> Result<(), LuaError> {
2222
Ok(())
2323
}
2424

25-
pub fn lds(_vm: &mut Vm, _instr: u32) -> Result<(), LuaError> {
26-
unreachable!("Strings are not implemented yet.")
25+
pub fn lds(vm: &mut Vm, instr: u32) -> Result<(), LuaError> {
26+
let val = vm.bytecode.get_string(second_arg(instr));
27+
vm.registers[first_arg(instr) as usize] = LuaVal::from(val.to_string());
28+
Ok(())
2729
}

luavm/src/lib/lua_values/lua_obj.rs

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,24 @@ use errors::LuaError;
44
pub trait LuaObj {
55
/// Clones the underlying type, and returns a box of it.
66
fn clone_box(&self) -> Box<LuaObj>;
7-
/// Checks whether the underlyning type is a float or not.
8-
fn is_float(&self) -> bool;
7+
/// Checks whther the underlying type is a float or an int.
8+
fn is_number(&self) -> bool;
9+
/// Returns true if the underlying type is either a float or a string.
10+
/// In Lua, if either of these two types are used in an arithmetic
11+
/// expression, then both arguments are converted to floats.
12+
fn is_aop_float(&self) -> bool;
13+
/// Checks whether the underlying type is a string or not.
14+
fn is_string(&self) -> bool;
915
/// Converts the underlying type to an int.
1016
fn to_int(&self) -> Result<i64, LuaError>;
1117
/// Converts the underlying type to a float.
1218
fn to_float(&self) -> Result<f64, LuaError>;
19+
/// Converts the underlying type to a string.
20+
fn to_string(&self) -> Result<String, LuaError>;
21+
/// Gets a reference to the underlying string.
22+
fn get_string_ref(&self) -> Option<&str> {
23+
None
24+
}
1325
}
1426

1527
/// Boxes the given `LuaObj`, and returns the address of the box.
@@ -32,13 +44,25 @@ impl LuaObj for LuaInt {
3244
Ok(self.v)
3345
}
3446

35-
fn is_float(&self) -> bool {
47+
fn is_number(&self) -> bool {
48+
true
49+
}
50+
51+
fn is_aop_float(&self) -> bool {
52+
false
53+
}
54+
55+
fn is_string(&self) -> bool {
3656
false
3757
}
3858

3959
fn to_float(&self) -> Result<f64, LuaError> {
4060
Ok(self.v as f64)
4161
}
62+
63+
fn to_string(&self) -> Result<String, LuaError> {
64+
Ok(self.v.to_string())
65+
}
4266
}
4367

4468
pub struct LuaFloat {
@@ -50,15 +74,65 @@ impl LuaObj for LuaFloat {
5074
Box::new(LuaFloat { v: self.v })
5175
}
5276

53-
fn is_float(&self) -> bool {
77+
fn is_number(&self) -> bool {
5478
true
5579
}
5680

81+
fn is_aop_float(&self) -> bool {
82+
true
83+
}
84+
85+
fn is_string(&self) -> bool {
86+
false
87+
}
88+
5789
fn to_int(&self) -> Result<i64, LuaError> {
5890
Err(LuaError::IntConversionErr)
5991
}
6092

6193
fn to_float(&self) -> Result<f64, LuaError> {
6294
Ok(self.v)
6395
}
96+
97+
fn to_string(&self) -> Result<String, LuaError> {
98+
Ok(self.v.to_string())
99+
}
100+
}
101+
102+
pub struct LuaString {
103+
pub v: String,
104+
}
105+
106+
impl LuaObj for LuaString {
107+
fn clone_box(&self) -> Box<LuaObj> {
108+
Box::new(LuaString { v: self.v.clone() })
109+
}
110+
111+
fn is_number(&self) -> bool {
112+
false
113+
}
114+
115+
fn is_aop_float(&self) -> bool {
116+
true
117+
}
118+
119+
fn is_string(&self) -> bool {
120+
true
121+
}
122+
123+
fn to_int(&self) -> Result<i64, LuaError> {
124+
self.v.parse().map_err(|_| LuaError::IntConversionErr)
125+
}
126+
127+
fn to_float(&self) -> Result<f64, LuaError> {
128+
self.v.parse().map_err(|_| LuaError::FloatConversionErr)
129+
}
130+
131+
fn to_string(&self) -> Result<String, LuaError> {
132+
Ok(self.v.clone())
133+
}
134+
135+
fn get_string_ref(&self) -> Option<&str> {
136+
Some(&self.v)
137+
}
64138
}

luavm/src/lib/lua_values/lua_table.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,22 @@ use LuaVal;
55
/// Represents a table in Lua.
66
#[derive(Trace, Finalize)]
77
pub struct LuaTable {
8-
v: GcCell<HashMap<String, LuaVal>>,
8+
v: GcCell<HashMap<LuaVal, LuaVal>>,
99
}
1010

1111
impl LuaTable {
1212
/// Creates a table with the given keys, and values.
13-
pub fn new(hm: HashMap<String, LuaVal>) -> LuaTable {
13+
pub fn new(hm: HashMap<LuaVal, LuaVal>) -> LuaTable {
1414
LuaTable { v: GcCell::new(hm) }
1515
}
1616

1717
/// Sets the given attribute to `val`.
18-
pub fn set(&self, attr: &str, val: LuaVal) {
19-
self.v
20-
.borrow_mut()
21-
.entry(attr.to_string())
22-
.or_insert(LuaVal::new())
23-
.set(val);
18+
pub fn set_attr(&self, attr: LuaVal, val: LuaVal) {
19+
self.v.borrow_mut().insert(attr, val);
2420
}
2521

2622
/// Gets a reference to given attribute.
27-
pub fn get_attr(&self, attr: &str) -> LuaVal {
23+
pub fn get_attr(&self, attr: &LuaVal) -> LuaVal {
2824
match self.v.borrow().get(attr) {
2925
Some(val) => val.clone(),
3026
None => LuaVal::new(),

0 commit comments

Comments
 (0)