Compare commits

...

3 Commits

Author SHA1 Message Date
Kayne Ruse bbb1e38649 Fixed parameter strings in data section
Fucking finally.
2026-05-26 18:51:24 +10:00
Kayne Ruse 190477add8 Fixed negative variables handled incorrectly 2026-05-26 18:01:49 +10:00
Kayne Ruse 69175e801a Fixed a hash collision causing null variables to be overwritten
Andrew, don't you dare run my code through a clanker again or I'll hunt
your Canuck ass down and beat you with a hockey stick.
2026-05-26 17:52:07 +10:00
12 changed files with 68 additions and 17 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ int inspect_bucket(Toy_Bucket** bucketHandle) {
unsigned char* ptr = iter->data;
while ((ptr - iter->data < iter->count) && *((int*)ptr) != 0) { //for each partition
while ((ptr >= iter->data) && (ptr < iter->data + iter->count) && *((int*)ptr) != 0) { //for each partition
if ( ( *((int*)ptr) & 1) == 0) { //is this partition still in use?
occupied++;
+4
View File
@@ -233,6 +233,10 @@ int inspect_instruction(unsigned char* bytecode, unsigned int pc, unsigned int j
printf(MARKER "MODULO %s\n", MARKER_VALUE(pc, unsigned char), bytecode[pc + 1] == TOY_OPCODE_ASSIGN ? "and ASSIGN" : "");
return 4;
case TOY_OPCODE_INVERT:
printf(MARKER "INVERT\n", MARKER_VALUE(pc, unsigned char));
return 4;
case TOY_OPCODE_COMPARE_EQUAL:
printf(MARKER "COMPARE %s\n", MARKER_VALUE(pc, unsigned char), bytecode[pc + 1] != TOY_OPCODE_NEGATE ? "==" : "!=");
return 4;
+3 -3
View File
@@ -26,7 +26,7 @@ unsigned char* readFile(char* path, int* size) {
//determine the file's length
fseek(file, 0L, SEEK_END);
*size = ftell(file);
*size = (int)ftell(file);
rewind(file);
//make some space
@@ -44,7 +44,7 @@ unsigned char* readFile(char* path, int* size) {
return NULL;
}
buffer[(*size)++] = '\0';
buffer[(*size)] = '\0';
//clean up and return
fclose(file);
@@ -334,7 +334,7 @@ int repl(const char* filepath, bool verbose) {
inputBuffer[--length] = '\0';
}
if (length == 0 || !inputBuffer[ strspn(inputBuffer, " \r\n\t") ]) {
if (length == 0 || inputBuffer[ strspn(inputBuffer, " \r\n\t") ] == '\0') {
printf("%s> ", prompt); //shows the terminal prompt and restart
continue;
}
+3 -2
View File
@@ -86,9 +86,10 @@ typedef enum Toy_AstFlag {
TOY_AST_FLAG_PREFIX_DECREMENT = 42,
TOY_AST_FLAG_POSTFIX_INCREMENT = 43,
TOY_AST_FLAG_POSTFIX_DECREMENT = 44,
TOY_AST_FLAG_INVERT = 45,
TOY_AST_FLAG_INVOKATION = 45,
TOY_AST_FLAG_ATTRIBUTE = 46,
TOY_AST_FLAG_INVOKATION = 46,
TOY_AST_FLAG_ATTRIBUTE = 47,
// TOY_AST_FLAG_TERNARY,
} Toy_AstFlag;
+1 -1
View File
@@ -172,7 +172,7 @@ static void attr_tableRemove(Toy_VM* vm, Toy_FunctionNative* self) {
Toy_Value Toy_private_handleTableAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
if (MATCH_VALUE_AND_CSTRING(attribute, "length")) {
return TOY_VALUE_FROM_INTEGER(TOY_VALUE_AS_ARRAY(compound)->count);
return TOY_VALUE_FROM_INTEGER(TOY_VALUE_AS_TABLE(compound)->count);
}
else if (MATCH_VALUE_AND_CSTRING(attribute, "insert")) {
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableInsert);
+18 -6
View File
@@ -78,6 +78,7 @@ static void emitByte(unsigned char** handle, unsigned int* capacity, unsigned in
((unsigned char*)(*handle))[(*count)++] = byte;
}
//BUG: There might be issues here when compiled on big-endian platforms
static void emitInt(unsigned char** handle, unsigned int* capacity, unsigned int* count, unsigned int bytes) {
char* ptr = (char*)&bytes;
emitByte(handle, capacity, count, *(ptr++));
@@ -168,8 +169,8 @@ static unsigned int emitString(Toy_Bytecode** mb, Toy_String* str) {
}
//mark the position within the jump index, reusing an existing entry if it exists
for (unsigned int i = 0; i < (*mb)->jumpsCount; i++) {
if ((*mb)->jumps[i] == dataAddr) {
for (unsigned int i = 0; i < (*mb)->jumpsCount; i += 4) {
if (*(unsigned int*)((*mb)->jumps + i) == dataAddr) {
//reuse, and finish
EMIT_INT(mb, code, i);
return 1;
@@ -200,13 +201,13 @@ static unsigned int emitParameters(Toy_Bytecode* mb, Toy_Ast* ast) {
}
//the address within the data section
char buffer[128];
snprintf(buffer, 128, "%.*s", ast->varDeclare.name->info.length, ast->varDeclare.name->leaf.data);
char buffer[256];
snprintf(buffer, 256, "%.*s", ast->varDeclare.name->info.length, ast->varDeclare.name->leaf.data);
unsigned int dataAddr = emitCStringToData(&(mb->data), &(mb->dataCapacity), &(mb->dataCount), buffer);
//check the param index for that entry i.e. don't reuse parameter names
for (unsigned int i = 0; i < mb->paramCount; i++) {
if (mb->param[i] == dataAddr) {
for (unsigned int i = 0; i < mb->paramCount; i+=4) {
if (*(unsigned int*)(mb->param + i) == dataAddr) {
//not allowed
fprintf(stderr, TOY_CC_ERROR "COMPILER ERROR: Function parameters must have unique names\n" TOY_CC_RESET);
mb->panic = true;
@@ -376,6 +377,17 @@ static unsigned int writeInstructionUnary(Toy_Bytecode** mb, Toy_AstUnary ast) {
result = 1;
}
else if (ast.flag == TOY_AST_FLAG_INVERT) {
result = writeBytecodeFromAst(mb, ast.child);
EMIT_BYTE(mb, code, TOY_OPCODE_INVERT);
//4-byte alignment
EMIT_BYTE(mb, code, 0);
EMIT_BYTE(mb, code, 0);
EMIT_BYTE(mb, code, 0);
}
else {
fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid AST unary flag found\n" TOY_CC_RESET);
exit(-1);
+1
View File
@@ -22,6 +22,7 @@ typedef enum Toy_OpcodeType {
TOY_OPCODE_MULTIPLY,
TOY_OPCODE_DIVIDE,
TOY_OPCODE_MODULO,
TOY_OPCODE_INVERT, //negative numbers
//comparison instructions
TOY_OPCODE_COMPARE_EQUAL,
+3 -3
View File
@@ -324,7 +324,7 @@ static Toy_AstFlag literal(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_As
case TOY_TOKEN_LITERAL_INTEGER: {
//filter the '_' character
char buffer[parser->previous.length];
char buffer[parser->previous.length + 1];
unsigned int i = 0, o = 0;
do {
@@ -341,7 +341,7 @@ static Toy_AstFlag literal(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_As
case TOY_TOKEN_LITERAL_FLOAT: {
//filter the '_' character
char buffer[parser->previous.length];
char buffer[parser->previous.length + 1];
unsigned int i = 0, o = 0;
do {
@@ -417,7 +417,7 @@ static Toy_AstFlag unary(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast*
}
else {
//actually emit the negation node
Toy_private_emitAstUnary(bucketHandle, rootHandle, TOY_AST_FLAG_NEGATE);
Toy_private_emitAstUnary(bucketHandle, rootHandle, TOY_AST_FLAG_INVERT);
}
}
+4
View File
@@ -1,5 +1,6 @@
#include "toy_print.h"
#include <assert.h>
#include <stdio.h>
static Toy_callbackType printCallback = puts;
@@ -19,14 +20,17 @@ void Toy_assertFailure(const char* msg) {
}
void Toy_setPrintCallback(Toy_callbackType cb) {
assert(cb);
printCallback = cb;
}
void Toy_setErrorCallback(Toy_callbackType cb) {
assert(cb);
errorCallback = cb;
}
void Toy_setAssertFailureCallback(Toy_callbackType cb) {
assert(cb);
assertCallback = cb;
}
+1 -1
View File
@@ -48,7 +48,7 @@ static void probeAndInsert(Toy_Scope* scope, Toy_String* key, Toy_Value value, T
}
//if this spot is free, insert and return
if (TOY_VALUE_IS_NULL(scope->data[probe].value)) {
if (scope->data[probe].key == NULL) { //fuck my life
scope->data[probe] = entry;
scope->count++;
scope->maxPsl = entry.psl > scope->maxPsl ? entry.psl : scope->maxPsl;
+22
View File
@@ -73,6 +73,8 @@ static void processRead(Toy_VM* vm) {
//grab the jump as an integer
unsigned int jump = *((int*)(vm->code + vm->jumpsAddr + READ_INT(vm)));
//BUG: the jump parameter could cause an out of bounds read if it's malformed
//jumps are relative to the data address
char* cstring = (char*)(vm->code + vm->dataAddr + jump);
@@ -552,6 +554,25 @@ static void processIterate(Toy_VM* vm) {
}
static void processArithmetic(Toy_VM* vm, Toy_OpcodeType opcode) {
//BUGFIX: handle negative variables
if (opcode == TOY_OPCODE_INVERT) {
Toy_Value value = Toy_popStack(&vm->stack);
if (TOY_VALUE_IS_INTEGER(value)) {
int intermediate = TOY_VALUE_AS_INTEGER(value);
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_INTEGER(-intermediate));
}
else if (TOY_VALUE_IS_FLOAT(value)) {
float intermediate = TOY_VALUE_AS_FLOAT(value);
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_FLOAT(-intermediate));
}
else {
Toy_error("Can't negate a non-number");
Toy_freeValue(value);
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_NULL());
}
return;
}
Toy_Value right = Toy_popStack(&vm->stack);
Toy_Value left = Toy_popStack(&vm->stack);
@@ -1094,6 +1115,7 @@ static unsigned int process(Toy_VM* vm) {
case TOY_OPCODE_MULTIPLY:
case TOY_OPCODE_DIVIDE:
case TOY_OPCODE_MODULO:
case TOY_OPCODE_INVERT:
processArithmetic(vm, opcode);
break;
+7
View File
@@ -157,4 +157,11 @@ print !false; //true
print a;
}
{
//Yet Another Cosmic Joke
var a = null;
var i = 42;
print a;
}
//TODO: type casting