integrate assembler
This commit is contained in:
parent
a542346b3d
commit
4534d8480a
|
@ -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" }
|
||||||
|
|
17
src/main.rs
17
src/main.rs
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
103
src/uxn/mod.rs
103
src/uxn/mod.rs
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue