Skip to content

Commit

Permalink
Remove macro_attr and newtype dependencies
Browse files Browse the repository at this point in the history
This will let us remove a bunch of previously public types and make them private. Making a cleaner interface.
  • Loading branch information
CeleritasCelery committed Jan 23, 2025
1 parent a57f186 commit 808826a
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 214 deletions.
2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ fallible-streaming-iterator = { workspace = true }
text-buffer = { workspace = true }
rune-macros = { workspace = true }
rune-core = { workspace = true }
newtype-derive-2018 = "0.2.2"
macro-attr-2018 = "3.0.0"
bumpalo = { version = "3.15.3", features = ["collections"] }
libc = "0.2.153"
base64 = "0.22.1"
Expand Down
48 changes: 18 additions & 30 deletions src/core/cons.rs
Original file line number Diff line number Diff line change
@@ -1,47 +1,35 @@
use crate::derive_markable;

use super::gc::{Block, GcHeap, GcState, Trace};
use super::object::{CloneIn, Gc, IntoObject, ObjCell, Object, ObjectType, NIL};
use crate::NewtypeMarkable;
use anyhow::{anyhow, Result};
use rune_core::hashmap::HashSet;
use rune_macros::Trace;
use std::fmt::{self, Debug, Display, Write};

mod iter;

pub(crate) use iter::*;

mod sealed {
use super::*;
#[derive(Eq)]
pub(crate) struct ConsInner {
pub(super) mutable: bool,
pub(super) car: ObjCell,
pub(super) cdr: ObjCell,
}
}

pub(in crate::core) use sealed::ConsInner;

#[derive(PartialEq, Eq, Trace)]
#[derive(Trace)]
pub(crate) struct Cons(GcHeap<ConsInner>);

NewtypeMarkable!(() pub(crate) struct Cons());

