Jelajahi Sumber

implemeting mnemonics SET, RJMP, SET, BSET, CSET, DSET, ESET, FSET,

with tests.
Wilfried Klaas 6 tahun lalu
induk
melakukan
3acee42798

+ 7 - 0
SimpleServo.tps

@@ -9,5 +9,12 @@ block Kommentar
 PORT 0x0F
 WAIT 200ms  ; inline Kommentar
 NOP
+SET 0x04
+BSET
+CSET
+DSET
+ESET
+FSET
+RJMP 0x06
 RJMP :loop
 JMP 0x08 ;this will cause an syntax error

+ 5 - 0
src/main/java/de/mcs/tools/sps/mnemonic/AbstractMnemonic.java

@@ -124,4 +124,9 @@ public abstract class AbstractMnemonic implements Mnemonic {
   public boolean hasArgument() {
     return false;
   }
+
+  @Override
+  public boolean isLabel() {
+    return false;
+  }
 }

+ 2 - 0
src/main/java/de/mcs/tools/sps/mnemonic/BSET.java

@@ -24,6 +24,8 @@ package de.mcs.tools.sps.mnemonic;
 import de.mcs.tools.sps.exceptions.SyntaxError;
 
 /**
+ * BSET: setting register B to value of register A
+ * 
  * @author wklaa_000
  *
  */

+ 2 - 0
src/main/java/de/mcs/tools/sps/mnemonic/CSET.java

@@ -24,6 +24,8 @@ package de.mcs.tools.sps.mnemonic;
 import de.mcs.tools.sps.exceptions.SyntaxError;
 
 /**
+ * CSET: setting register C to value of register A
+ * 
  * @author wklaa_000
  *
  */

+ 2 - 0
src/main/java/de/mcs/tools/sps/mnemonic/DSET.java

@@ -24,6 +24,8 @@ package de.mcs.tools.sps.mnemonic;
 import de.mcs.tools.sps.exceptions.SyntaxError;
 
 /**
+ * DSET: setting register D to value of register A
+ * 
  * @author wklaa_000
  *
  */

+ 2 - 0
src/main/java/de/mcs/tools/sps/mnemonic/ESET.java

@@ -24,6 +24,8 @@ package de.mcs.tools.sps.mnemonic;
 import de.mcs.tools.sps.exceptions.SyntaxError;
 
 /**
+ * ESET: setting register E to value of register A
+ * 
  * @author wklaa_000
  *
  */

+ 2 - 0
src/main/java/de/mcs/tools/sps/mnemonic/FSET.java

@@ -24,6 +24,8 @@ package de.mcs.tools.sps.mnemonic;
 import de.mcs.tools.sps.exceptions.SyntaxError;
 
 /**
+ * FSET: setting register F to value of register A
+ * 
  * @author wklaa_000
  *
  */

+ 1 - 0
src/main/java/de/mcs/tools/sps/mnemonic/JMP.java

@@ -26,6 +26,7 @@ import org.apache.commons.lang3.StringUtils;
 import de.mcs.tools.sps.exceptions.SyntaxError;
 
 /**
+ * 
  * @author wklaa_000
  *
  */

+ 2 - 0
src/main/java/de/mcs/tools/sps/mnemonic/Mnemonic.java

@@ -20,4 +20,6 @@ public interface Mnemonic {
 
   int getLineNumber();
 
+  boolean isLabel();
+
 }

+ 37 - 1
src/main/java/de/mcs/tools/sps/mnemonic/RJMP.java

@@ -21,22 +21,58 @@
  */
 package de.mcs.tools.sps.mnemonic;
 
+import org.apache.commons.lang3.StringUtils;
+
+import de.mcs.tools.sps.exceptions.IllegalArgument;
 import de.mcs.tools.sps.exceptions.SyntaxError;
 
 /**
+ * RJMP: Jump back x steps. x in range 0..15
+ * 
  * @author wklaa_000
  *
  */
 public class RJMP extends AbstractMnemonic implements Mnemonic {
 
+  int value;
+  private boolean isLabel;
+
   public RJMP(String line) throws SyntaxError {
     super(line);
+    value = 0;
+  }
+
+  @Override
+  public void checkArgument() throws SyntaxError {
+    if (StringUtils.isEmpty(getArgument())) {
+      throw new SyntaxError(getLineNumber(),
+          String.format("missing argument for %s.", this.getClass().getSimpleName()));
+    }
+    String argument = getArgument().trim();
+    if (argument.startsWith(":")) {
+      isLabel = true;
+      return;
+    }
+    value = getArgumentAsNumber();
+    if ((value < 0) || (value > 15)) {
+      throw new IllegalArgument(getLineNumber(),
+          String.format("argument %s is not in range 0..15 for %s.", getArgument(), this.getClass().getSimpleName()));
+    }
+    value = (byte) (value & 0xFF);
   }
 
   @Override
   public int getByte() {
     // TODO modifier x (0..15)
-    return 0x30;
+    return 0x30 + value;
   }
 
+  @Override
+  public boolean isLabel() {
+    return isLabel;
+  }
+
+  public void setValue(int value) {
+    this.value = value;
+  }
 }

