diff --git a/Cargo.lock b/Cargo.lock index 7c7db20..77c4d18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,15 +157,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "dependency-graph" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5143247629540606d0888beae9ca0e0b9a81a32151bfecd0b2be4a961155c24d" -dependencies = [ - "petgraph", -] - [[package]] name = "digest" version = "0.10.5" @@ -188,12 +179,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - [[package]] name = "generic-array" version = "0.14.6" @@ -249,21 +234,6 @@ dependencies = [ "unescape", ] -[[package]] -name = "henceforth" -version = "0.1.0" -dependencies = [ - "anyhow", - "clap", - "dependency-graph", - "hence", - "indexmap", - "itertools", - "lazy_static", - "parse_int", - "petgraph", -] - [[package]] name = "hermit-abi" version = "0.1.19" @@ -358,16 +328,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "petgraph" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" -dependencies = [ - "fixedbitset", - "indexmap", -] - [[package]] name = "ppv-lite86" version = "0.2.16" diff --git a/Cargo.toml b/Cargo.toml index 06c9a23..392b71c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = ["hence", "henceforth"] +members = ["hence"] diff --git a/hence/Cargo.toml b/hence/Cargo.toml index 4f258a0..a39a5d4 100644 --- a/hence/Cargo.toml +++ b/hence/Cargo.toml @@ -5,14 +5,6 @@ edition = "2021" authors = ["Dominic Grimm "] repository = "https://git.dergrimm.net/dergrimm/hence.git" -[lib] -name = "hence" -path = "src/lib/lib.rs" - -[[bin]] -name = "hence" -path = "src/bin/main.rs" - # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/hence/hence.circ b/hence/hence.circ deleted file mode 100644 index 057c374..0000000 --- a/hence/hence.circ +++ /dev/null @@ -1,201 +0,0 @@ - - - This file is intended to be loaded by Logisim-evolution v3.7.2(https://github.com/logisim-evolution/). - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - addr/data: 16 8 -3 7f fc 86 1 0 1 1 -0 2 85 82 6 0 5 85 -6 0 6 4 0 5 88 4 -0 6 88 89 3 ff ff 86 -32732*0 3 0 4 86 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/hence/lib/core.asm b/hence/lib/core.asm index b33bc16..f9dc64b 100644 --- a/hence/lib/core.asm +++ b/hence/lib/core.asm @@ -1,6 +1,5 @@ ; hence core lib -core: .define NULL, 0x0000 .define VOID, NULL @@ -12,44 +11,41 @@ core: .define CORE_KB, 1024 - core_mem: - .define CORE_MEM_PRG, (0 * CORE_KB) - .define CORE_MEM_PRG_END, (32 * CORE_KB) - .define CORE_MEM_ST, CORE_MEM_PRG_END - .define CORE_MEM_MEM, (40 * CORE_KB) - .define CORE_MEM_MEM_END, (48 * CORE_KB) - .define CORE_MEM_OUT, CORE_MEM_MEM_END - .define CORE_MEM_CHR, (CORE_MEM_MEM_END + 1) - .define CORE_MEM_KEY, (CORE_MEM_MEM_END + 2) + .define CORE_MEM_PRG, (0 * CORE_KB) + .define CORE_MEM_PRG_END, (32 * CORE_KB) + .define CORE_MEM_ST, CORE_MEM_PRG_END + .define CORE_MEM_MEM, (40 * CORE_KB) + .define CORE_MEM_MEM_END, (48 * CORE_KB) + .define CORE_MEM_OUT, CORE_MEM_MEM_END + .define CORE_MEM_CHR, (CORE_MEM_MEM_END + 1) + .define CORE_MEM_KEY, (CORE_MEM_MEM_END + 2) - core_reg: - .define CORE_REG_PC, 0x0 - .define CORE_REG_OPC, 0x1 - .define CORE_REG_ARG, 0x2 - .define CORE_REG_S, 0x3 - .define CORE_REG_SP, 0x4 - .define CORE_REG_A, 0x5 - .define CORE_REG_B, 0x6 - .define CORE_REG_C, 0x7 - .define CORE_REG_D, 0x8 + .define CORE_REG_PC, 0x0 + .define CORE_REG_OPC, 0x1 + .define CORE_REG_ARG, 0x2 + .define CORE_REG_S, 0x3 + .define CORE_REG_SP, 0x4 + .define CORE_REG_A, 0x5 + .define CORE_REG_B, 0x6 + .define CORE_REG_C, 0x7 + .define CORE_REG_D, 0x8 - core_alu: - .define CORE_ALU_NOT, 0x00 - .define CORE_ALU_AND, 0x01 - .define CORE_ALU_OR, 0x02 - .define CORE_ALU_XOR, 0x03 - .define CORE_ALU_LSH, 0x04 - .define CORE_ALU_RSH, 0x05 - .define CORE_ALU_ADD, 0x06 - .define CORE_ALU_SUB, 0x07 - .define CORE_ALU_MUL, 0x08 - .define CORE_ALU_DIV, 0x09 - .define CORE_ALU_CMP, 0x0a - .define CORE_ALU_EQ, 0x0b - .define CORE_ALU_LT, 0x0c - .define CORE_ALU_GT, 0x0d - .define CORE_ALU_LEQ, 0x0e - .define CORE_ALU_GEQ, 0x0f - .define CORE_ALU_BOL, 0x10 - .define CORE_ALU_INV, 0x11 - .define CORE_ALU_RND, 0x12 + .define CORE_ALU_NOT, 0x00 + .define CORE_ALU_AND, 0x01 + .define CORE_ALU_OR, 0x02 + .define CORE_ALU_XOR, 0x03 + .define CORE_ALU_LSH, 0x04 + .define CORE_ALU_RSH, 0x05 + .define CORE_ALU_ADD, 0x06 + .define CORE_ALU_SUB, 0x07 + .define CORE_ALU_MUL, 0x08 + .define CORE_ALU_DIV, 0x09 + .define CORE_ALU_CMP, 0x0a + .define CORE_ALU_EQ, 0x0b + .define CORE_ALU_LT, 0x0c + .define CORE_ALU_GT, 0x0d + .define CORE_ALU_LEQ, 0x0e + .define CORE_ALU_GEQ, 0x0f + .define CORE_ALU_BOL, 0x10 + .define CORE_ALU_INV, 0x11 + .define CORE_ALU_RND, 0x12 diff --git a/hence/lib/std.asm b/hence/lib/std.asm index 09972bf..97a70e9 100644 --- a/hence/lib/std.asm +++ b/hence/lib/std.asm @@ -2,66 +2,65 @@ .requires "$lib/core.asm" -std: - .macro std_tclr - ts NULL - .endmacro +.macro std_tclr + ts NULL +.endmacro - .macro std_rclr, lib_std_rclr_arg_0_reg - ts NULL - tlr lib_std_rclr_arg_0_reg - .endmacro +.macro std_rclr, lib_std_rclr_arg_0_reg + ts NULL + tlr lib_std_rclr_arg_0_reg +.endmacro - .macro std_alu, lib_std_alu_arg_0_op - ts lib_std_alu_arg_0_op - alu - .endmacro +.macro std_alu, lib_std_alu_arg_0_op + ts lib_std_alu_arg_0_op + alu +.endmacro - .macro std_get, lib_std_get_arg_0_addr - ts lib_std_get_arg_0_addr - get - .endmacro +.macro std_get, lib_std_get_arg_0_addr + ts lib_std_get_arg_0_addr + get +.endmacro - .macro std_set, lib_std_set_arg_0_addr - ts lib_std_set_arg_0_addr - set - .endmacro +.macro std_set, lib_std_set_arg_0_addr + ts lib_std_set_arg_0_addr + set +.endmacro - .macro std_cp, lib_std_cp_arg_0_from, lib_std_cp_arg_1_to - tsr lib_std_cp_arg_0_from - tlr lib_std_cp_arg_1_to - .endmacro +.macro std_cp, lib_std_cp_arg_0_from, lib_std_cp_arg_1_to + tsr lib_std_cp_arg_0_from + tlr lib_std_cp_arg_1_to +.endmacro - .macro std_mv, lib_std_mv_arg_0_from, lib_std_cp_arg_1_to - tsr lib_std_cp_arg_0_from - tlr lib_std_cp_arg_1_to - .std_rclr lib_std_cp_arg_1_to - .endmacro +.macro std_mv, lib_std_mv_arg_0_from, lib_std_cp_arg_1_to + tsr lib_std_cp_arg_0_from + tlr lib_std_cp_arg_1_to + .std_rclr lib_std_cp_arg_1_to +.endmacro - .macro std_rset, lib_std_init_arg_0_reg, lib_std_init_arg_1_val - ts lib_std_init_arg_1_val - tlr lib_std_init_arg_0_reg - .endmacro +.macro std_rset, lib_std_init_arg_0_reg, lib_std_init_arg_1_val + ts lib_std_init_arg_1_val + tlr lib_std_init_arg_0_reg +.endmacro - .macro std_jump, lib_std_jump_arg_0_label - .std_rset CORE_REG_PC, lib_std_jump_arg_0_label - .endmacro +.macro std_jump, lib_std_jump_arg_0_label + .std_rset CORE_REG_PC, lib_std_jump_arg_0_label +.endmacro - .macro std_cond_jump, lib_std_cond_jump_arg_0_label - ts lib_std_cond_jump_arg_0_label - tlrc CORE_REG_PC - .endmacro +.macro std_cond_jump, lib_std_cond_jump_arg_0_label + ts lib_std_cond_jump_arg_0_label + tlrc CORE_REG_PC +.endmacro - .macro std_stop - .std_rset CORE_REG_PC, 0xffff - .endmacro +.macro std_stop + .std_rset CORE_REG_PC, 0xffff +.endmacro - .macro std_inc, lib_std_inc_arg_0_reg - .std_rset lib_std_inc_arg_0_reg, 1 - .std_alu CORE_ALU_ADD - .endmacro +.macro std_inc, lib_std_inc_arg_0_reg + .std_rset lib_std_inc_arg_0_reg, 1 + .std_alu CORE_ALU_ADD +.endmacro - .macro std_ld - tss - pop - .endmacro +.macro std_ld + tss + pop +.endmacro diff --git a/hence/src/lib/arg.rs b/hence/src/arg.rs similarity index 100% rename from hence/src/lib/arg.rs rename to hence/src/arg.rs diff --git a/hence/src/lib/assembler.rs b/hence/src/assembler.rs similarity index 100% rename from hence/src/lib/assembler.rs rename to hence/src/assembler.rs diff --git a/hence/src/lib/emulator.rs b/hence/src/emulator.rs similarity index 100% rename from hence/src/lib/emulator.rs rename to hence/src/emulator.rs diff --git a/hence/src/lib/lexer.rs b/hence/src/lexer.rs similarity index 100% rename from hence/src/lib/lexer.rs rename to hence/src/lexer.rs diff --git a/hence/src/lib/lib.rs b/hence/src/lib.rs similarity index 100% rename from hence/src/lib/lib.rs rename to hence/src/lib.rs diff --git a/hence/src/bin/main.rs b/hence/src/main.rs similarity index 100% rename from hence/src/bin/main.rs rename to hence/src/main.rs diff --git a/hence/src/lib/parser.rs b/hence/src/parser.rs similarity index 100% rename from hence/src/lib/parser.rs rename to hence/src/parser.rs diff --git a/hence/src/lib/parser/ast.rs b/hence/src/parser/ast.rs similarity index 100% rename from hence/src/lib/parser/ast.rs rename to hence/src/parser/ast.rs diff --git a/henceforth/.gitignore b/henceforth/.gitignore deleted file mode 100644 index 204b6bf..0000000 --- a/henceforth/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -examples/*.asm -examples/*.bin diff --git a/henceforth/Cargo.toml b/henceforth/Cargo.toml deleted file mode 100644 index e4cb700..0000000 --- a/henceforth/Cargo.toml +++ /dev/null @@ -1,28 +0,0 @@ -[package] -name = "henceforth" -version = "0.1.0" -edition = "2021" -authors = ["Dominic Grimm "] -repository = "https://git.dergrimm.net/dergrimm/hence.git" - -[lib] -name = "henceforth" -path = "src/lib/lib.rs" - -[[bin]] -name = "henceforth" -path = "src/bin/main.rs" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -hence = { path = "../hence" } -clap = { version = "3.2.16", features = ["derive"] } -anyhow = { version = "1.0.62", features = ["backtrace"] } -itertools = "0.10.2" -parse_int = "0.6.0" -indexmap = "1.9.1" -lazy_static = "1.4.0" -dependency-graph = "0.1.5" -petgraph = "0.6.2" - diff --git a/henceforth/examples/test.fth b/henceforth/examples/test.fth deleted file mode 100644 index c661066..0000000 --- a/henceforth/examples/test.fth +++ /dev/null @@ -1,6 +0,0 @@ -: test1 40 ; -: test2 test1 2 ; - -1 1 = debug -if 69 else 42 then debug - diff --git a/henceforth/src/bin/main.rs b/henceforth/src/bin/main.rs deleted file mode 100644 index ebfd413..0000000 --- a/henceforth/src/bin/main.rs +++ /dev/null @@ -1,83 +0,0 @@ -use anyhow::Result; -use clap::{Parser, Subcommand}; -use hence::assembler::ToCode; -use std::fs; - -use henceforth::*; - -#[derive(Debug, Parser)] -#[clap(author, version, about, long_about = None)] -struct Cli { - #[clap(subcommand)] - commands: Commands, -} - -#[derive(Debug, Subcommand)] -enum Commands { - #[clap(about = "Lexes source code and outputs tokens")] - Lex { - #[clap(value_parser)] - src: String, - }, - #[clap(about = "Parses source code and outputs AST")] - Parse { - #[clap(value_parser)] - src: String, - }, - #[clap(about = "Compiles assembly from source code")] - Compile { - #[clap(value_parser)] - src: String, - #[clap(value_parser)] - out: Option, - #[clap(short, long, action)] - optimize: Option, - #[clap(long, action)] - dump: bool, - }, -} - -fn main() -> Result<()> { - let args = Cli::parse(); - match args.commands { - Commands::Lex { src } => { - let source = fs::read_to_string(src)?; - let tokens = lexer::lex(&source)?; - dbg!(tokens); - - Ok(()) - } - Commands::Parse { src } => { - let source = fs::read_to_string(src)?; - let tokens = lexer::lex(&source)?; - let body = parser::parse(tokens)?; - dbg!(body); - - Ok(()) - } - Commands::Compile { - src, - out, - optimize, - dump, - } => { - let source = fs::read_to_string(&src)?; - let tokens = lexer::lex(&source)?; - let ast = parser::parse(tokens)?; - let ast = compiler::compile(ast, optimize.unwrap_or(true))?; - let assembly = ast.to_code(); - - if let Some(x) = out { - fs::write(x, &assembly)?; - } - if dump { - println!("{}", assembly); - } - - Ok(()) - } - } -} - -#[cfg(test)] -mod tests {} diff --git a/henceforth/src/lib/compiler.rs b/henceforth/src/lib/compiler.rs deleted file mode 100644 index 87facdd..0000000 --- a/henceforth/src/lib/compiler.rs +++ /dev/null @@ -1,297 +0,0 @@ -use anyhow::{bail, Context, Result}; -use indexmap::IndexSet; -use itertools::Itertools; -use lazy_static::lazy_static; -use petgraph::{graph::NodeIndex, Graph}; -use std::collections::HashMap; - -use crate::parser; - -mod instruction; -pub use crate::compiler::instruction::Instruction; - -pub const TEMPLATE_ASM: &str = include_str!("compiler/templates/default.asm"); - -lazy_static! { - #[derive(Debug)] - pub static ref TEMPLATE: hence::parser::ast::Body = hence::parser::parse( - hence::lexer::lex(TEMPLATE_ASM).unwrap() - ) - .unwrap() - .body; -} - -pub trait Compilable { - fn compile(&self, data: &T) -> Result; -} - -#[derive(Debug)] -pub struct Word { - pub id: usize, - pub instructions: Vec, - pub times_used: usize, - pub callable_graph_node: NodeIndex, -} - -#[derive(Debug, PartialEq, Eq, Hash)] -pub struct Condition { - pub if_instructions: Vec, - pub else_instructions: Vec, - pub callable_graph_node: NodeIndex, -} - -#[derive(Debug)] -pub enum CallableId { - Word(String), - Condition(usize), -} - -#[derive(Debug)] -pub struct Data { - pub strings: IndexSet, - pub callable_graph: Graph, - pub words: HashMap, - pub conditions: Vec, -} - -impl Data { - pub fn default() -> Self { - Self { - // words: HashMap::new(), - // conditions: IndexSet::new(), - strings: IndexSet::new(), - callable_graph: Graph::new(), - words: HashMap::new(), - conditions: vec![], - } - } - - pub fn add_graph_edge(&mut self, origin: NodeIndex, instruction: Instruction) -> Result<()> { - match instruction { - Instruction::Call(x) => { - self.callable_graph.add_edge( - origin, - self.words - .get(&x) - .context(format!("Could not get already resolved referenced word: {}", x))? - .callable_graph_node, - (), - ); - } - Instruction::Condition(x) => { - self.callable_graph.add_edge( - origin, - self.conditions - .get(x) - .context(format!("Could not get already resolved referenced condition: {}", x))? - .callable_graph_node, - (), - ); - } - Instruction::Multiple { - instruction, - count: _, - } => { - self.add_graph_edge(origin, *instruction)?; - } - _ => {} - } - - Ok(()) - } - - pub fn add_graph_edges(&mut self, origin: NodeIndex, ins: Vec) -> Result<()> { - for instruction in ins { - self.add_graph_edge(origin, instruction)?; - } - - Ok(()) - } - - pub fn generate_instructions( - &mut self, - body: parser::ast::Body, - optimize: bool, - ) -> Result> { - let mut instructions: Vec = vec![]; - let mut iter = body.into_iter().peekable(); - while let Some(node) = iter.next() { - match node { - _ if optimize && iter.next_if_eq(&node).is_some() => { - let count = iter.by_ref().peeking_take_while(|n| *n == node).count() + 2; - instructions.push(Instruction::Multiple { - instruction: Box::new( - self.generate_instructions(vec![node], optimize)? - .into_iter() - .next() - .unwrap(), - ), - count, - }); - } - parser::ast::Node::Comment(_) => {} - parser::ast::Node::String { mode, string } => { - instructions.push(match mode.as_str() { - "." => { - let id = self.strings.insert_full(string).0; - Instruction::StringPrint(id) - } - "r" => { - let id = self.strings.insert_full(string).0; - Instruction::StringReference(id) - } - "asm" => Instruction::AsmQuote(string), - _ => bail!("Unknown string mode: {}", mode), - }); - } - parser::ast::Node::Number(x) => { - instructions.push(instruction::Instruction::Push(x)); - } - parser::ast::Node::WordDefinition { - name, - stack: _, - body, - } => { - if Instruction::from_word(&name).is_some() { - bail!("Word already exists as compiler instruction: {}", name); - } else if self.words.contains_key(&name) { - bail!("Word already exists as user word definition: {}", name); - } - - let origin = self - .callable_graph - .add_node(CallableId::Word(name.to_string())); - self.words.insert( - name.to_string(), - Word { - id: self.words.len(), - instructions: vec![], - times_used: 0, - callable_graph_node: origin, - }, - ); - let ins = self.generate_instructions(body, optimize)?; - self.words - .get_mut(&name) - .context(format!("Could not get word: {}", name))? - .instructions = ins.clone(); - self.add_graph_edges(origin, ins)?; - } - parser::ast::Node::Condition { if_body, else_body } => { - let if_instructions = self.generate_instructions(if_body, optimize)?; - let else_instructions = self.generate_instructions(else_body, optimize)?; - let id = self.conditions.len(); - let origin = self.callable_graph.add_node(CallableId::Condition(id)); - self.conditions.push(Condition { - if_instructions: if_instructions.clone(), - else_instructions: else_instructions.clone(), - callable_graph_node: origin, - }); - instructions.push(Instruction::Condition(id)); - self.add_graph_edges(origin, if_instructions)?; - self.add_graph_edges(origin, else_instructions)?; - dbg!(&self); - } - parser::ast::Node::Word(x) => { - if let Some(ins) = Instruction::from_word(&x) { - instructions.push(ins); - } else if let Some(w) = self.words.get_mut(&x) { - w.times_used += 1; - instructions.push(Instruction::Call(x)); - } else { - bail!("Word does not exist: {}", x); - } - } - } - } - - Ok(instructions) - } - - pub fn embed(&self, body: hence::parser::ast::Body) -> Result { - let mut x = TEMPLATE.to_vec(); - - // strings - for (id, s) in self.strings.iter().enumerate() { - x.extend([ - hence::parser::ast::Node::Label(format!("data_strings_{}", id)), - hence::parser::ast::Node::MacroCall { - name: "bytes".to_string(), - args: vec![hence::arg::Arg::String(s.to_string())], - }, - hence::parser::ast::Node::Label(format!("data_strings_end_{}", id)), - ]); - } - - // conditions - // for (id, c) in self.conditions.iter().enumerate() { - // x.push(hence::parser::ast::Node::Label(format!( - // "conditions_if_{}", - // id - // ))); - // x.extend(c.if_instructions.iter().map(|ins| ins.compile(self)).collect::>>()?.into_iter().flatten()); - // x.push(hence::parser::ast::Node::Label(format!("conditions_else_{}", id))); - // x.extend(c.else_instructions.iter().map(|ins| ins.compile(self)).collect::>>()?.into_iter().flatten()); - // } - - // words - // for (name, word) in &self - // .words - // .iter() - // .filter(|(_, w)| w.times_used > 1) - // .sorted_by(|a, b| Ord::cmp(&a.1.id, &b.1.id)) - // .collect::>() - // { - // x.extend(vec![ - // hence::parser::ast::Node::Label(format!("words_{}", word.id)), - // hence::parser::ast::Node::Comment(format!("word: \"{}\"", name)), - // ]); - // x.extend( - // word.instructions - // .iter() - // .map(|ins| ins.compile(self)) - // .collect::>>() - // .unwrap() - // .into_iter() - // .flatten() - // ); - // x.push(hence::parser::ast::Node::MacroCall { - // name: "return_call_stack_jump".to_string(), - // args: vec![], - // }); - // } - - x.extend([ - hence::parser::ast::Node::Label("main".to_string()), - hence::parser::ast::Node::MacroCall { - name: "main".to_string(), - args: vec![hence::arg::Arg::Variable("main".to_string())], - }, - ]); - x.extend(body); - x.push(hence::parser::ast::Node::MacroCall { - name: "std_stop".to_string(), - args: vec![], - }); - - Ok(x) - } -} - -pub fn compile(ast: parser::ast::AST, optimize: bool) -> Result { - let mut data = Data::default(); - let instructions = data.generate_instructions(ast.body, optimize)?; - - Ok(hence::parser::ast::AST { - body: data.embed( - instructions - .iter() - .map(|ins| ins.compile(&data)) - .collect::>>() - .unwrap() - .into_iter() - .flatten() - .collect(), - )?, - }) -} diff --git a/henceforth/src/lib/compiler/instruction.rs b/henceforth/src/lib/compiler/instruction.rs deleted file mode 100644 index 11f8ef0..0000000 --- a/henceforth/src/lib/compiler/instruction.rs +++ /dev/null @@ -1,1530 +0,0 @@ -use anyhow::{bail, Result}; - -use crate::compiler; - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum Instruction { - Nop, - Debug, - Quit, - Push(i32), - Drop, - Depth, - Pick, - Dup, - Swap, - Over, - Rot, - Nip, - I, - J, - Tuck, - Fetch, - FetchPrint, - Store, - PlusStore, - MinusStore, - Cells, - Allot, - Dot, - Emit, - Space, - Spaces, - Cr, - StringPrint(usize), - StringReference(usize), - Count, - Not, - And, - Nand, - Or, - Nor, - Xor, - Xnor, - Lsh, - Rsh, - Compare, - Eq, - Neq, - Lt, - Leq, - Gt, - Geq, - Min, - Max, - Boolean, - Invert, - Random, - Plus, - OnePlus, - TwoPlus, - Minus, - OneMinus, - TwoMinus, - Times, - Divide, - Mod, - AsmQuote(String), - - Multiple { - instruction: Box, - count: usize, - }, - - Call(String), - Condition(usize), -} - -impl compiler::Compilable for Instruction { - fn compile(&self, data: &compiler::Data) -> Result { - match self { - Instruction::Nop => Ok(vec![hence::parser::ast::Node::Call { - name: "nop".to_string(), - arg: None, - }]), - Instruction::Debug => Ok(vec![hence::parser::ast::Node::Call { - name: "dbg".to_string(), - arg: None, - }]), - Instruction::Quit => Ok(vec![hence::parser::ast::Node::MacroCall { - name: "std_stop".to_string(), - args: vec![], - }]), - Instruction::Push(x) => Ok(vec![hence::parser::ast::Node::Call { - name: "push".to_string(), - arg: Some(hence::arg::Arg::Number(*x as u16)), - }]), - Instruction::Drop => Ok(vec![hence::parser::ast::Node::Call { - name: "pop".to_string(), - arg: None, - }]), - Instruction::Depth => Ok(vec![ - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_SP".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Pick => Ok(vec![ - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_SP".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_SUB".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_rset".to_string(), - args: vec![ - hence::arg::Arg::Variable("CORE_REG_B".to_string()), - hence::arg::Arg::BinaryExpression { - left: Box::new(hence::arg::Arg::Variable( - "CORE_MEM_PRG_END".to_string(), - )), - right: Box::new(hence::arg::Arg::Number(2)), - op: hence::arg::BinaryExpressionOperator::Sub, - }, - ], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_ADD".to_string())], - }, - hence::parser::ast::Node::Call { - name: "get".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Dup => Ok(vec![ - hence::parser::ast::Node::Call { - name: "tss".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Swap => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Over => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tss".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Rot => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Nip => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "pop".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::I => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_get".to_string(), - args: vec![hence::arg::Arg::Variable("MEM_LOOP_I".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::J => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_get".to_string(), - args: vec![hence::arg::Arg::Variable("MEM_LOOP_J".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Tuck => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Fetch => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "get".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::FetchPrint => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "get".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_set".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_MEM_OUT".to_string())], - }, - ]), - Instruction::Store => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "set".to_string(), - arg: None, - }, - ]), - Instruction::PlusStore => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "get".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_ADD".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "set".to_string(), - arg: None, - }, - ]), - Instruction::MinusStore => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "get".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_SUB".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "set".to_string(), - arg: None, - }, - ]), - Instruction::Cells => Ok(vec![]), - Instruction::Allot => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_get".to_string(), - args: vec![hence::arg::Arg::Variable("MEM_ALLOC_PTR".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_ADD".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_set".to_string(), - args: vec![hence::arg::Arg::Variable("MEM_ALLOC_PTR".to_string())], - }, - ]), - Instruction::Dot => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_set".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_MEM_OUT".to_string())], - }, - ]), - Instruction::Emit => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_set".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_MEM_CHR".to_string())], - }, - ]), - Instruction::Space => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_rset".to_string(), - args: vec![ - hence::arg::Arg::Variable("CORE_REG_A".to_string()), - hence::arg::Arg::Char(' '), - ], - }, - hence::parser::ast::Node::MacroCall { - name: "std_set".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_MEM_CHR".to_string())], - }, - ]), - Instruction::Spaces => Ok(vec![]), - Instruction::Cr => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_rset".to_string(), - args: vec![ - hence::arg::Arg::Variable("CORE_REG_A".to_string()), - hence::arg::Arg::Char('\n'), - ], - }, - hence::parser::ast::Node::MacroCall { - name: "std_set".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_MEM_CHR".to_string())], - }, - ]), - Instruction::StringPrint(x) => { - let loop_label = format!("loop_strings_{}", x); - let data_label = format!("data_strings_{}", x); - let data_end_label = format!("data_strings_end_{}", x); - - Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_rset".to_string(), - args: vec![ - hence::arg::Arg::Variable("CORE_REG_B".to_string()), - hence::arg::Arg::Variable(data_label), - ], - }, - hence::parser::ast::Node::Label(loop_label.clone()), - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "get".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_set".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_MEM_CHR".to_string())], - }, - hence::parser::ast::Node::MacroCall { - name: "std_rset".to_string(), - args: vec![ - hence::arg::Arg::Variable("CORE_REG_A".to_string()), - hence::arg::Arg::Number(1), - ], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_ADD".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_rset".to_string(), - args: vec![ - hence::arg::Arg::Variable("CORE_REG_A".to_string()), - hence::arg::Arg::Variable(data_end_label), - ], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_GT".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_cond_jump".to_string(), - args: vec![hence::arg::Arg::Variable(loop_label)], - }, - ]) - } - Instruction::StringReference(x) => Ok(vec![ - hence::parser::ast::Node::Call { - name: "push".to_string(), - arg: Some(hence::arg::Arg::Variable(format!("data_strings_end_{}", x))), - }, - hence::parser::ast::Node::Call { - name: "push".to_string(), - arg: Some(hence::arg::Arg::Variable(format!("data_strings_{}", x))), - }, - ]), - Instruction::Count => Ok(vec![]), - Instruction::Not => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_NOT".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::And => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_AND".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Nand => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_AND".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_NOT".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Or => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_OR".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Nor => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_OR".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_NOT".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Xor => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_XOR".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Xnor => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_XOR".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_NOT".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Lsh => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_LSH".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Rsh => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_RSH".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Compare => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_CMP".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Eq => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_EQ".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Neq => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_EQ".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_INV".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Lt => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_LT".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Leq => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_LEQ".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Gt => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_GT".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Geq => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_GEQ".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Min => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_GT".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tlrc".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Max => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_LT".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tlrc".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Boolean => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_BOL".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Invert => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_INV".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Random => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_RND".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Plus => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_ADD".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::OnePlus => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_rset".to_string(), - args: vec![ - hence::arg::Arg::Variable("CORE_REG_B".to_string()), - hence::arg::Arg::Number(1), - ], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_ADD".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::TwoPlus => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_rset".to_string(), - args: vec![ - hence::arg::Arg::Variable("CORE_REG_B".to_string()), - hence::arg::Arg::Number(2), - ], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_ADD".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Minus => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_SUB".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::OneMinus => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_rset".to_string(), - args: vec![ - hence::arg::Arg::Variable("CORE_REG_B".to_string()), - hence::arg::Arg::Number(1), - ], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_SUB".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::TwoMinus => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_rset".to_string(), - args: vec![ - hence::arg::Arg::Variable("CORE_REG_B".to_string()), - hence::arg::Arg::Number(2), - ], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_SUB".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Times => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_MUL".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Divide => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "stack_transfer_alu".to_string(), - args: vec![], - }, - hence::parser::ast::Node::MacroCall { - name: "std_alu".to_string(), - args: vec![hence::arg::Arg::Variable("CORE_ALU_DIV".to_string())], - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - Instruction::Mod => Ok(vec![]), - // Instruction::Call(x) => match data.words.get(x) { - // Some(w) => { - // if w.times_used > 1 { - // Ok(vec![hence::parser::ast::Node::MacroCall { - // name: "call_stack_jump".to_string(), - // args: vec![hence::arg::Arg::Variable(format!("words_{}", w.id)), hence::arg::Arg::Variable("OFFSET".to_string())], - // }]) - // } else { - // Ok(w.instructions - // .iter() - // .map(|ins| ins.compile(data)) - // .collect::>>()? - // .into_iter() - // .flatten() - // .collect()) - // } - // } - // None => bail!("Unknown word: {}", x), - // }, - Instruction::Call(x) => bail!("Unknown word: {}", x), - Instruction::AsmQuote(x) => Ok(hence::parser::parse(hence::lexer::lex(x)?)?.body), - // Instruction::Condition(x) => Ok(vec![]), - Instruction::Condition(x) => { - dbg!(x); - - Ok(vec![]) - } - - Instruction::Multiple { instruction, count } => { - if *count == 0 { - Ok(vec![]) - } else if *count == 1 { - Ok(instruction.compile(data)?) - } else { - match **instruction { - Instruction::Nop => Ok(Instruction::Nop.compile(data)?), - Instruction::Quit => Ok(Instruction::Quit.compile(data)?), - Instruction::Push(x) => Ok([ - Instruction::Push(x).compile(data)?, - [hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }] - .into_iter() - .cycle() - .take(count - 1) - .collect(), - ] - .concat()), - Instruction::Depth => Ok([ - Instruction::Depth.compile(data)?, - Instruction::Multiple { - instruction: Box::new(Instruction::Dup), - count: count - 1, - } - .compile(data)?, - ] - .concat()), - Instruction::Dup => Ok([ - Instruction::Dup.compile(data)?, - [hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }] - .into_iter() - .cycle() - .take(count - 1) - .collect(), - ] - .concat()), - Instruction::Swap => { - if count % 2 == 0 { - Ok(vec![]) - } else { - Ok(Instruction::Swap.compile(data)?) - } - } - Instruction::Over => Ok([ - Instruction::Over.compile(data)?, - (0..count - 1) - .flat_map(|n| { - if n % 2 == 0 { - vec![ - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable( - "CORE_REG_A".to_string(), - )), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ] - } else { - vec![ - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable( - "CORE_REG_B".to_string(), - )), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ] - } - }) - .collect(), - ] - .concat()), - Instruction::Rot => match count % 3 { - 0 => Ok(vec![]), - 1 => Ok(Instruction::Rot.compile(data)?), - 2 => Ok(vec![ - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }, - hence::parser::ast::Node::Call { - name: "tlr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - hence::parser::ast::Node::Call { - name: "tsr".to_string(), - arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())), - }, - hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }, - ]), - x => bail!("Remainder of count % 3 cannot be higher than 3: {}", x), - }, - Instruction::Nip => Ok([ - vec![hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }], - [hence::parser::ast::Node::Call { - name: "pop".to_string(), - arg: None, - }] - .into_iter() - .cycle() - .take(*count) - .collect(), - vec![hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }], - ] - .concat()), - Instruction::I | Instruction::J => Ok([ - instruction.compile(data)?, - [hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }] - .into_iter() - .cycle() - .take(count - 1) - .collect(), - ] - .concat()), - Instruction::Fetch => Ok([ - vec![hence::parser::ast::Node::MacroCall { - name: "std_ld".to_string(), - args: vec![], - }], - [hence::parser::ast::Node::Call { - name: "get".to_string(), - arg: None, - }] - .into_iter() - .cycle() - .take(*count) - .collect(), - vec![hence::parser::ast::Node::Call { - name: "tls".to_string(), - arg: None, - }], - ] - .concat()), - Instruction::Space | Instruction::Cr => Ok([ - instruction.compile(data)?, - [hence::parser::ast::Node::Call { - name: "set".to_string(), - arg: None, - }] - .into_iter() - .cycle() - .take(count - 1) - .collect(), - ] - .concat()), - _ => { - let compiled = instruction.compile(data)?; - let len = compiled.len() * count; - Ok(compiled.into_iter().cycle().take(len).collect()) - } - } - } - } - } - } -} - -impl Instruction { - pub fn from_word(word: &str) -> Option { - match word.to_lowercase().as_str() { - "nop" => Some(Instruction::Nop), - "debug" => Some(Instruction::Debug), - "quit" => Some(Instruction::Quit), - "drop" => Some(Instruction::Drop), - "depth" => Some(Instruction::Depth), - "pick" => Some(Instruction::Pick), - "dup" => Some(Instruction::Dup), - "swap" => Some(Instruction::Swap), - "over" => Some(Instruction::Over), - "rot" => Some(Instruction::Rot), - "nip" => Some(Instruction::Nip), - "i" => Some(Instruction::I), - "j" => Some(Instruction::J), - "tuck" => Some(Instruction::Tuck), - "@" => Some(Instruction::Fetch), - "?" => Some(Instruction::FetchPrint), - "!" => Some(Instruction::Store), - "+!" => Some(Instruction::PlusStore), - "-!" => Some(Instruction::MinusStore), - "cells" => Some(Instruction::Cells), - "allot" => Some(Instruction::Allot), - "." => Some(Instruction::Dot), - "emit" => Some(Instruction::Emit), - "space" => Some(Instruction::Space), - "spaces" => Some(Instruction::Spaces), - "cr" => Some(Instruction::Cr), - "count" => Some(Instruction::Count), - "not" => Some(Instruction::Not), - "and" => Some(Instruction::And), - "nand" => Some(Instruction::Nand), - "or" => Some(Instruction::Or), - "nor" => Some(Instruction::Nor), - "xor" => Some(Instruction::Xor), - "xnor" => Some(Instruction::Xnor), - "lshift" => Some(Instruction::Lsh), - "rshift" => Some(Instruction::Rsh), - "compare" => Some(Instruction::Compare), - "=" => Some(Instruction::Eq), - "!=" => Some(Instruction::Neq), - "<" => Some(Instruction::Lt), - "<=" => Some(Instruction::Leq), - ">" => Some(Instruction::Gt), - ">=" => Some(Instruction::Geq), - "min" => Some(Instruction::Min), - "max" => Some(Instruction::Max), - "boolean" => Some(Instruction::Boolean), - "invert" => Some(Instruction::Invert), - "random" => Some(Instruction::Random), - "+" => Some(Instruction::Plus), - "1+" => Some(Instruction::OnePlus), - "2+" => Some(Instruction::TwoPlus), - "-" => Some(Instruction::Minus), - "1-" => Some(Instruction::OneMinus), - "2-" => Some(Instruction::TwoMinus), - "*" => Some(Instruction::Times), - "/" => Some(Instruction::Divide), - "mod" => Some(Instruction::Mod), - _ => None, - } - } -} diff --git a/henceforth/src/lib/compiler/templates/default.asm b/henceforth/src/lib/compiler/templates/default.asm deleted file mode 100644 index b54a29b..0000000 --- a/henceforth/src/lib/compiler/templates/default.asm +++ /dev/null @@ -1,63 +0,0 @@ -.include "$lib/core.asm" -.include "$lib/std.asm" -.include "$lib/main.asm" - -.define MEM_LOOP_I, CORE_MEM_MEM -.define MEM_LOOP_J, (MEM_LOOP_I + 1) -.define MEM_CALL_STACK_PTR, (MEM_LOOP_J + 1) -.define MEM_ALLOC_PTR, (MEM_CALL_STACK_PTR + 16) - -.macro stack_transfer_alu - .std_ld - tlr CORE_REG_B - .std_ld - tlr CORE_REG_A -.endmacro - -.macro call_stack_jump, call_stack_jump_arg_0_label, call_stack_jump_arg_1_offset - .std_rset CORE_REG_C, call_stack_jump_arg_0_label - .std_rset CORE_REG_D, (call_stack_jump_arg_1_offset + 7) - ts call_stack_jump - tlr CORE_REG_PC -.endmacro - -.macro return_call_stack_jump - .std_jump return_call_stack_jump -.endmacro - -.std_rset CORE_REG_A, MEM_CALL_STACK_PTR -.std_set MEM_CALL_STACK_PTR - -.std_rset CORE_REG_A, (MEM_ALLOC_PTR + 1) -.std_set MEM_ALLOC_PTR - -.jump_main - -call_stack_jump: - .std_get MEM_CALL_STACK_PTR - tlr CORE_REG_A - .std_rset CORE_REG_B, 1 - .std_alu CORE_ALU_ADD - tlr CORE_REG_A - tlr CORE_REG_B - .std_set MEM_CALL_STACK_PTR - - tsr CORE_REG_D - tlr CORE_REG_A - tsr CORE_REG_B - set - tsr CORE_REG_C - tlr CORE_REG_PC - -return_call_stack_jump: - .std_get MEM_CALL_STACK_PTR - tlr CORE_REG_A - tlr CORE_REG_C - .std_rset CORE_REG_B, 1 - .std_alu CORE_ALU_SUB - tlr CORE_REG_A - .std_set MEM_CALL_STACK_PTR - - tsr CORE_REG_C - get - tlr CORE_REG_PC diff --git a/henceforth/src/lib/lexer.rs b/henceforth/src/lib/lexer.rs deleted file mode 100644 index edc3e83..0000000 --- a/henceforth/src/lib/lexer.rs +++ /dev/null @@ -1,84 +0,0 @@ -use anyhow::Result; -use hence::assembler::ToCode; -use itertools::Itertools; - -#[derive(Debug)] -pub enum Token { - Newline(usize), - Whitespace(usize), - - ParenComment(String), - BackslashComment(String), - DoubleDashComment(String), - - StringLiteral { mode: String, string: String }, - Number(String), - Word(String), -} - -impl ToCode for Token { - fn to_code(&self) -> String { - match self { - Token::Newline(x) => ["\n"].into_iter().cycle().take(*x).join(""), - Token::Whitespace(x) => [" "].into_iter().cycle().take(*x).join(""), - Token::ParenComment(x) => format!("( {})", x), - Token::BackslashComment(x) => format!("\\{}", x), - Token::DoubleDashComment(x) => format!("-- {}", x), - Token::StringLiteral { mode, string } => format!("{}\" {}\"", mode, string), - Token::Number(x) | Token::Word(x) => x.clone(), - } - } -} - -pub fn is_space(c: char) -> bool { - c.is_whitespace() || c == '\n' -} - -pub fn lex(source: &str) -> Result> { - let mut chars = source.chars().peekable(); - let mut tokens: Vec = vec![]; - - while let Some(c) = chars.peek() { - tokens.push(match c { - '\n' => Token::Newline(chars.peeking_take_while(|&c| c == '\n').count()), - _ if c.is_whitespace() => { - Token::Whitespace(chars.peeking_take_while(|&c| c.is_whitespace()).count()) - } - '\\' => Token::BackslashComment(chars.peeking_take_while(|&c| c != '\n').collect()), - _ if c.is_numeric() => { - Token::Number(chars.peeking_take_while(|&c| !is_space(c)).collect()) - } - _ => { - let x: String = chars.peeking_take_while(|&c| !is_space(c)).collect(); - let mut iter = x.chars(); - - match x.as_str() { - "(" => Token::ParenComment( - chars.by_ref().skip(1).take_while(|&c| c != ')').collect(), - ), - "--" => Token::DoubleDashComment( - chars.by_ref().take_while(|&c| c != '\n').collect(), - ), - _ if x.ends_with('"') => Token::StringLiteral { - mode: x.chars().take(x.len() - 1).collect(), - string: chars.by_ref().skip(1).take_while(|&c| c != '"').collect(), - }, - _ if iter.next() == Some('-') => { - if let Some(c) = iter.next() { - if c.is_numeric() { - Token::Number(x) - } else { - Token::Word(x) - } - } else { - Token::Word(x) - } - } - _ => Token::Word(x), - } - } - }); - } - - Ok(tokens) -} diff --git a/henceforth/src/lib/lib.rs b/henceforth/src/lib/lib.rs deleted file mode 100644 index ac7a00d..0000000 --- a/henceforth/src/lib/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod compiler; -pub mod lexer; -pub mod parser; diff --git a/henceforth/src/lib/parser.rs b/henceforth/src/lib/parser.rs deleted file mode 100644 index f1d6e35..0000000 --- a/henceforth/src/lib/parser.rs +++ /dev/null @@ -1,168 +0,0 @@ -use anyhow::{bail, Result}; -use parse_int; - -use crate::lexer; - -pub mod ast; - -pub fn parse_stack_state(s: Option<&str>) -> Vec { - match s { - Some(x) if !x.trim().is_empty() => { - x.split_whitespace().map(|x| x.trim().to_string()).collect() - } - _ => vec![], - } -} - -pub fn parse_stack_result(s: &str) -> ast::StackResult { - let mut splitter = s.splitn(2, "--"); - - ast::StackResult { - before: parse_stack_state(splitter.next()), - after: parse_stack_state(splitter.next()), - } -} - -pub fn parse(tokens: Vec) -> Result { - let mut iter = tokens.into_iter().peekable(); - let mut body: ast::Body = vec![]; - - while let Some(token) = iter.next() { - match token { - lexer::Token::Newline(_) | lexer::Token::Whitespace(_) => {} - lexer::Token::ParenComment(x) - | lexer::Token::BackslashComment(x) - | lexer::Token::DoubleDashComment(x) => { - body.push(ast::Node::Comment(x.trim().to_string())); - } - lexer::Token::StringLiteral { mode, string } => { - body.push(ast::Node::String { mode, string }); - } - lexer::Token::Number(x) => body.push(ast::Node::Number(parse_int::parse(&x)?)), - lexer::Token::Word(x) => match x.as_str() { - ":" => { - let mut depth: usize = 1; - let mut content = iter - .by_ref() - .take_while(|t| match t { - lexer::Token::Word(x) => match x.as_str() { - ":" => { - depth += 1; - true - } - ";" => { - depth -= 1; - depth != 0 - } - _ => true, - }, - _ => true, - }) - .collect::>() - .into_iter() - .peekable(); - if depth != 0 { - bail!("Unbalanced word definitions"); - } - - let name = match content.find(|t| { - !matches!(t, lexer::Token::Newline(_) | lexer::Token::Whitespace(_)) - }) { - Some(t) => match t { - lexer::Token::Word(x) => x.clone(), - _ => bail!("Word definition name must be a word itself: {:?}", t), - }, - None => bail!("Word definition can not be empty"), - }; - let stack = loop { - if let Some(t) = content.peek() { - match t { - lexer::Token::Newline(_) | lexer::Token::Whitespace(_) => { - content.next(); - } - lexer::Token::ParenComment(x) - | lexer::Token::BackslashComment(x) - | lexer::Token::DoubleDashComment(x) => { - let y = &x.to_string(); - content.next(); - break Some(parse_stack_result(y)); - } - _ => break None, - } - } else { - break None; - } - }; - - body.push(ast::Node::WordDefinition { - name, - stack, - body: parse(content.collect())?.body, - }); - } - "if" => { - let mut depth: usize = 1; - let mut else_used = false; - let if_toks: Vec<_> = iter - .by_ref() - .take_while(|t| match t { - lexer::Token::Word(x) => match x.as_str() { - "if" => { - depth += 1; - true - } - "else" => { - if depth == 1 { - else_used = true; - false - } else { - true - } - } - "then" => { - depth -= 1; - depth != 0 - } - _ => true, - }, - _ => true, - }) - .collect(); - let else_toks: Vec<_> = if else_used { - iter.by_ref() - .take_while(|t| match t { - lexer::Token::Word(x) => match x.as_str() { - "if" => { - depth += 1; - true - } - "then" => { - depth -= 1; - depth != 0 - } - _ => true, - }, - _ => true, - }) - .collect() - } else { - vec![] - }; - if depth != 0 { - bail!("Unbalanced conditions"); - } - - body.push(ast::Node::Condition { - if_body: parse(if_toks)?.body, - else_body: parse(else_toks)?.body, - }); - } - _ => { - body.push(ast::Node::Word(x)); - } - }, - } - } - - Ok(ast::AST { body }) -} diff --git a/henceforth/src/lib/parser/ast.rs b/henceforth/src/lib/parser/ast.rs deleted file mode 100644 index 28f3ef8..0000000 --- a/henceforth/src/lib/parser/ast.rs +++ /dev/null @@ -1,90 +0,0 @@ -use hence::assembler::ToCode; -use itertools::Itertools; - -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct StackResult { - pub before: Vec, - pub after: Vec, -} - -impl ToCode for StackResult { - fn to_code(&self) -> String { - format!( - "{}--{}", - if self.before.is_empty() { - "".to_string() - } else { - format!("{} ", self.before.join(" ")) - }, - if self.after.is_empty() { - "".to_string() - } else { - format!("{} ", self.after.join(" ")) - } - ) - } -} - -#[derive(Debug, PartialEq, Eq)] -pub enum Node { - Comment(String), - String { - mode: String, - string: String, - }, - Number(i32), - WordDefinition { - name: String, - stack: Option, - body: Body, - }, - Condition { - if_body: Body, - else_body: Body, - }, - Word(String), -} - -impl ToCode for Node { - fn to_code(&self) -> String { - match self { - Node::Comment(x) => format!("\\ {}", x), - Node::String { mode, string } => format!("{}\" {}\"", mode, string), - Node::Number(x) => x.to_string(), - Node::WordDefinition { name, stack, body } => format!( - ": {}{} {} ;", - name, - match stack { - Some(x) => format!(" {}", x.to_code()), - None => "".to_string(), - }, - body.iter().map(|x| x.to_code()).join(" ") - ), - Node::Condition { if_body, else_body } => { - if else_body.is_empty() { - format!("if {} then", if_body.iter().map(|x| x.to_code()).join(" ")) - } else { - format!( - "if {} else {} then", - if_body.iter().map(|x| x.to_code()).join(" "), - else_body.iter().map(|x| x.to_code()).join(" ") - ) - } - } - Node::Word(x) => x.clone(), - } - } -} - -pub type Body = Vec; - -#[derive(Debug)] -pub struct AST { - pub body: Body, -} - -impl ToCode for AST { - fn to_code(&self) -> String { - self.body.iter().map(|x| x.to_code()).join(" ") - } -}