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) { void freeInterpreter(Interpreter* interpreter) {
FREE_ARRAY(char, interpreter->bytecode, interpreter->length);
freeLiteralArray(&interpreter->literalCache); freeLiteralArray(&interpreter->literalCache);
interpreter->scope = popScope(interpreter->scope); interpreter->scope = popScope(interpreter->scope);
FREE_ARRAY(char, interpreter->bytecode, interpreter->length);
freeLiteralArray(&interpreter->stack); freeLiteralArray(&interpreter->stack);
} }

View File

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

View File

@@ -32,6 +32,25 @@ static void printToBuffer(const char* str) {
globalPrintCount += strlen(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 //exposed functions
void printLiteral(Literal literal) { void printLiteral(Literal literal) {
printLiteralCustom(literal, stdoutWrapper); printLiteralCustom(literal, stdoutWrapper);
@@ -194,7 +213,7 @@ Literal _toStringLiteral(char* str) {
} }
Literal _toIdentifierLiteral(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) { char* copyString(char* original, int length) {
@@ -238,7 +257,7 @@ bool literalsAreEqual(Literal lhs, Literal rhs) {
//TODO: literal array and literal dictionary equality checks //TODO: literal array and literal dictionary equality checks
case LITERAL_IDENTIFIER: 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 false;
} }
return !strncmp(AS_IDENTIFIER(lhs), AS_IDENTIFIER(rhs), STRLEN_I(lhs)); 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) { int hashLiteral(Literal lit) {
switch(lit.type) { switch(lit.type) {
case LITERAL_NULL: case LITERAL_NULL:
@@ -306,7 +306,7 @@ int hashLiteral(Literal lit) {
} }
case LITERAL_IDENTIFIER: case LITERAL_IDENTIFIER:
return hashString(AS_IDENTIFIER(lit), STRLEN_I(lit)); return HASH_I(lit); //pre-computed
default: default:
//should never bee seen //should never bee seen

View File

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

View File

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