mirror of
https://gitlab.cs.washington.edu/fidelp/frustration.git
synced 2024-12-25 21:58:11 +01:00
recursion and iteration
This commit is contained in:
parent
c4f7fa6b93
commit
995e712359
1 changed files with 67 additions and 41 deletions
108
frustration.rs
108
frustration.rs
|
@ -2,7 +2,7 @@ use std::io;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
//const CORE_SIZE: usize = 65408
|
//const CORE_SIZE: usize = 65408
|
||||||
const CORE_SIZE: usize = 256;
|
const CORE_SIZE: usize = 512;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
enum State {
|
enum State {
|
||||||
|
@ -55,7 +55,7 @@ struct TableEntry {
|
||||||
immediate: bool
|
immediate: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const PRIMITIVES: [TableEntry; 24] = [
|
const PRIMITIVES: [TableEntry; 27] = [
|
||||||
TableEntry {f: ret , name: None, immediate: false},
|
TableEntry {f: ret , name: None, immediate: false},
|
||||||
TableEntry {f: lit , name: None, immediate: false},
|
TableEntry {f: lit , name: None, immediate: false},
|
||||||
TableEntry {f: add , name: Some(ShortName {bytes: *b"+ ", length: 1}), 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: 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: 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: 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: 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: lbracket, name: Some(ShortName {bytes: *b"[ ", length: 1}), immediate: true},
|
||||||
TableEntry {f: load , name: Some(ShortName {bytes: *b"@ ", length: 1}), immediate: false},
|
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: 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: 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: 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: store , name: Some(ShortName {bytes: *b"! ", length: 1}), immediate: false},
|
||||||
TableEntry {f: sub , 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: 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: 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: 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}
|
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) {
|
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) {
|
fn immediate(c: &mut Core) {
|
||||||
|
@ -282,43 +289,14 @@ fn ret_d(c: &mut Core) {
|
||||||
ret(c);
|
ret(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Inner interpreter ---
|
// --- Control flow ---
|
||||||
|
fn if_skip(c: &mut Core) {
|
||||||
fn fetch(c: &mut Core) -> u16 {
|
let truthy = pop(c);
|
||||||
let ip = c.ip as usize;
|
let retaddr = from_r(c);
|
||||||
let opcode = u16::from_le_bytes(c.ram[ip..=ip+1].try_into().unwrap());
|
to_r(c, retaddr + if truthy == 0 { 2 } else { 0 });
|
||||||
c.ip += 2;
|
|
||||||
return opcode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute(c: &mut Core, opcode: u16) {
|
// --- I/O ---
|
||||||
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 ---
|
|
||||||
|
|
||||||
fn dot(c: &mut Core) {
|
fn dot(c: &mut Core) {
|
||||||
print!("{} ", pop(c));
|
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
|
// note: this is an inline primitive, not a dict entry
|
||||||
fn lit(c: &mut Core) {
|
fn lit(c: &mut Core) {
|
||||||
let ip = c.ip as usize;
|
let ip = c.ip as usize;
|
||||||
|
@ -368,6 +348,42 @@ fn div(c: &mut Core) {
|
||||||
push(c, v2.saturating_div(v1));
|
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 ---
|
// --- Outer interpreter ---
|
||||||
|
|
||||||
fn lbracket(c: &mut Core) {
|
fn lbracket(c: &mut Core) {
|
||||||
|
@ -446,6 +462,16 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create : ] create ] [ 65535 ,
|
/*
|
||||||
// create ; ] 65535 , [ ' [ , 65535 , immediate
|
create dog ] r> drop dup . 1 - dup ? dog ret [
|
||||||
// : dog 33 . ;
|
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
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in a new issue