integrate assembler

This commit is contained in:
phyto 2023-05-06 11:25:11 +00:00
parent a542346b3d
commit 4534d8480a
Signed by: phyto
SSH Key Fingerprint: SHA256:FJdIUDW+Q/c/oLlaNI7vrxCrv0VMxMgT6usJ+7A/wo0
3 changed files with 63 additions and 58 deletions

View File

@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
ruxnasm = { git = "https://git.disroot.org/phyto/ruxnasm.git" }

View File

@ -1,14 +1,15 @@
fn main() { fn main() {
let mut bf = read_stdin(); let mut bf = read_stdin();
braintal::bf::optimise::optimise(&mut bf); braintal::bf::optimise::optimise(&mut bf);
let tal = braintal::uxn::from_ops(&bf); let tal = braintal::uxn::from_ops(&bf);
dbg!(bf); dbg!(bf);
print!("{}", tal); use std::io::Write;
std::io::stdout().write(&tal);
} }
fn read_stdin() -> Vec<braintal::bf::Op> { fn read_stdin() -> Vec<braintal::bf::Op> {
let stdin = std::io::stdin(); let stdin = std::io::stdin();
let buffer = std::io::read_to_string(stdin).unwrap(); let buffer = std::io::read_to_string(stdin).unwrap();
braintal::bf::str_to_ops(&buffer) braintal::bf::str_to_ops(&buffer)
} }

View File

@ -6,69 +6,72 @@
mod asm; mod asm;
use crate::bf::Op; use crate::bf::Op;
pub fn from_ops(s: &[Op]) -> String { pub fn from_ops(s: &[Op]) -> Vec<u8> {
let mut r = init(); let mut r = init();
let mut uxn_index = 0; let mut uxn_index = 0;
for (i, o) in s.iter().enumerate() { for (i, o) in s.iter().enumerate() {
let new = match_op(o, i, uxn_index); let new = match_op(o, i, uxn_index);
uxn_index += new.split_whitespace().count(); uxn_index += new.split_whitespace().count();
r.push_str(&new); r.push_str(&new);
r.push('\n'); r.push('\n');
} }
r.push_str("#0f DEO"); r.push_str("#0f DEO");
r dbg!(&r);
let (bin, _) = ruxnasm::assemble(r.as_bytes()).unwrap();
bin
} }
fn match_op(s: &Op, bf_index: usize, uxn_index: usize) -> String { fn match_op(s: &Op, bf_index: usize, uxn_index: usize) -> String {
use Op::*; use Op::*;
let mut prog = String::new(); let mut prog = String::new();
// Each addition MUST // Each addition MUST
// - Have each whitespace-seperated word equate to 1 byte of uxn // - Have each whitespace-seperated word equate to 1 byte of uxn
// - Leave the stack in the same format it was found // - Leave the stack in the same format it was found
match s { match s {
Add(1) => prog.push_str("DUP2 LDAk INC ROT ROT STA"), //INC is slightly smaller Add(1) => prog.push_str("DUP2 LDAk #01 ADD ROT ROT STA"), //INC is slightly smaller
Add(amt) if amt > &0 => prog.push_str(&format!("DUP2 LDAk LIT {:02} ADD ROT ROT STA", amt)), Add(amt) if amt > &0 => prog.push_str(&format!("DUP2 LDAk LIT {:02} ADD ROT ROT STA", amt)),
Add(amt) if amt < &0 => { Add(amt) if amt < &0 => {
prog.push_str(&format!("DUP2 LDAk LIT {:02} SUB ROT ROT STA", -amt)) prog.push_str(&format!("DUP2 LDAk LIT {:02} SUB ROT ROT STA", -amt))
} }
Seek(-1) => prog.push_str("INC2"), Seek(-1) => prog.push_str("#0001 ADD2"),
Seek(amt) if amt > &0 => prog.push_str(&format!("LIT 00 LIT {:02} SUB2", amt)), Seek(amt) if amt > &0 => prog.push_str(&format!("LIT 00 LIT {:02} SUB2", amt)),
Seek(amt) if amt < &0 => prog.push_str(&format!("LIT 00 LIT {:02} ADD2", -amt)), Seek(amt) if amt < &0 => prog.push_str(&format!("LIT 00 LIT {:02} ADD2", -amt)),
LoopStart(adr) => prog.push_str(&format!( LoopStart(adr) => prog.push_str(&format!(
"LDAk LIT 00 EQU ;{} JCN2 @{}", "LDAk LIT 00 EQU ;{} JCN2 @{}",
sanitize_num(*adr), sanitize_num(*adr),
sanitize_num(bf_index) sanitize_num(bf_index)
)), )),
LoopEnd(adr) => prog.push_str(&format!( LoopEnd(adr) => prog.push_str(&format!(
"LDAk ;{} JCN2 @{}", "LDAk ;{} JCN2 @{}",
sanitize_num(*adr), sanitize_num(*adr),
sanitize_num(bf_index) sanitize_num(bf_index)
)), )),
Output => prog.push_str("LDAk #18 DEO"), Output => prog.push_str("LDAk #18 DEO"),
Input => prog.push_str(&format!( Input => prog.push_str(&format!(
";{0} LIT 10 DEO2 BRK @{0} DUP2 LIT 12 DEI ROT ROT STA", ";{0} LIT 10 DEO2 BRK @{0} DUP2 LIT 12 DEI ROT ROT STA",
sanitize_num(bf_index) sanitize_num(bf_index)
)), )),
_ => panic!("Instruction used but not supported, please file a bug!"), _ => panic!("Instruction used but not supported, please file a bug!"),
} }
prog prog
} }
/// Load the pointer to the stack /// Load the pointer to the stack
fn init() -> String { fn init() -> String {
"|100\n#ffff\n".to_string() "|100\n#ffff\n".to_string()
} }
/// In tal you can't have raw decimals as symbol names, so we do a crude conversion. /// In tal you can't have raw decimals as symbol names, so we do a crude conversion.
fn sanitize_num(mut x: usize) -> String { fn sanitize_num(mut x: usize) -> String {
let mut r = String::from("_"); let mut r = String::from("_");
while x > 0 { while x > 0 {
r.push((0x41 + (x % 25)) as u8 as char); r.push((0x41 + (x % 25)) as u8 as char);
x /= 25; x /= 25;
} }
r r
} }