pre-computed identifer hashes

This commit is contained in:
2022-08-11 18:36:03 +01:00
parent 1430aefdf3
commit 00812e7a73
5 changed files with 34 additions and 27 deletions

View File

@@ -32,9 +32,9 @@ void initInterpreter(Interpreter* interpreter, unsigned char* bytecode, int leng
}
void freeInterpreter(Interpreter* interpreter) {
FREE_ARRAY(char, interpreter->bytecode, interpreter->length);
freeLiteralArray(&interpreter->literalCache);
interpreter->scope = popScope(interpreter->scope);
FREE_ARRAY(char, interpreter->bytecode, interpreter->length);
freeLiteralArray(&interpreter->stack);
}

View File

@@ -10,12 +10,18 @@ typedef void (*PrintFn)(const char*);
//the interpreter acts depending on the bytecode instructions
typedef struct Interpreter {
LiteralArray literalCache; //generally doesn't change after initialization
Scope* scope;
//input
unsigned char* bytecode;
int length;
int count;
LiteralArray literalCache; //read-only - built from the bytecode
//operation
Scope* scope;
LiteralArray stack;
//output
// LiteralDictionary exports; //read-write - interface with Toy from C
PrintFn printOutput;
PrintFn assertOutput;
} Interpreter;

View File

@@ -32,6 +32,25 @@ static void printToBuffer(const char* str) {
globalPrintCount += strlen(str);
}
//hash util functions
static unsigned int hashString(const char* string, int length) {
unsigned int hash = 2166136261u;
for (int i = 0; i < length; i++) {
hash *= string[i];
hash *= 16777619;
}
return hash;
}
static unsigned int hash(unsigned int x) {
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = (x >> 16) ^ x;
return x;
}
//exposed functions
void printLiteral(Literal literal) {
printLiteralCustom(literal, stdoutWrapper);
@@ -194,7 +213,7 @@ Literal _toStringLiteral(char* str) {
}
Literal _toIdentifierLiteral(char* str) {
return ((Literal){LITERAL_IDENTIFIER,{.identifier.ptr = (char*)str,.identifier.length = strlen((char*)str)}});
return ((Literal){LITERAL_IDENTIFIER,{.identifier.ptr = (char*)str,.identifier.length = strlen((char*)str), .identifier.hash=hashString(str, strlen((char*)str))}});
}
char* copyString(char* original, int length) {
@@ -238,7 +257,7 @@ bool literalsAreEqual(Literal lhs, Literal rhs) {
//TODO: literal array and literal dictionary equality checks
case LITERAL_IDENTIFIER:
if (STRLEN_I(lhs) != STRLEN_I(rhs)) {
if (HASH_I(lhs) != HASH_I(rhs) && STRLEN_I(lhs) != STRLEN_I(rhs)) {
return false;
}
return !strncmp(AS_IDENTIFIER(lhs), AS_IDENTIFIER(rhs), STRLEN_I(lhs));
@@ -250,25 +269,6 @@ bool literalsAreEqual(Literal lhs, Literal rhs) {
}
}
//hash functions
static unsigned int hashString(const char* string, int length) {
unsigned int hash = 2166136261u;
for (int i = 0; i < length; i++) {
hash *= string[i];
hash *= 16777619;
}
return hash;
}
static unsigned int hash(unsigned int x) {
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = (x >> 16) ^ x;
return x;
}
int hashLiteral(Literal lit) {
switch(lit.type) {
case LITERAL_NULL:
@@ -306,7 +306,7 @@ int hashLiteral(Literal lit) {
}
case LITERAL_IDENTIFIER:
return hashString(AS_IDENTIFIER(lit), STRLEN_I(lit));
return HASH_I(lit); //pre-computed
default:
//should never bee seen

View File

@@ -36,6 +36,7 @@ typedef struct {
struct { //for variable names
char* ptr;
int length;
int hash;
} identifier;
//TODO: type
@@ -99,7 +100,7 @@ void freeLiteral(Literal literal);
#define STRLEN(lit) ((lit).as.string.length)
#define STRLEN_I(lit) ((lit).as.identifier.length)
#define TYPES(lit) ((lit).as.identifier.types)
#define HASH_I(lit) ((lit).as.identifier.hash)
//BUGFIX: macros are not functions
bool _isTruthy(Literal x);

View File

@@ -476,7 +476,7 @@ ParseRule* getRule(TokenType type) {
return &parseRules[type];
}
//static analasys
//constant folding
static bool calcStaticBinaryArithmetic(Node** nodeHandle) {
switch((*nodeHandle)->binary.opcode) {
case OP_ADDITION: