mirror of
https://gitlab.cs.washington.edu/fidelp/frustration.git
synced 2024-12-25 21:58:11 +01:00
create, and all pieces needed for : ;
This commit is contained in:
parent
75304a0c82
commit
673e53349b
1 changed files with 103 additions and 24 deletions
|
@ -3,7 +3,7 @@ use std::io;
|
|||
use std::convert::TryInto;
|
||||
|
||||
//const CORE_SIZE: usize = 65408
|
||||
const CORE_SIZE: usize = 192;
|
||||
const CORE_SIZE: usize = 256;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
enum State {
|
||||
|
@ -11,6 +11,13 @@ enum State {
|
|||
Interpreting
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Post {
|
||||
Nothing,
|
||||
EatWord,
|
||||
EatLine,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Core {
|
||||
ram: [u8; CORE_SIZE],
|
||||
|
@ -18,6 +25,8 @@ struct Core {
|
|||
dp: u16, // newest link field, or 0
|
||||
here: u16, // first unused byte
|
||||
state: State,
|
||||
next_token: Option<String>,
|
||||
post: Post,
|
||||
dstack: [u16; 16],
|
||||
tds: usize, // post-incremented; exceeds top by one
|
||||
rstack: [u16; 16],
|
||||
|
@ -47,12 +56,16 @@ struct TableEntry {
|
|||
immediate: bool
|
||||
}
|
||||
|
||||
const PRIMITIVES: [TableEntry; 14] = [
|
||||
const PRIMITIVES: [TableEntry; 18] = [
|
||||
TableEntry {f: ret , name: None, immediate: false},
|
||||
TableEntry {f: lit , name: None, immediate: false},
|
||||
TableEntry {f: call , name: Some(ShortName {bytes: *b"cal", length: 4}), immediate: false},
|
||||
TableEntry {f: create_ , name: Some(ShortName {bytes: *b"cre", length: 6}), immediate: false},
|
||||
TableEntry {f: immediate,name: Some(ShortName {bytes: *b"imm", length: 9}), immediate: false},
|
||||
TableEntry {f: tick , name: Some(ShortName {bytes: *b"' ", length: 1}), immediate: false},
|
||||
TableEntry {f: dot , name: Some(ShortName {bytes: *b". ", length: 1}), immediate: false},
|
||||
TableEntry {f: dump , name: Some(ShortName {bytes: *b"dum", length: 4}), immediate: false},
|
||||
TableEntry {f: word , name: Some(ShortName {bytes: *b"wor", length: 4}), immediate: false},
|
||||
TableEntry {f: comma_ , name: Some(ShortName {bytes: *b", ", length: 1}), immediate: false},
|
||||
TableEntry {f: store , name: Some(ShortName {bytes: *b"! ", length: 1}), immediate: false},
|
||||
TableEntry {f: load , name: Some(ShortName {bytes: *b"@ ", length: 1}), immediate: false},
|
||||
|
@ -67,6 +80,8 @@ const PRIMITIVES: [TableEntry; 14] = [
|
|||
fn new_core() -> Core {
|
||||
let mut c = Core {
|
||||
ram: [0; CORE_SIZE], ip: 0, dp: 0, here: 2, state: State::Interpreting,
|
||||
next_token: None,
|
||||
post: Post::Nothing,
|
||||
dstack: [0; 16], tds: 0,
|
||||
rstack: [0; 16], trs: 0 };
|
||||
init_dictionary(&mut c);
|
||||
|
@ -84,6 +99,17 @@ fn create(c: &mut Core, name: ShortName) {
|
|||
c.here = (addr+6) as u16;
|
||||
}
|
||||
|
||||
fn create_(c: &mut Core) {
|
||||
match &c.next_token {
|
||||
Some(t) => {
|
||||
let short_name = truncate_name(t);
|
||||
create(c, short_name);
|
||||
c.post = Post::EatWord;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn find(c: &mut Core, name: ShortName) -> Option<u16> {
|
||||
let mut addr = c.dp as usize;
|
||||
while addr != 0 {
|
||||
|
@ -127,6 +153,29 @@ fn is_immediate(c: &mut Core, addr: u16) -> bool {
|
|||
return (c.ram[(addr as usize) - 4] & 0x80) != 0;
|
||||
}
|
||||
|
||||
fn tick(c: &mut Core) {
|
||||
match &c.next_token {
|
||||
Some(t) => {
|
||||
let name = t.to_string();
|
||||
let addr = find(c, truncate_name(&name));
|
||||
match addr {
|
||||
Some(xt) => {
|
||||
push(c, xt);
|
||||
c.post = Post::EatWord;
|
||||
}
|
||||
None => {
|
||||
println!(" ' cannot find {}", name);
|
||||
c.post = Post::EatLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
println!(" ' needs an argument");
|
||||
c.post = Post::EatLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn comma(c: &mut Core, val: u16) {
|
||||
let addr = c.here as usize;
|
||||
c.ram[addr..=addr+1].copy_from_slice(&val.to_le_bytes());
|
||||
|
@ -228,6 +277,16 @@ fn dump(c: &mut Core) {
|
|||
println!("{:?}", c);
|
||||
}
|
||||
|
||||
fn word(c: &mut Core) {
|
||||
match &c.next_token {
|
||||
Some(t) => {
|
||||
println!("{}", t);
|
||||
c.post = Post::EatWord;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// note: this is an inline primitive, not a dict entry
|
||||
fn lit(c: &mut Core) {
|
||||
let ip = c.ip as usize;
|
||||
|
@ -271,11 +330,19 @@ fn rbracket(c: &mut Core) {
|
|||
|
||||
fn outer(c: &mut Core, s: &str) {
|
||||
let ss = s.trim();
|
||||
let tokens = ss.split(" ");
|
||||
for t in tokens {
|
||||
let mut tokens = ss.split(" ").peekable();
|
||||
loop {
|
||||
c.post = Post::Nothing;
|
||||
match tokens.next() {
|
||||
Some(t) => {
|
||||
c.next_token = match tokens.peek() {
|
||||
Some(t) => { Some(t.to_string()) }
|
||||
None => { None }
|
||||
};
|
||||
match find(c, truncate_name(t)) {
|
||||
Some(addr) => {
|
||||
if c.state == State::Interpreting || is_immediate(c, addr) {
|
||||
to_r(c, c.ip);
|
||||
c.ip = addr;
|
||||
inner(c);
|
||||
} else {
|
||||
|
@ -299,6 +366,14 @@ fn outer(c: &mut Core, s: &str) {
|
|||
}
|
||||
}
|
||||
}
|
||||
None => { break ; }
|
||||
}
|
||||
match c.post {
|
||||
Post::EatWord => { _ = tokens.next(); }
|
||||
Post::EatLine => { break; }
|
||||
Post::Nothing => { }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -311,3 +386,7 @@ fn main() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create : ] create ] [ 65535 ,
|
||||
// create ; ] 65535 , [ ' [ , 65535 , immediate
|
||||
// : dog 33 . ;
|
||||
|
|
Loading…
Reference in a new issue