mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
pre-computed identifer hashes
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user