diff --git a/src/compiler.c b/src/compiler.c index cd6c33b..dbd63f3 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -168,8 +168,8 @@ static noom_Exit noomC_compile_expr( const noomP_Parser* parser, noomV_Function* func, const noomP_Node* node, - // retc of -1 means all values!!!!!!!!!!! - int retc) { + // retc of -1 means all values!!!!!!!!!!! + int retc) { noom_Exit result; // Baba is You OST is a very cool soundtrack to code to Can recommend if (node->type == NOOMP_NODE_NILLITERAL) { @@ -193,7 +193,7 @@ static noom_Exit noomC_compile_expr( compiler->curstack++; unsigned char fucking_destination = func->constsize; noom_Exit result = noomC_addconst_str(compiler, vm, "but DID YOU KNOW", 16); - if(result) return result; + if (result) return result; return noomC_emit_Aus(func, NOOMV_INSTR_PUSHCONST, 0, fucking_destination); } if (node->type == NOOMP_NODE_BINARYOPERATOR) { @@ -234,21 +234,21 @@ static noom_Exit noomC_compile_expr( // welcome to multivalue hell unsigned char returnToGlory = compiler->curstack; noom_bool_t isMethod = node->type == NOOMP_NODE_METHODCALL; - if((result = noomC_compile_expr(vm, compiler, parser, func, node->subnodes[0], 1))) return result; + if ((result = noomC_compile_expr(vm, compiler, parser, func, node->subnodes[0], 1))) return result; unsigned char funcIdx = compiler->curstack; - if(isMethod) { - noomP_Node *field = node->subnodes[1]; - const char *fieldname = parser->code + field->source_offset; + if (isMethod) { + noomP_Node* field = node->subnodes[1]; + const char* fieldname = parser->code + field->source_offset; noom_uint_t fieldlen = noomL_tokenlen(fieldname, 0, parser->version); noom_uint_t constidx = func->constsize; - if((result = noomC_addconst_str(compiler, vm, fieldname, fieldlen))) return result; - if((result = noomC_emit_Aus(func, NOOMV_INSTR_GETMETHOD, 0, constidx))) return result; + if ((result = noomC_addconst_str(compiler, vm, fieldname, fieldlen))) return result; + if ((result = noomC_emit_Aus(func, NOOMV_INSTR_GETMETHOD, 0, constidx))) return result; } - for(int i = isMethod ? 2 : 1; i < node->subnodec; i++) { - noom_bool_t isLast = i == (node->subnodec-1); - if((result = noomC_compile_expr(vm, compiler, parser, func, node->subnodes[i], isLast ? -1 : 1))) return result; + for (int i = isMethod ? 2 : 1; i < node->subnodec; i++) { + noom_bool_t isLast = i == (node->subnodec - 1); + if ((result = noomC_compile_expr(vm, compiler, parser, func, node->subnodes[i], isLast ? -1 : 1))) return result; } - return noomC_emit_Aus(func, NOOMV_INSTR_CALL, funcIdx, retc+1); + return noomC_emit_Aus(func, NOOMV_INSTR_CALL, funcIdx, retc + 1); } if (node->type == NOOMP_NODE_VARIABLE) { noomC_LocalInfo info; @@ -264,20 +264,20 @@ static noom_Exit noomC_compile_expr( return noomC_emit_Aus(func, NOOMV_INSTR_PUSHUPVAL, 0, info.idx); case NOOMC_GLOBAL: { noom_uint_t constidx = compiler->target->constsize; - if((result = noomC_addconst_str(compiler, vm, varname, namelen))) return result; - if(parser->version == NOOM_VERSION_51) { + if ((result = noomC_addconst_str(compiler, vm, varname, namelen))) return result; + if (parser->version == NOOM_VERSION_51) { return noomC_emit_Aus(func, NOOMV_INSTR_PUSHGLOBAL, 0, constidx); } noomC_LocalInfo _ENV; - if((result = noomC_identifyLocal(compiler, &_ENV, "_ENV", 4))) return result; + if ((result = noomC_identifyLocal(compiler, &_ENV, "_ENV", 4))) return result; // not meant to be possible - if(_ENV.type == NOOMC_GLOBAL) return NOOM_EINTERNAL; + if (_ENV.type == NOOMC_GLOBAL) return NOOM_EINTERNAL; // most likely branch in human history - if(_ENV.type == NOOMC_UPVAL) { + if (_ENV.type == NOOMC_UPVAL) { return noomC_emit_Aus(func, NOOMV_INSTR_PUSHUPVAL, _ENV.idx, constidx); } // bitchass - if((result = noomC_emit_Aus(func, NOOMV_INSTR_PUSHVAL, 0, _ENV.idx))) return result; + if ((result = noomC_emit_Aus(func, NOOMV_INSTR_PUSHVAL, 0, _ENV.idx))) return result; return noomC_emit_Aus(func, NOOMV_INSTR_GETFIELD, 0, constidx); } } @@ -413,14 +413,14 @@ static noom_Exit noomC_add_stuff_to_function(noom_LuaVM* vm, noomC_Compiler* com return noomC_compile_block(vm, compiler, parser, func, node); } - if(node->type == NOOMP_NODE_CALL || node->type == NOOMP_NODE_METHODCALL) { + if (node->type == NOOMP_NODE_CALL || node->type == NOOMP_NODE_METHODCALL) { return noomC_compile_expr(vm, compiler, parser, func, node, 0); } return NOOM_EINTERNAL; } -noom_Exit noomC_compile(noom_LuaVM* vm, const noomP_Parser* parser, const noomP_Node* node, noomV_String* chunkname, noomV_Table* env, noomV_Value *outFunc) { +noom_Exit noomC_compile(noom_LuaVM* vm, const noomP_Parser* parser, const noomP_Node* node, noomV_String* chunkname, noomV_Table* env, noomV_Value* outFunc) { if (node->type != NOOMP_NODE_PROGRAM) return NOOM_EINTERNAL; noomV_Function* program = noomV_allocFunc(vm, chunkname); diff --git a/src/compiler.h b/src/compiler.h index 2a13742..694fee7 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -39,4 +39,4 @@ typedef struct noomC_Compiler { void noomC_compiler_init(noomC_Compiler* compiler); // pushes the compiled function on the stack, or just crashes lol -noom_Exit noomC_compile(noom_LuaVM* vm, const noomP_Parser* parser, const noomP_Node* node, noomV_String* chunkname, noomV_Table* env, noomV_Value *outFunc); +noom_Exit noomC_compile(noom_LuaVM* vm, const noomP_Parser* parser, const noomP_Node* node, noomV_String* chunkname, noomV_Table* env, noomV_Value* outFunc); diff --git a/src/gc.c b/src/gc.c index eb0165c..f75e2c5 100644 --- a/src/gc.c +++ b/src/gc.c @@ -1,59 +1,59 @@ #include "noom.h" #include "vm.h" -static void noomG_grayObj(noom_LuaVM *vm, noomV_Object *obj); +static void noomG_grayObj(noom_LuaVM* vm, noomV_Object* obj); -static void noomG_grayValue(noom_LuaVM *vm, noomV_Value value) { - if(value.tag != NOOMV_VOBJ) return; +static void noomG_grayValue(noom_LuaVM* vm, noomV_Value value) { + if (value.tag != NOOMV_VOBJ) return; noomG_grayObj(vm, value.obj); } -static void noomG_grayObj(noom_LuaVM *vm, noomV_Object *obj) { - if(obj == 0) return; - if(obj->marked) return; +static void noomG_grayObj(noom_LuaVM* vm, noomV_Object* obj) { + if (obj == 0) return; + if (obj->marked) return; obj->marked = 1; obj->nextGray = vm->graySet; vm->graySet = obj; } -void noomG_markObj(noom_LuaVM *vm, noomV_Object *obj) { - if(obj->tag == NOOMV_OPOINTER) { - noomV_Pointer *p = (noomV_Pointer *)obj; +void noomG_markObj(noom_LuaVM* vm, noomV_Object* obj) { + if (obj->tag == NOOMV_OPOINTER) { + noomV_Pointer* p = (noomV_Pointer*)obj; noomG_grayValue(vm, p->value); return; } - if(obj->tag == NOOMV_OFUNC) { - noomV_Function *f = (noomV_Function *)obj; + if (obj->tag == NOOMV_OFUNC) { + noomV_Function* f = (noomV_Function*)obj; noomG_grayObj(vm, &f->chunkname->obj); noomG_grayObj(vm, &f->env->obj); - for(noom_uint_t i = 0; i < f->constsize; i++) { + for (noom_uint_t i = 0; i < f->constsize; i++) { noomG_grayValue(vm, f->consts[i]); } - for(noom_uint_t i = 0; i < f->protosize; i++) { - noomG_grayObj(vm, (noomV_Object *)f->protos[i]); + for (noom_uint_t i = 0; i < f->protosize; i++) { + noomG_grayObj(vm, (noomV_Object*)f->protos[i]); } return; } - if(obj->tag == NOOMV_OTABLE) { - noomV_Table *t = (noomV_Table *)obj; - noomG_grayObj(vm, (noomV_Object *)t->meta); - for(noom_uint_t i = 0; i < t->entries*2; i++) { + if (obj->tag == NOOMV_OTABLE) { + noomV_Table* t = (noomV_Table*)obj; + noomG_grayObj(vm, (noomV_Object*)t->meta); + for (noom_uint_t i = 0; i < t->entries * 2; i++) { noomG_grayValue(vm, t->entrydata[i]); } return; } - if(obj->tag == NOOMV_OTHREAD) { - noomV_Thread *thrd = (noomV_Thread *)obj; - for(noom_uint_t i = 0; i < thrd->stacklen; i++) { + if (obj->tag == NOOMV_OTHREAD) { + noomV_Thread* thrd = (noomV_Thread*)obj; + for (noom_uint_t i = 0; i < thrd->stacklen; i++) { noomG_grayValue(vm, thrd->stack[i]); } - for(noom_uint_t i = 0; i < thrd->calldepth; i++) { + for (noom_uint_t i = 0; i < thrd->calldepth; i++) { noomV_CallFrame cf = thrd->calls[i]; noomG_grayValue(vm, cf.errhandler); } noomG_grayValue(vm, thrd->errObj); - noomG_grayObj(vm, (noomV_Object *)thrd->resuming); - noomG_grayObj(vm, (noomV_Object *)thrd->resumedBy); + noomG_grayObj(vm, (noomV_Object*)thrd->resuming); + noomG_grayObj(vm, (noomV_Object*)thrd->resumedBy); return; } } @@ -61,19 +61,19 @@ void noomG_markObj(noom_LuaVM *vm, noomV_Object *obj) { void noom_gc(noom_LuaVM* vm) { vm->graySet = 0; - noomG_grayObj(vm, (noomV_Object *)vm->mainThread); - noomG_grayObj(vm, (noomV_Object *)vm->globals); - noomG_grayObj(vm, (noomV_Object *)vm->registry); + noomG_grayObj(vm, (noomV_Object*)vm->mainThread); + noomG_grayObj(vm, (noomV_Object*)vm->globals); + noomG_grayObj(vm, (noomV_Object*)vm->registry); - while(vm->graySet) { + while (vm->graySet) { noomG_markObj(vm, vm->graySet); vm->graySet = vm->graySet->nextGray; } - noomV_Object **sweep = &vm->heap; - while(*sweep) { - noomV_Object *current = *sweep; - if(current->marked) { + noomV_Object** sweep = &vm->heap; + while (*sweep) { + noomV_Object* current = *sweep; + if (current->marked) { sweep = ¤t->next; } else { *sweep = current->next; @@ -85,5 +85,5 @@ void noom_gc(noom_LuaVM* vm) { } void noom_trygc(noom_LuaVM* vm) { - if(vm->objCount >= vm->gcTarget) noom_gc(vm); + if (vm->objCount >= vm->gcTarget) noom_gc(vm); } diff --git a/src/main.c b/src/main.c index d4f87cc..027f1b5 100644 --- a/src/main.c +++ b/src/main.c @@ -41,7 +41,7 @@ int the_theoretical_function_to_execute_your_code_that_should_be_replaced_later( noomP_Parser parser; noomP_Node* program; - noom_LuaVM *vm = noom_createVM(NOOM_VERSION_51); + noom_LuaVM* vm = noom_createVM(NOOM_VERSION_51); // goodbye "shitass" you will be missed int success = noomP_parse(code, filename, NOOM_VERSION_51, &program, &parser); @@ -98,35 +98,35 @@ int the_theoretical_function_to_execute_your_code_that_should_be_replaced_later( noomV_Value peak; noom_Exit e = noomC_compile(vm, &parser, program, 0, 0, &peak); - if(e) { + if (e) { printf("error: %d\n", e); exit(e); } - noomV_Function *f = (noomV_Function *)peak.obj; + noomV_Function* f = (noomV_Function*)peak.obj; - for(int i = 0; i < f->codesize; i++) { + for (int i = 0; i < f->codesize; i++) { noomV_Inst inst = f->code[i]; noomV_DisInfo dis = noomV_disInfo[inst.op]; printf("%s %d ", dis.name, inst.a); - switch(dis.arg) { - case NOOMV_DIS_NONE: - break; - case NOOMV_DIS_BC: - printf("%d, %d", inst.b, inst.c); - break; - case NOOMV_DIS_uD: - printf("%d", inst.us); - break; - case NOOMV_DIS_sD: - printf("%d", inst.ss); - break; + switch (dis.arg) { + case NOOMV_DIS_NONE: + break; + case NOOMV_DIS_BC: + printf("%d, %d", inst.b, inst.c); + break; + case NOOMV_DIS_uD: + printf("%d", inst.us); + break; + case NOOMV_DIS_sD: + printf("%d", inst.ss); + break; } printf("\n"); } - + // freeing time noomP_Node* last_node = parser.last_node; while (last_node) { diff --git a/src/noom.h b/src/noom.h index 4c6e8ed..6fa44e8 100644 --- a/src/noom.h +++ b/src/noom.h @@ -228,11 +228,11 @@ noom_Exit noom_yieldk(noom_LuaVM* vm, noom_uint_t n, noom_KFunction* f, void* ct #define noom_yield(vm, n) noom_yieldk((vm), (n), 0, 0) // push the current error handler -noom_Exit noom_pusherrhandler(noom_LuaVM *vm); +noom_Exit noom_pusherrhandler(noom_LuaVM* vm); // pops the top value and sets it as the error handler. // nil is a perfectly fine error handler, it just does not get called. // In the case of an error, noom_callk() will also call this error handler. -noom_Exit noom_seterrhandler(noom_LuaVM *vm); +noom_Exit noom_seterrhandler(noom_LuaVM* vm); // Like a noom_call, except instead of calling, it resumes coroutines. // This cannot yield but allows yields. diff --git a/src/vm.c b/src/vm.c index f166823..0190c9e 100644 --- a/src/vm.c +++ b/src/vm.c @@ -4,154 +4,154 @@ #include const noomV_Value noomV_nil = { - .tag = NOOMV_VNIL, - .isptr = 0, - .autoclose = 0, + .tag = NOOMV_VNIL, + .isptr = 0, + .autoclose = 0, }; noomV_DisInfo noomV_disInfo[NOOMV_INSTR_NOP2] = { - [NOOMV_INSTR_PUSHVAL] = { - .name = "PUSHVAL", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_PUSHCONST] = { - .name = "PUSHCONST", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_PUSHGLOBAL] = { - .name = "PUSHGLOBAL", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_PUSHINT] = { - .name = "PUSHINT", - .arg = NOOMV_DIS_sD, - }, - [NOOMV_INSTR_PUSHNIL] = { - .name = "PUSHNIL", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_PUSHBOOLS] = { - .name = "PUSHBOOLS", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_PUSHUPVAL] = { - .name = "PUSHUPVAL", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_PUSHARGS] = { - .name = "PUSHARGS", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_CREATETABLE] = { - .name = "CREATETABLE", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_PUSHCLOSURE] = { - .name = "PUSHCLOSURE", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_CALL] = { - .name = "CALL", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_GETTABLE] = { - .name = "GETTABLE", - .arg = NOOMV_DIS_NONE, - }, - // pops (table, field, value), and sets `table[field] = value` - [NOOMV_INSTR_SETTABLE] = { - .name = "SETTABLE", - .arg = NOOMV_DIS_NONE, - }, - [NOOMV_INSTR_SETLIST] = { - .name = "SETLIST", - .arg = NOOMV_DIS_uD, - }, - // pops table, pushes `table[consts[op.uD]]`, an optimization for indexing fields - [NOOMV_INSTR_GETFIELD] = { - .name = "GETFIELD", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_SETFIELD] = { - .name = "SETFIELD", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_GETUPFIELD] = { - .name = "GETUPFIELD", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_ISNTR_SETUPFIELD] = { - .name = "SETUPFIELD", - .arg = NOOMV_DIS_uD, - }, + [NOOMV_INSTR_PUSHVAL] = { + .name = "PUSHVAL", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_PUSHCONST] = { + .name = "PUSHCONST", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_PUSHGLOBAL] = { + .name = "PUSHGLOBAL", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_PUSHINT] = { + .name = "PUSHINT", + .arg = NOOMV_DIS_sD, + }, + [NOOMV_INSTR_PUSHNIL] = { + .name = "PUSHNIL", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_PUSHBOOLS] = { + .name = "PUSHBOOLS", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_PUSHUPVAL] = { + .name = "PUSHUPVAL", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_PUSHARGS] = { + .name = "PUSHARGS", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_CREATETABLE] = { + .name = "CREATETABLE", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_PUSHCLOSURE] = { + .name = "PUSHCLOSURE", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_CALL] = { + .name = "CALL", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_GETTABLE] = { + .name = "GETTABLE", + .arg = NOOMV_DIS_NONE, + }, + // pops (table, field, value), and sets `table[field] = value` + [NOOMV_INSTR_SETTABLE] = { + .name = "SETTABLE", + .arg = NOOMV_DIS_NONE, + }, + [NOOMV_INSTR_SETLIST] = { + .name = "SETLIST", + .arg = NOOMV_DIS_uD, + }, + // pops table, pushes `table[consts[op.uD]]`, an optimization for indexing fields + [NOOMV_INSTR_GETFIELD] = { + .name = "GETFIELD", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_SETFIELD] = { + .name = "SETFIELD", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_GETUPFIELD] = { + .name = "GETUPFIELD", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_ISNTR_SETUPFIELD] = { + .name = "SETUPFIELD", + .arg = NOOMV_DIS_uD, + }, - [NOOMV_INSTR_OP] = { - .name = "OP", - .arg = NOOMV_DIS_BC, - }, + [NOOMV_INSTR_OP] = { + .name = "OP", + .arg = NOOMV_DIS_BC, + }, - [NOOMV_INSTR_SETVAL] = { - .name = "SETVAL", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_SETUPVAL] = { - .name = "SETUPVAL", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_SETGLOBAL] = { - .name = "SETGLOBAL", - .arg = NOOMV_DIS_uD, - }, + [NOOMV_INSTR_SETVAL] = { + .name = "SETVAL", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_SETUPVAL] = { + .name = "SETUPVAL", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_SETGLOBAL] = { + .name = "SETGLOBAL", + .arg = NOOMV_DIS_uD, + }, - [NOOMV_INSTR_RET] = { - .name = "RET", - .arg = NOOMV_DIS_uD, - }, + [NOOMV_INSTR_RET] = { + .name = "RET", + .arg = NOOMV_DIS_uD, + }, - [NOOMV_INSTR_JMP] = { - .name = "JMP", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_CJMP] = { - .name = "CJMP", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_CNJMP] = { - .name = "CNJMP", - .arg = NOOMV_DIS_uD, - }, + [NOOMV_INSTR_JMP] = { + .name = "JMP", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_CJMP] = { + .name = "CJMP", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_CNJMP] = { + .name = "CNJMP", + .arg = NOOMV_DIS_uD, + }, - // For bullshit + // For bullshit - // Take the top value without popping it, push `value[consts[op.uD]]` like GETFIELD would, then swap the top 2 values. - // This is for a:foo() and such - [NOOMV_INSTR_GETMETHOD] = { - .name = "GETMETHOD", - .arg = NOOMV_DIS_uD, - }, - // rotate the the top op.a items by op.sD - [NOOMV_INSTR_ROTATE] = { - .name = "ROTATE", - .arg = NOOMV_DIS_sD, - }, - [NOOMV_INSTR_POP] = { - .name = "POP", - .arg = NOOMV_DIS_uD, - }, - [NOOMV_INSTR_SETSTACK] = { - .name = "SETSTACK", - .arg = NOOMV_DIS_uD, - }, + // Take the top value without popping it, push `value[consts[op.uD]]` like GETFIELD would, then swap the top 2 values. + // This is for a:foo() and such + [NOOMV_INSTR_GETMETHOD] = { + .name = "GETMETHOD", + .arg = NOOMV_DIS_uD, + }, + // rotate the the top op.a items by op.sD + [NOOMV_INSTR_ROTATE] = { + .name = "ROTATE", + .arg = NOOMV_DIS_sD, + }, + [NOOMV_INSTR_POP] = { + .name = "POP", + .arg = NOOMV_DIS_uD, + }, + [NOOMV_INSTR_SETSTACK] = { + .name = "SETSTACK", + .arg = NOOMV_DIS_uD, + }, - [NOOMV_INSTR_CONCAT] = { - .name = "CONCAT", - .arg = NOOMV_DIS_uD, - }, + [NOOMV_INSTR_CONCAT] = { + .name = "CONCAT", + .arg = NOOMV_DIS_uD, + }, - [NOOMV_INSTR_CLOSE] = { - .name = "CLOSE", - .arg = NOOMV_DIS_uD, - }, + [NOOMV_INSTR_CLOSE] = { + .name = "CLOSE", + .arg = NOOMV_DIS_uD, + }, }; noomV_Object* noomV_allocObj(noom_LuaVM* vm, noomV_ObjTag tag, noom_uint_t size) { @@ -199,9 +199,9 @@ noomV_Function* noomV_allocFunc(noom_LuaVM* vm, noomV_String* chunkname) { return f; } -noomV_Table *noomV_allocTable(noom_LuaVM *vm, noom_uint_t arraylen, noom_uint_t fields) { - noomV_Table *t = (noomV_Table *)noomV_allocObj(vm, NOOMV_OTABLE, sizeof(noomV_Table)); - if(t == 0) return 0; +noomV_Table* noomV_allocTable(noom_LuaVM* vm, noom_uint_t arraylen, noom_uint_t fields) { + noomV_Table* t = (noomV_Table*)noomV_allocObj(vm, NOOMV_OTABLE, sizeof(noomV_Table)); + if (t == 0) return 0; // not computed t->len = 0; // no metatable @@ -213,38 +213,38 @@ noomV_Table *noomV_allocTable(noom_LuaVM *vm, noom_uint_t arraylen, noom_uint_t t->entries = 0; t->entrydata = noom_alloc(sizeof(noomV_Value) * 2 * cap); // dw about freeing t, its in the VM heap so it'll get GC'd out - if(t->entrydata == 0) return 0; + if (t->entrydata == 0) return 0; t->entries = cap; - for(size_t i = 0; i < cap*2; i++) { + for (size_t i = 0; i < cap * 2; i++) { t->entrydata[i].tag = NOOMV_VNIL; } return t; } noom_uint_t noomV_rawhashValue(noomV_Value v) { - switch(v.tag) { - case NOOMV_VNIL: - return 0; - case NOOMV_VINT: - return v.integer; - case NOOMV_VBOOL: - return v.boolean ? 1 : 0; - case NOOMV_VNUM: - // TODO: see if we should bitcast instead - return v.number; - case NOOMV_VCFUNC: - return (noom_uint_t)v.cfunc; - case NOOMV_VLUSER: - return (noom_uint_t)v.lightuserdata; - case NOOMV_VOBJ: { - noomV_Object *o = v.obj; - if(o->tag != NOOMV_OSTR) return (noom_uint_t)o; + switch (v.tag) { + case NOOMV_VNIL: + return 0; + case NOOMV_VINT: + return v.integer; + case NOOMV_VBOOL: + return v.boolean ? 1 : 0; + case NOOMV_VNUM: + // TODO: see if we should bitcast instead + return v.number; + case NOOMV_VCFUNC: + return (noom_uint_t)v.cfunc; + case NOOMV_VLUSER: + return (noom_uint_t)v.lightuserdata; + case NOOMV_VOBJ: { + noomV_Object* o = v.obj; + if (o->tag != NOOMV_OSTR) return (noom_uint_t)o; - noomV_String *s = (noomV_String *)o; - if(s->hash == 0) { + noomV_String* s = (noomV_String*)o; + if (s->hash == 0) { // https://en.wikipedia.org/wiki/Jenkins_hash_function#one_at_a_time noom_uint_t hash = 0; - for(noom_uint_t i = 0; i < s->len; i++) { + for (noom_uint_t i = 0; i < s->len; i++) { hash += (unsigned char)s->data[i]; hash += (hash << 10); hash ^= (hash >> 6); @@ -262,8 +262,8 @@ noom_uint_t noomV_rawhashValue(noomV_Value v) { noom_bool_t noomV_isNil(noomV_Value key) { return key.tag == NOOMV_VNIL; } noom_bool_t noomV_isLegalKey(noomV_Value key) { - if(key.tag == NOOMV_VNIL) return 0; - if(key.tag == NOOMV_VNUM) { + if (key.tag == NOOMV_VNIL) return 0; + if (key.tag == NOOMV_VNUM) { noom_float_t n = key.number; // true for all except NaN, which is an illegal key! return n == n; @@ -273,76 +273,76 @@ noom_bool_t noomV_isLegalKey(noomV_Value key) { noom_bool_t noomV_rawequalValue(noomV_Value a, noomV_Value b) { // special case: integers and numbers - if(a.tag == NOOMV_VINT && b.tag == NOOMV_VNUM) { + if (a.tag == NOOMV_VINT && b.tag == NOOMV_VNUM) { return a.integer == b.number; } - if(a.tag == NOOMV_VNUM && b.tag == NOOMV_VINT) { + if (a.tag == NOOMV_VNUM && b.tag == NOOMV_VINT) { return a.number == b.integer; } - if(a.tag != b.tag) return 0; - switch(a.tag) { - case NOOMV_VNIL: - return 1; - case NOOMV_VINT: - return a.integer == b.integer; - case NOOMV_VBOOL: - return (a.boolean != 0) == (b.boolean != 0); - case NOOMV_VNUM: - return a.number == b.number; - case NOOMV_VCFUNC: - return a.cfunc == b.cfunc; - case NOOMV_VLUSER: - return a.lightuserdata == b.lightuserdata; - case NOOMV_VOBJ: { - noomV_Object *aObj = a.obj; - noomV_Object *bObj = b.obj; - if(aObj == bObj) return 1; - if(aObj->tag != bObj->tag) return 0; - if(aObj->tag != NOOMV_OSTR) return aObj == bObj; + if (a.tag != b.tag) return 0; + switch (a.tag) { + case NOOMV_VNIL: + return 1; + case NOOMV_VINT: + return a.integer == b.integer; + case NOOMV_VBOOL: + return (a.boolean != 0) == (b.boolean != 0); + case NOOMV_VNUM: + return a.number == b.number; + case NOOMV_VCFUNC: + return a.cfunc == b.cfunc; + case NOOMV_VLUSER: + return a.lightuserdata == b.lightuserdata; + case NOOMV_VOBJ: { + noomV_Object* aObj = a.obj; + noomV_Object* bObj = b.obj; + if (aObj == bObj) return 1; + if (aObj->tag != bObj->tag) return 0; + if (aObj->tag != NOOMV_OSTR) return aObj == bObj; - noomV_String *strA = (noomV_String *)aObj; - noomV_String *strB = (noomV_String *)bObj; - if(strA->len != strB->len) return 0; - if(strA->hash != 0 && strB->hash != 0 && strA->hash != strB->hash) return 0; - for(noom_uint_t i = 0; i < strA->len; i++) { - if(strA->data[i] != strB->data[i]) return 0; + noomV_String* strA = (noomV_String*)aObj; + noomV_String* strB = (noomV_String*)bObj; + if (strA->len != strB->len) return 0; + if (strA->hash != 0 && strB->hash != 0 && strA->hash != strB->hash) return 0; + for (noom_uint_t i = 0; i < strA->len; i++) { + if (strA->data[i] != strB->data[i]) return 0; } return 1; } } } -noomV_Value noomV_rawgetTable(noomV_Table *t, noomV_Value key) { - if(!noomV_isLegalKey(key)) return noomV_nil; +noomV_Value noomV_rawgetTable(noomV_Table* t, noomV_Value key) { + if (!noomV_isLegalKey(key)) return noomV_nil; noom_uint_t hash = noomV_rawhashValue(key); noom_uint_t start = hash % t->entries; - for(noom_uint_t i = 0; i < t->entries; i++) { + for (noom_uint_t i = 0; i < t->entries; i++) { noom_uint_t idx = (start + i) % t->entries; // unallocated entry, bye-bye - if(t->entrydata[idx].tag == NOOMV_VNIL) break; + if (t->entrydata[idx].tag == NOOMV_VNIL) break; // isptr on a key means its a tombstone - if(t->entrydata[idx].isptr) continue; - if(noomV_rawequalValue(t->entrydata[idx], key)) { + if (t->entrydata[idx].isptr) continue; + if (noomV_rawequalValue(t->entrydata[idx], key)) { return t->entrydata[idx + t->entries]; } } return noomV_nil; } -noomV_Value noomV_rawgetiTable(noomV_Table *t, noom_int_t idx) { - return noomV_rawgetTable(t, (noomV_Value) { .tag = NOOMV_VINT, .integer = idx }); +noomV_Value noomV_rawgetiTable(noomV_Table* t, noom_int_t idx) { + return noomV_rawgetTable(t, (noomV_Value){.tag = NOOMV_VINT, .integer = idx}); } // TODO: implement // used should be at most ~80% of entrydata because // that's standard practice and we're not computer scientists -noom_Exit noomV_rawsetTable(noom_LuaVM *vm, noomV_Table *t, noomV_Value key, noomV_Value val) { - if(!noomV_isLegalKey(key)) { +noom_Exit noomV_rawsetTable(noom_LuaVM* vm, noomV_Table* t, noomV_Value key, noomV_Value val) { + if (!noomV_isLegalKey(key)) { noomV_setErrorStr(vm, vm->currentThread, "illegal key"); return NOOM_ERUNTIME; } noom_uint_t target = t->entries * 80 / 100; - if(t->used > target) { + if (t->used > target) { // TODO: resize hashtable } // prevent awkward bugs @@ -352,15 +352,15 @@ noom_Exit noomV_rawsetTable(noom_LuaVM *vm, noomV_Table *t, noomV_Value key, noo val.autoclose = 0; noom_uint_t hash = noomV_rawhashValue(key); noom_uint_t idx = hash % t->entries; - while(1) { + while (1) { noomV_Value key2 = t->entrydata[idx]; // tombstone! - if(key2.isptr) { + if (key2.isptr) { t->entrydata[idx] = key; t->entrydata[idx + t->entries] = val; return NOOM_OK; } - if(noomV_rawequalValue(key, key2)) { + if (noomV_rawequalValue(key, key2)) { // HOLY SHIET!!!!! t->entrydata[idx + t->entries] = val; return NOOM_OK; @@ -371,20 +371,20 @@ noom_Exit noomV_rawsetTable(noom_LuaVM *vm, noomV_Table *t, noomV_Value key, noo return NOOM_OK; } -noom_uint_t noomV_rawlenTable(noomV_Table *t) { +noom_uint_t noomV_rawlenTable(noomV_Table* t) { noom_uint_t guess = t->len; // TODO: optimize with a bsearch - while(1) { - if(!noomV_isNil(noomV_rawgetiTable(t, guess+1))) guess++; - if(guess == 0) break; - if(noomV_isNil(noomV_rawgetiTable(t, guess))) guess--; + while (1) { + if (!noomV_isNil(noomV_rawgetiTable(t, guess + 1))) guess++; + if (guess == 0) break; + if (noomV_isNil(noomV_rawgetiTable(t, guess))) guess--; } return t->len = guess; } -noomV_Thread *noomV_allocCoroutine(noom_LuaVM *vm) { - noomV_Thread *thrd = (noomV_Thread *)noomV_allocObj(vm, NOOMV_OTHREAD, sizeof(noomV_Thread)); - if(thrd == 0) return 0; +noomV_Thread* noomV_allocCoroutine(noom_LuaVM* vm) { + noomV_Thread* thrd = (noomV_Thread*)noomV_allocObj(vm, NOOMV_OTHREAD, sizeof(noomV_Thread)); + if (thrd == 0) return 0; thrd->resumedBy = 0; thrd->resuming = 0; thrd->calldepth = 0; @@ -394,16 +394,16 @@ noomV_Thread *noomV_allocCoroutine(noom_LuaVM *vm) { thrd->errObj = noomV_nil; thrd->calls = noom_alloc(sizeof(noomV_CallFrame) * thrd->callcap); - if(thrd->calls == 0) return 0; + if (thrd->calls == 0) return 0; thrd->stack = noom_alloc(sizeof(noomV_Value) * thrd->stackcap); - if(thrd->stack == 0) return 0; + if (thrd->stack == 0) return 0; return thrd; } -void noomV_setErrorStr(noom_LuaVM *vm, noomV_Thread *coro, const char *str) { - noomV_String *s = noomV_allocStr(vm, str, noom_strlen(str)); - if(s == 0) { +void noomV_setErrorStr(noom_LuaVM* vm, noomV_Thread* coro, const char* str) { + noomV_String* s = noomV_allocStr(vm, str, noom_strlen(str)); + if (s == 0) { coro->errObj = vm->oomVal; return; } @@ -411,8 +411,8 @@ void noomV_setErrorStr(noom_LuaVM *vm, noomV_Thread *coro, const char *str) { coro->errObj.obj = &s->obj; } -noom_Exit noomV_setErrorFromExit(noom_LuaVM *vm, noomV_Thread *coro, noom_Exit exit) { - switch(exit) { +noom_Exit noomV_setErrorFromExit(noom_LuaVM* vm, noomV_Thread* coro, noom_Exit exit) { + switch (exit) { case NOOM_OK: coro->errObj = noomV_nil; break; @@ -445,20 +445,20 @@ noom_Exit noomV_setErrorFromExit(noom_LuaVM *vm, noomV_Thread *coro, noom_Exit e return exit; } -void noomV_freeObj(noom_LuaVM *vm, noomV_Object* obj) { - if(obj->tag == NOOMV_OFUNC) { - noomV_Function *f = (noomV_Function *)obj; +void noomV_freeObj(noom_LuaVM* vm, noomV_Object* obj) { + if (obj->tag == NOOMV_OFUNC) { + noomV_Function* f = (noomV_Function*)obj; noom_free(f->consts); noom_free(f->upvals); noom_free(f->locals); noom_free(f->code); } - if(obj->tag == NOOMV_OTABLE) { - noomV_Table *t = (noomV_Table *)obj; + if (obj->tag == NOOMV_OTABLE) { + noomV_Table* t = (noomV_Table*)obj; noom_free(t->entrydata); } - if(obj->tag == NOOMV_OTHREAD) { - noomV_Thread *thrd = (noomV_Thread *)obj; + if (obj->tag == NOOMV_OTHREAD) { + noomV_Thread* thrd = (noomV_Thread*)obj; noom_free(thrd->stack); noom_free(thrd->calls); } @@ -466,32 +466,32 @@ void noomV_freeObj(noom_LuaVM *vm, noomV_Object* obj) { vm->objCount--; } -noom_Exit noomV_pushCallFrame(noom_LuaVM *vm, noomV_Thread *coro, noomV_CallFrame cf); +noom_Exit noomV_pushCallFrame(noom_LuaVM* vm, noomV_Thread* coro, noomV_CallFrame cf); -noomV_CallFrame *noomV_topCallFrame(noomV_Thread *coro) { - if(coro->calldepth == 0) return 0; +noomV_CallFrame* noomV_topCallFrame(noomV_Thread* coro) { + if (coro->calldepth == 0) return 0; return &coro->calls[coro->calldepth - 1]; } -noom_Exit noomV_setThreadStackSize(noom_LuaVM *vm, noomV_Thread *coro, noom_int_t stack) { - if(stack < 0) { +noom_Exit noomV_setThreadStackSize(noom_LuaVM* vm, noomV_Thread* coro, noom_int_t stack) { + if (stack < 0) { noomV_setErrorStr(vm, coro, "stack underflow"); return NOOM_ERUNTIME; } - if(stack > NOOM_MAXSTACK) return NOOM_ELIMIT; - if(stack > coro->stackcap) { + if (stack > NOOM_MAXSTACK) return NOOM_ELIMIT; + if (stack > coro->stackcap) { noom_uint_t newCap = coro->stackcap; - while(newCap < stack) newCap *= 2; + while (newCap < stack) newCap *= 2; - noomV_Value *newStack = noom_realloc(coro->stack, sizeof(noomV_Value) * coro->stackcap); - if(newStack == 0) return NOOM_ENOMEM; + noomV_Value* newStack = noom_realloc(coro->stack, sizeof(noomV_Value) * coro->stackcap); + if (newStack == 0) return NOOM_ENOMEM; coro->stack = newStack; coro->stackcap = newCap; } // NIL-ify - if(coro->stacklen < stack) { - for(int i = coro->stacklen; i < stack; i++) { + if (coro->stacklen < stack) { + for (int i = coro->stacklen; i < stack; i++) { coro->stack[i] = noomV_nil; } return NOOM_OK; @@ -519,28 +519,28 @@ noom_LuaVM* noom_createVM(noom_LuaVersion version) { vm->gcTarget = 100; vm->gcRatio = 2; - const char *oomStr = "out of memory"; - vm->oomVal.obj = (noomV_Object *)noomV_allocStr(vm, oomStr, noom_strlen(oomStr)); - if(vm->oomVal.obj == 0) goto rip; + const char* oomStr = "out of memory"; + vm->oomVal.obj = (noomV_Object*)noomV_allocStr(vm, oomStr, noom_strlen(oomStr)); + if (vm->oomVal.obj == 0) goto rip; vm->registry = noomV_allocTable(vm, 0, 1); - if(vm->registry == 0) goto rip; + if (vm->registry == 0) goto rip; vm->globals = noomV_allocTable(vm, 0, 32); - if(vm->globals == 0) goto rip; + if (vm->globals == 0) goto rip; vm->mainThread = noomV_allocCoroutine(vm); - if(vm->mainThread == 0) goto rip; + if (vm->mainThread == 0) goto rip; vm->currentThread = vm->mainThread; // goal: put _G in the registry as the _G key - noomV_String *_G = noomV_allocStr(vm, "_G", 2); - if(_G == 0) goto rip; + noomV_String* _G = noomV_allocStr(vm, "_G", 2); + if (_G == 0) goto rip; - noomV_Value _GKey = { .tag = NOOMV_VOBJ, .obj = &_G->obj, .isptr = 0, .autoclose = 0 }; - noomV_Value _GVal = { .tag = NOOMV_VOBJ, .obj = &vm->globals->obj, .isptr = 0, .autoclose = 0 }; + noomV_Value _GKey = {.tag = NOOMV_VOBJ, .obj = &_G->obj, .isptr = 0, .autoclose = 0}; + noomV_Value _GVal = {.tag = NOOMV_VOBJ, .obj = &vm->globals->obj, .isptr = 0, .autoclose = 0}; noom_Exit err = noomV_rawsetTable(vm, vm->registry, _GKey, _GVal); - if(err) goto rip; + if (err) goto rip; assert(noomV_rawequalValue(noomV_rawgetTable(vm->registry, _GKey), _GVal)); diff --git a/src/vm.h b/src/vm.h index f9e7d9c..a03214d 100644 --- a/src/vm.h +++ b/src/vm.h @@ -50,7 +50,7 @@ typedef struct noomV_Value { noom_bool_t boolean; noom_int_t integer; noom_float_t number; - noom_CFunction *cfunc; + noom_CFunction* cfunc; void* lightuserdata; noomV_Object* obj; struct noomV_Pointer* ptr; @@ -183,7 +183,7 @@ typedef enum noomV_Opcode : unsigned char { } noomV_Opcode; typedef struct noomV_DisInfo { - const char *name; + const char* name; enum { NOOMV_DIS_NONE, NOOMV_DIS_BC, @@ -316,7 +316,7 @@ typedef struct noomV_CallFrame { noom_uint_t returnCount; noom_bool_t isC; noomV_Value errhandler; - noomV_Pointer **upvals; + noomV_Pointer** upvals; union { struct { // program counter @@ -364,31 +364,31 @@ extern const noomV_Value noomV_nil; noomV_Object* noomV_allocObj(noom_LuaVM* vm, noomV_ObjTag tag, noom_uint_t size); noomV_String* noomV_allocStr(noom_LuaVM* vm, const char* str, noom_uint_t len); noomV_Function* noomV_allocFunc(noom_LuaVM* vm, noomV_String* chunkname); -noomV_Table *noomV_allocTable(noom_LuaVM *vm, noom_uint_t arraylen, noom_uint_t fields); +noomV_Table* noomV_allocTable(noom_LuaVM* vm, noom_uint_t arraylen, noom_uint_t fields); noom_uint_t noomV_rawhashValue(noomV_Value v); noom_bool_t noomV_isNil(noomV_Value key); noom_bool_t noomV_isLegalKey(noomV_Value key); noom_bool_t noomV_rawequalValue(noomV_Value a, noomV_Value b); -noomV_Value noomV_rawgetTable(noomV_Table *t, noomV_Value key); -noomV_Value noomV_rawgetiTable(noomV_Table *t, noom_int_t idx); -noom_Exit noomV_rawsetTable(noom_LuaVM *vm, noomV_Table *t, noomV_Value key, noomV_Value val); -noom_uint_t noomV_rawlenTable(noomV_Table *t); +noomV_Value noomV_rawgetTable(noomV_Table* t, noomV_Value key); +noomV_Value noomV_rawgetiTable(noomV_Table* t, noom_int_t idx); +noom_Exit noomV_rawsetTable(noom_LuaVM* vm, noomV_Table* t, noomV_Value key, noomV_Value val); +noom_uint_t noomV_rawlenTable(noomV_Table* t); -noomV_Thread *noomV_allocCoroutine(noom_LuaVM *vm); +noomV_Thread* noomV_allocCoroutine(noom_LuaVM* vm); -void noomV_setErrorStr(noom_LuaVM *vm, noomV_Thread *coro, const char *str); +void noomV_setErrorStr(noom_LuaVM* vm, noomV_Thread* coro, const char* str); // if exit is ERUNTIME or EERROR, does nothing as it assumes the error is already set! // It will clear any errors on NOOM_OK!!! // Returns the exit for convenience -noom_Exit noomV_setErrorFromExit(noom_LuaVM *vm, noomV_Thread *coro, noom_Exit exit); +noom_Exit noomV_setErrorFromExit(noom_LuaVM* vm, noomV_Thread* coro, noom_Exit exit); -void noomV_freeObj(noom_LuaVM *vm, noomV_Object* obj); +void noomV_freeObj(noom_LuaVM* vm, noomV_Object* obj); -noom_Exit noomV_pushCallFrame(noom_LuaVM *vm, noomV_Thread *coro, noomV_CallFrame cf); +noom_Exit noomV_pushCallFrame(noom_LuaVM* vm, noomV_Thread* coro, noomV_CallFrame cf); // can return NULL if we are not in a call, such as in C API setup. -noomV_CallFrame *noomV_topCallFrame(noomV_Thread *coro); +noomV_CallFrame* noomV_topCallFrame(noomV_Thread* coro); -noom_Exit noomV_setThreadStackSize(noom_LuaVM *vm, noomV_Thread *coro, noom_int_t stack); +noom_Exit noomV_setThreadStackSize(noom_LuaVM* vm, noomV_Thread* coro, noom_int_t stack); #endif