More tweaks on Meta<S>.
This commit is contained in:
parent
662213fb94
commit
bfc418a55e
1 changed files with 44 additions and 26 deletions
70
src/vm.rs
70
src/vm.rs
|
|
@ -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)?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue