diff --git a/src/include/wren.h b/src/include/wren.h index 45d5d3b9..7c67fe10 100644 --- a/src/include/wren.h +++ b/src/include/wren.h @@ -15,8 +15,8 @@ // A monotonically increasing numeric representation of the version number. Use // this if you want to do range checks over versions. -#define WREN_VERSION_NUMBER (WREN_VERSION_MAJOR * 1000000 + \ - WREN_VERSION_MINOR * 1000 + \ +#define WREN_VERSION_NUMBER (WREN_VERSION_MAJOR * 1000000 + \ + WREN_VERSION_MINOR * 1000 + \ WREN_VERSION_PATCH) // A single virtual machine for executing Wren code. diff --git a/src/vm/wren_common.h b/src/vm/wren_common.h index c3b5682c..e04bcc9a 100644 --- a/src/vm/wren_common.h +++ b/src/vm/wren_common.h @@ -114,17 +114,17 @@ #define MAX_FIELDS 255 // Use the VM's allocator to allocate an object of [type]. -#define ALLOCATE(vm, type) \ +#define ALLOCATE(vm, type) \ ((type*)wrenReallocate(vm, NULL, 0, sizeof(type))) // Use the VM's allocator to allocate an object of [mainType] containing a // flexible array of [count] objects of [arrayType]. -#define ALLOCATE_FLEX(vm, mainType, arrayType, count) \ - ((mainType*)wrenReallocate(vm, NULL, 0, \ - sizeof(mainType) + sizeof(arrayType) * (count))) +#define ALLOCATE_FLEX(vm, mainType, arrayType, count) \ + ((mainType*)wrenReallocate(vm, NULL, 0, \ + sizeof(mainType) + sizeof(arrayType) * (count))) // Use the VM's allocator to allocate an array of [count] elements of [type]. -#define ALLOCATE_ARRAY(vm, type, count) \ +#define ALLOCATE_ARRAY(vm, type, count) \ ((type*)wrenReallocate(vm, NULL, 0, sizeof(type) * (count))) // Use the VM's allocator to free the previously allocated memory at [pointer]. @@ -156,17 +156,15 @@ #include - #define ASSERT(condition, message) \ - do \ - { \ - if (!(condition)) \ - { \ - fprintf(stderr, "[%s:%d] Assert failed in %s(): %s\n", \ - __FILE__, __LINE__, __func__, message); \ - abort(); \ - } \ - } \ - while(0) + #define ASSERT(condition, message) \ + do { \ + if (!(condition)) \ + { \ + fprintf(stderr, "[%s:%d] Assert failed in %s(): %s\n", \ + __FILE__, __LINE__, __func__, message); \ + abort(); \ + } \ + } while (false) // Indicates that we know execution should never reach this point in the // program. In debug mode, we assert this fact because it's a bug to get here. @@ -175,18 +173,16 @@ // compiler the code can't be reached. This avoids "missing return" warnings // in some cases and also lets it perform some optimizations by assuming the // code is never reached. - #define UNREACHABLE() \ - do \ - { \ - fprintf(stderr, "[%s:%d] This code should not be reached in %s()\n", \ - __FILE__, __LINE__, __func__); \ - abort(); \ - } \ - while (0) + #define UNREACHABLE() \ + do { \ + fprintf(stderr, "[%s:%d] This code should not be reached in %s()\n", \ + __FILE__, __LINE__, __func__); \ + abort(); \ + } while (false) #else - #define ASSERT(condition, message) do {} while (0) + #define ASSERT(condition, message) do { } while (false) // Tell the compiler that this part of the code will never be reached. #if defined( _MSC_VER ) diff --git a/src/vm/wren_core.c b/src/vm/wren_core.c index 34a13c8b..4aca5bb0 100644 --- a/src/vm/wren_core.c +++ b/src/vm/wren_core.c @@ -259,12 +259,12 @@ static void call_fn(WrenVM* vm, Value* args, int numArgs) wrenCallFunction(vm, vm->fiber, AS_CLOSURE(args[0]), numArgs + 1); } -#define DEF_FN_CALL(numArgs) \ - DEF_PRIMITIVE(fn_call##numArgs) \ - { \ - call_fn(vm, args, numArgs); \ - return false; \ - } \ +#define DEF_FN_CALL(numArgs) \ + DEF_PRIMITIVE(fn_call##numArgs) \ + { \ + call_fn(vm, args, numArgs); \ + return false; \ + } DEF_FN_CALL(0) DEF_FN_CALL(1) @@ -600,11 +600,11 @@ DEF_PRIMITIVE(num_pi) } // Defines a primitive on Num that calls infix [op] and returns [type]. -#define DEF_NUM_INFIX(name, op, type) \ - DEF_PRIMITIVE(num_##name) \ - { \ - if (!validateNum(vm, args[1], "Right operand")) return false; \ - RETURN_##type(AS_NUM(args[0]) op AS_NUM(args[1])); \ +#define DEF_NUM_INFIX(name, op, type) \ + DEF_PRIMITIVE(num_##name) \ + { \ + if (!validateNum(vm, args[1], "Right operand")) return false; \ + RETURN_##type(AS_NUM(args[0]) op AS_NUM(args[1])); \ } DEF_NUM_INFIX(minus, -, NUM) @@ -617,13 +617,13 @@ DEF_NUM_INFIX(lte, <=, BOOL) DEF_NUM_INFIX(gte, >=, BOOL) // Defines a primitive on Num that call infix bitwise [op]. -#define DEF_NUM_BITWISE(name, op) \ - DEF_PRIMITIVE(num_bitwise##name) \ - { \ - if (!validateNum(vm, args[1], "Right operand")) return false; \ - uint32_t left = (uint32_t)AS_NUM(args[0]); \ - uint32_t right = (uint32_t)AS_NUM(args[1]); \ - RETURN_NUM(left op right); \ +#define DEF_NUM_BITWISE(name, op) \ + DEF_PRIMITIVE(num_bitwise##name) \ + { \ + if (!validateNum(vm, args[1], "Right operand")) return false; \ + uint32_t left = (uint32_t)AS_NUM(args[0]); \ + uint32_t right = (uint32_t)AS_NUM(args[1]); \ + RETURN_NUM(left op right); \ } DEF_NUM_BITWISE(And, &) @@ -633,10 +633,10 @@ DEF_NUM_BITWISE(LeftShift, <<) DEF_NUM_BITWISE(RightShift, >>) // Defines a primitive method on Num that returns the result of [fn]. -#define DEF_NUM_FN(name, fn) \ - DEF_PRIMITIVE(num_##name) \ - { \ - RETURN_NUM(fn(AS_NUM(args[0]))); \ +#define DEF_NUM_FN(name, fn) \ + DEF_PRIMITIVE(num_##name) \ + { \ + RETURN_NUM(fn(AS_NUM(args[0]))); \ } DEF_NUM_FN(abs, fabs) diff --git a/src/vm/wren_debug.c b/src/vm/wren_debug.c index d0b8b743..0ed8231f 100644 --- a/src/vm/wren_debug.c +++ b/src/vm/wren_debug.c @@ -121,9 +121,9 @@ static int dumpInstruction(WrenVM* vm, ObjFn* fn, int i, int* lastLine) #define READ_BYTE() (bytecode[i++]) #define READ_SHORT() (i += 2, (bytecode[i - 2] << 8) | bytecode[i - 1]) - #define BYTE_INSTRUCTION(name) \ - printf("%-16s %5d\n", name, READ_BYTE()); \ - break; \ + #define BYTE_INSTRUCTION(name) \ + printf("%-16s %5d\n", name, READ_BYTE()); \ + break switch (code) { diff --git a/src/vm/wren_primitive.h b/src/vm/wren_primitive.h index c2261c3b..21b6a00a 100644 --- a/src/vm/wren_primitive.h +++ b/src/vm/wren_primitive.h @@ -5,23 +5,27 @@ // Binds a primitive method named [name] (in Wren) implemented using C function // [fn] to `ObjClass` [cls]. -#define PRIMITIVE(cls, name, function) \ - { \ - int symbol = wrenSymbolTableEnsure(vm, \ - &vm->methodNames, name, strlen(name)); \ - Method method; \ - method.type = METHOD_PRIMITIVE; \ - method.as.primitive = prim_##function; \ - wrenBindMethod(vm, cls, symbol, method); \ - } +#define PRIMITIVE(cls, name, function) \ + do { \ + int symbol = wrenSymbolTableEnsure(vm, \ + &vm->methodNames, name, strlen(name)); \ + Method method; \ + method.type = METHOD_PRIMITIVE; \ + method.as.primitive = prim_##function; \ + wrenBindMethod(vm, cls, symbol, method); \ + } while (false) // Defines a primitive method whose C function name is [name]. This abstracts // the actual type signature of a primitive function and makes it clear which C // functions are invoked as primitives. -#define DEF_PRIMITIVE(name) \ +#define DEF_PRIMITIVE(name) \ static bool prim_##name(WrenVM* vm, Value* args) -#define RETURN_VAL(value) do { args[0] = value; return true; } while (0) +#define RETURN_VAL(value) \ + do { \ + args[0] = value; \ + return true; \ + } while (false) #define RETURN_OBJ(obj) RETURN_VAL(OBJ_VAL(obj)) #define RETURN_BOOL(value) RETURN_VAL(BOOL_VAL(value)) @@ -30,17 +34,17 @@ #define RETURN_NUM(value) RETURN_VAL(NUM_VAL(value)) #define RETURN_TRUE RETURN_VAL(TRUE_VAL) -#define RETURN_ERROR(msg) \ - do { \ - vm->fiber->error = wrenNewStringLength(vm, msg, sizeof(msg) - 1); \ - return false; \ - } while (0); +#define RETURN_ERROR(msg) \ + do { \ + vm->fiber->error = wrenNewStringLength(vm, msg, sizeof(msg) - 1); \ + return false; \ + } while (false) -#define RETURN_ERROR_FMT(msg, arg) \ - do { \ - vm->fiber->error = wrenStringFormat(vm, msg, arg); \ - return false; \ - } while (0); +#define RETURN_ERROR_FMT(msg, arg) \ + do { \ + vm->fiber->error = wrenStringFormat(vm, msg, arg); \ + return false; \ + } while (false) // Validates that the given [arg] is a function. Returns true if it is. If not, // reports an error and returns false. diff --git a/src/vm/wren_utils.h b/src/vm/wren_utils.h index 4e43524d..b6c5a6d6 100644 --- a/src/vm/wren_utils.h +++ b/src/vm/wren_utils.h @@ -13,54 +13,54 @@ typedef struct sObjString ObjString; // We need buffers of a few different types. To avoid lots of casting between // void* and back, we'll use the preprocessor as a poor man's generics and let // it generate a few type-specific ones. -#define DECLARE_BUFFER(name, type) \ - typedef struct \ - { \ - type* data; \ - int count; \ - int capacity; \ - } name##Buffer; \ - void wren##name##BufferInit(name##Buffer* buffer); \ - void wren##name##BufferClear(WrenVM* vm, name##Buffer* buffer); \ - void wren##name##BufferFill(WrenVM* vm, name##Buffer* buffer, type data, \ - int count); \ +#define DECLARE_BUFFER(name, type) \ + typedef struct \ + { \ + type* data; \ + int count; \ + int capacity; \ + } name##Buffer; \ + void wren##name##BufferInit(name##Buffer* buffer); \ + void wren##name##BufferClear(WrenVM* vm, name##Buffer* buffer); \ + void wren##name##BufferFill(WrenVM* vm, name##Buffer* buffer, type data, \ + int count); \ void wren##name##BufferWrite(WrenVM* vm, name##Buffer* buffer, type data) // This should be used once for each type instantiation, somewhere in a .c file. -#define DEFINE_BUFFER(name, type) \ - void wren##name##BufferInit(name##Buffer* buffer) \ - { \ - buffer->data = NULL; \ - buffer->capacity = 0; \ - buffer->count = 0; \ - } \ - \ - void wren##name##BufferClear(WrenVM* vm, name##Buffer* buffer) \ - { \ - wrenReallocate(vm, buffer->data, 0, 0); \ - wren##name##BufferInit(buffer); \ - } \ - \ - void wren##name##BufferFill(WrenVM* vm, name##Buffer* buffer, type data, \ - int count) \ - { \ - if (buffer->capacity < buffer->count + count) \ - { \ - int capacity = wrenPowerOf2Ceil(buffer->count + count); \ - buffer->data = (type*)wrenReallocate(vm, buffer->data, \ - buffer->capacity * sizeof(type), capacity * sizeof(type)); \ - buffer->capacity = capacity; \ - } \ - \ - for (int i = 0; i < count; i++) \ - { \ - buffer->data[buffer->count++] = data; \ - } \ - } \ - \ - void wren##name##BufferWrite(WrenVM* vm, name##Buffer* buffer, type data) \ - { \ - wren##name##BufferFill(vm, buffer, data, 1); \ +#define DEFINE_BUFFER(name, type) \ + void wren##name##BufferInit(name##Buffer* buffer) \ + { \ + buffer->data = NULL; \ + buffer->capacity = 0; \ + buffer->count = 0; \ + } \ + \ + void wren##name##BufferClear(WrenVM* vm, name##Buffer* buffer) \ + { \ + wrenReallocate(vm, buffer->data, 0, 0); \ + wren##name##BufferInit(buffer); \ + } \ + \ + void wren##name##BufferFill(WrenVM* vm, name##Buffer* buffer, type data, \ + int count) \ + { \ + if (buffer->capacity < buffer->count + count) \ + { \ + int capacity = wrenPowerOf2Ceil(buffer->count + count); \ + buffer->data = (type*)wrenReallocate(vm, buffer->data, \ + buffer->capacity * sizeof(type), capacity * sizeof(type)); \ + buffer->capacity = capacity; \ + } \ + \ + for (int i = 0; i < count; i++) \ + { \ + buffer->data[buffer->count++] = data; \ + } \ + } \ + \ + void wren##name##BufferWrite(WrenVM* vm, name##Buffer* buffer, type data) \ + { \ + wren##name##BufferFill(vm, buffer, data, 1); \ } DECLARE_BUFFER(Byte, uint8_t); diff --git a/src/vm/wren_vm.c b/src/vm/wren_vm.c index cdcc3c2f..d272c0c6 100644 --- a/src/vm/wren_vm.c +++ b/src/vm/wren_vm.c @@ -797,36 +797,34 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber) // Use this after a CallFrame has been pushed or popped to refresh the local // variables. - #define LOAD_FRAME() \ - frame = &fiber->frames[fiber->numFrames - 1]; \ - stackStart = frame->stackStart; \ - ip = frame->ip; \ - fn = frame->closure->fn; + #define LOAD_FRAME() \ + do { \ + frame = &fiber->frames[fiber->numFrames - 1]; \ + stackStart = frame->stackStart; \ + ip = frame->ip; \ + fn = frame->closure->fn; \ + } while (false) // Terminates the current fiber with error string [error]. If another calling // fiber is willing to catch the error, transfers control to it, otherwise // exits the interpreter. - #define RUNTIME_ERROR() \ - do \ - { \ - STORE_FRAME(); \ - runtimeError(vm); \ - if (vm->fiber == NULL) return WREN_RESULT_RUNTIME_ERROR; \ - fiber = vm->fiber; \ - LOAD_FRAME(); \ - DISPATCH(); \ - } \ - while (false) + #define RUNTIME_ERROR() \ + do { \ + STORE_FRAME(); \ + runtimeError(vm); \ + if (vm->fiber == NULL) return WREN_RESULT_RUNTIME_ERROR; \ + fiber = vm->fiber; \ + LOAD_FRAME(); \ + DISPATCH(); \ + } while (false) #if WREN_DEBUG_TRACE_INSTRUCTIONS // Prints the stack and instruction before each instruction is executed. - #define DEBUG_TRACE_INSTRUCTIONS() \ - do \ - { \ - wrenDumpStack(fiber); \ - wrenDumpInstruction(vm, fn, (int)(ip - fn->code.data)); \ - } \ - while (false) + #define DEBUG_TRACE_INSTRUCTIONS() \ + do { \ + wrenDumpStack(fiber); \ + wrenDumpInstruction(vm, fn, (int)(ip - fn->code.data)); \ + } while (false) #else #define DEBUG_TRACE_INSTRUCTIONS() do { } while (false) #endif @@ -842,19 +840,17 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber) #define INTERPRET_LOOP DISPATCH(); #define CASE_CODE(name) code_##name - #define DISPATCH() \ - do \ - { \ - DEBUG_TRACE_INSTRUCTIONS(); \ - goto *dispatchTable[instruction = (Code)READ_BYTE()]; \ - } \ - while (false) + #define DISPATCH() \ + do { \ + DEBUG_TRACE_INSTRUCTIONS(); \ + goto *dispatchTable[instruction = (Code)READ_BYTE()]; \ + } while (false) #else - #define INTERPRET_LOOP \ - loop: \ - DEBUG_TRACE_INSTRUCTIONS(); \ + #define INTERPRET_LOOP \ + loop: \ + DEBUG_TRACE_INSTRUCTIONS(); \ switch (instruction = (Code)READ_BYTE()) #define CASE_CODE(name) case CODE_##name