impl std::ops::Deref for Cons {
type Target = GcHeap<ConsInner>;
derive_markable!(Cons);

fn deref(&self) -> &Self::Target {
&self.0
}
struct ConsInner {
mutable: bool,
car: ObjCell,
cdr: ObjCell,
}

// TODO: we need to handle loops in equal
impl PartialEq for ConsInner {
impl PartialEq for Cons {
fn eq(&self, other: &Self) -> bool {
self.car() == other.car() && self.cdr() == other.cdr()
}
}

impl Eq for Cons {}

impl Cons {
// SAFETY: Cons must always be allocated in the GC heap, it cannot live on
// the stack. Otherwise it could outlive it's objects since it has no
Expand Down Expand Up @@ -84,27 +72,27 @@ impl Cons {
}
}

impl ConsInner {
impl Cons {
pub(crate) fn car(&self) -> Object {
self.car.get()
self.0.car.get()
}

pub(crate) fn cdr(&self) -> Object {
self.cdr.get()
self.0.cdr.get()
}

pub(crate) fn set_car(&self, new_car: Object) -> Result<()> {
if self.mutable {
unsafe { self.car.as_mut().set(new_car) }
if self.0.mutable {
unsafe { self.0.car.as_mut().set(new_car) }
Ok(())
} else {
Err(anyhow!("Attempt to call setcar on immutable cons cell"))
}
}

pub(crate) fn set_cdr(&self, new_cdr: Object) -> Result<()> {
if self.mutable {
unsafe { self.cdr.as_mut().set(new_cdr) }
if self.0.mutable {
unsafe { self.0.cdr.as_mut().set(new_cdr) }
Ok(())
} else {
Err(anyhow!("Attempt to call setcdr on immutable cons cell"))
Expand Down
4 changes: 2 additions & 2 deletions src/core/gc/heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ impl<'a, T: Markable<Value = NonNull<T>>> Markable for &'a T {
}

#[macro_export]
macro_rules! NewtypeMarkable {
(() $vis:vis struct $name:ident $($tail:tt)+) => {
macro_rules! derive_markable {
($name:ident) => {
impl $crate::core::gc::Markable for $name {
type Value = std::ptr::NonNull<Self>;

Expand Down
26 changes: 15 additions & 11 deletions src/core/object/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ use crate::{
error::{Type, TypeError},
gc::{Block, Context, GcHeap, GcState, Trace},
},
NewtypeMarkable,
derive_markable,
};
use anyhow::{bail, Result};
use macro_attr_2018::macro_attr;
use newtype_derive_2018::*;
use rune_macros::Trace;
use std::{
fmt::Display,
Expand Down Expand Up @@ -117,16 +115,16 @@ pub(crate) struct BufferData {
}

#[derive(Debug)]
pub(crate) struct LispBufferInner {
struct LispBufferInner {
text_buffer: Mutex<Option<BufferData>>,
}

macro_attr! {
/// A lisp handle to a buffer. This is a just a reference type and does not give
/// access to the contents until it is locked and a `OpenBuffer` is returned.
#[derive(PartialEq, Eq, Trace, NewtypeDebug!, NewtypeDisplay!, NewtypeDeref!, NewtypeMarkable!)]
pub(crate) struct LispBuffer(GcHeap<LispBufferInner>);
}
#[derive(PartialEq, Eq, Trace)]
pub(crate) struct LispBuffer(GcHeap<LispBufferInner>);

derive_markable!(LispBuffer);

impl LispBuffer {
pub(crate) fn create(name: String, block: &Block<true>) -> &LispBuffer {
Expand All @@ -142,7 +140,7 @@ impl LispBuffer {
}

pub(in crate::core) fn lock(&self) -> Result<OpenBuffer<'_>> {
let guard = self.text_buffer.lock().unwrap();
let guard = self.0.text_buffer.lock().unwrap();
if guard.is_none() {
bail!("selecting deleted buffer");
}
Expand Down Expand Up @@ -170,9 +168,9 @@ impl PartialEq<LispBuffer> for OpenBuffer<'_> {

impl Eq for LispBufferInner {}

impl Display for LispBufferInner {
impl Display for LispBuffer {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let data = self.text_buffer.lock().unwrap();
let data = self.0.text_buffer.lock().unwrap();
let name = match data.as_ref() {
Some(buf) => &buf.name,
None => "deleted buffer",
Expand All @@ -181,6 +179,12 @@ impl Display for LispBufferInner {
}
}

impl std::fmt::Debug for LispBuffer {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
Display::fmt(self, f)
}
}

impl Trace for LispBufferInner {
fn trace(&self, _v: &mut GcState) {
// Implement once we hold gc data in the buffer
Expand Down
26 changes: 16 additions & 10 deletions src/core/object/float.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
use super::{CloneIn, IntoObject};
use crate::core::gc::{Block, GcHeap, GcState, Trace};
use crate::NewtypeMarkable;
use macro_attr_2018::macro_attr;
use newtype_derive_2018::*;
use crate::derive_markable;
use rune_macros::Trace;
use std::fmt::{Debug, Display};

macro_attr! {
/// A wrapper type for floats to work around issues with Eq. Rust only allows
/// types to be used in match statements if they derive Eq. Even if you never
/// actually use that field in a match. So we need a float wrapper that
/// implements that trait.
#[derive(PartialEq, NewtypeDeref!, NewtypeMarkable!, Trace)]
pub(crate) struct LispFloat(GcHeap<f64>);
/// A wrapper type for floats to work around issues with Eq. Rust only allows
/// types to be used in match statements if they derive Eq. Even if you never
/// actually use that field in a match. So we need a float wrapper that
/// implements that trait.
#[derive(PartialEq, Trace)]
pub(crate) struct LispFloat(GcHeap<f64>);

derive_markable!(LispFloat);

impl std::ops::Deref for LispFloat {
type Target = f64;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl LispFloat {
Expand Down
22 changes: 14 additions & 8 deletions src/core/object/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ use crate::{
env::Env,
gc::{GcHeap, Rt, Slot},
},
NewtypeMarkable,
derive_markable,
};
use anyhow::{bail, ensure, Result};
use macro_attr_2018::macro_attr;
use newtype_derive_2018::*;
use rune_macros::Trace;
use std::fmt::{self, Debug, Display};

Expand All @@ -28,11 +26,19 @@ pub(crate) struct ByteFnPrototype {
pub(super) constants: Slot<&'static LispVec>,
}

macro_attr! {
/// A function implemented in lisp. Note that all functions are byte compiled,
/// so this contains the byte-code representation of the function.
#[derive(PartialEq, Eq, NewtypeDeref!, NewtypeMarkable!, Trace)]
pub(crate) struct ByteFn(GcHeap<ByteFnPrototype>);
/// A function implemented in lisp. Note that all functions are byte compiled,
/// so this contains the byte-code representation of the function.
#[derive(PartialEq, Eq, Trace)]
pub(crate) struct ByteFn(GcHeap<ByteFnPrototype>);

derive_markable!(ByteFn);

impl std::ops::Deref for ByteFn {
type Target = ByteFnPrototype;

fn deref(&self) -> &Self::Target {
&self.0
}
}

define_unbox!(ByteFn, Func, &'ob ByteFn);
Expand Down
Loading

0 comments on commit 808826a

Please sign in to comment.