Clean up project structure
All checks were successful
per-push tests / build (push) Successful in 32s
per-push tests / test-utility (push) Successful in 32s
per-push tests / test-frontend (push) Successful in 34s
per-push tests / test-backend (push) Successful in 30s
per-push tests / timed-decomposer-parse (push) Successful in 26s
All checks were successful
per-push tests / build (push) Successful in 32s
per-push tests / test-utility (push) Successful in 32s
per-push tests / test-frontend (push) Successful in 34s
per-push tests / test-backend (push) Successful in 30s
per-push tests / timed-decomposer-parse (push) Successful in 26s
The number package is moved into its own package henceforth referred to as "organelle". Hyphae and Mycelium are updated accordingly. In addition, Hyphae gets a copy of the sexpr module of Mycelium. This will not remain a copy, rather it will be the basis of a heap manager module within Mycelium to be worked on in the future. Fixes #32 Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
parent
6f95381e5e
commit
8d2d0ebf0c
12 changed files with 247 additions and 10 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
|
@ -134,8 +134,8 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|||
name = "hyphae"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"mycelium",
|
||||
"num",
|
||||
"organelle",
|
||||
"serde",
|
||||
"toml",
|
||||
]
|
||||
|
|
@ -166,7 +166,7 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
|||
name = "mycelium"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"num",
|
||||
"organelle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -248,6 +248,13 @@ version = "1.21.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "organelle"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["mycelium", "decomposer", "hyphae"]
|
||||
members = ["mycelium", "decomposer", "hyphae", "organelle"]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
mycelium = { path = "../mycelium" }
|
||||
organelle = { path = "../organelle" }
|
||||
num = { version = "0.4.3", features = ["alloc"] }
|
||||
|
||||
[build-dependencies]
|
||||
|
|
|
|||
219
hyphae/src/heap.rs
Normal file
219
hyphae/src/heap.rs
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
/* Mycelium Scheme
|
||||
* Copyright (C) 2025 Ava Affine
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use core::fmt::{self, Formatter};
|
||||
use core::ops::Index;
|
||||
use core::cell::RefCell;
|
||||
|
||||
use alloc::format;
|
||||
use alloc::rc::Rc;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::string::String;
|
||||
|
||||
use organelle::Number;
|
||||
|
||||
#[derive(Default, Clone, PartialEq)]
|
||||
pub enum Datum {
|
||||
Number(Number),
|
||||
Bool(bool),
|
||||
List(Rc<Ast>),
|
||||
Symbol(String),
|
||||
Char(u8),
|
||||
String(Vec<u8>),
|
||||
Vector(RefCell<Vec<Rc<Datum>>>),
|
||||
ByteVector(RefCell<Vec<u8>>),
|
||||
#[default]
|
||||
None,
|
||||
}
|
||||
|
||||
fn byte_to_escaped_char(b: u8) -> String {
|
||||
// alarm, backspace, delete
|
||||
match b {
|
||||
_ if b > 31 && b < 127 => String::from(b as char),
|
||||
_ => format!("x{:x}", b),
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt_vec<T: fmt::Display>(ve: &RefCell<Vec<T>>) -> String {
|
||||
let v = ve.borrow();
|
||||
if v.len() == 0 {
|
||||
return String::new()
|
||||
}
|
||||
let mut s = format!("{}", v[0]);
|
||||
let mut i = v.iter();
|
||||
i.next(); // discard
|
||||
i.for_each(|e| {
|
||||
s = format!("{} {}", s, e);
|
||||
});
|
||||
|
||||
s
|
||||
}
|
||||
|
||||
impl fmt::Display for Datum {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Datum::Number(n) => write!(f, "{}", Into::<String>::into(*n)),
|
||||
Datum::Bool(n) => write!(f, "{}", if *n {"#t"} else {"#f"}),
|
||||
Datum::List(n) => write!(f, "{n}"),
|
||||
Datum::Symbol(n) => write!(f, "{n}"),
|
||||
Datum::Char(n) => write!(f, "#\\{}",
|
||||
byte_to_escaped_char(*n)),
|
||||
Datum::String(n) =>
|
||||
write!(f, "\"{}\"", String::from_utf8_lossy(&*n)),
|
||||
Datum::Vector(n) => write!(f, "#({})", fmt_vec(n)),
|
||||
Datum::ByteVector(n) => write!(f, "#u8({})", fmt_vec(n)),
|
||||
Datum::None => Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* WARNING
|
||||
* This is in a sense overloaded.
|
||||
* Instead of using this to print debugging information for the
|
||||
* Rust code, I have instead overloaded it to print the most
|
||||
* maximal expanded valid syntax for this Datum
|
||||
*/
|
||||
impl fmt::Debug for Datum {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Datum::Number(n) => write!(f, "{}", Into::<String>::into(*n)),
|
||||
Datum::Bool(n) => write!(f, "{}", if *n {"#t"} else {"#f"}),
|
||||
Datum::List(n) => write!(f, "{n}"),
|
||||
Datum::Char(n) => write!(f, "{}",
|
||||
byte_to_escaped_char(*n)),
|
||||
Datum::Symbol(n) => write!(f, "{n}"),
|
||||
Datum::String(n) =>
|
||||
write!(f, "\"{}\"", String::from_utf8_lossy(&*n)),
|
||||
Datum::Vector(n) => write!(f, "#({n:?})"),
|
||||
Datum::ByteVector(n) => write!(f, "#u8({n:?})"),
|
||||
Datum::None => Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Default, Clone, PartialEq)]
|
||||
pub struct Ast(pub Rc<Datum>, pub Rc<Datum>);
|
||||
|
||||
impl Ast {
|
||||
pub fn subsl(&self, start: isize, end: isize) -> Ast {
|
||||
if end - start == 1 {
|
||||
return Ast(Rc::from(self[start as usize].clone()), Rc::from(Datum::None))
|
||||
}
|
||||
|
||||
if end == 0 {
|
||||
return Ast(
|
||||
Rc::from((*(self.0)).clone()),
|
||||
Rc::from(Datum::None)
|
||||
)
|
||||
}
|
||||
|
||||
let Datum::List(ref next) = *self.1 else {
|
||||
panic!("index into improper list form")
|
||||
};
|
||||
|
||||
if start <= 0 {
|
||||
Ast(
|
||||
Rc::from((*(self.0)).clone()),
|
||||
Rc::from(Datum::List(
|
||||
Rc::from(next.subsl(start - 1, end - 1))))
|
||||
)
|
||||
|
||||
} else {
|
||||
next.subsl(start - 1, end - 1)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
let Datum::List(ref next) = *self.1 else {
|
||||
return 1
|
||||
};
|
||||
1 + next.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for Ast {
|
||||
type Item = Rc<Datum>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Datum::List(n) = &*self.1 {
|
||||
let tmp_pair = n;
|
||||
self.0 = tmp_pair.0.clone();
|
||||
self.1 = tmp_pair.1.clone();
|
||||
return Some(self.0.clone());
|
||||
}
|
||||
|
||||
if let Datum::None = *self.1 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let tmp = self.1.clone();
|
||||
self.0 = Rc::from(Datum::None);
|
||||
self.1 = Rc::from(Datum::None);
|
||||
return Some(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<usize> for Ast {
|
||||
type Output = Datum;
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
if index == 0 {
|
||||
if let Datum::None = *self.0 {
|
||||
panic!("out of bounds indexing into AST")
|
||||
} else {
|
||||
self.0.as_ref()
|
||||
}
|
||||
} else {
|
||||
let Datum::List(ref next) = *self.1 else {
|
||||
panic!("out of bounds indexing into AST")
|
||||
};
|
||||
|
||||
next.index(index - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Ast {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "({}", self.0)?;
|
||||
let mut cur = self;
|
||||
while let Datum::List(next) = &*cur.1 {
|
||||
cur = &next;
|
||||
write!(f, " {}", cur.0)?;
|
||||
}
|
||||
|
||||
if let Datum::None = &*cur.1 {
|
||||
write!(f, ")")
|
||||
} else {
|
||||
write!(f, " . {})", cur.1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Ast {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "({}", self.0)?;
|
||||
let mut cur = self;
|
||||
let mut end = 1;
|
||||
while let Datum::List(next) = &*cur.1 {
|
||||
cur = &next;
|
||||
end += 1;
|
||||
write!(f, "({} . ", cur.0)?
|
||||
}
|
||||
write!(f, "{}{}", cur.1, ")".repeat(end))
|
||||
}
|
||||
}
|
||||
|
|
@ -22,5 +22,6 @@ pub mod stackstack;
|
|||
pub mod instr;
|
||||
pub mod vm;
|
||||
pub mod util;
|
||||
pub mod heap;
|
||||
|
||||
extern crate alloc;
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@
|
|||
*/
|
||||
|
||||
|
||||
use mycelium::sexpr::Datum;
|
||||
use mycelium::number::{Fraction, Number, Numeric};
|
||||
use organelle::{Fraction, Number, Numeric};
|
||||
|
||||
use crate::hmap::QuickMap;
|
||||
use crate::stackstack::StackStack;
|
||||
use crate::instr as i;
|
||||
use crate::util::{Operand, Program, Address};
|
||||
use crate::heap::Datum;
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
num = { version = "0.4.3", features = ["alloc"] }
|
||||
organelle = { path = "../organelle" }
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
pub mod sexpr;
|
||||
pub mod lexer;
|
||||
pub mod parser;
|
||||
pub mod number;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use crate::lexer::{
|
|||
E_CHAR_TOO_LONG,
|
||||
E_END_OF_DOCUMENT
|
||||
};
|
||||
use crate::number::{Number, Numeric};
|
||||
use organelle::{Number, Numeric};
|
||||
use crate::sexpr::{Datum, Ast};
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ use alloc::rc::Rc;
|
|||
use alloc::vec::Vec;
|
||||
use alloc::string::String;
|
||||
|
||||
use crate::number::Number;
|
||||
use organelle::Number;
|
||||
|
||||
#[derive(Default, Clone, PartialEq)]
|
||||
pub enum Datum {
|
||||
|
|
|
|||
8
organelle/Cargo.toml
Normal file
8
organelle/Cargo.toml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "organelle"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
num = { version = "0.4.3", features = ["alloc"] }
|
||||
|
||||
|
|
@ -15,6 +15,9 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::string::String;
|
||||
use alloc::format;
|
||||
use alloc::fmt::Debug;
|
||||
Loading…
Add table
Add a link
Reference in a new issue