mirror of
https://gitlab.cs.washington.edu/fidelp/frustration.git
synced 2025-02-05 20:45:59 +01:00
immediate mode
This commit is contained in:
parent
f2d9b7a092
commit
53521b70f4
1 changed files with 45 additions and 15 deletions
|
@ -6,7 +6,7 @@ use std::convert::TryInto;
|
|||
//const CORE_SIZE: usize = 65280
|
||||
const CORE_SIZE: usize = 128;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
enum State {
|
||||
Compiling,
|
||||
Interpreting
|
||||
|
@ -43,19 +43,22 @@ fn truncate_name(name: &str) -> ShortName {
|
|||
|
||||
struct TableEntry {
|
||||
f: Primitive,
|
||||
name: ShortName
|
||||
name: ShortName,
|
||||
immediate: bool
|
||||
}
|
||||
|
||||
// NOTE: lazy_static or SyncLazy would allow nicer init
|
||||
const PRIMITIVES: [TableEntry; 8] = [
|
||||
TableEntry {f: ret , name: ShortName {bytes: ['r' as u8, 'e' as u8, 't' as u8], length: 3}},
|
||||
TableEntry {f: dot , name: ShortName {bytes: ['.' as u8, 32, 32], length: 1}},
|
||||
TableEntry {f: store, name: ShortName {bytes: ['!' as u8, 32, 32], length: 1}},
|
||||
TableEntry {f: load , name: ShortName {bytes: ['@' as u8, 32, 32], length: 1}},
|
||||
TableEntry {f: add , name: ShortName {bytes: ['+' as u8, 32, 32], length: 1}},
|
||||
TableEntry {f: sub , name: ShortName {bytes: ['-' as u8, 32, 32], length: 1}},
|
||||
TableEntry {f: mul , name: ShortName {bytes: ['*' as u8, 32, 32], length: 1}},
|
||||
TableEntry {f: div , name: ShortName {bytes: ['/' as u8, 32, 32], length: 1}}
|
||||
const PRIMITIVES: [TableEntry; 10] = [
|
||||
TableEntry {f: ret , name: ShortName {bytes: ['r' as u8, 'e' as u8, 't' as u8], length: 3}, immediate: false},
|
||||
TableEntry {f: dot , name: ShortName {bytes: ['.' as u8, 32, 32], length: 1}, immediate: false},
|
||||
TableEntry {f: store, name: ShortName {bytes: ['!' as u8, 32, 32], length: 1}, immediate: false},
|
||||
TableEntry {f: load , name: ShortName {bytes: ['@' as u8, 32, 32], length: 1}, immediate: false},
|
||||
TableEntry {f: add , name: ShortName {bytes: ['+' as u8, 32, 32], length: 1}, immediate: false},
|
||||
TableEntry {f: sub , name: ShortName {bytes: ['-' as u8, 32, 32], length: 1}, immediate: false},
|
||||
TableEntry {f: mul , name: ShortName {bytes: ['*' as u8, 32, 32], length: 1}, immediate: false},
|
||||
TableEntry {f: div , name: ShortName {bytes: ['/' as u8, 32, 32], length: 1}, immediate: false},
|
||||
TableEntry {f: lbracket , name: ShortName {bytes: ['[' as u8, 32, 32], length: 1}, immediate: true},
|
||||
TableEntry {f: rbracket , name: ShortName {bytes: [']' as u8, 32, 32], length: 1}, immediate: false}
|
||||
];
|
||||
|
||||
fn new_core() -> Core {
|
||||
|
@ -71,15 +74,35 @@ fn create(c: &mut Core, name: ShortName) {
|
|||
let addr: usize = c.here as usize;
|
||||
c.ram[addr+0..=addr+1].copy_from_slice(&c.dp.to_le_bytes());
|
||||
c.dp = addr as u16;
|
||||
c.ram[addr+2] = name.length;
|
||||
c.ram[addr+2] = name.length & 0x7f;
|
||||
c.ram[addr+3..=addr+5].copy_from_slice(&name.bytes);
|
||||
c.here = (addr+6) as u16;
|
||||
}
|
||||
|
||||
fn smudge(c: &mut Core) {
|
||||
c.ram[(c.dp as usize) + 2] ^= 0x40;
|
||||
}
|
||||
|
||||
fn immediate(c: &mut Core) {
|
||||
c.ram[(c.dp as usize) + 2] ^= 0x80;
|
||||
}
|
||||
|
||||
fn is_immediate(c: &mut Core, addr: u16) -> bool {
|
||||
return (c.ram[(addr as usize) - 4] & 0x80) != 0;
|
||||
}
|
||||
|
||||
fn lbracket(c: &mut Core) {
|
||||
c.state = State::Interpreting;
|
||||
}
|
||||
|
||||
fn rbracket(c: &mut Core) {
|
||||
c.state = State::Compiling;
|
||||
}
|
||||
|
||||
fn find(c: &mut Core, name: ShortName) -> Option<u16> {
|
||||
let mut addr = c.dp as usize;
|
||||
while addr != 0 {
|
||||
if c.ram[addr+2] == name.length {
|
||||
if (c.ram[addr+2] & 0x7f) == name.length {
|
||||
if c.ram[addr+3..=addr+5] == name.bytes {
|
||||
return Some((addr+6) as u16);
|
||||
}
|
||||
|
@ -93,6 +116,9 @@ fn init_dictionary(c: &mut Core) {
|
|||
let mut opcode = 65535;
|
||||
for p in PRIMITIVES {
|
||||
create(c, p.name);
|
||||
if p.immediate {
|
||||
immediate(c);
|
||||
}
|
||||
comma(c, opcode);
|
||||
comma(c, 65535); // ret
|
||||
opcode -= 1;
|
||||
|
@ -221,8 +247,12 @@ fn outer(c: &mut Core, s: &str) {
|
|||
_ => {
|
||||
match find(c, truncate_name(t)) {
|
||||
Some(addr) => {
|
||||
c.ip = addr;
|
||||
inner(c);
|
||||
if c.state == State::Interpreting || is_immediate(c, addr) {
|
||||
c.ip = addr;
|
||||
inner(c);
|
||||
} else {
|
||||
comma(c, addr);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let val = t.parse::<u16>();
|
||||
|
|
Loading…
Add table
Reference in a new issue