diff --git a/src/pk_core.c b/src/pk_core.c index ba150ed..e963a48 100644 --- a/src/pk_core.c +++ b/src/pk_core.c @@ -1217,6 +1217,14 @@ Var varBitRshift(PKVM* vm, Var v1, Var v2) { return VAR_NULL; } +Var varBitNot(PKVM* vm, Var v) { + int64_t i; + + if (!validateInteger(vm, v, &i, "Unary operand")) return VAR_NULL; + + return VAR_NUM((double)(~i)); +} + bool varGreater(Var v1, Var v2) { double d1, d2; diff --git a/src/pk_core.h b/src/pk_core.h index ff391ce..205ad37 100644 --- a/src/pk_core.h +++ b/src/pk_core.h @@ -41,6 +41,7 @@ Var varBitOr(PKVM* vm, Var v1, Var v2); // Returns v1 | v2. Var varBitXor(PKVM* vm, Var v1, Var v2); // Returns v1 ^ v2. Var varBitLshift(PKVM* vm, Var v1, Var v2); // Returns v1 << v2. Var varBitRshift(PKVM* vm, Var v1, Var v2); // Returns v1 >> v2. +Var varBitNot(PKVM* vm, Var v); // Returns ~v. bool varGreater(Var v1, Var v2); // Returns v1 > v2. bool varLesser(Var v1, Var v2); // Returns v1 < v2. diff --git a/src/pk_vm.c b/src/pk_vm.c index e2896c8..1044440 100644 --- a/src/pk_vm.c +++ b/src/pk_vm.c @@ -1220,7 +1220,17 @@ static PkResult runFiber(PKVM* vm, Fiber* fiber) { } OPCODE(BIT_NOT): - TODO; + { + // Don't pop yet, we need the reference for gc. + Var val = PEEK(-1); + + Var result = varBitNot(vm, val); + DROP(); // val + PUSH(result); + + CHECK_ERROR(); + DISPATCH(); + } // Do not ever use PUSH(binaryOp(vm, POP(), POP())); // Function parameters are not evaluated in a defined order in C. diff --git a/tests/lang/basics.pk b/tests/lang/basics.pk index c197c4f..f14b3c8 100644 --- a/tests/lang/basics.pk +++ b/tests/lang/basics.pk @@ -73,6 +73,11 @@ assert(8 >> 1 == 0x4) assert(8 >> 2 == 0b10) assert(0xa >> 1 == 5) +assert(~8 == -9) +assert(~1 == -2) +assert(~0b0 == -1) +assert(~0x1 == -2) + x = 42 ; assert((x&=51) == 34) x = 123 ; assert((x&=324) == 64) for i in 0..1000