HyphaeVM - WIP
This commit is a WORK IN PROGRESS for the base implementation of the HyphaeVM. This will be squashed into a larger commit eventually when the work of implementing the HyphaeVM is finished. Of note, the ISA is mostly finished and much of the VM design is in place. Yet to be done are a few traps in mycelium, migrating pieces like the number package and the sexpr package into the VM package, and of course much testing. Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
parent
3a0a141738
commit
4ad319213d
17 changed files with 2073 additions and 17 deletions
109
hyphae/build.rs
Normal file
109
hyphae/build.rs
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
use std::{env, fs};
|
||||
use std::fs::File;
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::path::Path;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Document {
|
||||
pub instructions: Vec<Instruction>,
|
||||
}
|
||||
|
||||
// dont warn about unused fields in json instruction struct
|
||||
#[allow(dead_code)]
|
||||
#[derive(Deserialize)]
|
||||
struct Instruction {
|
||||
pub name: String,
|
||||
pub args: Vec<String>,
|
||||
pub output: String,
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let output_path = Path::new(&env::var("OUT_DIR").unwrap())
|
||||
.join("hyphae_instr.rs");
|
||||
let input = fs::read_to_string("instructions.toml")
|
||||
.unwrap();
|
||||
let mut output_file =
|
||||
BufWriter::new(File::create(&output_path).unwrap());
|
||||
|
||||
let instruction_table: Document =
|
||||
toml::from_str(&input)
|
||||
.expect("hyphae: failed to parse instructions.toml");
|
||||
|
||||
let mut isa = "#[repr(transparent)]\n".to_owned();
|
||||
isa += "#[derive(Clone, Debug, PartialEq)]\n";
|
||||
isa += "pub struct Operation(pub u8);\n\n";
|
||||
|
||||
let mut isa_from_byte = "impl TryFrom<u8> for Operation {\n".to_owned();
|
||||
isa_from_byte += " type Error = &'static str;\n";
|
||||
isa_from_byte += " fn try_from(v: u8) -> Result<Self, Self::Error> {\n";
|
||||
isa_from_byte += " match v {\n";
|
||||
|
||||
|
||||
let mut isa_fromstr = "impl FromStr for Operation {\n".to_owned();
|
||||
isa_fromstr += " type Err = &'static str;\n";
|
||||
isa_fromstr += " fn from_str(v: &str) -> Result<Self, Self::Err> {\n";
|
||||
isa_fromstr += " match v {\n";
|
||||
|
||||
let mut isa_from_str = "impl TryFrom<&str> for Operation {\n".to_owned();
|
||||
isa_from_str += " type Error = &'static str;\n";
|
||||
isa_from_str += " fn try_from(v: &str) -> Result<Self, Self::Error> {\n";
|
||||
isa_from_str += " match v {\n";
|
||||
|
||||
let mut isa_num_args = "impl Operation {\n".to_owned();
|
||||
isa_num_args += " pub fn num_args(&self) -> Result<u8, &'static str> {\n";
|
||||
isa_num_args += " match self.0 {\n";
|
||||
|
||||
instruction_table.instructions.iter()
|
||||
.enumerate()
|
||||
.for_each(|(idx, instr)| {
|
||||
let const_name = instr.name.to_ascii_uppercase();
|
||||
|
||||
isa += format!("pub const {}: Operation = Operation({});\n",
|
||||
const_name, idx).as_str();
|
||||
|
||||
isa_from_byte += format!(" {} => Ok({}),\n", idx, const_name)
|
||||
.as_str();
|
||||
|
||||
isa_from_str += format!(" \"{}\" => Ok({}),\n",
|
||||
const_name, const_name).as_str();
|
||||
|
||||
isa_fromstr += format!(" \"{}\" => Ok({}),\n",
|
||||
const_name, const_name).as_str();
|
||||
|
||||
isa_num_args += format!(" {} => Ok({}),\n", idx, instr.args.len())
|
||||
.as_str()
|
||||
});
|
||||
|
||||
isa_from_byte += " _ => Err(\"illegal instruction\"),\n";
|
||||
isa_from_byte += " }\n";
|
||||
isa_from_byte += " }\n";
|
||||
isa_from_byte += "}\n\n";
|
||||
|
||||
isa_from_str += " _ => Err(\"illegal instruction\"),\n";
|
||||
isa_from_str += " }\n";
|
||||
isa_from_str += " }\n";
|
||||
isa_from_str += "}\n\n";
|
||||
|
||||
isa_fromstr += " _ => Err(\"illegal instruction\"),\n";
|
||||
isa_fromstr += " }\n";
|
||||
isa_fromstr += " }\n";
|
||||
isa_fromstr += "}\n\n";
|
||||
|
||||
isa_num_args += " _ => Err(\"illegal instruction\"),\n";
|
||||
isa_num_args += " }\n";
|
||||
isa_num_args += " }\n";
|
||||
isa_num_args += "}\n\n";
|
||||
|
||||
isa += "\n";
|
||||
isa += isa_from_byte.as_str();
|
||||
isa += isa_from_str.as_str();
|
||||
isa += isa_fromstr.as_str();
|
||||
isa += isa_num_args.as_str();
|
||||
|
||||
write!(&mut output_file, "use core::str::FromStr;\n\n\n").unwrap();
|
||||
write!(&mut output_file, "{}", isa).unwrap();
|
||||
println!("cargo::rerun-if-changed=build.rs");
|
||||
println!("cargo::rerun-if-changed=instructions.json");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue