WIP HyphaeVM
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. Do note the in progress number package implementation in snippets Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
parent
3a0a141738
commit
0476160ae3
17 changed files with 2065 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