+ 23 - 1
src/main/java/de/mcs/tools/sps/mnemonic/SET.java

@@ -21,22 +21,44 @@
  */
 package de.mcs.tools.sps.mnemonic;
 
+import org.apache.commons.lang3.StringUtils;
+
+import de.mcs.tools.sps.exceptions.IllegalArgument;
 import de.mcs.tools.sps.exceptions.SyntaxError;
 
 /**
+ * SET #x: Setting register A to a static value. x in range 0..15;
+ * 
  * @author wklaa_000
  *
  */
 public class SET extends AbstractMnemonic implements Mnemonic {
 
+  byte value;
+
   public SET(String line) throws SyntaxError {
     super(line);
+    value = 0;
+  }
+
+  @Override
+  public void checkArgument() throws SyntaxError {
+    if (StringUtils.isEmpty(getArgument())) {
+      throw new SyntaxError(getLineNumber(),
+          String.format("missing argument for %s.", this.getClass().getSimpleName()));
+    }
+    int myValue = getArgumentAsNumber();
+    if ((myValue < 0) || (myValue > 15)) {
+      throw new IllegalArgument(getLineNumber(),
+          String.format("argument %s is not in range 0..15 for %s.", getArgument(), this.getClass().getSimpleName()));
+    }
+    value = (byte) (myValue & 0xFF);
   }
 
   @Override
   public int getByte() {
     // TODO modifier x (0..15)
-    return 0x40;
+    return 0x40 + value;
   }
 
 }

+ 2 - 0
src/main/java/de/mcs/tools/sps/mnemonic/SWAP.java

@@ -24,6 +24,8 @@ package de.mcs.tools.sps.mnemonic;
 import de.mcs.tools.sps.exceptions.SyntaxError;
 
 /**
+ * SWAP: swapping register A and B
+ * 
  * @author wklaa_000
  *
  */

+ 4 - 0
src/main/java/de/mcs/tools/sps/mnemonic/WAIT.java

@@ -27,6 +27,10 @@ import de.mcs.tools.sps.exceptions.IllegalArgument;
 import de.mcs.tools.sps.exceptions.SyntaxError;
 
 /**
+ * WAIT: wating a little time. Argument should be in range 0..15 or one of this
+ * enumerations: 1ms, 2ms, 5ms, 10ms, 20ms, 50ms, 100ms, 200ms, 500ms, 1s, 2s,
+ * 5s, 10s, 20s, 30s, 60s
+ * 
  * @author wklaa_000
  *
  */

+ 80 - 0
src/test/java/de/mcs/tools/sps/mnemonic/TestRJMP.java

