Skip to content

Commit 1bc545b

Browse files
committed
Print op.
1 parent a9f653d commit 1bc545b

File tree

2 files changed

+93
-48
lines changed

2 files changed

+93
-48
lines changed

src/main/java/io/github/coderodde/simple/stack/machine/MachineLanguageSpecification.java

Lines changed: 88 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/main/java/io/github/coderodde/simple/stack/machine/SimpleStackMachine.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,14 +236,14 @@ int readWordFromTape(final int address) {
236236
nb3;
237237
}
238238

239-
void writeWordToTape(final int address, int number) {
239+
void writeWordToTape(final int address, int word) {
240240

241241
final byte[] bytes = new byte[Integer.BYTES];
242242

243-
bytes[0] = (byte) (number & 0xffL);
244-
bytes[1] = (byte)((number >>= Byte.SIZE) & 0xffL);
245-
bytes[2] = (byte)((number >>= Byte.SIZE) & 0xffL);
246-
bytes[3] = (byte)((number >> Byte.SIZE) & 0xffL);
243+
bytes[0] = (byte) (word & 0xffL);
244+
bytes[1] = (byte)((word >>= Byte.SIZE) & 0xffL);
245+
bytes[2] = (byte)((word >>= Byte.SIZE) & 0xffL);
246+
bytes[3] = (byte)((word >> Byte.SIZE) & 0xffL);
247247

248248
System.arraycopy(bytes,
249249
0,

0 commit comments

Comments
 (0)