Browse Source

initial operation parsing

jmelesky 4 years ago
parent
commit
b469eaec1f
1 changed files with 159 additions and 0 deletions
  1. 159 0
      src/main.rs

+ 159 - 0
src/main.rs

@@ -0,0 +1,159 @@
+use std::collections::HashMap;
+use std::fmt;
+use std::fs::File;
+
+enum UMOp {
+    ConditionalMove(u8, u8, u8),
+    ArrayIndex(u8, u8, u8),
+    ArrayAmend(u8, u8, u8),
+    Add(u8, u8, u8),
+    Mult(u8, u8, u8),
+    Div(u8, u8, u8),
+    NotAnd(u8, u8, u8),
+
+    Halt,
+    Allocate(u8, u8),
+    Abandon(u8),
+    Output(u8),
+    Input(u8),
+    Load(u8, u8),
+
+    Value(u8, u32),
+}
+
+const REGS: [&str; 8] = ["A", "B", "C", "D", "E", "F", "G", "H"];
+
+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]),
+            UMOp::ArrayIndex(a, b, c) =>
+                format!("ArrIndex #{} <- #{}[#{}]",
+                        REGS[*a as usize],
+                        REGS[*b as usize],
+                        REGS[*c as usize]),
+            UMOp::ArrayAmend(a, b, c) =>
+                format!("ArrAmend #{}[#{}] <- #{}",
+                        REGS[*a as usize],
+                        REGS[*b as usize],
+                        REGS[*c as usize]),
+            UMOp::Add(a, b, c) =>
+                format!("Add #{} <- #{} + #{}",
+                        REGS[*a as usize],
+                        REGS[*b as usize],
+                        REGS[*c as usize]),
+            UMOp::Mult(a, b, c) =>
+                format!("Mult #{} <- #{} * #{}",
+                        REGS[*a as usize],
+                        REGS[*b as usize],
+                        REGS[*c as usize]),
+            UMOp::Div(a, b, c) =>
+                format!("Div #{} <- #{} / #{}",
+                        REGS[*a as usize],
+                        REGS[*b as usize],
+                        REGS[*c as usize]),
+            UMOp::NotAnd(a, b, c) =>
+                format!("NotAnd #{} <- #{} !&& #{}",
+                        REGS[*a as usize],
+                        REGS[*b as usize],
+                        REGS[*c as usize]),
+            UMOp::Halt =>
+                format!("Halt!"),
+            UMOp::Allocate(b, c) =>
+                format!("Alloc #{} <- [#{}]",
+                        REGS[*b as usize],
+                        REGS[*c as usize]),
+            UMOp::Abandon(c) =>
+                format!("Abandon @#{}",
+                        REGS[*c as usize]),
+            UMOp::Output(c) =>
+                format!("Output #{}",
+                        REGS[*c as usize]),
+            UMOp::Input(c) =>
+                format!("Output #{} <-",
+                        REGS[*c as usize]),
+            UMOp::Load(b, c) =>
+                format!("Load <- #{}[#{}]",
+                        REGS[*b as usize],
+                        REGS[*c as usize]),
+            UMOp::Value(a, val) =>
+                format!("Value <- #{} <- $#{}",
+                        REGS[*a as usize],
+                        val),
+        };
+        write!(f, "{}", repr)
+    }
+}
+
+fn num_extract(masks_map: &HashMap<&str, (u32,u32)>,
+               num: u32, mask_name: &str) -> u32 {
+    let masktup = masks_map.get(mask_name).unwrap();
+    (num & masktup.0) >> masktup.1
+}
+
+fn parse_instr(masks_map: HashMap<&str, (u32,u32)>,
+               instr: u32) -> UMOp {
+    let opcode = num_extract(&masks_map, instr, "op_mask");
+    let rega   = num_extract(&masks_map, instr, "rega_mask") as u8;
+    let regb   = num_extract(&masks_map, instr, "regb_mask") as u8;
+    let regc   = num_extract(&masks_map, instr, "regc_mask") as u8;
+    let alta   = num_extract(&masks_map, instr, "alta_mask") as u8;
+    let val    = num_extract(&masks_map, instr, "val_mask");
+    match opcode {
+        0  => UMOp::ConditionalMove(rega, regb, regc),
+        1  => UMOp::ArrayIndex(rega, regb, regc),
+        2  => UMOp::ArrayAmend(rega, regb, regc),
+        3  => UMOp::Add(rega, regb, regc),
+        4  => UMOp::Mult(rega, regb, regc),
+        5  => UMOp::Div(rega, regb, regc),
+        6  => UMOp::NotAnd(rega, regb, regc),
+        7  => UMOp::Halt,
+        8  => UMOp::Allocate(regb, regc),
+        9  => UMOp::Abandon(regc),
+        10 => UMOp::Output(regc),
+        11 => UMOp::Input(regc),
+        12 => UMOp::Load(regb, regc),
+        13 => UMOp::Value(alta, val),
+        _  => panic!("Bad Instruction! ({})", instr)
+    }
+}
+
+
+fn main() {
+
+    let mut masks_map: HashMap<&str, (u32,u32)> = HashMap::new();
+    masks_map.insert("op_mask",   (0b11110000000000000000000000000000, 28));
+    masks_map.insert("rega_mask", (0b00000000000000000000000111000000,  6));
+    masks_map.insert("regb_mask", (0b00000000000000000000000000111000,  3));
+    masks_map.insert("regc_mask", (0b00000000000000000000000000000111,  0));
+    masks_map.insert("alta_mask", (0b00001110000000000000000000000000, 25));
+    masks_map.insert("val_mask",  (0b00000001111111111111111111111111,  0));
+
+
+    let mut codexfile = File::open(&Path::new("codex.umz"))
+
+
+
+
+
+
+    let add_instr                = 0b00110000000000000000000001010011;
+
+
+
+
+    
+
+
+    let full_op = parse_instr(masks_map, add_instr);
+
+
+    println!("Hello, world! - {}", full_op);
+}
+
+