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

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