@@ -39,7 +39,7 @@ public static final class PopInstructionImplementation
3939
4040 @ Override
4141 public void execute (SimpleStackMachine machine ) {
42- machine .checkTapeReserve (Integer . BYTES );
42+ machine .checkTapeReserve (1 );
4343 machine .advanceInstructionPointer ();
4444 machine .pop ();
4545 }
@@ -48,14 +48,18 @@ public void execute(SimpleStackMachine machine) {
4848 public static final class LoadInstructionImplementation
4949 implements InstructionImplementation {
5050
51+ /**
52+ * Pops the address and pushes the word at that address to the stack.
53+ *
54+ * @param machine the target machine.
55+ */
5156 @ Override
5257 public void execute (SimpleStackMachine machine ) {
5358 machine .checkTapeReserve (1 );
59+ machine .requireStackSize (1 );
5460 machine .advanceInstructionPointer ();
5561
56- final int address =
57- machine .readWordFromTape (machine .getInstructionPointer ());
58-
62+ final int address = machine .pop ();
5963 final int datum = machine .readWordFromTape (address );
6064
6165 machine .push (datum );
@@ -65,22 +69,21 @@ public void execute(SimpleStackMachine machine) {
6569 public static final class StoreInstructionImplementation
6670 implements InstructionImplementation {
6771
72+ /**
73+ * Pops the word and the address and stores the word at the address.
74+ *
75+ * @param machine the target machine.
76+ */
6877 @ Override
6978 public void execute (SimpleStackMachine machine ) {
79+ machine .checkTapeReserve (1 );
7080 machine .requireStackSize (2 );
71- machine .checkTapeReserve (2 * Integer .BYTES );
7281 machine .advanceInstructionPointer ();
7382
74- final int address =
75- machine .readWordFromTape (machine .getInstructionPointer ());
76-
77- machine .advanceInstructionPointer (Integer .BYTES );
78-
79- final int datum = machine .readWordFromTape (
80- machine .getInstructionPointer ());
83+ final int address = machine .pop ();
84+ final int word = machine .pop ();
8185
82- machine .writeWordToTape (address , datum );
83- machine .advanceInstructionPointer (Integer .BYTES );
86+ machine .writeWordToTape (address , word );
8487 }
8588 }
8689
@@ -91,7 +94,7 @@ public static final class ConstInstructionImplementation
9194 extends PushInstructionImplementation {
9295
9396 @ Override
94- public void execute (SimpleStackMachine machine ) {
97+ public void execute (final SimpleStackMachine machine ) {
9598 super .execute (machine );
9699 }
97100 }
@@ -112,19 +115,10 @@ public void execute(final SimpleStackMachine machine) {
112115 machine .requireStackSize (2 );
113116 machine .advanceInstructionPointer ();
114117
115- final int number1 =
116- machine .readWordFromTape (machine .getInstructionPointer ());
117-
118- machine .advanceInstructionPointer (Integer .BYTES );
119-
120- final int number2 =
121- machine .readWordFromTape (
122- machine .getInstructionPointer ());
118+ final Integer word1 = machine .pop ();
119+ final Integer word2 = machine .pop ();
123120
124- machine .pop ();
125- machine .pop ();
126- machine .push (func .apply (number1 , number2 ));
127- machine .advanceInstructionPointer (Long .BYTES * 2 );
121+ machine .push (func .apply (word1 , word2 ));
128122 }
129123 }
130124
@@ -205,8 +199,11 @@ public static final class SwapInstructionImplementation
205199 public void execute (final SimpleStackMachine machine ) {
206200 machine .checkTapeReserve (1 );
207201 machine .requireStackSize (2 );
202+ machine .advanceInstructionPointer ();
203+
208204 final int number1 = machine .pop ();
209205 final int number2 = machine .pop ();
206+
210207 machine .push (number1 );
211208 machine .push (number2 );
212209 }
@@ -219,17 +216,23 @@ public static final class CompareInstructionImplementation
219216 public void execute (final SimpleStackMachine machine ) {
220217 machine .checkTapeReserve (1 );
221218 machine .requireStackSize (2 );
222- final long number1 = machine .pop ();
223- final long number2 = machine .pop ();
224- final int cmp = Long .compare (number1 ,
225- number2 );
219+ machine .advanceInstructionPointer ();
226220
221+ final int number1 = machine .pop ();
222+ final int number2 = machine .pop ();
223+
224+ final int cmp = Integer .compare (number1 ,
225+ number2 );
227226 if (cmp < 0 ) {
228- machine .flags ().belowFlag = true ;
227+ machine .flags ().belowFlag = true ;
228+ machine .flags ().notEqualFlag = true ;
229229 } else if (cmp > 0 ) {
230- machine .flags ().aboveFlag = true ;
230+ machine .flags ().aboveFlag = true ;
231+ machine .flags ().notEqualFlag = true ;
231232 } else {
232233 machine .flags ().equalFlag = true ;
234+ machine .flags ().aboveFlag = false ;
235+ machine .flags ().belowFlag = false ;
233236 }
234237 }
235238 }
@@ -250,7 +253,7 @@ public void execute(final SimpleStackMachine machine) {
250253 machine .flags ().belowZeroFlag = true ;
251254 machine .flags ().notZeroFlag = true ;
252255 } else {
253- machine .flags ().zeroFlag = true ;
256+ machine .flags ().zeroFlag = true ;
254257 machine .flags ().aboveZeroFlag = false ;
255258 machine .flags ().belowZeroFlag = false ;
256259 }
@@ -260,13 +263,17 @@ public void execute(final SimpleStackMachine machine) {
260263 public static final class UnconditionalJumpInstructionImplementation
261264 implements InstructionImplementation {
262265
266+ /**
267+ * Pops the jump address and jumps to it.
268+ *
269+ * @param machine the target machine.
270+ */
263271 @ Override
264272 public void execute (final SimpleStackMachine machine ) {
265- machine .checkTapeReserve (1 + Long .BYTES );
273+ machine .checkTapeReserve (1 );
274+ machine .requireStackSize (1 );
266275 machine .advanceInstructionPointer ();
267- final int jumpAddress =
268- (int ) machine .readWordFromTape (
269- machine .getInstructionPointer ());
276+ final int jumpAddress = machine .pop ();
270277
271278 machine .checkTapeReserve (jumpAddress );
272279 machine .setInstructionPointer (jumpAddress );
@@ -279,20 +286,27 @@ public static final class HaltInstructionImplementation
279286 @ Override
280287 public void execute (final SimpleStackMachine machine ) {
281288 machine .checkTapeReserve (1 );
289+ machine .advanceInstructionPointer ();
282290 machine .requestHalt ();
283291 }
284292 }
285293
286294 public static final class CallInstructionImplementation
287295 implements InstructionImplementation {
288296
297+ /**
298+ * Pops the call address, pushes the return address and enters a
299+ * function.
300+ *
301+ * @param machine the target machine.
302+ */
289303 @ Override
290304 public void execute (final SimpleStackMachine machine ) {
291- machine .checkTapeReserve (1 + Integer .BYTES );
305+ machine .requireStackSize (1 );
306+ machine .checkTapeReserve (1 );
292307 machine .advanceInstructionPointer ();
293308
294- final int address =
295- machine .readWordFromTape (machine .getInstructionPointer ());
309+ final int address = machine .pop ();
296310
297311 machine .advanceInstructionPointer (Integer .BYTES );
298312 machine .push (machine .getInstructionPointer ());
@@ -305,6 +319,7 @@ public static final class ReturnInstructionImplementation
305319
306320 @ Override
307321 public void execute (final SimpleStackMachine machine ) {
322+ machine .requireStackSize (1 );
308323 machine .checkTapeReserve (1 );
309324 machine .advanceInstructionPointer ();
310325
@@ -488,7 +503,7 @@ public void execute(final SimpleStackMachine machine) {
488503 machine .readWordFromTape (
489504 machine .getInstructionPointer ());
490505
491- machine .setInstructionPointer (address );
506+ machine .setInstructionPointer (address );
492507 }
493508 }
494509 }
@@ -501,8 +516,38 @@ public void execute(final SimpleStackMachine machine) {
501516 machine .checkTapeReserve (1 );
502517 machine .requireStackSize (1 );
503518 machine .advanceInstructionPointer ();
504- machine .printNumber (machine .pop ());
519+
520+ final int stringLength = machine .pop ();
521+ final int startAddress = machine .pop ();
522+
523+ System .out .println (processStringPrint (machine ,
524+ stringLength ,
525+ startAddress ));
526+ }
527+ }
528+
529+ private static String processStringPrint (final SimpleStackMachine machine ,
530+ final int stringLength ,
531+ final int startAddress ) {
532+ final int numberOfWords =
533+ stringLength * Character .BYTES +
534+ (stringLength % 2 == 0 ? 0 : 1 );
535+
536+ final int [] words = new int [numberOfWords ];
537+
538+ for (int i = 0 ; i < words .length ; i ++) {
539+ words [i ] = machine .readWordFromTape (startAddress + i );
540+ }
541+
542+ final char [] characterData = new char [stringLength ];
543+
544+ for (int i = 0 ; i < characterData .length ; ++i ) {
545+ final int word = words [i / Character .BYTES ];
546+ final int diffIndex = i % Character .BYTES == 0 ? 0 : 1 ;
547+ characterData [i ] = (char )(words [i / 2 + diffIndex ]);
505548 }
549+
550+ return new String (characterData );
506551 }
507552
508553 public static final class PrintStringInstructionImplementation
0 commit comments