More tweaks on Meta<S>.

This commit is contained in:
paladin 2026-10-01 09:11:00 +01:00
parent 662213fb94
commit bfc418a55e

View file

@ -2,7 +2,7 @@
use crate::parser::{BinaryOp, Piece, UnaryOp, parse}; use crate::parser::{BinaryOp, Piece, UnaryOp, parse};
use deimos::gc::{Allocates, AnyId, FreeList, Id, MaybeId, Traverse}; use deimos::gc::{Allocates, AnyId, FreeList, Id, MaybeId, Traverse};
use deimos::map::{Equivalent, Hashed, Hashes, Map, Set}; use deimos::map::{DisplacementSet, Equivalent, Hashed, Hashes, Map, TableEntry};
use std::fmt::{Debug, Display, Formatter}; use std::fmt::{Debug, Display, Formatter};
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
@ -193,7 +193,7 @@ impl PartialEq for CachedString {
self.1 == other.1 && self.0 == other.0 self.1 == other.1 && self.0 == other.0
} }
} }
/*#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct CachedStringEntry(Option<CachedString>); struct CachedStringEntry(Option<CachedString>);
impl Hashes for CachedStringEntry { impl Hashes for CachedStringEntry {
fn hashed(&self) -> Hashed { fn hashed(&self) -> Hashed {
@ -212,11 +212,18 @@ impl Equivalent<Self> for CachedStringEntry {
None => false, None => false,
} }
} }
}*/ }
impl Equivalent<&str> for CachedString { impl TableEntry for CachedStringEntry {
const VACANT: Self = CachedStringEntry(None);
fn is_vacant(&self) -> bool {
self.0.is_none()
}
}
impl Equivalent<&str> for CachedStringEntry {
fn matches(&self, string: &&str) -> bool { fn matches(&self, string: &&str) -> bool {
self.0.as_ref().eq(*string) self.0.as_ref().unwrap().0.as_ref().eq(*string)
} }
} }
@ -365,24 +372,39 @@ macro_rules! read_only {
}; };
} }
type MetaFieldSet<S> = fn(
&mut Machine<S>,
id: AnyId,
index: Value,
value: Value,
needle: Needle,
) -> Result<Value, RunError>;
type MetaFieldGet<S> = fn(&mut Machine<S>, id: AnyId, index: Value, needle: Needle) -> Result<(), RunError>;
pub struct MetaField<S> { pub struct MetaField<S> {
set: fn( set: MetaFieldSet<S>,
&mut Machine<S>, get: MetaFieldGet<S>,
id: AnyId,
index: Value,
value: Value,
needle: Needle,
) -> Result<Value, RunError>,
get: fn(&mut Machine<S>, id: AnyId, index: Value, needle: Needle) -> Result<(), RunError>,
} }
pub struct Meta<S> { pub struct Meta<S> {
pub string: fn(&mut Machine<S>, id: AnyId, needle: Needle) -> Result<Value, RunError>, pub string: fn(&mut Machine<S>, id: AnyId, needle: Needle) -> Result<Value, RunError>,
pub number: fn(&mut Machine<S>, id: AnyId, needle: Needle) -> Result<Value, RunError>, pub number: fn(&mut Machine<S>, id: AnyId, needle: Needle) -> Result<Value, RunError>,
pub get: fn(&mut Machine<S>, id: AnyId, index: Value, needle: Needle) -> Result<Value, RunError>,
pub set: fn(&mut Machine<S>, id: AnyId, index: Value, value: Value, needle: Needle) -> Result<(), RunError>,
pub traverse: fn(&mut Machine<S>, id: AnyId) -> Result<(), RunError>,
pub fields: Map<Value, MetaField<S>>, pub fields: Map<Value, MetaField<S>>,
pub constants: pub constants: Map<Value, Value>,
Map<Value, fn(&mut Machine<S>, id: AnyId, needle: Needle) -> Result<Value, RunError>>, }
pub traverse: fn(id: AnyId) -> Result<(), RunError>,
impl<S> Default for Meta<S> {
fn default() -> Self {
Meta {
string: |machine, id, needle| Err(RunError::new("Type does not implement to string.")),
number: |machine, id, needle| Err(RunError::new("Type does not implement to number.")),
get: |machine, id, index, needle|,
set: |machine, id, index, value, needle| (),
traverse: |machine, id| (),
}
}
} }
pub type ForeignFunction<S> = fn(&mut Machine<S>, needle: Needle) -> Result<(), RunError>; pub type ForeignFunction<S> = fn(&mut Machine<S>, needle: Needle) -> Result<(), RunError>;
@ -396,7 +418,7 @@ pub struct Machine<S> {
upvalues: FreeList<Upvalue>, upvalues: FreeList<Upvalue>,
natives: FreeList<ForeignFunction<S>>, natives: FreeList<ForeignFunction<S>>,
metas: FreeList<Meta<S>>, metas: FreeList<Meta<S>>,
cache: Set<CachedString>, cache: DisplacementSet<CachedStringEntry>,
meta_strings: MetaStrings, meta_strings: MetaStrings,
} }
@ -613,10 +635,10 @@ impl<S> Machine<S> {
// todo: why Result of RunError? // todo: why Result of RunError?
if string.len() < SHORT_STRING_LEN { if string.len() < SHORT_STRING_LEN {
match self.cache.get(string) { match self.cache.get(string) {
Some(ref entry) => Ok(Value::CachedString(entry.clone())), Some(ref entry) => Ok(Value::CachedString(entry.0.as_ref().unwrap().clone())),
None => { None => {
let cached = CachedString(Rc::from(string), string.hashed()); let cached = CachedString(Rc::from(string), string.hashed());
self.cache.set(cached.clone()); self.cache.set(CachedStringEntry(Some(cached.clone())));
Ok(Value::CachedString(cached)) Ok(Value::CachedString(cached))
} }
} }
@ -774,9 +796,7 @@ impl<S> Machine<S> {
table.set(index, value) table.set(index, value)
} }
} }
Value::Object(id, meta) => { Value::Object(id, meta) => (self.metas.get(&meta.into()).set)(self, id, index, value, dispatch.needle()),
(self.metas.get(&meta.into()).set)(self, id, index, value, dispatch.needle())
}
Value::Function(_callable) => Err(RunError("Function index unimplemented".to_string())), Value::Function(_callable) => Err(RunError("Function index unimplemented".to_string())),
} }
} }
@ -804,9 +824,7 @@ impl<S> Machine<S> {
table.get(index.clone()) table.get(index.clone())
} }
} }
Value::Object(mut object, ..) => { Value::Object(id, meta) => (self.metas.get(&meta.into()).get)(self, id, index, dispatch.needle()),
Err(RunError("Object index unimplemented".to_string()))
}
Value::Function(_callable) => Err(RunError("Function index unimplemented".to_string())), Value::Function(_callable) => Err(RunError("Function index unimplemented".to_string())),
} }
} }
@ -1319,7 +1337,7 @@ impl<S> Machine<S> {
upvalues: FreeList::new(), upvalues: FreeList::new(),
natives: FreeList::new(), natives: FreeList::new(),
meta_strings: MetaStrings::new(), meta_strings: MetaStrings::new(),
cache: Set::new(), cache: DisplacementSet::new(),
}; };
machine.init_meta_strings()?; machine.init_meta_strings()?;
load(&mut machine)?; load(&mut machine)?;