mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-22 07:20:05 +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
|
// 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,8 +202,26 @@ 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
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user