Add new base object stuff, gc dependency
I'm not writing my own GC, it's a huge pain in Rust. I'm using the gc library instead. Base object stuff implementation is here too. Hopefully going to start using ObjPtr instead of Value next. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
34
Cargo.lock
generated
34
Cargo.lock
generated
@@ -52,6 +52,27 @@ dependencies = [
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gc"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3edaac0f5832202ebc99520cb77c932248010c4645d20be1dc62d6579f5b3752"
|
||||
dependencies = [
|
||||
"gc_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gc_derive"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60df8444f094ff7885631d80e78eb7d88c3c2361a98daaabb06256e4500db941"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
@@ -181,6 +202,7 @@ dependencies = [
|
||||
name = "sybil"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"gc",
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"structopt",
|
||||
@@ -198,6 +220,18 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
|
||||
@@ -10,3 +10,4 @@ thiserror = "1.0"
|
||||
structopt = "0.3"
|
||||
regex = "1.5"
|
||||
lazy_static = "1.4"
|
||||
gc = { version = "0.4", features = ["derive"] }
|
||||
199
src/object.rs
199
src/object.rs
@@ -4,24 +4,25 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use crate::syn::ast::SpStmt;
|
||||
use crate::vm::{error::Result, machine::Machine};
|
||||
use crate::vm::{error::*, machine::Machine};
|
||||
use crate::{scope::Scope, syn::span::Span, vm::inst::SpInst};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use gc::{unsafe_empty_trace, Finalize, Gc, Trace};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{self, Debug, Display};
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub type ObjPtr = Gc<dyn Obj>;
|
||||
pub type Str = String;
|
||||
pub type Int = i64;
|
||||
pub type Float = f64;
|
||||
pub type VTable = HashMap<String, Value>;
|
||||
pub type VTable = HashMap<String, ObjPtr>;
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// Quote
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A handle to a quote pointing to an element in a `QuoteTable`.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Finalize)]
|
||||
pub struct Quote(usize);
|
||||
|
||||
impl Quote {
|
||||
@@ -30,6 +31,10 @@ impl Quote {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Trace for Quote {
|
||||
unsafe_empty_trace!();
|
||||
}
|
||||
|
||||
/// A table of compiled quotes, their expression trees, and their spans.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct QuoteTable {
|
||||
@@ -135,12 +140,16 @@ pub enum BuiltinExit {
|
||||
Return,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Finalize)]
|
||||
pub struct BuiltinFn {
|
||||
name: Rc<String>,
|
||||
fun: Rc<BuiltinFnPtr>,
|
||||
}
|
||||
|
||||
unsafe impl Trace for BuiltinFn {
|
||||
unsafe_empty_trace!();
|
||||
}
|
||||
|
||||
impl PartialEq for BuiltinFn {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
(&self.fun as *const _ as usize) == (&other.fun as *const _ as usize)
|
||||
@@ -172,3 +181,179 @@ impl Debug for BuiltinFn {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// An object that has a vtable and common functions.
|
||||
pub trait Obj: Trace + Finalize {
|
||||
/// Gets the vtable for this object.
|
||||
fn vtable(&self) -> &VTable;
|
||||
|
||||
/// Gets the vtable for this object, mutably.
|
||||
fn vtable_mut(&mut self) -> &mut VTable;
|
||||
|
||||
/// Calls this object.
|
||||
fn call(&self, machine: &mut Machine) -> Result<()>;
|
||||
|
||||
/// Gets a value in the vtable.
|
||||
///
|
||||
/// This has a default implementation, so it probably doesn't need to be
|
||||
/// implemented.
|
||||
fn get(&self, key: &str) -> Option<ObjPtr> {
|
||||
self.vtable().get(key).cloned()
|
||||
}
|
||||
|
||||
/// Sets a value in the vtable.
|
||||
///
|
||||
/// This has a default implementation, so it probably doesn't need to be
|
||||
/// implemented.
|
||||
fn set(&mut self, key: String, value: ObjPtr) -> Option<ObjPtr> {
|
||||
self.vtable_mut().insert(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! vtable {
|
||||
($($key:expr => $value:expr),* $(,)?) => {{
|
||||
VTable::from(
|
||||
[
|
||||
$(
|
||||
($key.to_string(), $value)
|
||||
),*
|
||||
]
|
||||
)
|
||||
}};
|
||||
}
|
||||
|
||||
#[derive(Trace, Finalize)]
|
||||
pub struct FloatObj {
|
||||
value: Float,
|
||||
vtable: VTable,
|
||||
}
|
||||
|
||||
impl Obj for FloatObj {
|
||||
fn vtable(&self) -> &VTable {
|
||||
&self.vtable
|
||||
}
|
||||
|
||||
fn vtable_mut(&mut self) -> &mut VTable {
|
||||
&mut self.vtable
|
||||
}
|
||||
|
||||
fn call(&self, _: &mut Machine) -> Result<()> {
|
||||
Err(RuntimeError::CannotCall("float value".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Trace, Finalize)]
|
||||
pub struct IntObj {
|
||||
value: Int,
|
||||
vtable: VTable,
|
||||
}
|
||||
|
||||
impl IntObj {
|
||||
pub fn new(value: Int) -> Self {
|
||||
IntObj {
|
||||
value,
|
||||
vtable: vtable! {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Obj for IntObj {
|
||||
fn vtable(&self) -> &VTable {
|
||||
&self.vtable
|
||||
}
|
||||
|
||||
fn vtable_mut(&mut self) -> &mut VTable {
|
||||
&mut self.vtable
|
||||
}
|
||||
|
||||
fn call(&self, _: &mut Machine) -> Result<()> {
|
||||
Err(RuntimeError::CannotCall("int value".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Trace, Finalize)]
|
||||
pub struct StrObj {
|
||||
value: String,
|
||||
vtable: VTable,
|
||||
}
|
||||
|
||||
impl StrObj {
|
||||
pub fn new(value: String) -> Self {
|
||||
StrObj {
|
||||
value,
|
||||
vtable: vtable! {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Obj for StrObj {
|
||||
fn vtable(&self) -> &VTable {
|
||||
&self.vtable
|
||||
}
|
||||
|
||||
fn vtable_mut(&mut self) -> &mut VTable {
|
||||
&mut self.vtable
|
||||
}
|
||||
|
||||
fn call(&self, _: &mut Machine) -> Result<()> {
|
||||
Err(RuntimeError::CannotCall("string value".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Trace, Finalize)]
|
||||
pub struct QuoteObj {
|
||||
value: Quote,
|
||||
vtable: VTable,
|
||||
}
|
||||
|
||||
impl QuoteObj {
|
||||
pub fn new(value: Quote) -> Self {
|
||||
QuoteObj {
|
||||
value,
|
||||
vtable: vtable! {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Obj for QuoteObj {
|
||||
fn vtable(&self) -> &VTable {
|
||||
&self.vtable
|
||||
}
|
||||
|
||||
fn vtable_mut(&mut self) -> &mut VTable {
|
||||
&mut self.vtable
|
||||
}
|
||||
|
||||
fn call(&self, _: &mut Machine) -> Result<()> {
|
||||
Err(RuntimeError::CannotCall("quote value".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Trace, Finalize)]
|
||||
pub struct BuiltinFnObj {
|
||||
value: BuiltinFn,
|
||||
vtable: VTable,
|
||||
}
|
||||
|
||||
impl BuiltinFnObj {
|
||||
pub fn new(value: BuiltinFn) -> Self {
|
||||
BuiltinFnObj {
|
||||
value,
|
||||
vtable: vtable! {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Obj for BuiltinFnObj {
|
||||
fn vtable(&self) -> &VTable {
|
||||
&self.vtable
|
||||
}
|
||||
|
||||
fn vtable_mut(&mut self) -> &mut VTable {
|
||||
&mut self.vtable
|
||||
}
|
||||
|
||||
fn call(&self, _: &mut Machine) -> Result<()> {
|
||||
Err(RuntimeError::CannotCall("quote value".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user