fixed a lot of regressions and made strings somewhat functional

This commit is contained in:
2026-07-05 13:35:03 +02:00
parent 81d020bb74
commit 9016b9fc53
5 changed files with 194 additions and 101 deletions

View File

@@ -1,6 +1,7 @@
#include "noom.h" #include "noom.h"
#include "compiler.h" #include "compiler.h"
#include "helper.h" #include "helper.h"
#include <stdio.h>
// COMPILATION!!!!!!!!!!!!!!!!!!! // COMPILATION!!!!!!!!!!!!!!!!!!!
// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⢲⣞⣭⣟⣿⣻⣷⢶⢦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⢲⣞⣭⣟⣿⣻⣷⢶⢦⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
@@ -33,7 +34,8 @@ typedef struct noomC_LocalInfo {
enum { NOOMC_GLOBAL, enum { NOOMC_GLOBAL,
NOOMC_LOCAL, NOOMC_LOCAL,
NOOMC_UPVAL } type; NOOMC_UPVAL } type;
unsigned int idx; unsigned short idx;
noom_bool_t isConst;
} noomC_LocalInfo; } noomC_LocalInfo;
noom_Exit noomC_addLocal(noomC_Compiler* c, noomC_Local local) { noom_Exit noomC_addLocal(noomC_Compiler* c, noomC_Local local) {
@@ -48,15 +50,72 @@ noom_Exit noomC_addUpval(noomC_Compiler* c, noomC_Upval upval) {
return NOOM_OK; return NOOM_OK;
} }
int noomC_stealUpval(noomC_Compiler* c, const char* name, noom_uint_t namelen) { noom_Exit noomC_addconst(noomV_Function* func, noomV_Value val) {
if (func->constsize == NOOM_USHORT_MAX) return NOOM_PLEASEHELPMEIAMSCARED;
noomV_Value* newConsts = noom_realloc(func->consts, sizeof(noomV_Value) * (func->constsize + 1));
if (newConsts == 0) return NOOM_ENOMEM;
func->consts = newConsts;
func->consts[func->constsize++] = val;
return NOOM_OK;
}
noom_Exit noomC_addconst_str(noomC_Compiler* c, noom_LuaVM* vm, const char* str, noom_uint_t len, noom_uint_t *outIdx) {
noomV_Function *f = c->target;
for(int i = 0; i < f->constsize; i++) {
noomV_Value v = f->consts[i];
if (v.tag != NOOMV_VOBJ) continue;
noomV_Object* o = v.obj;
if (o->tag != NOOMV_OSTR) continue;
noomV_String* s = (noomV_String*)o;
if (noom_memeq(s->data, s->len, str, len)) {
*outIdx = i;
return NOOM_OK;
}
}
noomV_String* s = 0;
{
noomC_Compiler *cp = c;
while(cp) {
for(int i = 0; i < f->constsize; i++) {
noomV_Value v = f->consts[i];
if (v.tag != NOOMV_VOBJ) continue;
noomV_Object* o = v.obj;
if (o->tag != NOOMV_OSTR) continue;
noomV_String* os = (noomV_String*)o;
if (noom_memeq(os->data, os->len, str, len)) {
s = os;
goto found;
}
}
cp = cp->parent;
}
}
s = noomV_allocStr(vm, str, len);
if (s == 0) return NOOM_ENOMEM;
found:
*outIdx = c->target->constsize;
return noomC_addconst(c->target, (noomV_Value){.tag = NOOMV_VOBJ, .autoclose = 0, .isptr = 0, .obj = (noomV_Object*)s});
}
noom_Exit noomC_stealUpval(noomC_Compiler* c, const char* name, noom_uint_t namelen, noomC_LocalInfo *local) {
// hold on hold on hold on but what if... // hold on hold on hold on but what if...
for (unsigned i = 0; i < c->upvalc; i++) { for (unsigned i = 0; i < c->upvalc; i++) {
const noomC_Upval u = c->upvals[i]; const noomC_Upval u = c->upvals[i];
if (noom_memeq(u.name, u.namelen, name, namelen)) return (int)i; if (noom_memeq(u.name, u.namelen, name, namelen)) {
local->type = NOOMC_UPVAL;
local->idx = i;
local->isConst = u.constant;
return NOOM_OK;
}
} }
// damn it // damn it
if (c->parent == 0) return -1; if (c->parent == 0) {
// signal that this is not found
local->type = NOOMC_GLOBAL;
local->isConst = 0;
return NOOM_OK;
}
// maybe you have smth useful // maybe you have smth useful
for (int i = (int)c->parent->localc - 1; i >= 0; i--) { for (int i = (int)c->parent->localc - 1; i >= 0; i--) {
@@ -64,58 +123,79 @@ int noomC_stealUpval(noomC_Compiler* c, const char* name, noom_uint_t namelen) {
if (l.dropped) continue; if (l.dropped) continue;
if (noom_memeq(l.name, l.namelen, name, namelen)) { if (noom_memeq(l.name, l.namelen, name, namelen)) {
// yay!!!! wahoo!!!! yippee!!!!!!!!!!! // yay!!!! wahoo!!!! yippee!!!!!!!!!!!
if (c->upvalc == NOOMC_MAXUPVAL) return -1;
noomC_Upval upval; noomC_Upval upval;
upval.name = name; upval.name = name;
upval.namelen = namelen; upval.namelen = namelen;
upval.slot = (unsigned short)l.stackslot; upval.slot = (unsigned short)l.stackslot;
upval.stolen = 0; upval.isParentUpvalue = 0;
upval.constant = l.constant; upval.constant = l.constant;
const unsigned idx = c->upvalc; local->type = NOOMC_UPVAL;
c->upvals[c->upvalc++] = upval; local->idx = c->upvalc;
return (int)idx; local->isConst = upval.constant;
return noomC_addUpval(c, upval);
} }
} }
const int parent_upval = noomC_stealUpval(c->parent, name, namelen); noomC_LocalInfo parentUpval;
if (parent_upval >= 0) { noom_Exit e = noomC_stealUpval(c->parent, name, namelen, &parentUpval);
if (c->upvalc == NOOMC_MAXUPVAL) return -1; if(e) return e;
if(parentUpval.type == NOOMC_GLOBAL) {
// not found
*local = parentUpval;
return NOOM_OK;
}
noomC_Upval upval; noomC_Upval upval;
upval.name = name; upval.name = name;
upval.namelen = namelen; upval.namelen = namelen;
upval.slot = (unsigned short)parent_upval; upval.slot = parentUpval.idx;
upval.stolen = 1; upval.isParentUpvalue = 1;
upval.constant = c->parent->upvals[parent_upval].constant; upval.constant = parentUpval.isConst;
const unsigned idx = c->upvalc; local->type = NOOMC_UPVAL;
c->upvals[c->upvalc++] = upval; local->idx = c->upvalc;
return (int)idx; local->isConst = upval.constant;
return noomC_addUpval(c, upval);
} }
return -1; static noom_Exit noomC_identifyLocal(noomC_Compiler* compiler, const char* name, noom_uint_t namelen, noomC_LocalInfo *info) {
}
static noomC_LocalInfo noomC_identifyLocal(noomC_Compiler* compiler, const char* name, noom_uint_t namelen) {
for (int i = compiler->localc - 1; i >= 0; i--) { for (int i = compiler->localc - 1; i >= 0; i--) {
const noomC_Local l = compiler->locals[i]; const noomC_Local l = compiler->locals[i];
if (l.dropped) continue; if (l.dropped) continue;
if (noom_memeq(l.name, l.namelen, name, namelen)) { if (noom_memeq(l.name, l.namelen, name, namelen)) {
return (noomC_LocalInfo){ .type = NOOMC_LOCAL, .idx = l.stackslot }; info->type = NOOMC_LOCAL;
info->idx = l.stackslot;
info->isConst = l.constant;
return NOOM_OK;
} }
} }
const int upval_idx = noomC_stealUpval(compiler, name, namelen); return noomC_stealUpval(compiler, name, namelen, info);
if (upval_idx >= 0) {
return (noomC_LocalInfo){ .type = NOOMC_UPVAL, .idx = (unsigned)upval_idx };
} }
return (noomC_LocalInfo){ .type = NOOMC_GLOBAL }; static noom_Exit noomC_identifyLocalAndSet(noomC_Compiler* compiler, noom_LuaVM *vm, const char* name, noom_uint_t namelen) {
} // TODO: burn this with fire
noomC_LocalInfo info;
static noom_Exit noomC_identifyLocalAndSet(noomC_Compiler* compiler, const char* name, noom_uint_t namelen) { noom_Exit e = noomC_identifyLocal(compiler, name, namelen, &info);
const noomC_LocalInfo info = noomC_identifyLocal(compiler, name, namelen); if(e) return e;
if (info.type == NOOMC_LOCAL) return noomC_emit_AuD(compiler->target, NOOMV_INSTR_SETVAL, compiler->curstack++, (unsigned short)info.idx); if (info.type == NOOMC_LOCAL) return noomC_emit_AuD(compiler->target, NOOMV_INSTR_SETVAL, compiler->curstack++, (unsigned short)info.idx);
if (info.type == NOOMC_UPVAL) return noomC_emit_AuD(compiler->target, NOOMV_INSTR_SETUPVAL, compiler->curstack++, (unsigned short)info.idx); if (info.type == NOOMC_UPVAL) return noomC_emit_AuD(compiler->target, NOOMV_INSTR_SETUPVAL, compiler->curstack++, (unsigned short)info.idx);
if (info.type == NOOMC_GLOBAL) return noomC_emit_AuD(compiler->target, NOOMV_INSTR_SETGLOBAL, compiler->curstack++, (unsigned short)info.idx); noom_uint_t fieldIdx;
e = noomC_addconst_str(compiler, vm, name, namelen, &fieldIdx);
if(e) return e;
if (info.type == NOOMC_GLOBAL) {
if(vm->version > NOOM_VERSION_51) {
noomC_LocalInfo _ENV;
e = noomC_identifyLocal(compiler, "_ENV", 4, &_ENV);
if(e) return e;
if(_ENV.type == NOOMC_GLOBAL) return NOOM_EINTERNAL;
if(_ENV.type == NOOMC_UPVAL) {
return noomC_emit_AuD(compiler->target, NOOMV_INSTR_SETGLOBAL, compiler->curstack++, fieldIdx);
}
// TODO: impl this bullshit
return NOOM_EINTERNAL;
}
return noomC_emit_AuD(compiler->target, NOOMV_INSTR_SETGLOBAL, compiler->curstack++, fieldIdx);
}
return NOOM_EINTERNAL;
} }
void noomC_compiler_init(noomC_Compiler* compiler) { void noomC_compiler_init(noomC_Compiler* compiler) {
@@ -125,6 +205,13 @@ void noomC_compiler_init(noomC_Compiler* compiler) {
compiler->localc = 0; compiler->localc = 0;
compiler->upvalc = 0; compiler->upvalc = 0;
compiler->curstack = 0; compiler->curstack = 0;
compiler->stringTmpBuf = 0;
compiler->maxStringLen = 0;
}
void noomC_compiler_deinit(noomC_Compiler* compiler) {
noom_free(compiler->stringTmpBuf);
} }
noom_Exit noomC_emit(noomV_Function* func, noomV_Inst inst) { noom_Exit noomC_emit(noomV_Function* func, noomV_Inst inst) {
@@ -135,36 +222,6 @@ noom_Exit noomC_emit(noomV_Function* func, noomV_Inst inst) {
return NOOM_OK; return NOOM_OK;
} }
noom_Exit noomC_addconst(noomV_Function* func, noomV_Value val) {
if (func->constsize == NOOM_USHORT_MAX) return NOOM_PLEASEHELPMEIAMSCARED;
noomV_Value* newConsts = noom_realloc(func->consts, sizeof(noomV_Value) * (func->constsize + 1));
if (newConsts == 0) return NOOM_ENOMEM;
func->consts = newConsts;
func->consts[func->constsize++] = val;
return NOOM_OK;
}
noomV_String* noomC_internString(const noomC_Compiler* c, noom_LuaVM* vm, const char* str, noom_uint_t len) {
while (c) {
const noomV_Function* f = c->target;
for (int i = 0; i < f->constsize; i++) {
const noomV_Value v = f->consts[i];
if (v.tag != NOOMV_VOBJ) continue;
noomV_Object* o = v.obj;
if (o->tag != NOOMV_OSTR) continue;
noomV_String* s = (noomV_String*)o;
if (noom_memeq(s->data, s->len, str, len)) return s;
}
c = c->parent;
}
return noomV_allocStr(vm, str, len);
}
noom_Exit noomC_addconst_str(noomC_Compiler* c, noom_LuaVM* vm, const char* str, noom_uint_t len) {
noomV_String* s = noomC_internString(c, vm, str, len);
if (s == 0) return NOOM_ENOMEM;
return noomC_addconst(c->target, (noomV_Value){.tag = NOOMV_VOBJ, .autoclose = 0, .isptr = 0, .obj = (noomV_Object*)s});
}
noom_BinOp noomC_lex_bin_op(const noomP_Parser* parser, noom_uint_t offset) { noom_BinOp noomC_lex_bin_op(const noomP_Parser* parser, noom_uint_t offset) {
const char* op = parser->code + offset; const char* op = parser->code + offset;
@@ -205,10 +262,20 @@ noom_UnaryOp noomC_lex_un_op(const noomP_Parser* parser, noom_uint_t offset) {
return 0; return 0;
} }
static const char* noomC_decode_string_token(const char* s, noom_LuaVersion how_the_fuck, noom_uint_t* outlen) { static const char* noomC_decode_string_token(noomC_Compiler *c, const char* s, noom_uint_t tokenlen, noom_LuaVersion how_the_fuck, noom_uint_t* outlen) {
// token is bigger than contents, so if we can't even fit token, we def can't fit contents
if(c->maxStringLen < tokenlen) {
char *s = noom_realloc(c->stringTmpBuf, tokenlen);
if(s == 0) return 0;
c->stringTmpBuf = s;
c->maxStringLen = tokenlen;
}
// really not good for now
noom_memcpy(c->stringTmpBuf, s + 1, tokenlen - 1);
*outlen = tokenlen - 2;
// nah fuck it TODO atom pls save me // nah fuck it TODO atom pls save me
// actually don't i will repair this one day // actually don't i will repair this one day
return s; return c->stringTmpBuf;
} }
noom_Exit noomC_compile_proto( noom_Exit noomC_compile_proto(
@@ -300,7 +367,7 @@ noom_Exit noomC_emit_assign_to(
if (target->type == NOOMP_NODE_VARIABLE) { if (target->type == NOOMP_NODE_VARIABLE) {
const char* varname = parser->code + target->source_offset; const char* varname = parser->code + target->source_offset;
noom_uint_t namelen = noomL_tokenlen(varname, 0, parser->version); noom_uint_t namelen = noomL_tokenlen(varname, 0, parser->version);
return noomC_identifyLocalAndSet(compiler, varname, namelen); return noomC_identifyLocalAndSet(compiler, vm, varname, namelen);
} }
if (target->type == NOOMP_NODE_GETFIELD) { if (target->type == NOOMP_NODE_GETFIELD) {
@@ -354,10 +421,11 @@ noom_Exit noomC_compile_expr(
} }
if (node->type == NOOMP_NODE_STRINGLITERAL) { if (node->type == NOOMP_NODE_STRINGLITERAL) {
const unsigned short const_idx = func->constsize; noom_uint_t const_idx;
noom_uint_t len; noom_uint_t len;
const char* sptr = noomC_decode_string_token(parser->code + node->source_offset, parser->version, &len); const char* sptr = noomC_decode_string_token(compiler, parser->code + node->source_offset, noomL_tokenlen(parser->code, node->source_offset, parser->version), parser->version, &len);
if ((result = noomC_addconst_str(compiler, vm, sptr, len)) != NOOM_OK) return result; if(sptr == 0) return NOOM_ENOMEM;
if ((result = noomC_addconst_str(compiler, vm, sptr, len, &const_idx)) != NOOM_OK) return result;
compiler->curstack++; compiler->curstack++;
return noomC_emit_AuD(func, NOOMV_INSTR_PUSHCONST, 0, const_idx); return noomC_emit_AuD(func, NOOMV_INSTR_PUSHCONST, 0, const_idx);
} }
@@ -387,9 +455,9 @@ noom_Exit noomC_compile_expr(
if (key_node->type == NOOMP_NODE_FIELDNAME) { if (key_node->type == NOOMP_NODE_FIELDNAME) {
// string key // string key
const unsigned short constidx = func->constsize; noom_uint_t constidx;
const noom_uint_t length = noomL_tokenlen(parser->code, key_node->source_offset, parser->version); const noom_uint_t length = noomL_tokenlen(parser->code, key_node->source_offset, parser->version);
if ((result = noomC_addconst_str(compiler, vm, parser->code + key_node->source_offset, length))) return result; if ((result = noomC_addconst_str(compiler, vm, parser->code + key_node->source_offset, length, &constidx))) return result;
if ((result = noomC_compile_expr(vm, compiler, parser, func, val_node, 1))) return result; if ((result = noomC_compile_expr(vm, compiler, parser, func, val_node, 1))) return result;
compiler->curstack--; compiler->curstack--;
if ((result = noomC_emit_AuD(func, NOOMV_INSTR_SETFIELD, table_slot, constidx))) return result; if ((result = noomC_emit_AuD(func, NOOMV_INSTR_SETFIELD, table_slot, constidx))) return result;
@@ -466,9 +534,9 @@ noom_Exit noomC_compile_expr(
if (node->type == NOOMP_NODE_GETFIELD) { if (node->type == NOOMP_NODE_GETFIELD) {
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;
noom_uint_t constidx = func->constsize; noom_uint_t constidx;
// dumbass oneliner // dumbass oneliner
if ((result = noomC_addconst_str(compiler, vm, parser->code + node->subnodes[1]->source_offset, noomL_tokenlen(parser->code, node->subnodes[1]->source_offset, parser->version)))) return result; if ((result = noomC_addconst_str(compiler, vm, parser->code + node->subnodes[1]->source_offset, noomL_tokenlen(parser->code, node->subnodes[1]->source_offset, parser->version), &constidx))) return result;
return noomC_emit_AuD(func, NOOMV_INSTR_GETFIELD, 0, (unsigned short)constidx); return noomC_emit_AuD(func, NOOMV_INSTR_GETFIELD, 0, (unsigned short)constidx);
} }
@@ -495,8 +563,8 @@ noom_Exit noomC_compile_expr(
if (isMethod) { if (isMethod) {
const char* fieldname = parser->code + node->subnodes[1]->source_offset; const char* fieldname = parser->code + node->subnodes[1]->source_offset;
const noom_uint_t fieldlen = noomL_tokenlen(parser->code, node->subnodes[1]->source_offset, parser->version); const noom_uint_t fieldlen = noomL_tokenlen(parser->code, node->subnodes[1]->source_offset, parser->version);
noom_uint_t constidx = func->constsize; noom_uint_t constidx;
if ((result = noomC_addconst_str(compiler, vm, fieldname, fieldlen))) return result; if ((result = noomC_addconst_str(compiler, vm, fieldname, fieldlen, &constidx))) return result;
compiler->curstack++; // self is pushed alongside the method compiler->curstack++; // self is pushed alongside the method
if ((result = noomC_emit_AuD(func, NOOMV_INSTR_GETMETHOD, funcIdx, (unsigned short)constidx))) return result; if ((result = noomC_emit_AuD(func, NOOMV_INSTR_GETMETHOD, funcIdx, (unsigned short)constidx))) return result;
} }
@@ -526,7 +594,38 @@ noom_Exit noomC_compile_expr(
if (node->type == NOOMP_NODE_VARIABLE) { if (node->type == NOOMP_NODE_VARIABLE) {
const char* varname = parser->code + node->source_offset; const char* varname = parser->code + node->source_offset;
noom_uint_t namelen = noomL_tokenlen(varname, 0, parser->version); noom_uint_t namelen = noomL_tokenlen(varname, 0, parser->version);
return noomC_identifyLocalAndSet(compiler, varname, namelen); noomC_LocalInfo info;
result = noomC_identifyLocal(compiler, varname, namelen, &info);
if(result) return result;
compiler->curstack++;
switch (info.type) {
case NOOMC_LOCAL:
return noomC_emit_AuD(func, NOOMV_INSTR_PUSHVAL, 0, info.idx);
case NOOMC_UPVAL:
return noomC_emit_AuD(func, NOOMV_INSTR_PUSHUPVAL, 0, info.idx);
case NOOMC_GLOBAL: {
noom_uint_t constidx;
if((result = noomC_addconst_str(compiler, vm, varname, namelen, &constidx))) return result;
if(parser->version == NOOM_VERSION_51) {
return noomC_emit_AuD(func, NOOMV_INSTR_PUSHGLOBAL, 0, constidx);
}
noomC_LocalInfo _ENV;
if((result = noomC_identifyLocal(compiler, "_ENV", 4, &_ENV))) return result;
// not meant to be possible
if(_ENV.type == NOOMC_GLOBAL) return NOOM_EINTERNAL;
// most likely branch in human history
if(_ENV.type == NOOMC_UPVAL) {
if((result = noomC_emit_AuD(func, NOOMV_INSTR_PUSHUPVAL, _ENV.idx, constidx))) return result;
} else {
// bitchass
if((result = noomC_emit_AuD(func, NOOMV_INSTR_PUSHVAL, 0, _ENV.idx))) return result;
}
return noomC_emit_AuD(func, NOOMV_INSTR_GETFIELD, 0, constidx);
}
}
// forgot a case
return NOOM_EINTERNAL;
} }
if (node->type == NOOMP_NODE_LAMBDAFUNCTIONLITERAL) { if (node->type == NOOMP_NODE_LAMBDAFUNCTIONLITERAL) {
@@ -706,6 +805,14 @@ noom_Exit noomC_add_stuff_to_function(noom_LuaVM* vm, noomC_Compiler* compiler,
while (place_count < node->subnodec && node->subnodes[place_count]->type == NOOMP_NODE_ASSIGNPLACE) place_count++; while (place_count < node->subnodec && node->subnodes[place_count]->type == NOOMP_NODE_ASSIGNPLACE) place_count++;
noom_uint_t value_count = node->subnodec - place_count; noom_uint_t value_count = node->subnodec - place_count;
// subtly wrong execution but also just wrong... order of instructions!
// TODO: burn it with fire
// WHY: assigning instructions fundamentally assume the value is on the top of the stack,
// so this is just bad. Lua also evalutes stuff differently, with f().x = g() calling f before g.
// IF WE WANT TO KEEP THE BROKEN ORDER: we should push all of the values first, then do the assignments in reverse order.
// IF WE WANT TO FIX THE ORDER: we'd need the emit_assign_to output extra information for the 2nd half of the assingment,
// so it can for example call f() and get th return but store how to assign to its result.
unsigned char value_base = (unsigned char)compiler->curstack; unsigned char value_base = (unsigned char)compiler->curstack;
for (noom_uint_t i = 0; i < value_count; i++) { for (noom_uint_t i = 0; i < value_count; i++) {
noom_bool_t is_last = i == value_count - 1; noom_bool_t is_last = i == value_count - 1;
@@ -884,11 +991,13 @@ noom_Exit noomC_compile(noom_LuaVM* vm, const noomP_Parser* parser, const noomP_
upval.name = "_ENV"; upval.name = "_ENV";
upval.namelen = 4; upval.namelen = 4;
upval.slot = 0; upval.slot = 0;
upval.stolen = 1; upval.isParentUpvalue = 1;
upval.constant = 0; upval.constant = 0;
noomC_addUpval(&compiler, upval); noomC_addUpval(&compiler, upval);
// TODO: we need to wrap the value as a *closure*, with one upvalue, the environment (_ENV). // TODO: we need to wrap the value as a *closure*, with one upvalue, the environment (_ENV).
} }
return noomC_compile_block(vm, &compiler, parser, program, node); noom_Exit err = noomC_compile_block(vm, &compiler, parser, program, node);
noomC_compiler_deinit(&compiler);
return err;
} }

View File

@@ -18,7 +18,7 @@ typedef struct noomC_Upval {
unsigned int namelen; unsigned int namelen;
unsigned short slot; unsigned short slot;
// if stolen, this means that slot is actually an upvalue index // if stolen, this means that slot is actually an upvalue index
noom_bool_t stolen; noom_bool_t isParentUpvalue;
noom_bool_t constant; noom_bool_t constant;
} noomC_Upval; } noomC_Upval;
@@ -29,6 +29,8 @@ typedef struct noomC_Compiler {
// steal constants from this // steal constants from this
struct noomC_Compiler* parent; struct noomC_Compiler* parent;
noomV_Function* target; noomV_Function* target;
char *stringTmpBuf;
noom_uint_t maxStringLen;
unsigned localc; unsigned localc;
unsigned upvalc; unsigned upvalc;
unsigned curstack; unsigned curstack;
@@ -36,19 +38,12 @@ typedef struct noomC_Compiler {
noomC_Upval upvals[NOOMC_MAXUPVAL]; noomC_Upval upvals[NOOMC_MAXUPVAL];
} noomC_Compiler; } noomC_Compiler;
// TODO: probably many of these don't really need to be exposed to other code but whatever
noom_Exit noomC_addLocal(noomC_Compiler* c, noomC_Local local);
noom_Exit noomC_addUpval(noomC_Compiler* c, noomC_Upval upval);
int noomC_stealUpval(noomC_Compiler* c, const char* name, noom_uint_t namelen);
void noomC_compiler_init(noomC_Compiler* compiler); void noomC_compiler_init(noomC_Compiler* compiler);
void noomC_compiler_deinit(noomC_Compiler* compiler);
noom_Exit noomC_emit(noomV_Function* func, noomV_Inst inst); noom_Exit noomC_emit(noomV_Function* func, noomV_Inst inst);
#define noomC_emit_ABC(func, _op, _a, _b, _c) noomC_emit((func), (noomV_Inst){.op = (_op), .a = (_a), .b = (_b), .c = (_c)}) #define noomC_emit_ABC(func, _op, _a, _b, _c) noomC_emit((func), (noomV_Inst){.op = (_op), .a = (_a), .b = (_b), .c = (_c)})
#define noomC_emit_AuD(func, _op, _a, _uD) noomC_emit((func), (noomV_Inst){.op = (_op), .a = (_a), .us = (_uD)}) #define noomC_emit_AuD(func, _op, _a, _uD) noomC_emit((func), (noomV_Inst){.op = (_op), .a = (_a), .us = (_uD)})
noom_Exit noomC_addconst(noomV_Function* func, noomV_Value val);
noomV_String* noomC_internString(const noomC_Compiler* c, noom_LuaVM* vm, const char* str, noom_uint_t len);
noom_Exit noomC_addconst_str(noomC_Compiler* c, noom_LuaVM* vm, const char* str, noom_uint_t len);
noom_BinOp noomC_lex_bin_op(const noomP_Parser* parser, noom_uint_t offset); noom_BinOp noomC_lex_bin_op(const noomP_Parser* parser, noom_uint_t offset);
noom_UnaryOp noomC_lex_un_op(const noomP_Parser* parser, noom_uint_t offset); noom_UnaryOp noomC_lex_un_op(const noomP_Parser* parser, noom_uint_t offset);

View File

@@ -133,6 +133,7 @@ int execute(const char* code, noom_LuaVersion version, const char* program_name,
if (e) { if (e) {
printf("error: %d\n", e); printf("error: %d\n", e);
noomP_freeNode(parser.last_node); noomP_freeNode(parser.last_node);
noom_destroyVM(vm);
return 1; return 1;
} }
noomP_freeNode(parser.last_node); noomP_freeNode(parser.last_node);

View File

@@ -76,14 +76,6 @@ noomV_DisInfo noomV_disInfo[NOOMV_INSTR_NOP2] = {
.name = "SETFIELD", .name = "SETFIELD",
.arg = NOOMV_DIS_uD, .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] = { [NOOMV_INSTR_OP] = {
.name = "OP", .name = "OP",
@@ -358,7 +350,7 @@ noom_Exit noomV_rawsetTable(noom_LuaVM* vm, noomV_Table* t, noomV_Value key, noo
noomV_Value key2 = t->entrydata[idx]; noomV_Value key2 = t->entrydata[idx];
// tombstone, for creation! // tombstone, for creation!
if(key2.isptr) { if(key2.isptr) {
freshTomb = t->entrydata + idx; if(freshTomb == 0) freshTomb = t->entrydata + idx;
idx++; idx++;
idx %= t->entries; idx %= t->entries;
count++; count++;

View File

@@ -130,10 +130,6 @@ typedef enum noomV_Opcode : unsigned char {
NOOMV_INSTR_GETFIELD, NOOMV_INSTR_GETFIELD,
// pops (table, value), sets `table[consts[op.uD]] = value`, an optimization for changing fields // pops (table, value), sets `table[consts[op.uD]] = value`, an optimization for changing fields
NOOMV_INSTR_SETFIELD, NOOMV_INSTR_SETFIELD,
// pushes `(*upvals[op.A])[consts[op.uD]]`
NOOMV_INSTR_GETUPFIELD,
// pops [value], sets `(*upvals[op.A])[consts[op.uD]] = value`
NOOMV_ISNTR_SETUPFIELD,
// does a unary or binary operation. // does a unary or binary operation.
// if op.a == 1, its a unary operation. // if op.a == 1, its a unary operation.