diff --git a/modules/callgrind.krk b/modules/callgrind.krk index fb6319c..961c65a 100644 --- a/modules/callgrind.krk +++ b/modules/callgrind.krk @@ -7,7 +7,7 @@ def processFile(sourcePath, pid, cmd): with fileio.open(sourcePath,'r') as f: for line in f.readlines(): let callerFile, callerFunc, callerLine, calleeFile, calleeFunc, calleeLine, nsecs = line.split(' ') - nsecs = int(nsecs) + nsecs = int(nsecs[:-2]) let data = funcs.get((callerFile,callerFunc),{}) let call = data.get((callerLine,calleeFile,calleeFunc,calleeLine),(0,0)) let out = (call[0] + 1, call[1] + nsecs) @@ -37,7 +37,7 @@ def processFile(sourcePath, pid, cmd): let count, nsecs = v totalNsecs -= nsecs - out.write(f'{startLine} {totalNsecs}\n') + out.write(f'{startLine} {totalNsecs}00\n') for k, v in value.items(): if not k: continue let sourceLine, file, func, destLine = k @@ -45,5 +45,5 @@ def processFile(sourcePath, pid, cmd): if file != sFile: out.write(f'cfi={file}\n') out.write(f'cfn={func}\n') out.write(f'calls={count} {destLine}\n') - out.write(f'{sourceLine} {totalNsecs}\n') + out.write(f'{sourceLine} {totalNsecs}00\n') out.write('\n') diff --git a/src/kuroko/kuroko.h b/src/kuroko/kuroko.h index 5e8c7f6..34322a0 100644 --- a/src/kuroko/kuroko.h +++ b/src/kuroko/kuroko.h @@ -8,20 +8,20 @@ #include #if defined(__EMSCRIPTEN__) -typedef long long krk_integer_type; -# define PRIkrk_int "%lld" -# define PRIkrk_hex "%llx" -# define parseStrInt strtoll +typedef int krk_integer_type; +# define PRIkrk_int "%d" +# define PRIkrk_hex "%x" +# define parseStrInt strtol #elif defined(_WIN32) -typedef long long krk_integer_type; -# define PRIkrk_int "%I64d" -# define PRIkrk_hex "%I64x" -# define parseStrInt strtoll +typedef int krk_integer_type; +# define PRIkrk_int "%I32d" +# define PRIkrk_hex "%I32x" +# define parseStrInt strtol # define ENABLE_THREADING # else -typedef long krk_integer_type; -# define PRIkrk_int "%ld" -# define PRIkrk_hex "%lx" +typedef int krk_integer_type; +# define PRIkrk_int "%d" +# define PRIkrk_hex "%x" # define parseStrInt strtol # define ENABLE_THREADING #endif diff --git a/src/kuroko/value.h b/src/kuroko/value.h index df62635..7727afe 100644 --- a/src/kuroko/value.h +++ b/src/kuroko/value.h @@ -4,6 +4,7 @@ * @brief Definitions for primitive stack references. */ #include +#include #include "kuroko.h" /** @@ -18,37 +19,26 @@ typedef struct KrkString KrkString; /** * @brief Tag enum for basic value types. * - * Value types are tagged unions of a handful of small - * types represented directly on the stack: Integers, - * double-precision floating point values, booleans, - * exception handler references, complex function argument - * processing sentinels, object reference pointers, and None. + * These are the values stored in the upper NaN bits of + * the boxed NaN values. */ typedef enum { - KRK_VAL_NONE, - KRK_VAL_BOOLEAN, - KRK_VAL_INTEGER, - KRK_VAL_FLOATING, - KRK_VAL_HANDLER, - KRK_VAL_OBJECT, - KRK_VAL_KWARGS, + KRK_VAL_BOOLEAN = 0xFFFC, + KRK_VAL_INTEGER = 0xFFFD, + KRK_VAL_HANDLER = 0xFFFE, + KRK_VAL_NONE = 0xFFFF, + KRK_VAL_KWARGS = 0x7FFC, + KRK_VAL_OBJECT = 0x7FFD, } KrkValueType; -/** - * @brief Stack value representation of a 'with' or 'try' block. - * - * When a 'with' or 'try' block is entered, a handler value is - * created on the stack representing the type (with, try) and the - * jump target to leave the block (entering the 'except' block of - * a 'try', if present, or calling the __exit__ method of an object - * __enter__'d by a 'with' block). When the relevant conditions are - * triggered in the VM, the stack will be scanned from top to bottom - * to look for these values. - */ -typedef struct { - unsigned short type; - unsigned short target; -} KrkJumpTarget; +#define KRK_VAL_MASK_BOOLEAN ((uint64_t)0xFFFC000000000000) /* 1..1100 */ +#define KRK_VAL_MASK_INTEGER ((uint64_t)0xFFFD000000000000) /* 1..1101 */ +#define KRK_VAL_MASK_HANDLER ((uint64_t)0xFFFE000000000000) /* 1..1110 */ +#define KRK_VAL_MASK_NONE ((uint64_t)0xFFFF000000000000) /* 1..1111 */ +#define KRK_VAL_MASK_KWARGS ((uint64_t)0x7FFC000000000000) /* 0..1100 */ +#define KRK_VAL_MASK_OBJECT ((uint64_t)0x7FFD000000000000) /* 0..1101 */ +#define KRK_VAL_MASK_NAN ((uint64_t)0x7FFC000000000000) +#define KRK_VAL_MASK_LOW ((uint64_t)0x0000FFFFFFFFFFFF) /** * @brief Stack reference or primative value. @@ -59,19 +49,11 @@ typedef struct { * direct copying rather than as pointers, avoiding the need to track * memory used by them. * - * Each value is a tagged union with a type (see the enum KrkValueType) - * and its contents. + * Implemented through basic NaN-boxing where the top sixteen bits are + * used as a tag (@ref KrkValueType) and the lower 32 or 48 bits contain + * the various primitive types. */ -typedef struct { - KrkValueType type; - union { - char boolean; - krk_integer_type integer; - double floating; - KrkJumpTarget handler; - KrkObj * object; - } as; -} KrkValue; +typedef uint64_t KrkValue; /** * @brief Flexible vector of stack references. @@ -183,30 +165,51 @@ extern int krk_valuesEqual(KrkValue a, KrkValue b); */ extern int krk_valuesSame(KrkValue a, KrkValue b); -#define BOOLEAN_VAL(value) ((KrkValue){KRK_VAL_BOOLEAN, {.integer = value}}) -#define NONE_VAL(value) ((KrkValue){KRK_VAL_NONE, {.integer = 0}}) -#define INTEGER_VAL(value) ((KrkValue){KRK_VAL_INTEGER, {.integer = value}}) -#define FLOATING_VAL(value) ((KrkValue){KRK_VAL_FLOATING,{.floating = value}}) -#define HANDLER_VAL(ty,ta) ((KrkValue){KRK_VAL_HANDLER, {.handler = (KrkJumpTarget){.type = ty, .target = ta}}}) -#define OBJECT_VAL(value) ((KrkValue){KRK_VAL_OBJECT, {.object = (KrkObj*)value}}) -#define KWARGS_VAL(value) ((KrkValue){KRK_VAL_KWARGS, {.integer = value}}) +#define NONE_VAL(value) ((KrkValue)(KRK_VAL_MASK_LOW | KRK_VAL_MASK_NONE)) +#define BOOLEAN_VAL(value) ((KrkValue)((uint32_t)(value) | KRK_VAL_MASK_BOOLEAN)) +#define INTEGER_VAL(value) ((KrkValue)((uint32_t)(value) | KRK_VAL_MASK_INTEGER)) +#define KWARGS_VAL(value) ((KrkValue)((uint32_t)(value) | KRK_VAL_MASK_KWARGS)) +#define OBJECT_VAL(value) ((KrkValue)(((uintptr_t)(value) & KRK_VAL_MASK_LOW) | KRK_VAL_MASK_OBJECT)) +#define HANDLER_VAL(ty,ta) ((KrkValue)((uint32_t)((((uint16_t)ty) << 16) | ((uint16_t)ta)) | KRK_VAL_MASK_HANDLER)) +#define FLOATING_VAL(value) (krk_dbl_as_val(value)) -#define AS_BOOLEAN(value) ((value).as.integer) -#define AS_INTEGER(value) ((value).as.integer) -#define AS_FLOATING(value) ((value).as.floating) -#define AS_HANDLER(value) ((value).as.handler) -#define AS_OBJECT(value) ((value).as.object) +#define KRK_VAL_TYPE(value) ((value) >> 48) -#define IS_BOOLEAN(value) ((value).type == KRK_VAL_BOOLEAN) -#define IS_NONE(value) ((value).type == KRK_VAL_NONE) -#define IS_INTEGER(value) (((value).type == KRK_VAL_INTEGER) || ((value.type) == KRK_VAL_BOOLEAN)) -#define IS_FLOATING(value) ((value).type == KRK_VAL_FLOATING) -#define IS_HANDLER(value) ((value).type == KRK_VAL_HANDLER) -#define IS_OBJECT(value) ((value).type == KRK_VAL_OBJECT) -#define IS_KWARGS(value) ((value).type == KRK_VAL_KWARGS) +#define AS_BOOLEAN(value) ((krk_integer_type)((value) & KRK_VAL_MASK_LOW)) +#define AS_INTEGER(value) ((krk_integer_type)((value) & KRK_VAL_MASK_LOW)) +#define AS_HANDLER(value) ((uint32_t)((value) & KRK_VAL_MASK_LOW)) +#define AS_OBJECT(value) ((KrkObj*)(uintptr_t)((value) & KRK_VAL_MASK_LOW)) +#define AS_FLOATING(value) (krk_val_as_dbl(value)) -#define IS_TRY_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER(value).type == OP_PUSH_TRY) -#define IS_WITH_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER(value).type == OP_PUSH_WITH) -#define IS_RAISE_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER(value).type == OP_RAISE) -#define IS_EXCEPT_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER(value).type == OP_FILTER_EXCEPT) +static inline double krk_val_as_dbl(KrkValue val) { + double out; + memcpy(&out,&val,sizeof(KrkValue)); + return out; +} +static inline KrkValue krk_dbl_as_val(double dbl) { + KrkValue out; + memcpy(&out,&dbl,sizeof(KrkValue)); + return out; +} + +#define IS_INTEGER(value) (((value) & KRK_VAL_MASK_HANDLER) == KRK_VAL_MASK_BOOLEAN) +#define IS_BOOLEAN(value) (((value) & KRK_VAL_MASK_NONE) == KRK_VAL_MASK_BOOLEAN) +#define IS_NONE(value) (((value) & KRK_VAL_MASK_NONE) == KRK_VAL_MASK_NONE) +#define IS_HANDLER(value) (((value) & KRK_VAL_MASK_NONE) == KRK_VAL_MASK_HANDLER) +#define IS_OBJECT(value) (((value) & KRK_VAL_MASK_NONE) == KRK_VAL_MASK_OBJECT) +#define IS_KWARGS(value) (((value) & KRK_VAL_MASK_NONE) == KRK_VAL_MASK_KWARGS) +#define IS_FLOATING(value) (((value) & KRK_VAL_MASK_NAN) != KRK_VAL_MASK_NAN) + +#define AS_HANDLER_TYPE(value) (AS_HANDLER(value) >> 16) +#define AS_HANDLER_TARGET(value) (AS_HANDLER(value) & 0xFFFF) +#define IS_TRY_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER_TYPE(value) == OP_PUSH_TRY) +#define IS_WITH_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER_TYPE(value) == OP_PUSH_WITH) +#define IS_RAISE_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER_TYPE(value) == OP_RAISE) +#define IS_EXCEPT_HANDLER(value) (IS_HANDLER(value) && AS_HANDLER_TYPE(value) == OP_FILTER_EXCEPT) + +#define KWARGS_SINGLE (INT32_MAX) +#define KWARGS_LIST (INT32_MAX-1) +#define KWARGS_DICT (INT32_MAX-2) +#define KWARGS_NIL (INT32_MAX-3) +#define KWARGS_UNSET (0) diff --git a/src/module_math.c b/src/module_math.c index 1a69ebb..379b3c3 100644 --- a/src/module_math.c +++ b/src/module_math.c @@ -18,7 +18,7 @@ } #define FORCE_FLOAT(arg) \ - if (!IS_FLOATING(arg)) { switch (arg.type) { \ + if (!IS_FLOATING(arg)) { switch (KRK_VAL_TYPE(arg)) { \ case KRK_VAL_INTEGER: arg = FLOATING_VAL(AS_INTEGER(arg)); break; \ case KRK_VAL_BOOLEAN: arg = FLOATING_VAL(AS_BOOLEAN(arg)); break; \ default: { \ diff --git a/src/obj_tuple.c b/src/obj_tuple.c index bf773cc..c60242a 100644 --- a/src/obj_tuple.c +++ b/src/obj_tuple.c @@ -16,7 +16,7 @@ static KrkValue _tuple_init(int argc, KrkValue argv[], int hasKw) { /* Convert this to a call to tupleOf(*arg) */ KrkValue tupleOf; krk_tableGet(&vm.builtins->fields, OBJECT_VAL(S("tupleOf")), &tupleOf); - krk_push(KWARGS_VAL(LONG_MAX-1)); + krk_push(KWARGS_VAL(KWARGS_LIST)); krk_push(argv[1]); krk_push(KWARGS_VAL(1)); krk_push(krk_callSimple(tupleOf, 3, 0)); diff --git a/src/table.c b/src/table.c index c280c17..ec4180a 100644 --- a/src/table.c +++ b/src/table.c @@ -22,13 +22,14 @@ void krk_freeTable(KrkTable * table) { } inline uint32_t krk_hashValue(KrkValue value) { - switch (value.type) { + switch (KRK_VAL_TYPE(value)) { case KRK_VAL_INTEGER: return (uint32_t)(AS_INTEGER(value)); - case KRK_VAL_FLOATING: return (uint32_t)(AS_FLOATING(value) * 1000); /* arbitrary; what's a good way to hash floats? */ case KRK_VAL_BOOLEAN: return (uint32_t)(AS_BOOLEAN(value)); case KRK_VAL_NONE: return 0; case KRK_VAL_OBJECT: return (uint32_t)(AS_OBJECT(value))->hash; - default: return 0; + default: + if (IS_FLOATING(value)) return (uint32_t)(AS_FLOATING(value) * 1000); /* arbitrary; what's a good way to hash floats? */ + return 0; } } diff --git a/src/value.c b/src/value.c index 14e22ae..b7fec17 100644 --- a/src/value.c +++ b/src/value.c @@ -48,38 +48,39 @@ void krk_printValue(FILE * f, KrkValue printable) { void krk_printValueSafe(FILE * f, KrkValue printable) { if (!IS_OBJECT(printable)) { - switch (printable.type) { + switch (KRK_VAL_TYPE(printable)) { case KRK_VAL_INTEGER: fprintf(f, PRIkrk_int, AS_INTEGER(printable)); break; case KRK_VAL_BOOLEAN: fprintf(f, "%s", AS_BOOLEAN(printable) ? "True" : "False"); break; - case KRK_VAL_FLOATING: fprintf(f, "%.16g", AS_FLOATING(printable)); break; case KRK_VAL_NONE: fprintf(f, "None"); break; case KRK_VAL_HANDLER: - switch (AS_HANDLER(printable).type) { - case OP_PUSH_TRY: fprintf(f, "{try->%d}", (int)AS_HANDLER(printable).target); break; - case OP_PUSH_WITH: fprintf(f, "{with->%d}", (int)AS_HANDLER(printable).target); break; - case OP_RAISE: fprintf(f, "{raise<-%d}", (int)AS_HANDLER(printable).target); break; - case OP_FILTER_EXCEPT: fprintf(f, "{except<-%d}", (int)AS_HANDLER(printable).target); break; - case OP_BEGIN_FINALLY: fprintf(f, "{finally<-%d}", (int)AS_HANDLER(printable).target); break; - case OP_RETURN: fprintf(f, "{return<-%d}", (int)AS_HANDLER(printable).target); break; + switch (AS_HANDLER_TYPE(printable)) { + case OP_PUSH_TRY: fprintf(f, "{try->%d}", (int)AS_HANDLER_TARGET(printable)); break; + case OP_PUSH_WITH: fprintf(f, "{with->%d}", (int)AS_HANDLER_TARGET(printable)); break; + case OP_RAISE: fprintf(f, "{raise<-%d}", (int)AS_HANDLER_TARGET(printable)); break; + case OP_FILTER_EXCEPT: fprintf(f, "{except<-%d}", (int)AS_HANDLER_TARGET(printable)); break; + case OP_BEGIN_FINALLY: fprintf(f, "{finally<-%d}", (int)AS_HANDLER_TARGET(printable)); break; + case OP_RETURN: fprintf(f, "{return<-%d}", (int)AS_HANDLER_TARGET(printable)); break; } break; case KRK_VAL_KWARGS: { - if (AS_INTEGER(printable) == LONG_MAX) { + if (AS_INTEGER(printable) == KWARGS_SINGLE) { fprintf(f, "{unpack single}"); - } else if (AS_INTEGER(printable) == LONG_MAX-1) { + } else if (AS_INTEGER(printable) == KWARGS_LIST) { fprintf(f, "{unpack list}"); - } else if (AS_INTEGER(printable) == LONG_MAX-2) { + } else if (AS_INTEGER(printable) == KWARGS_DICT) { fprintf(f, "{unpack dict}"); - } else if (AS_INTEGER(printable) == LONG_MAX-3) { + } else if (AS_INTEGER(printable) == KWARGS_NIL) { fprintf(f, "{unpack nil}"); - } else if (AS_INTEGER(printable) == 0) { + } else if (AS_INTEGER(printable) == KWARGS_UNSET) { fprintf(f, "{unset default}"); } else { fprintf(f, "{sentinel=" PRIkrk_int "}",AS_INTEGER(printable)); } break; } - default: break; + default: + if (IS_FLOATING(printable)) fprintf(f, "%.16g", AS_FLOATING(printable)); + break; } } else if (IS_STRING(printable)) { fprintf(f, "'"); @@ -137,7 +138,7 @@ void krk_printValueSafe(FILE * f, KrkValue printable) { } int krk_valuesSame(KrkValue a, KrkValue b) { - if (a.type != b.type) return 0; + if (KRK_VAL_TYPE(a) != KRK_VAL_TYPE(b)) return 0; if (IS_OBJECT(a)) return AS_OBJECT(a) == AS_OBJECT(b); return krk_valuesEqual(a,b); } @@ -145,13 +146,12 @@ int krk_valuesSame(KrkValue a, KrkValue b) { __attribute__((hot)) inline int krk_valuesEqual(KrkValue a, KrkValue b) { - if (a.type == b.type) { - switch (a.type) { + if (KRK_VAL_TYPE(a) == KRK_VAL_TYPE(b)) { + switch (KRK_VAL_TYPE(a)) { case KRK_VAL_BOOLEAN: return AS_BOOLEAN(a) == AS_BOOLEAN(b); case KRK_VAL_NONE: return 1; /* None always equals None */ case KRK_VAL_KWARGS: /* Equal if same number of args; may be useful for comparing sentinels (0) to arg lists. */ case KRK_VAL_INTEGER: return AS_INTEGER(a) == AS_INTEGER(b); - case KRK_VAL_FLOATING: return AS_FLOATING(a) == AS_FLOATING(b); case KRK_VAL_HANDLER: krk_runtimeError(vm.exceptions->valueError,"Invalid value"); return 0; case KRK_VAL_OBJECT: { if (AS_OBJECT(a) == AS_OBJECT(b)) return 1; @@ -159,33 +159,29 @@ int krk_valuesEqual(KrkValue a, KrkValue b) { default: break; } } + if (IS_FLOATING(a) && IS_FLOATING(b)) return AS_FLOATING(a) == AS_FLOATING(b); if (IS_KWARGS(a) || IS_KWARGS(b)) return 0; if (!IS_OBJECT(a) && !IS_OBJECT(b)) { - switch (a.type) { + switch (KRK_VAL_TYPE(a)) { case KRK_VAL_INTEGER: { - switch (b.type) { - case KRK_VAL_BOOLEAN: return AS_INTEGER(a) == AS_BOOLEAN(b); - case KRK_VAL_FLOATING: return (double)AS_INTEGER(a) == AS_FLOATING(b); - default: return 0; - } - } break; - case KRK_VAL_FLOATING: { - switch (b.type) { - case KRK_VAL_BOOLEAN: return AS_FLOATING(a) == (double)AS_BOOLEAN(b); - case KRK_VAL_INTEGER: return AS_FLOATING(a) == (double)AS_INTEGER(b); - default: return 0; - } + if (IS_BOOLEAN(b)) return AS_INTEGER(a) == AS_BOOLEAN(b); + else if (IS_FLOATING(b)) return (double)AS_INTEGER(a) == AS_FLOATING(b); + return 0; } break; case KRK_VAL_BOOLEAN: { - switch (b.type) { - case KRK_VAL_INTEGER: return AS_BOOLEAN(a) == AS_INTEGER(b); - case KRK_VAL_FLOATING: return (double)AS_BOOLEAN(a) == AS_FLOATING(b); - default: return 0; - } + if (IS_INTEGER(b)) return AS_INTEGER(a) == AS_BOOLEAN(b); + else if (IS_FLOATING(b)) return (double)AS_INTEGER(a) == AS_FLOATING(b); + return 0; } break; - default: return 0; + default: + if (IS_FLOATING(a)) { + if (IS_BOOLEAN(b)) return AS_FLOATING(a) == (double)AS_BOOLEAN(b); + else if (IS_INTEGER(b)) return AS_FLOATING(a) == (double)AS_INTEGER(b); + return 0; + } + break; } } diff --git a/src/vm.c b/src/vm.c index a72dcad..2f8bf4e 100644 --- a/src/vm.c +++ b/src/vm.c @@ -448,11 +448,9 @@ void krk_finalizeClass(KrkClass * _class) { * Internal version of type(). */ inline KrkClass * krk_getType(KrkValue of) { - switch (of.type) { + switch (KRK_VAL_TYPE(of)) { case KRK_VAL_INTEGER: return vm.baseClasses->intClass; - case KRK_VAL_FLOATING: - return vm.baseClasses->floatClass; case KRK_VAL_BOOLEAN: return vm.baseClasses->boolClass; case KRK_VAL_NONE: @@ -480,6 +478,7 @@ inline KrkClass * krk_getType(KrkValue of) { return vm.baseClasses->objectClass; } break; default: + if (IS_FLOATING(of)) return vm.baseClasses->floatClass; return vm.baseClasses->objectClass; } } @@ -557,9 +556,9 @@ int krk_processComplexArguments(int argCount, KrkValueArray * positionals, KrkTa KrkValue key = startOfExtras[i*2]; KrkValue value = startOfExtras[i*2 + 1]; if (IS_KWARGS(key)) { - if (AS_INTEGER(key) == LONG_MAX-1) { /* unpack list */ + if (AS_INTEGER(key) == KWARGS_LIST) { /* unpack list */ unpackIterableFast(value); - } else if (AS_INTEGER(key) == LONG_MAX-2) { /* unpack dict */ + } else if (AS_INTEGER(key) == KWARGS_DICT) { /* unpack dict */ if (!IS_INSTANCE(value)) { krk_runtimeError(vm.exceptions->typeError, "**expression value is not a dict."); return 0; @@ -577,7 +576,7 @@ int krk_processComplexArguments(int argCount, KrkValueArray * positionals, KrkTa } } } - } else if (AS_INTEGER(key) == LONG_MAX) { /* single value */ + } else if (AS_INTEGER(key) == KWARGS_SINGLE) { /* single value */ krk_writeValueArray(positionals, value); } } else if (IS_STRING(key)) { @@ -1002,19 +1001,21 @@ void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj * obj) { * going to take the else branch. */ int krk_isFalsey(KrkValue value) { - switch (value.type) { + switch (KRK_VAL_TYPE(value)) { case KRK_VAL_NONE: return 1; case KRK_VAL_BOOLEAN: return !AS_BOOLEAN(value); case KRK_VAL_INTEGER: return !AS_INTEGER(value); - case KRK_VAL_FLOATING: return !AS_FLOATING(value); case KRK_VAL_OBJECT: { switch (AS_OBJECT(value)->type) { case KRK_OBJ_STRING: return !AS_STRING(value)->codesLength; case KRK_OBJ_TUPLE: return !AS_TUPLE(value)->values.count; default: break; } + break; } - default: break; + default: + if (IS_FLOATING(value)) return !AS_FLOATING(value); + break; } KrkClass * type = krk_getType(value); @@ -2016,7 +2017,7 @@ _resumeHook: (void)0; KrkValue contextManager = krk_peek(2); KrkClass * type = krk_getType(contextManager); krk_push(contextManager); - if (AS_HANDLER(handler).type == OP_RAISE) { + if (AS_HANDLER_TYPE(handler) == OP_RAISE) { krk_push(OBJECT_VAL(krk_getType(exceptionObject))); krk_push(exceptionObject); KrkValue tracebackEntries = NONE_VAL(); @@ -2038,7 +2039,7 @@ _resumeHook: (void)0; krk_callSimple(OBJECT_VAL(type->_exit), 4, 0); if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) goto _finishException; } - if (AS_HANDLER(handler).type != OP_RETURN) break; + if (AS_HANDLER_TYPE(handler) != OP_RETURN) break; krk_pop(); /* handler */ } /* fallthrough */ case OP_RETURN: { @@ -2055,8 +2056,8 @@ _finishReturn: (void)0; ; stackOffset--); if (stackOffset >= (int)frame->slots) { krk_currentThread.stackTop = &krk_currentThread.stack[stackOffset + 1]; - frame->ip = frame->closure->function->chunk.code + AS_HANDLER(krk_peek(0)).target; - AS_HANDLER(krk_currentThread.stackTop[-1]).type = OP_RETURN; + frame->ip = frame->closure->function->chunk.code + AS_HANDLER_TARGET(krk_peek(0)); + krk_currentThread.stackTop[-1] = HANDLER_VAL(OP_RETURN,AS_HANDLER_TARGET(krk_peek(0))); krk_currentThread.stackTop[-2] = result; break; } @@ -2248,9 +2249,9 @@ _finishReturn: (void)0; break; case OP_FILTER_EXCEPT: { int isMatch = 0; - if (AS_HANDLER(krk_peek(1)).type == OP_RETURN) { + if (AS_HANDLER_TYPE(krk_peek(1)) == OP_RETURN) { isMatch = 0; - } else if (AS_HANDLER(krk_peek(1)).type == OP_END_FINALLY) { + } else if (AS_HANDLER_TYPE(krk_peek(1)) == OP_END_FINALLY) { isMatch = 0; } else if (IS_CLASS(krk_peek(0)) && krk_isInstanceOf(krk_peek(2), AS_CLASS(krk_peek(0)))) { isMatch = 1; @@ -2265,7 +2266,7 @@ _finishReturn: (void)0; isMatch = !IS_NONE(krk_peek(2)); } if (isMatch) { - AS_HANDLER(krk_currentThread.stackTop[-2]).type = OP_FILTER_EXCEPT; + krk_currentThread.stackTop[-2] = HANDLER_VAL(OP_FILTER_EXCEPT,AS_HANDLER_TARGET(krk_peek(1))); } krk_pop(); krk_push(BOOLEAN_VAL(isMatch)); @@ -2273,10 +2274,10 @@ _finishReturn: (void)0; } case OP_BEGIN_FINALLY: { if (IS_HANDLER(krk_peek(0))) { - if (AS_HANDLER(krk_peek(0)).type == OP_PUSH_TRY) { - AS_HANDLER(krk_currentThread.stackTop[-1]).type = OP_BEGIN_FINALLY; - } else if (AS_HANDLER(krk_peek(0)).type == OP_FILTER_EXCEPT) { - AS_HANDLER(krk_currentThread.stackTop[-1]).type = OP_BEGIN_FINALLY; + if (AS_HANDLER_TYPE(krk_peek(0)) == OP_PUSH_TRY) { + krk_currentThread.stackTop[-1] = HANDLER_VAL(OP_BEGIN_FINALLY,AS_HANDLER_TARGET(krk_peek(0))); + } else if (AS_HANDLER_TYPE(krk_peek(0)) == OP_FILTER_EXCEPT) { + krk_currentThread.stackTop[-1] = HANDLER_VAL(OP_BEGIN_FINALLY,AS_HANDLER_TARGET(krk_peek(0))); } } break; @@ -2284,12 +2285,12 @@ _finishReturn: (void)0; case OP_END_FINALLY: { KrkValue handler = krk_peek(0); if (IS_HANDLER(handler)) { - if (AS_HANDLER(handler).type == OP_RAISE || AS_HANDLER(handler).type == OP_END_FINALLY) { + if (AS_HANDLER_TYPE(handler) == OP_RAISE || AS_HANDLER_TYPE(handler) == OP_END_FINALLY) { krk_pop(); /* handler */ krk_currentThread.currentException = krk_pop(); krk_currentThread.flags |= KRK_THREAD_HAS_EXCEPTION; goto _finishException; - } else if (AS_HANDLER(handler).type == OP_RETURN) { + } else if (AS_HANDLER_TYPE(handler) == OP_RETURN) { krk_push(krk_peek(1)); goto _finishReturn; } @@ -2486,7 +2487,7 @@ _finishReturn: (void)0; case OP_EXPAND_ARGS_LONG: case OP_EXPAND_ARGS: { int type = OPERAND; - krk_push(KWARGS_VAL(LONG_MAX-type)); + krk_push(KWARGS_VAL(KWARGS_SINGLE-type)); break; } case OP_CLOSURE_LONG: @@ -2747,12 +2748,12 @@ _finishReturn: (void)0; _finishException: if (!handleException()) { frame = &krk_currentThread.frames[krk_currentThread.frameCount - 1]; - frame->ip = frame->closure->function->chunk.code + AS_HANDLER(krk_peek(0)).target; + frame->ip = frame->closure->function->chunk.code + AS_HANDLER_TARGET(krk_peek(0)); /* Stick the exception into the exception slot */ - if (AS_HANDLER(krk_currentThread.stackTop[-1]).type == OP_FILTER_EXCEPT) { - AS_HANDLER(krk_currentThread.stackTop[-1]).type = OP_END_FINALLY; + if (AS_HANDLER_TYPE(krk_currentThread.stackTop[-1])== OP_FILTER_EXCEPT) { + krk_currentThread.stackTop[-1] = HANDLER_VAL(OP_END_FINALLY,AS_HANDLER_TARGET(krk_peek(0))); } else { - AS_HANDLER(krk_currentThread.stackTop[-1]).type = OP_RAISE; + krk_currentThread.stackTop[-1] = HANDLER_VAL(OP_RAISE,AS_HANDLER_TARGET(krk_peek(0))); } krk_currentThread.stackTop[-2] = krk_currentThread.currentException; krk_currentThread.currentException = NONE_VAL(); diff --git a/test/day23.krk b/test/day23.krk index c4eaa33..76e8170 100644 --- a/test/day23.krk +++ b/test/day23.krk @@ -33,6 +33,6 @@ def __main__(): ordering[m3] = px m0 = ordering[m0] - print(ordering[1]*ordering[ordering[1]]) + print(str(float(ordering[1])*ordering[ordering[1]]).replace('.0','')) __main__() diff --git a/test/testSpecialDecorators.krk b/test/testSpecialDecorators.krk index 2367a8d..fada7aa 100644 --- a/test/testSpecialDecorators.krk +++ b/test/testSpecialDecorators.krk @@ -41,5 +41,5 @@ class Baz(object): let b = Baz() print(b.bar) -b.bar = 0xDEADBEEF +b.bar = 0xCAFE print(b.bar) diff --git a/test/testSpecialDecorators.krk.expect b/test/testSpecialDecorators.krk.expect index e581331..8de5ed5 100644 --- a/test/testSpecialDecorators.krk.expect +++ b/test/testSpecialDecorators.krk.expect @@ -8,6 +8,6 @@ Called as a setter: [102] test I am a Python-style @property! 42 -I am a Python-style @property's setter called with 3735928559 +I am a Python-style @property's setter called with 51966 I am a Python-style @property! -3735928559 +51966 diff --git a/tools/compile.c b/tools/compile.c index f75de65..dfb0317 100644 --- a/tools/compile.c +++ b/tools/compile.c @@ -303,7 +303,7 @@ static int doSecondPass(FILE * out) { for (size_t i = 0; i < func->chunk.constants.count; ++i) { KrkValue * val = &func->chunk.constants.values[i]; - switch (val->type) { + switch (KRK_VAL_TYPE(*val)) { case KRK_VAL_OBJECT: switch (AS_OBJECT(*val)->type) { case KRK_OBJ_STRING: @@ -329,10 +329,11 @@ static int doSecondPass(FILE * out) { case KRK_VAL_INTEGER: WRITE_INTEGER(AS_INTEGER(*val)); break; - case KRK_VAL_FLOATING: - WRITE_FLOATING(AS_FLOATING(*val)); - break; default: + if (IS_FLOATING(*val)) { + WRITE_FLOATING(AS_FLOATING(*val)); + break; + } fprintf(stderr, "Invalid value found in constants table," "this marashal format can not store '%s'\n",