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:
2022-01-17 19:54:19 -08:00
parent d06e1b82dd
commit aad0e8adc2
3 changed files with 228 additions and 8 deletions

34
Cargo.lock generated
View File

@@ -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"

View File

@@ -10,3 +10,4 @@ thiserror = "1.0"
structopt = "0.3"
regex = "1.5"
lazy_static = "1.4"
gc = { version = "0.4", features = ["derive"] }

View File

@@ -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()))
}
}