@@ -0,0 +1,80 @@
+package de.mcs.tools.sps.mnemonic;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import de.mcs.tools.sps.exceptions.IllegalArgument;
+import de.mcs.tools.sps.exceptions.SyntaxError;
+
+class TestRJMP {
+
+  private static final int BYTE_VALUE = 0x30;
+  private final String MNEMONIC = "RJMP";
+
+  @Test
+  void testMnemonic() throws SyntaxError {
+    RJMP rjmp = new RJMP(MNEMONIC + " 0x00");
+    rjmp.checkArgument();
+    assertEquals(BYTE_VALUE, rjmp.getByte());
+
+    rjmp = new RJMP(MNEMONIC + " 0x01");
+    rjmp.checkArgument();
+    assertEquals(BYTE_VALUE + 1, rjmp.getByte());
+
+    rjmp = new RJMP(MNEMONIC + " 0x0f");
+    rjmp.checkArgument();
+    assertEquals(BYTE_VALUE + 0x0f, rjmp.getByte());
+
+    rjmp = new RJMP(MNEMONIC + " :test");
+    rjmp.checkArgument();
+    assertTrue(rjmp.isLabel());
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      RJMP rjmp1 = new RJMP(MNEMONIC);
+      rjmp1.checkArgument();
+    });
+
+    Assertions.assertThrows(IllegalArgument.class, () -> {
+      RJMP rjmp1 = new RJMP(MNEMONIC + " 0x10");
+      rjmp1.checkArgument();
+    });
+
+    Assertions.assertThrows(IllegalArgument.class, () -> {
+      RJMP rjmp1 = new RJMP(MNEMONIC + " sieben");
+      rjmp1.checkArgument();
+    });
+
+    Assertions.assertThrows(IllegalArgument.class, () -> {
+      RJMP rjmp1 = new RJMP(MNEMONIC + " 12ms");
+      rjmp1.checkArgument();
+    });
+
+    Assertions.assertThrows(IllegalArgument.class, () -> {
+      RJMP rjmp1 = new RJMP(MNEMONIC + " 50s");
+      rjmp1.checkArgument();
+    });
+  }
+
+  @Test
+  void testMnemonicFactory() throws SyntaxError {
+    Mnemonic mnemonic = MnemonicFactory.getMnemonic(MNEMONIC + " 0x00", 0);
+    assertEquals(RJMP.class, mnemonic.getClass());
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      MnemonicFactory.getMnemonic(MNEMONIC, 0);
+    });
+
+    mnemonic = MnemonicFactory.getMnemonic(MNEMONIC + " 0x02", 0);
+    assertEquals(BYTE_VALUE + 0x02, mnemonic.getByte());
+
+    mnemonic = MnemonicFactory.getMnemonic(MNEMONIC + " 12", 0);
+    assertEquals(BYTE_VALUE + 12, mnemonic.getByte());
+
+    mnemonic = MnemonicFactory.getMnemonic(MNEMONIC + " 0b00001010", 0);
+    assertEquals(BYTE_VALUE + 10, mnemonic.getByte());
+
+  }
+}

+ 60 - 0
src/test/java/de/mcs/tools/sps/mnemonic/TestSET.java

@@ -0,0 +1,60 @@
+package de.mcs.tools.sps.mnemonic;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import de.mcs.tools.sps.exceptions.IllegalArgument;
+import de.mcs.tools.sps.exceptions.SyntaxError;
+
+class TestSET {
+
+  private static final int BYTE_VALUE = 0x40;
+  private final String MNEMONIC = "SET";
+
+  @Test
+  void testMnemonic() throws SyntaxError {
+    SET mnemonic = new SET(MNEMONIC + " 0x00");
+    mnemonic.checkArgument();
+    assertEquals(BYTE_VALUE, mnemonic.getByte());
+
+    mnemonic = new SET(MNEMONIC + " 0x01");
+    mnemonic.checkArgument();
+    assertEquals(BYTE_VALUE + 0x01, mnemonic.getByte());
+
+    mnemonic = new SET(MNEMONIC + " 0x0f");
+    mnemonic.checkArgument();
+    assertEquals(BYTE_VALUE + 0x0f, mnemonic.getByte());
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      SET mnemonic1 = new SET(MNEMONIC);
+      mnemonic1.checkArgument();
+    });
+
+    Assertions.assertThrows(IllegalArgument.class, () -> {
+      SET mnemonic1 = new SET(MNEMONIC + " 0x10");
+      mnemonic1.checkArgument();
+    });
+  }
+
+  @Test
+  void testMnemonicFactory() throws SyntaxError {
+    Mnemonic mnemonic = MnemonicFactory.getMnemonic(MNEMONIC + " 0x00", 0);
+    assertEquals(SET.class, mnemonic.getClass());
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      MnemonicFactory.getMnemonic(MNEMONIC, 0);
+    });
+
+    mnemonic = MnemonicFactory.getMnemonic(MNEMONIC + " 0x02", 0);
+    assertEquals(BYTE_VALUE + 0x02, mnemonic.getByte());
+
+    mnemonic = MnemonicFactory.getMnemonic(MNEMONIC + " 12", 0);
+    assertEquals(BYTE_VALUE + 12, mnemonic.getByte());
+
+    mnemonic = MnemonicFactory.getMnemonic(MNEMONIC + " 0b00001010", 0);
+    assertEquals(BYTE_VALUE + 10, mnemonic.getByte());
+
+  }
+}

