mirror of
https://gitlab.cs.washington.edu/fidelp/frustration.git
synced 2025-01-13 08:01:23 +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
127
frustration.rs
127
frustration.rs
|
@ -3,7 +3,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 = 192;
|
const CORE_SIZE: usize = 256;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
enum State {
|
enum State {
|
||||||
|
@ -11,6 +11,13 @@ enum State {
|
||||||
Interpreting
|
Interpreting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Post {
|
||||||
|
Nothing,
|
||||||
|
EatWord,
|
||||||
|
EatLine,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Core {
|
struct Core {
|
||||||
ram: [u8; CORE_SIZE],
|
ram: [u8; CORE_SIZE],
|
||||||
|
@ -18,6 +25,8 @@ struct Core {
|
||||||
dp: u16, // newest link field, or 0
|
dp: u16, // newest link field, or 0
|
||||||
here: u16, // first unused byte
|
here: u16, // first unused byte
|
||||||
state: State,
|
state: State,
|
||||||
|
next_token: Option<String>,
|
||||||
|
post: Post,
|
||||||
dstack: [u16; 16],
|
dstack: [u16; 16],
|
||||||
tds: usize, // post-incremented; exceeds top by one
|
tds: usize, // post-incremented; exceeds top by one
|
||||||
rstack: [u16; 16],
|
rstack: [u16; 16],
|
||||||
|
@ -47,12 +56,16 @@ struct TableEntry {
|
||||||
immediate: bool
|
immediate: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const PRIMITIVES: [TableEntry; 14] = [
|
const PRIMITIVES: [TableEntry; 18] = [
|
||||||
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: call , name: Some(ShortName {bytes: *b"cal", length: 4}), 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: 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: 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: comma_ , name: Some(ShortName {bytes: *b", ", length: 1}), 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: load , 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 {
|
fn new_core() -> Core {
|
||||||
let mut c = Core {
|
let mut c = Core {
|
||||||
ram: [0; CORE_SIZE], ip: 0, dp: 0, here: 2, state: State::Interpreting,
|
ram: [0; CORE_SIZE], ip: 0, dp: 0, here: 2, state: State::Interpreting,
|
||||||
|
next_token: None,
|
||||||
|
post: Post::Nothing,
|
||||||
dstack: [0; 16], tds: 0,
|
dstack: [0; 16], tds: 0,
|
||||||
rstack: [0; 16], trs: 0 };
|
rstack: [0; 16], trs: 0 };
|
||||||
init_dictionary(&mut c);
|
init_dictionary(&mut c);
|
||||||
|
@ -84,6 +99,17 @@ fn create(c: &mut Core, name: ShortName) {
|
||||||
c.here = (addr+6) as u16;
|
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> {
|
fn find(c: &mut Core, name: ShortName) -> Option<u16> {
|
||||||
let mut addr = c.dp as usize;
|
let mut addr = c.dp as usize;
|
||||||
while addr != 0 {
|
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;
|
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) {
|
fn comma(c: &mut Core, val: u16) {
|
||||||
let addr = c.here as usize;
|
let addr = c.here as usize;
|
||||||
c.ram[addr..=addr+1].copy_from_slice(&val.to_le_bytes());
|
c.ram[addr..=addr+1].copy_from_slice(&val.to_le_bytes());
|
||||||
|
@ -228,6 +277,16 @@ fn dump(c: &mut Core) {
|
||||||
println!("{:?}", c);
|
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
|
// 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;
|
||||||
|
@ -271,33 +330,49 @@ fn rbracket(c: &mut Core) {
|
||||||
|
|
||||||
fn outer(c: &mut Core, s: &str) {
|
fn outer(c: &mut Core, s: &str) {
|
||||||
let ss = s.trim();
|
let ss = s.trim();
|
||||||
let tokens = ss.split(" ");
|
let mut tokens = ss.split(" ").peekable();
|
||||||
for t in tokens {
|
loop {
|
||||||
match find(c, truncate_name(t)) {
|
c.post = Post::Nothing;
|
||||||
Some(addr) => {
|
match tokens.next() {
|
||||||
if c.state == State::Interpreting || is_immediate(c, addr) {
|
Some(t) => {
|
||||||
c.ip = addr;
|
c.next_token = match tokens.peek() {
|
||||||
inner(c);
|
Some(t) => { Some(t.to_string()) }
|
||||||
} else {
|
None => { None }
|
||||||
comma(c, addr);
|
};
|
||||||
}
|
match find(c, truncate_name(t)) {
|
||||||
}
|
Some(addr) => {
|
||||||
None => {
|
if c.state == State::Interpreting || is_immediate(c, addr) {
|
||||||
let val = t.parse::<u16>();
|
to_r(c, c.ip);
|
||||||
match val {
|
c.ip = addr;
|
||||||
Ok(n) => {
|
inner(c);
|
||||||
match c.state {
|
} else {
|
||||||
State::Interpreting => { push(c, n) }
|
comma(c, addr);
|
||||||
State::Compiling => {
|
}
|
||||||
comma(c, 65534); // lit
|
}
|
||||||
comma(c, n);
|
None => {
|
||||||
}
|
let val = t.parse::<u16>();
|
||||||
|
match val {
|
||||||
|
Ok(n) => {
|
||||||
|
match c.state {
|
||||||
|
State::Interpreting => { push(c, n) }
|
||||||
|
State::Compiling => {
|
||||||
|
comma(c, 65534); // lit
|
||||||
|
comma(c, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => { if t != "" { println!("{}?", t) }}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => { if t != "" { println!("{}?", t) }}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
None => { break ; }
|
||||||
}
|
}
|
||||||
|
match c.post {
|
||||||
|
Post::EatWord => { _ = tokens.next(); }
|
||||||
|
Post::EatLine => { break; }
|
||||||
|
Post::Nothing => { }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,3 +386,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create : ] create ] [ 65535 ,
|
||||||
|
// create ; ] 65535 , [ ' [ , 65535 , immediate
|
||||||
|
// : dog 33 . ;
|
||||||
|
|
Loading…
Reference in a new issue