diff --git a/henceforth/examples/test.fth b/henceforth/examples/test.fth index 11d41cb..841fa7b 100644 --- a/henceforth/examples/test.fth +++ b/henceforth/examples/test.fth @@ -1,13 +1 @@ -asm" -.std_get MEM_ALLOC_PTR -tls -dbg -pop -" -3 cells allot -asm" -.std_get MEM_ALLOC_PTR -tls -dbg -pop -" +random . cr diff --git a/henceforth/src/lib/compiler.rs b/henceforth/src/lib/compiler.rs index b2bcc2c..c5aa695 100644 --- a/henceforth/src/lib/compiler.rs +++ b/henceforth/src/lib/compiler.rs @@ -128,7 +128,7 @@ impl Data { hence::parser::ast::Node::MacroCall { name: "define".to_string(), args: vec![ - hence::arg::Arg::Variable("MEM_ALLOC_PTR".to_string()), + hence::arg::Arg::Variable("MEM_LOOP_I".to_string()), hence::arg::Arg::BinaryExpression { left: Box::new(hence::arg::Arg::Variable("CORE_MEM_MEM".to_string())), right: Box::new(hence::arg::Arg::Number(16)), @@ -136,6 +136,28 @@ impl Data { }, ], }, + hence::parser::ast::Node::MacroCall { + name: "define".to_string(), + args: vec![ + hence::arg::Arg::Variable("MEM_LOOP_J".to_string()), + hence::arg::Arg::BinaryExpression { + left: Box::new(hence::arg::Arg::Variable("MEM_LOOP_I".to_string())), + right: Box::new(hence::arg::Arg::Number(1)), + op: hence::arg::BinaryExpressionOperator::Add, + }, + ], + }, + hence::parser::ast::Node::MacroCall { + name: "define".to_string(), + args: vec![ + hence::arg::Arg::Variable("MEM_ALLOC_PTR".to_string()), + hence::arg::Arg::BinaryExpression { + left: Box::new(hence::arg::Arg::Variable("MEM_LOOP_J".to_string())), + right: Box::new(hence::arg::Arg::Number(1)), + op: hence::arg::BinaryExpressionOperator::Add, + }, + ], + }, // macros // stack_transfer_alu hence::parser::ast::Node::MacroCall { diff --git a/henceforth/src/lib/compiler/instruction.rs b/henceforth/src/lib/compiler/instruction.rs index 881a653..c87114b 100644 --- a/henceforth/src/lib/compiler/instruction.rs +++ b/henceforth/src/lib/compiler/instruction.rs @@ -53,6 +53,7 @@ pub enum Instruction { Max, Boolean, Invert, + Random, Plus, OnePlus, TwoPlus, @@ -121,6 +122,7 @@ impl Instruction { "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), @@ -361,8 +363,26 @@ impl compiler::Compilable for Instruct arg: None, }, ]), - Instruction::I => Ok(vec![]), - Instruction::J => Ok(vec![]), + 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(), @@ -611,7 +631,7 @@ impl compiler::Compilable for Instruct name: "std_rset".to_string(), args: vec![ hence::arg::Arg::Variable("CORE_REG_A".to_string()), - hence::arg::Arg::Char('\n'), + hence::arg::Arg::Char(' '), ], }, hence::parser::ast::Node::MacroCall { @@ -625,7 +645,7 @@ impl compiler::Compilable for Instruct name: "std_rset".to_string(), args: vec![ hence::arg::Arg::Variable("CORE_REG_A".to_string()), - hence::arg::Arg::Number(0x0a), + hence::arg::Arg::Char('\n'), ], }, hence::parser::ast::Node::MacroCall { @@ -700,26 +720,314 @@ impl compiler::Compilable for Instruct ]) } Instruction::Count => Ok(vec![]), - Instruction::Not => Ok(vec![]), - Instruction::And => Ok(vec![]), - Instruction::Nand => Ok(vec![]), - Instruction::Or => Ok(vec![]), - Instruction::Nor => Ok(vec![]), - Instruction::Xor => Ok(vec![]), - Instruction::Xnor => Ok(vec![]), - Instruction::Lsh => Ok(vec![]), - Instruction::Rsh => Ok(vec![]), - Instruction::Compare => Ok(vec![]), - Instruction::Eq => Ok(vec![]), - Instruction::Neq => Ok(vec![]), - Instruction::Lt => Ok(vec![]), - Instruction::Leq => Ok(vec![]), - Instruction::Gt => Ok(vec![]), - Instruction::Geq => 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![]), Instruction::Max => Ok(vec![]), - Instruction::Boolean => Ok(vec![]), - Instruction::Invert => Ok(vec![]), + 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(), @@ -1045,6 +1353,30 @@ impl compiler::Compilable for Instruct }], ] .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::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;