Skip to content

Commit e265143

Browse files
committed
...
1 parent a8e1dde commit e265143

File tree

3 files changed

+337
-59
lines changed

3 files changed

+337
-59
lines changed

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

Lines changed: 288 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public static final class NopInstructionImplementation
1414

1515
@Override
1616
public void execute(final SimpleStackMachine machine) {
17-
machine.checkReserve(1);
17+
machine.checkTapeReserve(1);
1818
machine.advanceInstructionPointer();
1919
}
2020
}
@@ -24,7 +24,7 @@ public void execute(final SimpleStackMachine machine) {
2424

2525
@Override
2626
public void execute(final SimpleStackMachine machine) {
27-
machine.checkReserve(1 + Long.BYTES);
27+
machine.checkTapeReserve(1 + Long.BYTES);
2828
machine.advanceInstructionPointer();
2929

3030
final long number =
@@ -39,7 +39,7 @@ public static final class PopInstructionImplementation
3939

4040
@Override
4141
public void execute(SimpleStackMachine machine) {
42-
machine.checkReserve(1);
42+
machine.checkTapeReserve(1);
4343
machine.advanceInstructionPointer();
4444
machine.pop();
4545
}
@@ -50,7 +50,7 @@ public static final class LoadInstructionImplementation
5050

5151
@Override
5252
public void execute(SimpleStackMachine machine) {
53-
machine.checkReserve(1 + Long.BYTES);
53+
machine.checkTapeReserve(1 + Long.BYTES);
5454
machine.advanceInstructionPointer();
5555

5656
final long address =
@@ -67,7 +67,7 @@ public static final class StoreInstructionImplementation
6767

6868
@Override
6969
public void execute(SimpleStackMachine machine) {
70-
machine.checkReserve(1 + 2 * Long.BYTES);
70+
machine.checkTapeReserve(1 + 2 * Long.BYTES);
7171
machine.advanceInstructionPointer();
7272

7373
final long address =
@@ -106,7 +106,7 @@ public BinaryArithmeticInstructionImplementation(
106106

107107
@Override
108108
public void execute(SimpleStackMachine machine) {
109-
machine.checkReserve(1 + 2 * Long.BYTES);
109+
machine.checkTapeReserve(1 + 2 * Long.BYTES);
110110
machine.requireStackSize(2);
111111
machine.advanceInstructionPointer();
112112

@@ -187,7 +187,7 @@ public static final class DuplicateInstructionImplementation
187187

188188
@Override
189189
public void execute(final SimpleStackMachine machine) {
190-
machine.checkReserve(1);
190+
machine.checkTapeReserve(1);
191191
machine.requireStackSize(1);
192192
machine.push(machine.top());
193193
machine.advanceInstructionPointer();
@@ -199,7 +199,7 @@ public static final class SwapInstructionImplementation
199199

200200
@Override
201201
public void execute(final SimpleStackMachine machine) {
202-
machine.checkReserve(1);
202+
machine.checkTapeReserve(1);
203203
machine.requireStackSize(2);
204204
final long number1 = machine.pop();
205205
final long number2 = machine.pop();
@@ -213,7 +213,7 @@ public static final class CompareInstructionImplementation
213213

214214
@Override
215215
public void execute(final SimpleStackMachine machine) {
216-
machine.checkReserve(1);
216+
machine.checkTapeReserve(1);
217217
machine.requireStackSize(2);
218218
final long number1 = machine.pop();
219219
final long number2 = machine.pop();
@@ -230,18 +230,41 @@ public void execute(final SimpleStackMachine machine) {
230230
}
231231
}
232232

233+
public static final class TestInstructionImplementation
234+
implements InstructionImplementation {
235+
236+
@Override
237+
public void execute(final SimpleStackMachine machine) {
238+
machine.checkTapeReserve(1);
239+
machine.requireStackSize(1);
240+
final long number = machine.pop();
241+
242+
if (number > 0L) {
243+
machine.flags().aboveZeroFlag = true;
244+
machine.flags().notZeroFlag = true;
245+
} else if (number < 0L) {
246+
machine.flags().belowZeroFlag = true;
247+
machine.flags().notZeroFlag = true;
248+
} else {
249+
machine.flags().zeroFlag = true;
250+
machine.flags().aboveZeroFlag = false;
251+
machine.flags().belowZeroFlag = false;
252+
}
253+
}
254+
}
255+
233256
public static final class UnconditionalJumpInstructionImplementation
234257
implements InstructionImplementation {
235258

236259
@Override
237260
public void execute(final SimpleStackMachine machine) {
238-
machine.checkReserve(1 + Long.BYTES);
261+
machine.checkTapeReserve(1 + Long.BYTES);
239262
machine.advanceInstructionPointer();
240263
final int jumpAddress =
241264
(int) machine.readNumberFromTape(
242265
machine.getInstructionPointer());
243266

244-
machine.checkReserve(jumpAddress);
267+
machine.checkTapeReserve(jumpAddress);
245268
machine.setInstructionPointer(jumpAddress);
246269
}
247270
}
@@ -251,9 +274,262 @@ public static final class HaltInstructionImplementation
251274

252275
@Override
253276
public void execute(final SimpleStackMachine machine) {
254-
machine.checkReserve(1);
277+
machine.checkTapeReserve(1);
255278
machine.requestHalt();
256279
}
257280
}
258281

282+
public static final class CallInstructionImplementation
283+
implements InstructionImplementation {
284+
285+
@Override
286+
public void execute(final SimpleStackMachine machine) {
287+
machine.checkTapeReserve(1 + Long.BYTES);
288+
machine.advanceInstructionPointer();
289+
290+
final long address = machine.readNumber();
291+
machine.advanceInstructionPointer(Long.BYTES);
292+
machine.push(machine.getInstructionPointer());
293+
machine.setInstructionPointer((int) address);
294+
}
295+
}
296+
297+
public static final class ReturnInstructionImplementation
298+
implements InstructionImplementation {
299+
300+
@Override
301+
public void execute(final SimpleStackMachine machine) {
302+
machine.checkTapeReserve(1);
303+
machine.advanceInstructionPointer();
304+
305+
final long address = machine.pop();
306+
machine.setInstructionPointer((int) address);
307+
}
308+
}
309+
310+
public static final class JumpIfZeroInstructionImplementation
311+
implements InstructionImplementation {
312+
313+
@Override
314+
public void execute(final SimpleStackMachine machine) {
315+
machine.checkTapeReserve(1 + Long.BYTES);
316+
machine.advanceInstructionPointer();
317+
318+
if (machine.flags().zeroFlag) {
319+
final long address = machine.readNumber();
320+
machine.setInstructionPointer((int) address);
321+
}
322+
}
323+
}
324+
325+
public static final class JumpIfNotZeroInstructionImplementation
326+
implements InstructionImplementation {
327+
328+
@Override
329+
public void execute(final SimpleStackMachine machine) {
330+
machine.checkTapeReserve(1 + Long.BYTES);
331+
machine.advanceInstructionPointer();
332+
333+
if (machine.flags().notZeroFlag) {
334+
final long address = machine.readNumber();
335+
machine.setInstructionPointer((int) address);
336+
}
337+
}
338+
}
339+
340+
public static final class JumpIfBelowZeroInstructionImplementation
341+
implements InstructionImplementation {
342+
343+
@Override
344+
public void execute(final SimpleStackMachine machine) {
345+
machine.checkTapeReserve(1 + Long.BYTES);
346+
machine.advanceInstructionPointer();
347+
348+
if (machine.flags().belowZeroFlag) {
349+
final long address = machine.readNumber();
350+
machine.setInstructionPointer((int) address);
351+
}
352+
}
353+
}
354+
355+
public static final class JumpIfAboveZeroInstructionImplementation
356+
implements InstructionImplementation {
357+
358+
@Override
359+
public void execute(final SimpleStackMachine machine) {
360+
machine.checkTapeReserve(1 + Long.BYTES);
361+
machine.advanceInstructionPointer();
362+
363+
if (machine.flags().aboveZeroFlag) {
364+
final long address = machine.readNumber();
365+
machine.setInstructionPointer((int) address);
366+
}
367+
}
368+
}
369+
370+
public static final class JumpIfEqualInstructionImplementation
371+
implements InstructionImplementation {
372+
373+
@Override
374+
public void execute(final SimpleStackMachine machine) {
375+
machine.checkTapeReserve(1 + Long.BYTES);
376+
machine.advanceInstructionPointer();
377+
378+
if (machine.flags().equalFlag) {
379+
final long address = machine.readNumber();
380+
machine.setInstructionPointer((int) address);
381+
}
382+
}
383+
}
384+
385+
public static final class JumpIfNotEqualInstructionImplementation
386+
implements InstructionImplementation {
387+
388+
@Override
389+
public void execute(final SimpleStackMachine machine) {
390+
machine.checkTapeReserve(1 + Long.BYTES);
391+
machine.advanceInstructionPointer();
392+
393+
if (!machine.flags().equalFlag) {
394+
final long address = machine.readNumber();
395+
machine.setInstructionPointer((int) address);
396+
}
397+
}
398+
}
399+
400+
public static final class JumpIfAboveInstructionImplementation
401+
implements InstructionImplementation {
402+
403+
@Override
404+
public void execute(final SimpleStackMachine machine) {
405+
machine.checkTapeReserve(1 + Long.BYTES);
406+
machine.advanceInstructionPointer();
407+
408+
if (machine.flags().aboveFlag) {
409+
final long address = machine.readNumber();
410+
machine.setInstructionPointer((int) address);
411+
}
412+
}
413+
}
414+
415+
public static final class JumpIfAboveOrEqualInstructionImplementation
416+
implements InstructionImplementation {
417+
418+
@Override
419+
public void execute(final SimpleStackMachine machine) {
420+
machine.checkTapeReserve(1 + Long.BYTES);
421+
machine.advanceInstructionPointer();
422+
423+
if (machine.flags().aboveFlag || machine.flags().equalFlag) {
424+
final long address = machine.readNumber();
425+
machine.setInstructionPointer((int) address);
426+
}
427+
}
428+
}
429+
430+
public static final class JumpIfBelowInstructionImplementation
431+
implements InstructionImplementation {
432+
433+
@Override
434+
public void execute(final SimpleStackMachine machine) {
435+
machine.checkTapeReserve(1 + Long.BYTES);
436+
machine.advanceInstructionPointer();
437+
438+
if (machine.flags().belowFlag) {
439+
final long address = machine.readNumber();
440+
machine.setInstructionPointer((int) address);
441+
}
442+
}
443+
}
444+
445+
public static final class JumpIfBelowOrEqualInstructionImplementation
446+
implements InstructionImplementation {
447+
448+
@Override
449+
public void execute(final SimpleStackMachine machine) {
450+
machine.checkTapeReserve(1 + Long.BYTES);
451+
machine.advanceInstructionPointer();
452+
453+
if (machine.flags().belowFlag || machine.flags().equalFlag) {
454+
final long address = machine.readNumber();
455+
machine.setInstructionPointer((int) address);
456+
}
457+
}
458+
}
459+
460+
public static final class PrintNumberInstructionImplementation
461+
implements InstructionImplementation {
462+
463+
@Override
464+
public void execute(final SimpleStackMachine machine) {
465+
machine.checkTapeReserve(1);
466+
machine.requireStackSize(1);
467+
machine.advanceInstructionPointer();
468+
machine.printNumber(machine.pop());
469+
}
470+
}
471+
472+
public static final class PrintStringInstructionImplementation
473+
implements InstructionImplementation {
474+
475+
@Override
476+
public void execute(final SimpleStackMachine machine) {
477+
machine.checkTapeReserve(1);
478+
machine.requireStackSize(2);
479+
machine.advanceInstructionPointer();
480+
481+
final int numberOfChars = (int) machine.pop();
482+
final int stringStartIndex = (int) machine.pop();
483+
final int numberOfNumbers =
484+
(int)(numberOfChars / Long.BYTES
485+
+ (numberOfChars % Long.BYTES == 0 ? 0 : 1));
486+
487+
final long[] stringData = new long[numberOfNumbers];
488+
489+
for (int p = stringStartIndex, i = 0; i < numberOfNumbers; ++i) {
490+
stringData[i] = machine.readNumber();
491+
machine.advanceInstructionPointer(Long.BYTES);
492+
}
493+
494+
final byte[] asciiString = new byte[numberOfChars];
495+
496+
for (int byteIndex = 0; byteIndex < numberOfChars; ++byteIndex) {
497+
final long textChunk = stringData[byteIndex / Long.BYTES];
498+
final byte byteChar =
499+
(byte)(((textChunk) >>>
500+
Byte.SIZE * (byteIndex % Long.BYTES)) & 0xff);
501+
502+
asciiString[byteIndex] = byteChar;
503+
}
504+
505+
final StringBuilder sb = new StringBuilder(numberOfChars);
506+
507+
for (int i = 0; i < asciiString.length; ++i) {
508+
sb.append((char)(asciiString[i]));
509+
}
510+
511+
System.out.println(sb.toString());
512+
}
513+
}
514+
515+
public static final class ReadStringInstructionImplementation
516+
implements InstructionImplementation {
517+
518+
@Override
519+
public void execute(SimpleStackMachine machine) {
520+
throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
521+
}
522+
}
523+
524+
public static final class ReadNumberInstructionImplementation
525+
implements InstructionImplementation {
526+
527+
@Override
528+
public void execute(SimpleStackMachine machine) {
529+
machine.checkTapeReserve(1);
530+
machine.requireStackSize(1);
531+
machine.advanceInstructionPointer();
532+
machine.readNumber();
533+
}
534+
}
259535
}

0 commit comments

Comments
 (0)