Compare commits
4 commits
main
...
usage-inst
| Author | SHA1 | Date | |
|---|---|---|---|
| 3260424a9a | |||
| d973ccd011 | |||
| f9d5a75531 | |||
| a3fa58c195 |
6 changed files with 29 additions and 190 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
|
@ -60,9 +60,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.53"
|
version = "4.5.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8"
|
checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
|
|
@ -70,9 +70,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.53"
|
version = "4.5.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00"
|
checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
|
|
@ -82,9 +82,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.5.49"
|
version = "4.5.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
|
checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|
@ -142,7 +142,6 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
name = "hyphae"
|
name = "hyphae"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
|
||||||
"num",
|
"num",
|
||||||
"organelle",
|
"organelle",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
||||||
|
|
@ -3,28 +3,9 @@ name = "hyphae"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
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]
|
[dependencies]
|
||||||
organelle = { path = "../organelle" }
|
organelle = { path = "../organelle" }
|
||||||
num = { version = "0.4.3", features = ["alloc"] }
|
num = { version = "0.4.3", features = ["alloc"] }
|
||||||
clap = { version = "4.5.53", features = ["derive"], optional = true }
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
serde = { version = "1.0", features = ["alloc", "derive"] }
|
serde = { version = "1.0", features = ["alloc", "derive"] }
|
||||||
|
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
/* 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 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<PathBuf>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
|
||||||
// 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<u8> = program.into();
|
|
||||||
let mut out_file = File::create(outfile)?;
|
|
||||||
out_file.write_all(&bytecode)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
/* 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 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<dyn Error>> {
|
|
||||||
// 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(())
|
|
||||||
}
|
|
||||||
|
|
@ -153,16 +153,16 @@ impl FromStr for Operand {
|
||||||
"$oper4" => Ok(Operand(Address::Oper4, 0)),
|
"$oper4" => Ok(Operand(Address::Oper4, 0)),
|
||||||
"true" => Ok(Operand(Address::Bool, 1)),
|
"true" => Ok(Operand(Address::Bool, 1)),
|
||||||
"false" => Ok(Operand(Address::Bool, 0)),
|
"false" => Ok(Operand(Address::Bool, 0)),
|
||||||
a if a.len() > 1 &&
|
a if a.chars().nth(0).unwrap() == '%' &&
|
||||||
a.chars().nth(0).unwrap() == '%' &&
|
a.len() > 1 &&
|
||||||
a[1..].parse::<usize>().is_ok() =>
|
a[1..].parse::<usize>().is_ok() =>
|
||||||
Ok(Operand(Address::Stack, a[1..].parse::<usize>().unwrap())),
|
Ok(Operand(Address::Stack, a[1..].parse::<usize>().unwrap())),
|
||||||
a if a.len() > 1 &&
|
a if a.chars().nth(0).unwrap() == '@' &&
|
||||||
a.chars().nth(0).unwrap() == '@' &&
|
a.len() > 1 &&
|
||||||
a[1..].parse::<usize>().is_ok() =>
|
a[1..].parse::<usize>().is_ok() =>
|
||||||
Ok(Operand(Address::Instr, a[1..].parse::<usize>().unwrap())),
|
Ok(Operand(Address::Instr, a[1..].parse::<usize>().unwrap())),
|
||||||
a if a.len() == 3 &&
|
a if a.chars().nth(0).unwrap() == '\'' &&
|
||||||
a.chars().nth(0).unwrap() == '\'' &&
|
a.len() == 3 &&
|
||||||
a.chars().nth(2).unwrap() == '\'' =>
|
a.chars().nth(2).unwrap() == '\'' =>
|
||||||
Ok(Operand(Address::Char, a.chars().nth(1).unwrap() as usize)),
|
Ok(Operand(Address::Char, a.chars().nth(1).unwrap() as usize)),
|
||||||
a if a.parse::<usize>().is_ok() =>
|
a if a.parse::<usize>().is_ok() =>
|
||||||
|
|
@ -232,11 +232,7 @@ impl Into<Vec<u8>> for Instruction {
|
||||||
impl FromStr for Instruction {
|
impl FromStr for Instruction {
|
||||||
type Err = &'static str;
|
type Err = &'static str;
|
||||||
fn from_str(v: &str) -> Result<Self, Self::Err> {
|
fn from_str(v: &str) -> Result<Self, Self::Err> {
|
||||||
let toks: Vec<&str> = v
|
let toks: Vec<&str> = v.trim().split(' ').collect();
|
||||||
.trim()
|
|
||||||
.split(' ')
|
|
||||||
.filter(|x| x.len() > 0)
|
|
||||||
.collect();
|
|
||||||
if toks.len() < 1 {
|
if toks.len() < 1 {
|
||||||
return Err("empty string");
|
return Err("empty string");
|
||||||
}
|
}
|
||||||
|
|
@ -260,7 +256,7 @@ impl FromStr for Instruction {
|
||||||
|
|
||||||
impl Display for Instruction {
|
impl Display for Instruction {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), E> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), E> {
|
||||||
write!(f, "{} \t", self.0)?;
|
write!(f, "{}\t", self.0)?;
|
||||||
if self.1.len() > 0 {
|
if self.1.len() > 0 {
|
||||||
write!(f, "{}", self.1[0])?;
|
write!(f, "{}", self.1[0])?;
|
||||||
}
|
}
|
||||||
|
|
@ -308,7 +304,6 @@ impl TryFrom<&[u8]> for Program {
|
||||||
}
|
}
|
||||||
cur += 1;
|
cur += 1;
|
||||||
while cur < value.len() {
|
while cur < value.len() {
|
||||||
|
|
||||||
let instruction: Instruction = value[cur..].try_into()?;
|
let instruction: Instruction = value[cur..].try_into()?;
|
||||||
cur += instruction.byte_length() as usize;
|
cur += instruction.byte_length() as usize;
|
||||||
prog.push(instruction);
|
prog.push(instruction);
|
||||||
|
|
@ -323,13 +318,9 @@ impl TryFrom<&[u8]> for Program {
|
||||||
|
|
||||||
impl Into<Vec<u8>> for Program {
|
impl Into<Vec<u8>> for Program {
|
||||||
fn into(self) -> Vec<u8> {
|
fn into(self) -> Vec<u8> {
|
||||||
let mut res: Vec<u8> = vec![DeserializerControlCode::DataChunk as u8];
|
let mut res: Vec<u8> = vec![];
|
||||||
for dat in self.0 {
|
for instr in self.0 {
|
||||||
res.append(&mut dat.into());
|
res.append(&mut instr.into())
|
||||||
}
|
|
||||||
res.push(DeserializerControlCode::CodeChunk as u8);
|
|
||||||
for instr in self.1 {
|
|
||||||
res.append(&mut instr.into());
|
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
@ -346,12 +337,12 @@ impl Display for Program {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), E> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), E> {
|
||||||
write!(f, "DATA:\n")?;
|
write!(f, "DATA:\n")?;
|
||||||
for i in self.0.iter() {
|
for i in self.0.iter() {
|
||||||
write!(f, " {}\n", i)?;
|
write!(f, " {}", i)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(f, "CODE:\n")?;
|
write!(f, "\nCODE:\n")?;
|
||||||
for i in self.1.iter() {
|
for i in self.1.iter() {
|
||||||
write!(f, " {}\n", i)?;
|
write!(f, " {}", i)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -363,10 +354,7 @@ impl FromStr for Program {
|
||||||
fn from_str(val: &str) -> Result<Self, Self::Err> {
|
fn from_str(val: &str) -> Result<Self, Self::Err> {
|
||||||
//let mut datum = vec![];
|
//let mut datum = vec![];
|
||||||
let mut instrs = vec![];
|
let mut instrs = vec![];
|
||||||
let lines: Vec<&str> = val
|
let lines: Vec<&str> = val.split('\n').collect();
|
||||||
.split('\n')
|
|
||||||
.filter(|x| x.len() > 0)
|
|
||||||
.collect();
|
|
||||||
let mut cur = 0;
|
let mut cur = 0;
|
||||||
let mut toggle = 0;
|
let mut toggle = 0;
|
||||||
|
|
||||||
|
|
@ -380,7 +368,7 @@ impl FromStr for Program {
|
||||||
match lines[cur] {
|
match lines[cur] {
|
||||||
"DATA:" => return Err("datum parser unimplemented"),
|
"DATA:" => return Err("datum parser unimplemented"),
|
||||||
"CODE:" => toggle = 1,
|
"CODE:" => toggle = 1,
|
||||||
_ => return Err("unknown section in document: "),
|
a => return Err("unknown section in document: "),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
10
readme.md
10
readme.md
|
|
@ -18,10 +18,10 @@ in about 55 milliseconds on average.
|
||||||
HyphaeVM is mostly implemented. The instruction set is defined and implemented,
|
HyphaeVM is mostly implemented. The instruction set is defined and implemented,
|
||||||
including extensibility interfaces and the VM layout. Additionally, instruction
|
including extensibility interfaces and the VM layout. Additionally, instruction
|
||||||
encoding and decoding are implemented. Garbage collection is implemented (via
|
encoding and decoding are implemented. Garbage collection is implemented (via
|
||||||
reference counting). Datum encoding/decoding and full program encoding/decoding
|
reference counting). Currently being implemented are datum encoding/decoding and
|
||||||
are also implemented. A live debugger is currently in the works. Concurrency
|
full program encoding/decoding. Yet to be approached are debugging routines, CLI
|
||||||
features have yet to be approached. However, some documentation has been written
|
utilities, and concurrency features. However, Documentation has been written on
|
||||||
on programming with HyphaeVM.
|
programming with HyphaeVM.
|
||||||
|
|
||||||
|
|
||||||
The R7RS-Small Scheme to HyphaeVM compiler is not implemented.
|
The R7RS-Small Scheme to HyphaeVM compiler is not implemented.
|
||||||
|
|
@ -53,7 +53,7 @@ cargo --version
|
||||||
rustup toolchain list
|
rustup toolchain list
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Clone repositories for dev toolchain and language
|
3. Clone repository
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone https://hephaestus.sunnypup.io/affine/Mycelium.git
|
git clone https://hephaestus.sunnypup.io/affine/Mycelium.git
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue