use crate::obj::{Obj, VTable}; use crate::syn::ast::SpStmt; use crate::vm::{error::*, machine::Machine}; use crate::{scope::Scope, syn::span::Span, vm::inst::SpInst}; use gc::{unsafe_empty_trace, Finalize, Gc, Trace}; use std::fmt::Debug; use std::rc::Rc; /// A handle to a quote pointing to an element in a `QuoteTable`. #[derive(Debug, Clone, Copy, PartialEq, Eq, Finalize)] pub struct Quote(usize); impl Quote { pub fn index(&self) -> usize { self.0 } } unsafe impl Trace for Quote { unsafe_empty_trace!(); } #[derive(Debug, Trace, Finalize)] pub struct QuoteObj { value: Quote, vtable: VTable, } impl QuoteObj { pub fn new(value: Quote) -> Gc { Gc::new(QuoteObj { value, vtable: vtable! {}, }) } #[allow(dead_code)] pub fn value(&self) -> Quote { self.value } } impl Obj for QuoteObj { fn vtable(&self) -> &VTable { &self.vtable } fn vtable_mut(&mut self) -> &mut VTable { &mut self.vtable } fn call(&self, _call_site: Option, machine: &mut Machine) -> Result<()> { machine.call_quote(self.value); Ok(()) } fn as_any(&self) -> &(dyn std::any::Any + 'static) { self } } /// A table of compiled quotes, their expression trees, and their spans. #[derive(Debug, Clone, Default)] pub struct QuoteTable { table: Vec<(Span, Scope, Vec, Rc>)>, } impl QuoteTable { pub fn insert( &mut self, span: Span, scope: Scope, quote: Vec, compiled: Rc>, ) -> Quote { let next = Quote(self.table.len()); self.table.push((span, scope, quote, compiled)); next } pub fn get(&self, quote: Quote) -> &(Span, Scope, Vec, Rc>) { &self.table[quote.index()] } }