mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-12-23 06:40:03 +00:00
fixed GC bug, extended strings
This commit is contained in:
parent
e784933517
commit
fe2bcf8ae6
27
src/clex.c
27
src/clex.c
@ -63,7 +63,7 @@ static void saveBuffer(CLexState *state) {
|
||||
}
|
||||
|
||||
// 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
|
||||
appendBuffer(state, '\0');
|
||||
|
||||
@ -72,6 +72,8 @@ static char *cutBuffer(CLexState *state) {
|
||||
size_t count = state->bufCount;
|
||||
size_t cap = state->bufCap;
|
||||
|
||||
*length = count - 1;
|
||||
|
||||
// reset lex state buffer!
|
||||
resetBuffer(state);
|
||||
|
||||
@ -85,8 +87,7 @@ static CToken makeToken(CLexState *state, CTokenType type) {
|
||||
token.line = state->line;
|
||||
|
||||
if (isBuffer(state)) { // is the buffer heap-allocated?
|
||||
token.length = state->bufCount;
|
||||
token.start = cutBuffer(state);
|
||||
token.start = cutBuffer(state, &token.length);
|
||||
} else {
|
||||
token.start = state->startChar;
|
||||
token.length = state->currentChar - state->startChar; // delta between start & current
|
||||
@ -201,8 +202,26 @@ CToken parseString(CLexState *state) {
|
||||
case 'r': case 'n': appendBuffer(state, '\n'); break;
|
||||
case 't': appendBuffer(state, '\t'); 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?
|
||||
}
|
||||
}
|
||||
|
||||
next(state); // consume special character
|
||||
|
@ -34,7 +34,7 @@ typedef enum {
|
||||
|
||||
// literals
|
||||
TOKEN_IDENTIFIER,
|
||||
TOKEN_STRING,
|
||||
TOKEN_STRING, // token.start is heap allocated and separate from the source string!
|
||||
TOKEN_NUMBER,
|
||||
TOKEN_NIL,
|
||||
TOKEN_TRUE,
|
||||
|
@ -107,8 +107,8 @@ static CTableEntry *findEntry(CTableEntry *entries, int mask, CValue key) {
|
||||
}
|
||||
}
|
||||
|
||||
static void resizeTbl(CState *state, CTable *tbl, size_t newCapacity) {
|
||||
if (cosmoT_checkShrink(state, tbl))
|
||||
static void resizeTbl(CState *state, CTable *tbl, int newCapacity, bool canShrink) {
|
||||
if (canShrink && cosmoT_checkShrink(state, tbl))
|
||||
return;
|
||||
|
||||
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) {
|
||||
// if count > 8 and active entries < tombstones
|
||||
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)); // shrink based on active entries to the next pow of 2
|
||||
resizeTbl(state, tbl, nextPow2(tbl->count - tbl->tombstones) * GROW_FACTOR, false); // shrink based on active entries to the next pow of 2
|
||||
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)) {
|
||||
// grow table
|
||||
int newCap = tbl->capacity * GROW_FACTOR;
|
||||
resizeTbl(state, tbl, newCap);
|
||||
resizeTbl(state, tbl, newCap, true);
|
||||
}
|
||||
|
||||
// insert into the table
|
||||
|
Loading…
Reference in New Issue
Block a user