diff --git a/frustration.rs b/frustration.rs index cbedd52..ef02cfa 100644 --- a/frustration.rs +++ b/frustration.rs @@ -2,7 +2,7 @@ use std::io; use std::convert::TryInto; //const CORE_SIZE: usize = 65408 -const CORE_SIZE: usize = 256; +const CORE_SIZE: usize = 512; #[derive(Debug, Eq, PartialEq)] enum State { @@ -55,7 +55,7 @@ struct TableEntry { immediate: bool } -const PRIMITIVES: [TableEntry; 24] = [ +const PRIMITIVES: [TableEntry; 27] = [ TableEntry {f: ret , name: None, immediate: false}, TableEntry {f: lit , name: None, immediate: false}, TableEntry {f: add , name: Some(ShortName {bytes: *b"+ ", length: 1}), immediate: false}, @@ -68,17 +68,20 @@ const PRIMITIVES: [TableEntry; 24] = [ TableEntry {f: dup , name: Some(ShortName {bytes: *b"dup", length: 3}), immediate: false}, TableEntry {f: dump , name: Some(ShortName {bytes: *b"dum", length: 4}), immediate: false}, TableEntry {f: from_r_d, name: Some(ShortName {bytes: *b"r> ", length: 2}), immediate: false}, + TableEntry {f: if_skip ,name: Some(ShortName {bytes: *b"? ", length: 1}), immediate: false}, TableEntry {f: immediate,name: Some(ShortName {bytes: *b"imm", length: 9}), immediate: false}, TableEntry {f: lbracket, name: Some(ShortName {bytes: *b"[ ", length: 1}), immediate: true}, TableEntry {f: load , name: Some(ShortName {bytes: *b"@ ", length: 1}), immediate: false}, TableEntry {f: mul , name: Some(ShortName {bytes: *b"* ", length: 1}), immediate: false}, TableEntry {f: ret_d , name: Some(ShortName {bytes: *b"ret", length: 3}), immediate: false}, TableEntry {f: rbracket, name: Some(ShortName {bytes: *b"] ", length: 1}), immediate: false}, + TableEntry {f: smudge , name: Some(ShortName {bytes: *b"smu", length: 6}), immediate: false}, TableEntry {f: store , name: Some(ShortName {bytes: *b"! ", length: 1}), immediate: false}, TableEntry {f: sub , name: Some(ShortName {bytes: *b"- ", length: 1}), immediate: false}, TableEntry {f: swap , name: Some(ShortName {bytes: *b"swa", length: 4}), immediate: false}, TableEntry {f: tick , name: Some(ShortName {bytes: *b"' ", length: 1}), immediate: false}, TableEntry {f: to_r_d , name: Some(ShortName {bytes: *b">r ", length: 2}), immediate: false}, + TableEntry {f: unsmudge, name: Some(ShortName {bytes: *b"uns", length: 8}), immediate: false}, TableEntry {f: word , name: Some(ShortName {bytes: *b"wor", length: 4}), immediate: false} ]; @@ -147,7 +150,11 @@ fn init_dictionary(c: &mut Core) { } fn smudge(c: &mut Core) { - c.ram[(c.dp as usize) + 2] ^= 0x40; + c.ram[(c.dp as usize) + 2] |= 0x40; +} + +fn unsmudge(c: &mut Core) { + c.ram[(c.dp as usize) + 2] &= 0xbf; } fn immediate(c: &mut Core) { @@ -282,43 +289,14 @@ fn ret_d(c: &mut Core) { ret(c); } -// --- Inner interpreter --- - -fn fetch(c: &mut Core) -> u16 { - let ip = c.ip as usize; - let opcode = u16::from_le_bytes(c.ram[ip..=ip+1].try_into().unwrap()); - c.ip += 2; - return opcode; +// --- Control flow --- +fn if_skip(c: &mut Core) { + let truthy = pop(c); + let retaddr = from_r(c); + to_r(c, retaddr + if truthy == 0 { 2 } else { 0 }); } -fn execute(c: &mut Core, opcode: u16) { - let primitive_index = (65535 - opcode) as usize; - if primitive_index < PRIMITIVES.len() { - (PRIMITIVES[primitive_index].f)(c); - } else { - // call - to_r(c, c.ip); - c.ip = opcode; - } -} - -fn step(c: &mut Core) { - let opcode = fetch(c); - execute(c, opcode); -} - -fn inner(c: &mut Core) { - loop { - step(c); - println!("ip={} trs={}", c.ip, c.trs); - if c.trs == 0 { - break; - } - } -} - -// --- Math --- - +// --- I/O --- fn dot(c: &mut Core) { print!("{} ", pop(c)); } @@ -337,6 +315,8 @@ fn word(c: &mut Core) { } } +// --- Math and logic --- + // note: this is an inline primitive, not a dict entry fn lit(c: &mut Core) { let ip = c.ip as usize; @@ -368,6 +348,42 @@ fn div(c: &mut Core) { push(c, v2.saturating_div(v1)); } + +// --- Inner interpreter --- + +fn fetch(c: &mut Core) -> u16 { + let ip = c.ip as usize; + let opcode = u16::from_le_bytes(c.ram[ip..=ip+1].try_into().unwrap()); + c.ip += 2; + return opcode; +} + +fn execute(c: &mut Core, opcode: u16) { + let primitive_index = (65535 - opcode) as usize; + if primitive_index < PRIMITIVES.len() { + (PRIMITIVES[primitive_index].f)(c); + } else { + // call + to_r(c, c.ip); + c.ip = opcode; + } +} + +fn step(c: &mut Core) { + let opcode = fetch(c); + execute(c, opcode); +} + +fn inner(c: &mut Core) { + loop { + step(c); + //println!("ip={} trs={}", c.ip, c.trs); + if c.trs == 0 { + break; + } + } +} + // --- Outer interpreter --- fn lbracket(c: &mut Core) { @@ -446,6 +462,16 @@ fn main() { } } -// create : ] create ] [ 65535 , -// create ; ] 65535 , [ ' [ , 65535 , immediate -// : dog 33 . ; +/* +create dog ] r> drop dup . 1 - dup ? dog ret [ +create dog smudge ] dog ret [ smudge +100 dog + +create : ] create smudge ] [ 65535 , +create ; ] unsmudge 65535 , [ ' [ , 65535 , immediate +: dog 33 . ; + +: dog [ unsmudge ] r> drop dup . 1 - dup ? dog ; +: dog dog ; +100 dog +*/