Fixed table indexing and construction, declarations and some instructions. Builds and passes indexing test.

This commit is contained in:
Christian Lincoln 2026-08-28 13:53:28 +01:00 committed by paladin
parent 93599ff5d7
commit 1e288b3948
5 changed files with 2984 additions and 2773 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -25,16 +25,19 @@ Notes:
type Displacement = u8; type Displacement = u8;
#[cfg(feature="bighash")] #[cfg(feature = "bighash")]
pub type Hashed = u64; pub type Hashed = u64;
#[cfg(not(feature="bighash"))] #[cfg(not(feature = "bighash"))]
pub type Hashed = u32; pub type Hashed = u32;
pub trait Equivalent<T>: Sized { pub trait Equivalent<T>: Sized {
fn matches(&self, other: &T) -> bool; fn matches(&self, other: &T) -> bool;
} }
impl<T> Equivalent<T> for T where T: PartialEq { impl<T> Equivalent<T> for T
where
T: PartialEq,
{
fn matches(&self, other: &T) -> bool { fn matches(&self, other: &T) -> bool {
self == other self == other
} }
@ -75,7 +78,13 @@ impl TableEntry for KeyValue {
} }
} }
fn is_vacant(&self) -> bool { fn is_vacant(&self) -> bool {
matches!(self,KeyValue { index: Value::Nil, .. }) matches!(
self,
KeyValue {
index: Value::Nil,
..
}
)
} }
} }
@ -87,7 +96,8 @@ struct Entry<E> {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Map<E: TableEntry + Clone> { // default representing vacancy! pub struct Map<E: TableEntry + Clone> {
// default representing vacancy!
map: Vec<Entry<E>>, map: Vec<Entry<E>>,
map_bounds: std::ops::Range<usize>, map_bounds: std::ops::Range<usize>,
map_count: usize, // number of elements in table map_count: usize, // number of elements in table
@ -95,14 +105,19 @@ pub struct Map<E: TableEntry + Clone> { // default representing vacancy!
impl<E: TableEntry + Clone> Map<E> { impl<E: TableEntry + Clone> Map<E> {
pub(crate) fn string_cache() { // todo: this isn't a clean way, maybe make a generic Map and use a specific one for the cache and the rest of the language pub(crate) fn string_cache() { // todo: this isn't a clean way, maybe make a generic Map and use a specific one for the cache and the rest of the language
} }
fn exchange_table(&mut self, len: usize) { fn exchange_table(&mut self, len: usize) {
let old = std::mem::replace(&mut self.map, vec![Entry { let old = std::mem::replace(
entry: E::new_vacant(), &mut self.map,
home: 0, vec![
displacement: 0, Entry {
}; len]); entry: E::new_vacant(),
home: 0,
displacement: 0,
};
len
],
);
for Entry { entry, .. } in old { for Entry { entry, .. } in old {
if entry.is_vacant() { if entry.is_vacant() {
self.set_table(entry) self.set_table(entry)
@ -202,7 +217,11 @@ impl<E: TableEntry + Clone> Map<E> {
self.set_table(entry); self.set_table(entry);
} }
} }
pub(crate) fn rem_table<K>(&mut self, index: K) where E: Equivalent<K>, K: Hashes { pub(crate) fn rem_table<K>(&mut self, index: K)
where
E: Equivalent<K>,
K: Hashes,
{
if self.map.len() == 0 { if self.map.len() == 0 {
return; return;
} }
@ -256,9 +275,12 @@ impl<E: TableEntry + Clone> Map<E> {
} }
} }
pub(crate) fn get_table<K>(&mut self, index: K) -> Option<&E> pub(crate) fn get_table<K>(&mut self, index: K) -> Option<&E>
where E: Equivalent<K>, K: Hashes { where
E: Equivalent<K>,
K: Hashes,
{
if self.map.len() == 0 { if self.map.len() == 0 {
return None return None;
} }
let location = index.hashed() as usize % self.map.len(); let location = index.hashed() as usize % self.map.len();
let home = &self.map[location]; let home = &self.map[location];
@ -377,7 +399,7 @@ impl Table {
} else { } else {
self.table.set_table(KeyValue { self.table.set_table(KeyValue {
index: Value::Integer(index), index: Value::Integer(index),
value: item value: item,
}) })
} }
} }
@ -387,25 +409,28 @@ impl Table {
Value::Nil => Err(RunError( Value::Nil => Err(RunError(
"Attempt to set new index of table with key: nil".to_string(), "Attempt to set new index of table with key: nil".to_string(),
)), )),
index => Ok(self.table.set_table(KeyValue { index => Ok(self.table.set_table(KeyValue { index, value })),
index,
value
})),
} }
} }
pub fn get(&mut self, index: Value) -> Result<Value, RunError> { pub fn get(&mut self, index: Value) -> Result<Value, RunError> {
match index { match index {
Value::Integer(index) => Ok(self Value::Integer(index) => Ok(self
.array .array
.get(index as usize) .get(index as usize - 1)
.unwrap_or(&Value::Nil) .unwrap_or(&Value::Nil)
.clone()), .clone()),
Value::Nil => Err(RunError("Attempt to index table with key: nil".to_string())), Value::Nil => Err(RunError("Attempt to index table with key: nil".to_string())),
index => { // todo: move this into the Map index => {
Ok(self.table.get_table(index).unwrap_or(&KeyValue { // todo: move this into the Map
index: Value::Nil, Ok(self
value: Value::Nil, .table
}).value.clone()) .get_table(index)
.unwrap_or(&KeyValue {
index: Value::Nil,
value: Value::Nil,
})
.value
.clone())
} }
} }
} }

View file

@ -1 +1,2 @@
local table = {} local table = { "hello", "friend" }
print(table[1], table[2])

1643
src/vm.rs

File diff suppressed because it is too large Load diff