+ 158 - 0
src/test/java/de/mcs/tools/sps/mnemonic/TestSingleMnemonics.java

@@ -0,0 +1,158 @@
+package de.mcs.tools.sps.mnemonic;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import de.mcs.tools.sps.exceptions.SyntaxError;
+
+class TestSingleMnemonics {
+
+  @Test
+  void testSWAP() throws SyntaxError {
+    SWAP mno = new SWAP("SWAP");
+    assertEquals(0x50, mno.getByte());
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      SWAP mno1 = new SWAP("SWAP akfhaskh");
+      mno1.checkArgument();
+    });
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      SWAP mno1 = new SWAP("SWAP 12");
+      mno1.checkArgument();
+    });
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      SWAP mno1 = new SWAP("SWAP :label");
+      mno1.checkArgument();
+    });
+  }
+
+  @Test
+  void testBSET() throws SyntaxError {
+    BSET mno = new BSET("BSET");
+    assertEquals(0x51, mno.getByte());
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      BSET mno1 = new BSET("BSET akfhaskh");
+      mno1.checkArgument();
+    });
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      BSET mno1 = new BSET("BSET 12");
+      mno1.checkArgument();
+    });
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      BSET mno1 = new BSET("BSET :label");
+      mno1.checkArgument();
+    });
+  }
+
+  @Test
+  void testCSET() throws SyntaxError {
+    CSET mno = new CSET("CSET");
+    assertEquals(0x52, mno.getByte());
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      CSET mno1 = new CSET("CSET akfhaskh");
+      mno1.checkArgument();
+    });
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      CSET mno1 = new CSET("CSET 12");
+      mno1.checkArgument();
+    });
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      CSET mno1 = new CSET("CSET :label");
+      mno1.checkArgument();
+    });
+  }
+
+  @Test
+  void testDSET() throws SyntaxError {
+    DSET mno = new DSET("DSET");
+    assertEquals(0x53, mno.getByte());
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      DSET mno1 = new DSET("DSET akfhaskh");
+      mno1.checkArgument();
+    });
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      DSET mno1 = new DSET("DSET 12");
+      mno1.checkArgument();
+    });
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      DSET mno1 = new DSET("DSET :label");
+      mno1.checkArgument();
+    });
+  }
+
+  @Test
+  void testESET() throws SyntaxError {
+    ESET mno = new ESET("ESET");
+    assertEquals(0x5d, mno.getByte());
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      ESET mno1 = new ESET("ESET akfhaskh");
+      mno1.checkArgument();
+    });
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      ESET mno1 = new ESET("ESET 12");
+      mno1.checkArgument();
+    });
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      ESET mno1 = new ESET("ESET :label");
+      mno1.checkArgument();
+    });
+  }
+
+  @Test
+  void testFSET() throws SyntaxError {
+    FSET mno = new FSET("FSET");
+    assertEquals(0x5e, mno.getByte());
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      FSET mno1 = new FSET("FSET akfhaskh");
+      mno1.checkArgument();
+    });
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      FSET mno1 = new FSET("FSET 12");
+      mno1.checkArgument();
+    });
+
+    Assertions.assertThrows(SyntaxError.class, () -> {
+      FSET mno1 = new FSET("FSET :label");
+      mno1.checkArgument();
+    });
+  }
+
+  @Test
+  void testMnemonicFactory() throws SyntaxError {
+    Mnemonic mnemonic = MnemonicFactory.getMnemonic("SWAP", 0);
+    assertEquals(SWAP.class, mnemonic.getClass());
+
+    mnemonic = MnemonicFactory.getMnemonic("BSET", 0);
+    assertEquals(BSET.class, mnemonic.getClass());
+
+    mnemonic = MnemonicFactory.getMnemonic("CSET", 0);
+    assertEquals(CSET.class, mnemonic.getClass());
+
+    mnemonic = MnemonicFactory.getMnemonic("DSET", 0);
+    assertEquals(DSET.class, mnemonic.getClass());
+
+    mnemonic = MnemonicFactory.getMnemonic("ESET", 0);
+    assertEquals(ESET.class, mnemonic.getClass());
+
+    mnemonic = MnemonicFactory.getMnemonic("FSET", 0);
+    assertEquals(FSET.class, mnemonic.getClass());
+  }
+}