Compare commits
2 commits
0e47e5658a
...
e310b901c3
| Author | SHA1 | Date | |
|---|---|---|---|
| e310b901c3 | |||
| 4fb7e78c2a |
3 changed files with 76 additions and 25 deletions
|
|
@ -1,6 +1,3 @@
|
|||
# NOTE: keep libc out of this, thats what trap vector is for
|
||||
# NOTE: to programmers: only registers allow mutable acess
|
||||
|
||||
[[addressing_modes]]
|
||||
name = "expr"
|
||||
mutable = true
|
||||
|
|
@ -36,6 +33,20 @@ symbol = "N"
|
|||
example = "const $expr, 100"
|
||||
description = "Numeric addressing mode provides read only integer constants to instructions"
|
||||
|
||||
[[addressing_modes]]
|
||||
name = "char"
|
||||
mutable = false
|
||||
symbol = "'N'"
|
||||
example = "const $expr, 'c'"
|
||||
description = "Char addressing mode provides read only character constants to instructions"
|
||||
|
||||
[[addressing_modes]]
|
||||
name = "boolean"
|
||||
mutable = false
|
||||
symbol = "{true|false}"
|
||||
example = "const $expr, true"
|
||||
description = "Boolean addressing mode provides read only booleans to instructions"
|
||||
|
||||
[[instructions]]
|
||||
name = "trap"
|
||||
args = ["index"]
|
||||
|
|
|
|||
|
|
@ -26,14 +26,16 @@ use core::mem::transmute;
|
|||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Address {
|
||||
Stack = 0xf0, // immutable access only
|
||||
Instr = 0xf1, // immutable access only
|
||||
Expr = 0xf2, // mutable access allowed
|
||||
Oper1 = 0xf3, // mutable access allowed
|
||||
Oper2 = 0xf4, // mutable access allowed
|
||||
Oper3 = 0xf5, // mutable access allowed
|
||||
Oper4 = 0xf6, // mutable access allowed
|
||||
Numer = 0xf8, // immutable access only
|
||||
Stack = 0xf0, // immutable access only
|
||||
Instr = 0xf1, // immutable access only
|
||||
Expr = 0xf2, // mutable access allowed
|
||||
Oper1 = 0xf3, // mutable access allowed
|
||||
Oper2 = 0xf4, // mutable access allowed
|
||||
Oper3 = 0xf5, // mutable access allowed
|
||||
Oper4 = 0xf6, // mutable access allowed
|
||||
Numer = 0xf8, // immutable access only
|
||||
Bool = 0xf9, // immutable access only
|
||||
Char = 0xfa, // immutable access only
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
|
|
@ -55,14 +57,16 @@ impl TryFrom<u8> for Address {
|
|||
type Error = &'static str;
|
||||
fn try_from(val: u8) -> Result<Self, Self::Error> {
|
||||
match val {
|
||||
_ if val == Address::Stack as u8 => Ok(Address::Stack),
|
||||
_ if val == Address::Instr as u8 => Ok(Address::Instr),
|
||||
_ if val == Address::Expr as u8 => Ok(Address::Expr),
|
||||
_ if val == Address::Oper1 as u8 => Ok(Address::Oper1),
|
||||
_ if val == Address::Oper2 as u8 => Ok(Address::Oper2),
|
||||
_ if val == Address::Oper3 as u8 => Ok(Address::Oper3),
|
||||
_ if val == Address::Oper4 as u8 => Ok(Address::Oper4),
|
||||
_ if val == Address::Numer as u8 => Ok(Address::Numer),
|
||||
_ if val == Address::Stack as u8 => Ok(Address::Stack),
|
||||
_ if val == Address::Instr as u8 => Ok(Address::Instr),
|
||||
_ if val == Address::Expr as u8 => Ok(Address::Expr),
|
||||
_ if val == Address::Oper1 as u8 => Ok(Address::Oper1),
|
||||
_ if val == Address::Oper2 as u8 => Ok(Address::Oper2),
|
||||
_ if val == Address::Oper3 as u8 => Ok(Address::Oper3),
|
||||
_ if val == Address::Oper4 as u8 => Ok(Address::Oper4),
|
||||
_ if val == Address::Numer as u8 => Ok(Address::Numer),
|
||||
_ if val == Address::Bool as u8 => Ok(Address::Bool),
|
||||
_ if val == Address::Char as u8 => Ok(Address::Char),
|
||||
_ => Err("illegal addressing mode")
|
||||
}
|
||||
}
|
||||
|
|
@ -74,6 +78,8 @@ impl Address {
|
|||
Address::Stack => (usize::BITS / 8) as u8,
|
||||
Address::Instr => (usize::BITS / 8) as u8,
|
||||
Address::Numer => (usize::BITS / 8) as u8,
|
||||
Address::Bool => 1,
|
||||
Address::Char => 1,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,6 +170,8 @@ impl VM {
|
|||
Address::Oper4 => &self.oper[3],
|
||||
Address::Stack => &self.stack[$oper.1],
|
||||
Address::Numer => e!("cannot access constant numeric data"),
|
||||
Address::Char => e!("cannot access constant char data"),
|
||||
Address::Bool => e!("cannot access constant bool data"),
|
||||
Address::Instr => e!("bad access to instruction data"),
|
||||
}
|
||||
};
|
||||
|
|
@ -405,11 +407,14 @@ impl VM {
|
|||
},
|
||||
|
||||
i::CONST => access!(&instr.1[0], {
|
||||
let Operand(Address::Numer, num) = instr.1[1] else {
|
||||
e!("illegal argument to CONST instruction");
|
||||
};
|
||||
|
||||
Datum::Number(Number::Fra(Fraction(num as isize, 1))).into()
|
||||
match instr.1[1].0 {
|
||||
Address::Numer =>
|
||||
Datum::Number(Number::Fra(Fraction(instr.1[1].1 as isize, 1)))
|
||||
.into(),
|
||||
Address::Bool => Datum::Bool(instr.1[1].1 > 0).into(),
|
||||
Address::Char => Datum::Char(instr.1[1].1 as u8).into(),
|
||||
_ => e!("illegal argument to CONST instruction"),
|
||||
}
|
||||
}),
|
||||
|
||||
i::MKVEC => self.expr = Datum::Vector(vec![]).into(),
|
||||
|
|
@ -629,7 +634,7 @@ mod tests {
|
|||
fn chk_err(&self, state: &VM) -> bool {
|
||||
if let Datum::String(ref msg) = *state.errr {
|
||||
let msg = unsafe { str::from_utf8_unchecked(msg) };
|
||||
if msg == self.errr.unwrap() {
|
||||
if self.errr.is_some() && msg == self.errr.unwrap() {
|
||||
true
|
||||
} else {
|
||||
print!("expected error {:?}, got {:?}\n", self.errr, msg);
|
||||
|
|
@ -1117,6 +1122,35 @@ mod tests {
|
|||
assert!(case.test_passes(&vm));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn isa_consts() {
|
||||
let mut vm = VM::from(Program(vec![
|
||||
Instruction(i::CONST, vec![Operand(Address::Expr, 0),
|
||||
Operand(Address::Numer, 1)]),
|
||||
Instruction(i::PUSH, vec![Operand(Address::Expr, 0)]),
|
||||
Instruction(i::CONST, vec![Operand(Address::Expr, 0),
|
||||
Operand(Address::Char, 'a' as u8 as usize)]),
|
||||
Instruction(i::PUSH, vec![Operand(Address::Expr, 0)]),
|
||||
Instruction(i::CONST, vec![Operand(Address::Expr, 0),
|
||||
Operand(Address::Bool, 1)]),
|
||||
Instruction(i::PUSH, vec![Operand(Address::Expr, 0)]),
|
||||
]));
|
||||
|
||||
let case = TestResult{
|
||||
expr: None,
|
||||
stack: vec![
|
||||
(0, Datum::Bool(true).into()),
|
||||
(1, Datum::Char('a' as u8).into()),
|
||||
(2, Datum::Number(Number::Fra(Fraction(1, 1))).into()),
|
||||
],
|
||||
syms: vec![],
|
||||
errr: None,
|
||||
};
|
||||
|
||||
vm.run_program();
|
||||
assert!(case.test_passes(&vm));
|
||||
}
|
||||
|
||||
/*
|
||||
#[test]
|
||||
fn isa_index() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue