|
@@ -1,6 +1,14 @@
|
|
|
use std::collections::HashMap;
|
|
|
use std::fmt;
|
|
|
-use std::fs::File;
|
|
|
+use std::fs;
|
|
|
+
|
|
|
+struct UMState {
|
|
|
+ program_counter: u32,
|
|
|
+ regs: [u32; 8],
|
|
|
+ mem: Vec<u32>
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
|
|
|
enum UMOp {
|
|
|
ConditionalMove(u8, u8, u8),
|
|
@@ -21,69 +29,82 @@ enum UMOp {
|
|
|
Value(u8, u32),
|
|
|
}
|
|
|
|
|
|
-const REGS: [&str; 8] = ["A", "B", "C", "D", "E", "F", "G", "H"];
|
|
|
+
|
|
|
+fn reg(i:u8) -> &'static str {
|
|
|
+ match i {
|
|
|
+ 0 => "A",
|
|
|
+ 1 => "B",
|
|
|
+ 2 => "C",
|
|
|
+ 3 => "D",
|
|
|
+ 4 => "E",
|
|
|
+ 5 => "F",
|
|
|
+ 6 => "G",
|
|
|
+ 7 => "H",
|
|
|
+ _ => panic!("Bad register! {}",i)
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
impl fmt::Display for UMOp {
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
let repr = match self {
|
|
|
UMOp::ConditionalMove(a, b, c) =>
|
|
|
format!("Conditional #{} <- {} ? #{} : #{}",
|
|
|
- REGS[*a as usize],
|
|
|
- REGS[*c as usize],
|
|
|
- REGS[*b as usize],
|
|
|
- REGS[*a as usize]),
|
|
|
+ reg(*a),
|
|
|
+ reg(*c),
|
|
|
+ reg(*b),
|
|
|
+ reg(*a)),
|
|
|
UMOp::ArrayIndex(a, b, c) =>
|
|
|
format!("ArrIndex #{} <- #{}[#{}]",
|
|
|
- REGS[*a as usize],
|
|
|
- REGS[*b as usize],
|
|
|
- REGS[*c as usize]),
|
|
|
+ reg(*a),
|
|
|
+ reg(*b),
|
|
|
+ reg(*c)),
|
|
|
UMOp::ArrayAmend(a, b, c) =>
|
|
|
format!("ArrAmend #{}[#{}] <- #{}",
|
|
|
- REGS[*a as usize],
|
|
|
- REGS[*b as usize],
|
|
|
- REGS[*c as usize]),
|
|
|
+ reg(*a),
|
|
|
+ reg(*b),
|
|
|
+ reg(*c)),
|
|
|
UMOp::Add(a, b, c) =>
|
|
|
format!("Add #{} <- #{} + #{}",
|
|
|
- REGS[*a as usize],
|
|
|
- REGS[*b as usize],
|
|
|
- REGS[*c as usize]),
|
|
|
+ reg(*a),
|
|
|
+ reg(*b),
|
|
|
+ reg(*c)),
|
|
|
UMOp::Mult(a, b, c) =>
|
|
|
format!("Mult #{} <- #{} * #{}",
|
|
|
- REGS[*a as usize],
|
|
|
- REGS[*b as usize],
|
|
|
- REGS[*c as usize]),
|
|
|
+ reg(*a),
|
|
|
+ reg(*b),
|
|
|
+ reg(*c)),
|
|
|
UMOp::Div(a, b, c) =>
|
|
|
format!("Div #{} <- #{} / #{}",
|
|
|
- REGS[*a as usize],
|
|
|
- REGS[*b as usize],
|
|
|
- REGS[*c as usize]),
|
|
|
+ reg(*a),
|
|
|
+ reg(*b),
|
|
|
+ reg(*c)),
|
|
|
UMOp::NotAnd(a, b, c) =>
|
|
|
format!("NotAnd #{} <- #{} !&& #{}",
|
|
|
- REGS[*a as usize],
|
|
|
- REGS[*b as usize],
|
|
|
- REGS[*c as usize]),
|
|
|
+ reg(*a),
|
|
|
+ reg(*b),
|
|
|
+ reg(*c)),
|
|
|
UMOp::Halt =>
|
|
|
format!("Halt!"),
|
|
|
UMOp::Allocate(b, c) =>
|
|
|
format!("Alloc #{} <- [#{}]",
|
|
|
- REGS[*b as usize],
|
|
|
- REGS[*c as usize]),
|
|
|
+ reg(*b),
|
|
|
+ reg(*c)),
|
|
|
UMOp::Abandon(c) =>
|
|
|
format!("Abandon @#{}",
|
|
|
- REGS[*c as usize]),
|
|
|
+ reg(*c)),
|
|
|
UMOp::Output(c) =>
|
|
|
format!("Output #{}",
|
|
|
- REGS[*c as usize]),
|
|
|
+ reg(*c)),
|
|
|
UMOp::Input(c) =>
|
|
|
format!("Output #{} <-",
|
|
|
- REGS[*c as usize]),
|
|
|
+ reg(*c)),
|
|
|
UMOp::Load(b, c) =>
|
|
|
format!("Load <- #{}[#{}]",
|
|
|
- REGS[*b as usize],
|
|
|
- REGS[*c as usize]),
|
|
|
+ reg(*b),
|
|
|
+ reg(*c)),
|
|
|
UMOp::Value(a, val) =>
|
|
|
format!("Value <- #{} <- $#{}",
|
|
|
- REGS[*a as usize],
|
|
|
+ reg(*a),
|
|
|
val),
|
|
|
};
|
|
|
write!(f, "{}", repr)
|
|
@@ -135,6 +156,7 @@ fn main() {
|
|
|
masks_map.insert("val_mask", (0b00000001111111111111111111111111, 0));
|
|
|
|
|
|
|
|
|
+ let codex = &fs::read("codex.umz");
|
|
|
|
|
|
|
|
|
|