fixed GC bug, extended strings

This commit is contained in:
CPunch 2020-11-27 19:34:54 -06:00
parent e784933517
commit fe2bcf8ae6
3 changed files with 28 additions and 10 deletions

View File

@ -63,7 +63,7 @@ static void saveBuffer(CLexState *state) {
} }
// resets the lex state buffer & returns the allocated buffer as a null terminated string // resets the lex state buffer & returns the allocated buffer as a null terminated string
static char *cutBuffer(CLexState *state) { static char *cutBuffer(CLexState *state, int *length) {
// append the null terminator // append the null terminator
appendBuffer(state, '\0'); appendBuffer(state, '\0');
@ -72,6 +72,8 @@ static char *cutBuffer(CLexState *state) {
size_t count = state->bufCount; size_t count = state->bufCount;
size_t cap = state->bufCap; size_t cap = state->bufCap;
*length = count - 1;
// reset lex state buffer! // reset lex state buffer!
resetBuffer(state); resetBuffer(state);
@ -85,8 +87,7 @@ static CToken makeToken(CLexState *state, CTokenType type) {
token.line = state->line; token.line = state->line;
if (isBuffer(state)) { // is the buffer heap-allocated? if (isBuffer(state)) { // is the buffer heap-allocated?
token.length = state->bufCount; token.start = cutBuffer(state, &token.length);
token.start = cutBuffer(state);
} else { } else {
token.start = state->startChar; token.start = state->startChar;
token.length = state->currentChar - state->startChar; // delta between start & current token.length = state->currentChar - state->startChar; // delta between start & current
@ -201,9 +202,27 @@ CToken parseString(CLexState *state) {
case 'r': case 'n': appendBuffer(state, '\n'); break; case 'r': case 'n': appendBuffer(state, '\n'); break;
case 't': appendBuffer(state, '\t'); break; case 't': appendBuffer(state, '\t'); break;
case '\\': appendBuffer(state, '\\'); break; case '\\': appendBuffer(state, '\\'); break;
default: default: {
if (isNumerical(peek(state))) {
char *numStart = state->currentChar;
// consume the number
while (isNumerical(peek(state)))
next(state);
state->currentChar--; // since next() is called after
int num = (int)strtol(numStart, NULL, 10);
if (num > 255) // sanity check
return makeError(state, "Character out of range! > 255!");
appendBuffer(state, num);
break;
}
return makeError(state, "Unknown special character!"); // TODO: maybe a more descriptive error? return makeError(state, "Unknown special character!"); // TODO: maybe a more descriptive error?
} }
}
next(state); // consume special character next(state); // consume special character
break; break;

View File

@ -34,7 +34,7 @@ typedef enum {
// literals // literals
TOKEN_IDENTIFIER, TOKEN_IDENTIFIER,
TOKEN_STRING, TOKEN_STRING, // token.start is heap allocated and separate from the source string!
TOKEN_NUMBER, TOKEN_NUMBER,
TOKEN_NIL, TOKEN_NIL,
TOKEN_TRUE, TOKEN_TRUE,

View File

@ -107,8 +107,8 @@ static CTableEntry *findEntry(CTableEntry *entries, int mask, CValue key) {
} }
} }
static void resizeTbl(CState *state, CTable *tbl, size_t newCapacity) { static void resizeTbl(CState *state, CTable *tbl, int newCapacity, bool canShrink) {
if (cosmoT_checkShrink(state, tbl)) if (canShrink && cosmoT_checkShrink(state, tbl))
return; return;
size_t size = sizeof(CTableEntry) * newCapacity; size_t size = sizeof(CTableEntry) * newCapacity;
@ -152,8 +152,7 @@ static void resizeTbl(CState *state, CTable *tbl, size_t newCapacity) {
bool cosmoT_checkShrink(CState *state, CTable *tbl) { bool cosmoT_checkShrink(CState *state, CTable *tbl) {
// if count > 8 and active entries < tombstones // if count > 8 and active entries < tombstones
if (tbl->count > MIN_TABLE_CAPACITY && (tbl->count - tbl->tombstones < tbl->tombstones || tbl->tombstones > 50)) { if (tbl->count > MIN_TABLE_CAPACITY && (tbl->count - tbl->tombstones < tbl->tombstones || tbl->tombstones > 50)) {
tbl->tombstones = 0; resizeTbl(state, tbl, nextPow2(tbl->count - tbl->tombstones) * GROW_FACTOR, false); // shrink based on active entries to the next pow of 2
resizeTbl(state, tbl, nextPow2((tbl->count - tbl->tombstones) * GROW_FACTOR)); // shrink based on active entries to the next pow of 2
return true; return true;
} }
@ -166,7 +165,7 @@ COSMO_API CValue* cosmoT_insert(CState *state, CTable *tbl, CValue key) {
if (tbl->count + 1 > (int)(tbl->capacity * MAX_TABLE_FILL)) { if (tbl->count + 1 > (int)(tbl->capacity * MAX_TABLE_FILL)) {
// grow table // grow table
int newCap = tbl->capacity * GROW_FACTOR; int newCap = tbl->capacity * GROW_FACTOR;
resizeTbl(state, tbl, newCap); resizeTbl(state, tbl, newCap, true);
} }
// insert into the table // insert into the table