remove obsolete ships
[fleet.git] / misc / obsolete-ships / ArithmeticShip.java
diff --git a/misc/obsolete-ships/ArithmeticShip.java b/misc/obsolete-ships/ArithmeticShip.java
new file mode 100644 (file)
index 0000000..3335c26
--- /dev/null
@@ -0,0 +1,162 @@
+package edu.berkeley.fleet.interpreter.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+/*
+You should note the following:
+I haven't implemented all the link-out policies.
+You can give the SHIP a single cmd with up to four operations.  For
+example, "ADD ZERO 0 SUBTRACT SIGN 1 MAX MAX 0".  These will be done
+in left-to-right order.
+You can use any link-out policy with any operation, though some don't
+make much sense.
+*/
+
+/**
+ * @author Dominic Antonelli <dantonel@berkeley.edu>
+ */
+public class ArithmeticShip extends InterpreterShip {
+
+    private int link;
+
+    DataInbox A = new DataInbox(this, "A");
+    DataInbox B = new DataInbox(this, "B");
+    DataInbox cmd = new DataInbox(this, "cmd");
+    DataOutbox out = new DataOutbox(this, "out");
+
+    public ArithmeticShip(Interpreter fleet, String name) {
+        super(fleet, name);
+    }
+
+    public enum Operation {
+        // NOTE: NOP is not to be used, but rather simply prevents other ops from using opcode 0
+        // This is so that we can detect the "end" of a command - when the command is all zero
+        NOP       { int eval(int a, int b, int link) { System.out.println("ERROR: Arith_NOP\n"); return 0; } },
+        ADD       { int eval(int a, int b, int link) { return a + b + link;            } },
+        SUBTRACT  { int eval(int a, int b, int link) { return a - b + link;            } },
+        COPY_A    { int eval(int a, int b, int link) { return a + link;                } },
+        COPY_B    { int eval(int a, int b, int link) { return b + link;                } },
+        SELECT    { int eval(int a, int b, int link) { return ((link==1) ? b : a);     } },
+        NEGATE_A  { int eval(int a, int b, int link) { return -(a+link);               } },
+        NEGATE_B  { int eval(int a, int b, int link) { return -(b+link);               } },
+        ABS_A     { int eval(int a, int b, int link) { a+=link; return (a<0 ? -a : a); } },
+        ABS_B     { int eval(int a, int b, int link) { b+=link; return (b<0 ? -b : b); } },
+        MAX       { int eval(int a, int b, int link) { return (a>b ?  a : b) + link;   } },
+        MIN       { int eval(int a, int b, int link) { return (a<b ?  a : b) + link;   } },
+        INC_A     { int eval(int a, int b, int link) { return a+1+link;                } },
+        INC_B     { int eval(int a, int b, int link) { return b+1+link;                } },
+        RESERVED1 { int eval(int a, int b, int link) { System.out.println("ERROR: Arith_RESERVED0\n"); return 0; } },
+        RESERVED2 { int eval(int a, int b, int link) { System.out.println("ERROR: Arith_RESERVED1\n"); return 0; } };
+
+
+
+        // Do arithmetic op represented by this constant
+        abstract int eval(int a, int b, int link);
+        public static Operation convertInt( int i ) {
+            return values()[i];
+        }
+    }
+
+    public enum LinkOutPolicy {
+        LINK_IN, ZERO, CARRY, SIGN, OLD_SIGN, OVERFLOW, MAX, MIN;
+        public static LinkOutPolicy convertInt( int i ) {
+            return values()[i];
+        }
+    }
+
+    private long savedCommand = 0;
+
+    public void service() {
+        if (!out.readyForDataFromShip()) return;
+        if (!A.dataReadyForShip()) return;
+        if (!B.dataReadyForShip()) return;
+
+        long command;
+
+        if (savedCommand != 0) {
+            command = savedCommand;
+        } else if (!cmd.dataReadyForShip()) {
+            return;
+        } else {
+            command = cmd.removeDataForShip();
+        }
+
+        int inA = A.removeDataForShip();
+        int inB = B.removeDataForShip();
+        int linkInPolicy = (int)(command & 0x1);
+        LinkOutPolicy linkOutPolicy = LinkOutPolicy.convertInt((int)((command >> 1) & 0x7));
+        Operation op = Operation.convertInt((int)((command >> 4) & 0xf));
+        int result = 0;
+
+        int oldLink = link;
+        if (op == Operation.SELECT) {
+            link = link ^ linkInPolicy; // LinkInPolicy = 1 mean flip the selection for the SELECT op.
+        } else {
+            link = link & linkInPolicy; // If linkInPolicy is zero, unset the link bit for the upcoming computation.
+                                        // NOTE: The final value of link will be computed after eval.
+        }
+
+        result = op.eval(inA, inB, link);
+
+        switch (linkOutPolicy) {
+            case LINK_IN:
+                link = oldLink;
+                break;
+            case ZERO:
+                link = (result == 0) ? 1 : 0;
+//                link = 0;
+                break;
+            case SIGN:
+                link = (result >> 31) & 0x1;
+                break;
+            case MAX:
+                if (inA > inB) link = 1; else link = 0;
+                break;
+            case MIN:
+                if (inA < inB) link = 1; else link = 0;
+                break;
+            case CARRY:
+            case OLD_SIGN:
+            case OVERFLOW:
+                System.out.println("ERROR: non-implemented linkOutPolicy selected");
+                break;
+            default:
+                System.out.println("ERROR: Unknown linkOutPolicy selected");
+                break;
+        };
+        out.addDataFromShip(result);
+
+        savedCommand = command >> 8;
+
+//        System.out.println("Link is now " + link);
+    }
+
+    public int resolveShipSpecificConstant(String shipSpecificData) {
+        String[] data = shipSpecificData.split("\\s");
+        int result = 0;
+
+        if ((data.length % 3) != 0) {
+            System.out.println("ERROR: ArithmeticShip received invalid ShipSpecificConstant");
+        }
+        for (int i = data.length - 1; i >= 2; i-=3) {
+            result <<= 8;
+            if (data[i].equals("1")) {
+                result |= 1;
+            }
+            for (LinkOutPolicy policy : LinkOutPolicy.values()) {
+                if (data[i-1].equals(policy.toString())) {
+                    result |= (policy.ordinal() << 1);
+                }
+            }
+            for (Operation op : Operation.values()) {
+                if (data[i-2].equals(op.toString())) {
+                    result |= (op.ordinal() << 4);
+                }
+            }
+        }
+        return result;
+    }
+}