From a3fa58c195d8afc242043bef53c4cbe7604312e5 Mon Sep 17 00:00:00 2001 From: Kolby Heacock Date: Thu, 4 Dec 2025 13:24:20 -0700 Subject: [PATCH 1/6] added license info --- readme.md | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 576233d..f8f049e 100644 --- a/readme.md +++ b/readme.md @@ -8,6 +8,7 @@ project: a POSIX shell interpreter as well as a compiled to bytecode language fo running on ESP32 devices. ## Current Status + The lexer and parser are implemented. On an X86 machine equipped with 64GB RAM and an AMD Ryzen 7900 CPU this lexer and parser are capable of creating a fully validated abstract syntax tree from approximately 11200 lines of handwritten scheme @@ -32,4 +33,44 @@ R7RS-Large is not implemented. The Linux/Mac/Windows runtime and extended compiler is not implemented. -Documentation is not implemented. +Documentation is still in progress. + +## Installation + +1. Install the Rust programming language. Here are the instructions for Unix-like dev environments for installing the nightly build for Rust + +``` +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs/ | sh +source $HOME/.cargo/env +rustup toolchain install nightly +rustup override set nightly +``` + +1. Verify nightly Rust dev env + +``` +cargo --version +rustup toolchain list +``` + +1. Clone repositories for dev toolchain and language + +``` +git clone https://code.forgejo.org/msrd0/rust-toolchain.git +git clone https://hephaestus.sunnypup.io/affine/Mycelium.git + ``` + +## Testing + +1. Run all project's unit tests + +``` +cargo test --all-features +``` + +## License + +GNU General Public License 3 + +Copyright (C) 2025 Ava Affine + From f9d5a755318beb367f21cc7bc9439baa6c771d12 Mon Sep 17 00:00:00 2001 From: Kolby Heacock Date: Thu, 4 Dec 2025 13:34:10 -0700 Subject: [PATCH 2/6] updated members in Cagro.toml --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 32c5fb0..df6ee70 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ cargo-features = ["profile-rustflags"] [workspace] resolver = "2" -members = ["mycelium", "decomposer", "hyphae", "organelle", "fairy-ring"] +members = ["mycelium", "decomposer", "hyphae", "organelle"] [profile.release] opt-level = 3 From d973ccd0112a2129eccc4cf1c50e9141818f5119 Mon Sep 17 00:00:00 2001 From: Kolby Heacock Date: Thu, 4 Dec 2025 13:46:20 -0700 Subject: [PATCH 3/6] updated readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index f8f049e..6a2ef2c 100644 --- a/readme.md +++ b/readme.md @@ -33,7 +33,7 @@ R7RS-Large is not implemented. The Linux/Mac/Windows runtime and extended compiler is not implemented. -Documentation is still in progress. +Documentation is not implemented. ## Installation From 3260424a9a89ce944bed1a9bddeb298b69b0217f Mon Sep 17 00:00:00 2001 From: Kolby Heacock Date: Thu, 4 Dec 2025 13:52:49 -0700 Subject: [PATCH 4/6] updated numbering --- readme.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 6a2ef2c..bd558e7 100644 --- a/readme.md +++ b/readme.md @@ -46,17 +46,16 @@ rustup toolchain install nightly rustup override set nightly ``` -1. Verify nightly Rust dev env +2. Verify nightly Rust dev env ``` cargo --version rustup toolchain list ``` -1. Clone repositories for dev toolchain and language +3. Clone repository ``` -git clone https://code.forgejo.org/msrd0/rust-toolchain.git git clone https://hephaestus.sunnypup.io/affine/Mycelium.git ``` From 141ba43362015ee727ffd71246b0895279fc011d Mon Sep 17 00:00:00 2001 From: Kolby Heacock Date: Thu, 4 Dec 2025 19:04:21 -0700 Subject: [PATCH 5/6] add usage instructions --- Cargo.toml | 2 +- readme.md | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 32c5fb0..df6ee70 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ cargo-features = ["profile-rustflags"] [workspace] resolver = "2" -members = ["mycelium", "decomposer", "hyphae", "organelle", "fairy-ring"] +members = ["mycelium", "decomposer", "hyphae", "organelle"] [profile.release] opt-level = 3 diff --git a/readme.md b/readme.md index 576233d..4dc3cdf 100644 --- a/readme.md +++ b/readme.md @@ -8,6 +8,7 @@ project: a POSIX shell interpreter as well as a compiled to bytecode language fo running on ESP32 devices. ## Current Status + The lexer and parser are implemented. On an X86 machine equipped with 64GB RAM and an AMD Ryzen 7900 CPU this lexer and parser are capable of creating a fully validated abstract syntax tree from approximately 11200 lines of handwritten scheme @@ -33,3 +34,42 @@ The Linux/Mac/Windows runtime and extended compiler is not implemented. Documentation is not implemented. + +## Installation + +1. Install the Rust programming language. Here are the instructions for Unix-like dev environments for installing the nightly build for Rust + +``` +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs/ | sh +source $HOME/.cargo/env +rustup toolchain install nightly +rustup override set nightly +``` + +2. Verify nightly Rust dev env + +``` +cargo --version +rustup toolchain list +``` + +3. Clone repositories for dev toolchain and language + +``` +git clone https://hephaestus.sunnypup.io/affine/Mycelium.git + ``` + +## Testing + +1. Run all project's unit tests + +``` +cargo test --all-features +``` + +## License + +GNU General Public License 3 + +Copyright (C) 2025 Ava Affine + From 3af5997a1505c095548697acf1e4a01e027727ab Mon Sep 17 00:00:00 2001 From: Ava Affine Date: Mon, 15 Dec 2025 18:28:28 +0000 Subject: [PATCH 6/6] Hyphae: add assembler and disassembler This commit adds hyphae binaries for an assembler and a disassembler As well as some fixes for observed misbehavior during manual verification. The new binaries are hphc for compiling assmbly files and hphdump for inspecting compiled hyphae binary. Signed-off-by: Ava Affine --- Cargo.lock | 13 ++++--- hyphae/Cargo.toml | 19 ++++++++++ hyphae/src/bin/hphc.rs | 77 +++++++++++++++++++++++++++++++++++++++ hyphae/src/bin/hphdump.rs | 52 ++++++++++++++++++++++++++ hyphae/src/serializer.rs | 48 +++++++++++++++--------- readme.md | 8 ++-- 6 files changed, 189 insertions(+), 28 deletions(-) create mode 100644 hyphae/src/bin/hphc.rs create mode 100644 hyphae/src/bin/hphdump.rs diff --git a/Cargo.lock b/Cargo.lock index 35bd457..f9dd845 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,9 +60,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "clap" -version = "4.5.38" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", "clap_derive", @@ -70,9 +70,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.38" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstream", "anstyle", @@ -82,9 +82,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", @@ -142,6 +142,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" name = "hyphae" version = "0.1.0" dependencies = [ + "clap", "num", "organelle", "serde", diff --git a/hyphae/Cargo.toml b/hyphae/Cargo.toml index 06538cd..4d8fe1b 100644 --- a/hyphae/Cargo.toml +++ b/hyphae/Cargo.toml @@ -3,9 +3,28 @@ name = "hyphae" version = "0.1.0" edition = "2024" +[lib] +name = "hyphae" +crate-type = ["lib"] +path = "src/lib.rs" + +[[bin]] +name = "hphc" +path = "src/bin/hphc.rs" +required-features = ["cli"] + +[[bin]] +name = "hphdump" +path = "src/bin/hphdump.rs" +required-features = ["cli"] + +[features] +cli = ["clap"] + [dependencies] organelle = { path = "../organelle" } num = { version = "0.4.3", features = ["alloc"] } +clap = { version = "4.5.53", features = ["derive"], optional = true } [build-dependencies] serde = { version = "1.0", features = ["alloc", "derive"] } diff --git a/hyphae/src/bin/hphc.rs b/hyphae/src/bin/hphc.rs new file mode 100644 index 0000000..6e5f35a --- /dev/null +++ b/hyphae/src/bin/hphc.rs @@ -0,0 +1,77 @@ +/* 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 . + */ + +use hyphae; + +use clap::Parser; + +use std::path::PathBuf; +use std::fs::{read, File}; +use std::io::Write; +use std::error::Error; +use std::str::FromStr; + +const HPHC_SUFFIX: &str= "hph"; +const HPHC_DEFAULT: &str = "out"; + +#[derive(Parser, Debug)] +#[command(version, about = "HyphaeVM assembly compiler")] +struct Args { + /// path to input program assembly + compile: PathBuf, + + /// path for output bytecode + #[arg(short = 'o')] + output: Option, +} + +fn main() -> Result<(), Box> { + // parse arguments + let args = Args::parse(); + + // set output filepath + let outfile = args.output + .or(Some({ + let mut c = args.compile.clone(); + if c.as_path().is_dir() || c.as_path().file_name().is_none() { + c = String::from(HPHC_DEFAULT).into(); + } else { + c = c.as_path().file_name().unwrap().into(); + } + + c.set_extension(HPHC_SUFFIX); + c + })) + .unwrap(); + + // check input validity + if args.compile.as_path().is_dir() { + panic!("will not compile directory!"); + } + + // compile input program + let input_bytes = read(args.compile)?; + let input = str::from_utf8(input_bytes.as_slice())?; + let program = hyphae::serializer::Program::from_str(input)?; + + // dump program bytecode to output + let bytecode: Vec = program.into(); + let mut out_file = File::create(outfile)?; + out_file.write_all(&bytecode)?; + + Ok(()) +} diff --git a/hyphae/src/bin/hphdump.rs b/hyphae/src/bin/hphdump.rs new file mode 100644 index 0000000..d083a9f --- /dev/null +++ b/hyphae/src/bin/hphdump.rs @@ -0,0 +1,52 @@ +/* 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 . + */ + +use hyphae; + +use clap::Parser; + +use std::path::PathBuf; +use std::fs::read; +use std::error::Error; + +#[derive(Parser, Debug)] +#[command(version, about = "HyphaeVM compiled binary inspector")] +struct Args { + /// path to input program + decompile: PathBuf, +} + +fn main() -> Result<(), Box> { + // parse arguments + let args = Args::parse(); + + // check input validity + if args.decompile.as_path().is_dir() { + panic!("cannot dump directory!"); + } + + // load input program + let program: hyphae::serializer::Program; + program = read(args.decompile)? + .as_slice() + .try_into()?; + + // Display + println!("{}", program); + + Ok(()) +} diff --git a/hyphae/src/serializer.rs b/hyphae/src/serializer.rs index e0b990c..91186be 100644 --- a/hyphae/src/serializer.rs +++ b/hyphae/src/serializer.rs @@ -153,16 +153,16 @@ impl FromStr for Operand { "$oper4" => Ok(Operand(Address::Oper4, 0)), "true" => Ok(Operand(Address::Bool, 1)), "false" => Ok(Operand(Address::Bool, 0)), - a if a.chars().nth(0).unwrap() == '%' && - a.len() > 1 && - a[1..].parse::().is_ok() => + a if a.len() > 1 && + a.chars().nth(0).unwrap() == '%' && + a[1..].parse::().is_ok() => Ok(Operand(Address::Stack, a[1..].parse::().unwrap())), - a if a.chars().nth(0).unwrap() == '@' && - a.len() > 1 && - a[1..].parse::().is_ok() => + a if a.len() > 1 && + a.chars().nth(0).unwrap() == '@' && + a[1..].parse::().is_ok() => Ok(Operand(Address::Instr, a[1..].parse::().unwrap())), - a if a.chars().nth(0).unwrap() == '\'' && - a.len() == 3 && + a if a.len() == 3 && + a.chars().nth(0).unwrap() == '\'' && a.chars().nth(2).unwrap() == '\'' => Ok(Operand(Address::Char, a.chars().nth(1).unwrap() as usize)), a if a.parse::().is_ok() => @@ -232,7 +232,11 @@ impl Into> for Instruction { impl FromStr for Instruction { type Err = &'static str; fn from_str(v: &str) -> Result { - let toks: Vec<&str> = v.trim().split(' ').collect(); + let toks: Vec<&str> = v + .trim() + .split(' ') + .filter(|x| x.len() > 0) + .collect(); if toks.len() < 1 { return Err("empty string"); } @@ -256,7 +260,7 @@ impl FromStr for Instruction { impl Display for Instruction { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), E> { - write!(f, "{}\t", self.0)?; + write!(f, "{} \t", self.0)?; if self.1.len() > 0 { write!(f, "{}", self.1[0])?; } @@ -304,6 +308,7 @@ impl TryFrom<&[u8]> for Program { } cur += 1; while cur < value.len() { + let instruction: Instruction = value[cur..].try_into()?; cur += instruction.byte_length() as usize; prog.push(instruction); @@ -318,9 +323,13 @@ impl TryFrom<&[u8]> for Program { impl Into> for Program { fn into(self) -> Vec { - let mut res: Vec = vec![]; - for instr in self.0 { - res.append(&mut instr.into()) + let mut res: Vec = vec![DeserializerControlCode::DataChunk as u8]; + for dat in self.0 { + res.append(&mut dat.into()); + } + res.push(DeserializerControlCode::CodeChunk as u8); + for instr in self.1 { + res.append(&mut instr.into()); } res } @@ -337,12 +346,12 @@ impl Display for Program { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), E> { write!(f, "DATA:\n")?; for i in self.0.iter() { - write!(f, " {}", i)?; + write!(f, " {}\n", i)?; } - write!(f, "\nCODE:\n")?; + write!(f, "CODE:\n")?; for i in self.1.iter() { - write!(f, " {}", i)?; + write!(f, " {}\n", i)?; } Ok(()) @@ -354,7 +363,10 @@ impl FromStr for Program { fn from_str(val: &str) -> Result { //let mut datum = vec![]; let mut instrs = vec![]; - let lines: Vec<&str> = val.split('\n').collect(); + let lines: Vec<&str> = val + .split('\n') + .filter(|x| x.len() > 0) + .collect(); let mut cur = 0; let mut toggle = 0; @@ -368,7 +380,7 @@ impl FromStr for Program { match lines[cur] { "DATA:" => return Err("datum parser unimplemented"), "CODE:" => toggle = 1, - a => return Err("unknown section in document: "), + _ => return Err("unknown section in document: "), } } diff --git a/readme.md b/readme.md index 4dc3cdf..cea4fce 100644 --- a/readme.md +++ b/readme.md @@ -18,10 +18,10 @@ in about 55 milliseconds on average. HyphaeVM is mostly implemented. The instruction set is defined and implemented, including extensibility interfaces and the VM layout. Additionally, instruction encoding and decoding are implemented. Garbage collection is implemented (via -reference counting). Currently being implemented are datum encoding/decoding and -full program encoding/decoding. Yet to be approached are debugging routines, CLI -utilities, and concurrency features. However, Documentation has been written on -programming with HyphaeVM. +reference counting). Datum encoding/decoding and full program encoding/decoding +are also implemented. A live debugger is currently in the works. Concurrency +features have yet to be approached. However, some documentation has been written +on programming with HyphaeVM. The R7RS-Small Scheme to HyphaeVM compiler is not implemented.