• R/O
  • SSH

kink: Commit

Kink runtime


Commit MetaInfo

Révision13c7732d0e4bf000538a3ca9138a62cabceaeb33 (tree)
l'heure2020-10-25 19:47:26
Auteurmiyakawataku
Commitermiyakawataku

Message de Log

handle JumpIfNeInsn in StackMachine

Change Summary

Modification

diff -r aed121df1343 -r 13c7732d0e4b src/main/java/org/kink_lang/kink/StackMachine.java
--- a/src/main/java/org/kink_lang/kink/StackMachine.java Sun Oct 25 19:38:54 2020 +0900
+++ b/src/main/java/org/kink_lang/kink/StackMachine.java Sun Oct 25 19:47:26 2020 +0900
@@ -530,6 +530,7 @@
530530 case Opcodes.MULNUM: { insnMulNum(); return; }
531531 case Opcodes.GOTO: { insnGoto(qinsn); return; }
532532 case Opcodes.IFEQ: { insnIfEq(); return; }
533+ case Opcodes.JUMPIFNE: { insnJumpIfNe(qinsn); return; }
533534 case Opcodes.IFLT: { insnIfLt(); return; }
534535 case Opcodes.IFVEC: { insnIfVec(); return; }
535536 case Opcodes.IFPLAINNUM: { insnIfPlainNum(); return; }
@@ -940,6 +941,19 @@
940941 }
941942
942943 /**
944+ * Executes JUMPIFNE instruction.
945+ */
946+ private void insnJumpIfNe(Qinsn qinsn) {
947+ Val stackTop = this.dataStack.pop();
948+ Val test = (Val) qinsn.getObjOperand1();
949+ if (! stackTop.equals(test)) {
950+ int destProgramCounter = qinsn.getIntOperand();
951+ // subtract 1 because the PC is incremented in handleQblock
952+ this.programCounter = destProgramCounter - 1;
953+ }
954+ }
955+
956+ /**
943957 * Executes IFLT instruction.
944958 */
945959 private void insnIfLt() {
diff -r aed121df1343 -r 13c7732d0e4b src/test/java/org/kink_lang/kink/StackMachineTest.java
--- a/src/test/java/org/kink_lang/kink/StackMachineTest.java Sun Oct 25 19:38:54 2020 +0900
+++ b/src/test/java/org/kink_lang/kink/StackMachineTest.java Sun Oct 25 19:47:26 2020 +0900
@@ -540,6 +540,7 @@
540540 }
541541
542542 // }}}2
543+
543544 // IFEQ {{{2
544545
545546 @Test
@@ -631,6 +632,91 @@
631632 }
632633
633634 // }}}2
635+
636+ // JUMPIFNE {{{2
637+
638+ @Test
639+ public void test_run_qblock_jumpifne_true_with_int() {
640+ Wire wire = new Wire(List.of(
641+ new ArgInsn(0, 100),
642+ new JumpIfNeInsn(intHolder.of(999), "ne", 101),
643+ new KonstInsn(vm.str.of("ok"), 102),
644+ new RetInsn(103),
645+ new LabelPseudoInsn("ne"),
646+ new KonstInsn(vm.str.of("bad"), 104),
647+ new RetInsn(105)), 1, 0, List.of());
648+ WireToQblockTranslator w2q = new WireToQblockTranslator(
649+ vm, "foo.kn", "if \\0 equals 999 then return 'ok' else 'bad'", 0, 999);
650+
651+ Qblock qblock = w2q.apply(wire);
652+ FunVal fun = new EnclosedQblockFunVal(vm, qblock, vm.binding.newBinding());
653+ FunVal caller = vm.fun.make().action(c -> c.call(fun).args(intHolder.of(999)));
654+ StrVal result = (StrVal) runFun(caller);
655+ assertThat(result.getString()).isEqualTo("ok");
656+ }
657+
658+ @Test
659+ public void test_run_qblock_jumpifne_false_with_int() {
660+ Wire wire = new Wire(List.of(
661+ new ArgInsn(0, 100),
662+ new JumpIfNeInsn(intHolder.of(999), "ne", 102),
663+ new KonstInsn(vm.str.of("ok"), 103),
664+ new RetInsn(104),
665+ new LabelPseudoInsn("ne"),
666+ new KonstInsn(vm.str.of("bad"), 105),
667+ new RetInsn(106)), 1, 0, List.of());
668+ WireToQblockTranslator w2q = new WireToQblockTranslator(
669+ vm, "foo.kn", "if \\0 equals 999 then return 'ok' else 'bad'", 0, 999);
670+
671+ Qblock qblock = w2q.apply(wire);
672+ FunVal fun = new EnclosedQblockFunVal(vm, qblock, vm.binding.newBinding());
673+ FunVal caller = vm.fun.make().action(c -> c.call(fun).args(intHolder.of(777)));
674+ StrVal result = (StrVal) runFun(caller);
675+ assertThat(result.getString()).isEqualTo("bad");
676+ }
677+
678+ @Test
679+ public void test_run_qblock_jumpifne_true_with_str() {
680+ Wire wire = new Wire(List.of(
681+ new ArgInsn(0, 100),
682+ new JumpIfNeInsn(vm.str.of("foobar"), "ne", 101),
683+ new KonstInsn(vm.str.of("ok"), 102),
684+ new RetInsn(103),
685+ new LabelPseudoInsn("ne"),
686+ new KonstInsn(vm.str.of("bad"), 104),
687+ new RetInsn(105)), 1, 0, List.of());
688+ WireToQblockTranslator w2q = new WireToQblockTranslator(
689+ vm, "foo.kn", "if \\0 equals 'foobar' then return 'ok' else 'bad'", 0, 999);
690+
691+ Qblock qblock = w2q.apply(wire);
692+ FunVal fun = new EnclosedQblockFunVal(vm, qblock, vm.binding.newBinding());
693+ FunVal caller = vm.fun.make().action(c -> c.call(fun).args(vm.str.of("foobar")));
694+ StrVal result = (StrVal) runFun(caller);
695+ assertThat(result.getString()).isEqualTo("ok");
696+ }
697+
698+ @Test
699+ public void test_run_qblock_jumpifne_false_with_str() {
700+ Wire wire = new Wire(List.of(
701+ new ArgInsn(0, 100),
702+ new JumpIfNeInsn(vm.str.of("foobar"), "ne", 101),
703+ new KonstInsn(vm.str.of("ok"), 102),
704+ new RetInsn(103),
705+ new LabelPseudoInsn("ne"),
706+ new KonstInsn(vm.str.of("bad"), 104),
707+ new RetInsn(105)), 1, 0, List.of());
708+ WireToQblockTranslator w2q = new WireToQblockTranslator(
709+ vm, "foo.kn", "if \\0 equals 'foobar' then return 'ok' else 'bad'", 0, 999);
710+
711+ Qblock qblock = w2q.apply(wire);
712+ FunVal fun = new EnclosedQblockFunVal(vm, qblock, vm.binding.newBinding());
713+ FunVal caller = vm.fun.make().action(c -> c.call(fun).args(vm.str.of("boo")));
714+ StrVal result = (StrVal) runFun(caller);
715+ assertThat(result.getString()).isEqualTo("bad");
716+ }
717+
718+ // }}}2
719+
634720 // IFLT {{{2
635721
636722 @Test
Afficher sur ancien navigateur de dépôt.