Skip to content

Commit

Permalink
Added tables to the scripts, untested
Browse files Browse the repository at this point in the history
This also has a lot of bugfixing.
  • Loading branch information
Ratstail91 committed Dec 24, 2024
1 parent 4faa0c0 commit b092b8c
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 51 deletions.
33 changes: 33 additions & 0 deletions scripts/tables.toy
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//1-D table
var a = ["alpha": 1, "beta": 2, "gamma": 3];
a["beta"] = 6;

print a;
assert a == ["alpha": 1, "beta": 6, "gamma": 3], "1-D tables failed";

//nested
var b = [
"outer": ["inner": true],
"alpha": 1,
"beta": 2,
"gamma": 3
];

print b;
assert b == ["alpha": 1, "beta": 2, "gamma": 3, "outer": ["inner": true]], "nested tables failed";

//test empty tables
var empty = [:];

print empty;
assert empty == [:], "empty tables failed";

//test trailing commas
var trailing = [
"alpha":1,
"beta":2,
"gamma":3,
];

print trailing;
assert trailing == ["alpha": 1, "beta": 2, "gamma": 3], "trailing tables failed";
5 changes: 5 additions & 0 deletions scripts/valgrind.toy
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var barr = [
[1, 2, 3],
// [4, 5, 6],
// [7, 8, 9]
];
11 changes: 6 additions & 5 deletions source/toy_array.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
#include <stdlib.h>

Toy_Array* Toy_resizeArray(Toy_Array* paramArray, unsigned int capacity) {
if (capacity == 0) {
free(paramArray);
return NULL;
}

//if some values will be removed, free them first
if (paramArray != NULL && paramArray->count > capacity) {
for (unsigned int i = capacity; i < paramArray->count; i++) {
Toy_freeValue(paramArray->data[i]);
}
}

//if you're freeing everything, just return
if (capacity == 0) {
free(paramArray);
return NULL;
}

unsigned int originalCapacity = paramArray == NULL ? 0 : paramArray->capacity;

Toy_Array* array = realloc(paramArray, capacity * sizeof(Toy_Value) + sizeof(Toy_Array));
Expand Down
5 changes: 3 additions & 2 deletions source/toy_ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ typedef enum Toy_AstFlag {
TOY_AST_FLAG_COMPARE_GREATER_EQUAL = 25,

TOY_AST_FLAG_COMPOUND_ARRAY = 30,
// TOY_AST_FLAG_COMPOUND_TABLE = 31,
TOY_AST_FLAG_COMPOUND_TABLE = 31,
TOY_AST_FLAG_COLLECTION = 32,
TOY_AST_FLAG_INDEX = 33,
TOY_AST_FLAG_PAIR = 33,
TOY_AST_FLAG_INDEX = 34,

TOY_AST_FLAG_AND = 40,
TOY_AST_FLAG_OR = 41,
Expand Down
34 changes: 28 additions & 6 deletions source/toy_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ static ParsingTuple parsingRulesetTable[] = {
{PREC_OR,NULL,binary},// TOY_TOKEN_OPERATOR_OR,
{PREC_NONE,unary,NULL},// TOY_TOKEN_OPERATOR_NEGATE,
{PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_QUESTION,
{PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_COLON,
{PREC_GROUP,compound,aggregate},// TOY_TOKEN_OPERATOR_COLON,

{PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_SEMICOLON, // ;
{PREC_GROUP,NULL,aggregate},// TOY_TOKEN_OPERATOR_COMMA, // ,
Expand Down Expand Up @@ -576,21 +576,39 @@ static Toy_AstFlag compound(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_A
return TOY_AST_FLAG_NONE;
}

//BUGFIX: special case for empty tables
if (match(parser, TOY_TOKEN_OPERATOR_COLON)) {
consume(parser, TOY_TOKEN_OPERATOR_BRACKET_RIGHT, "Expected ']' at the end of empty table");
Toy_private_emitAstPass(bucketHandle, rootHandle);
Toy_private_emitAstAggregate(bucketHandle, rootHandle, TOY_AST_FLAG_PAIR, *rootHandle);
Toy_private_emitAstCompound(bucketHandle, rootHandle, TOY_AST_FLAG_COMPOUND_TABLE);
return TOY_AST_FLAG_NONE;
}

parsePrecedence(bucketHandle, parser, rootHandle, PREC_GROUP);

//peek inside to see what you have
Toy_AstFlag flag = TOY_AST_FLAG_NONE;
if ((*rootHandle)->type == TOY_AST_AGGREGATE) {
//1 element in a table will mean the top-level node is a collection
flag = (*rootHandle)->aggregate.flag;

//more than 1 element in a table will mean you need to check the last element in the collection to find a pair
if (flag == TOY_AST_FLAG_COLLECTION && (*rootHandle)->aggregate.right->type == TOY_AST_AGGREGATE) {
flag = (*rootHandle)->aggregate.right->aggregate.flag; //yes, this is hacky
}
}

//BUGFIX: special case for trailing commas
if (parser->previous.type == TOY_TOKEN_OPERATOR_BRACKET_RIGHT && parser->current.type != TOY_TOKEN_OPERATOR_BRACKET_RIGHT) {
Toy_private_emitAstCompound(bucketHandle, rootHandle, TOY_AST_FLAG_COMPOUND_ARRAY);
//NOTE: will probably need tweaking for tables
Toy_private_emitAstCompound(bucketHandle, rootHandle, flag == TOY_AST_FLAG_PAIR ? TOY_AST_FLAG_COMPOUND_TABLE : TOY_AST_FLAG_COMPOUND_ARRAY);
return TOY_AST_FLAG_NONE;
}

consume(parser, TOY_TOKEN_OPERATOR_BRACKET_RIGHT, "Expected ']' at the end of compound expression");
Toy_private_emitAstCompound(bucketHandle, rootHandle, TOY_AST_FLAG_COMPOUND_ARRAY);
Toy_private_emitAstCompound(bucketHandle, rootHandle, flag == TOY_AST_FLAG_PAIR ? TOY_AST_FLAG_COMPOUND_TABLE : TOY_AST_FLAG_COMPOUND_ARRAY);

return TOY_AST_FLAG_NONE;

//TODO: read in a table
}
else if (parser->previous.type == TOY_TOKEN_OPERATOR_BRACKET_RIGHT) {
//allows for trailing commas
Expand All @@ -613,6 +631,10 @@ static Toy_AstFlag aggregate(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_
parsePrecedence(bucketHandle, parser, rootHandle, PREC_GROUP); //NOT +1, as compounds are right-recursive
return TOY_AST_FLAG_COLLECTION;
}
if (parser->previous.type == TOY_TOKEN_OPERATOR_COLON) {
parsePrecedence(bucketHandle, parser, rootHandle, PREC_GROUP); //NOT +1, as compounds are right-recursive
return TOY_AST_FLAG_PAIR;
}
else if (parser->previous.type == TOY_TOKEN_OPERATOR_BRACKET_LEFT) {
parsePrecedence(bucketHandle, parser, rootHandle, PREC_GROUP);
consume(parser, TOY_TOKEN_OPERATOR_BRACKET_RIGHT, "Expected ']' at the end of index expression");
Expand Down
20 changes: 19 additions & 1 deletion source/toy_routine.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ static unsigned int writeInstructionCompound(Toy_Routine** rt, Toy_AstCompound a
unsigned int result = writeRoutineCode(rt, ast.child);

if (ast.flag == TOY_AST_FLAG_COMPOUND_ARRAY) {
//signal how many values to read in as an array value
//signal how many values to read in as array elements
EMIT_BYTE(rt, code, TOY_OPCODE_READ);
EMIT_BYTE(rt, code, TOY_VALUE_ARRAY);

Expand All @@ -279,6 +279,20 @@ static unsigned int writeInstructionCompound(Toy_Routine** rt, Toy_AstCompound a

return 1; //leaves only 1 value on the stack
}
if (ast.flag == TOY_AST_FLAG_COMPOUND_TABLE) {
//signal how many values to read in as table elements
EMIT_BYTE(rt, code, TOY_OPCODE_READ);
EMIT_BYTE(rt, code, TOY_VALUE_TABLE);

//4-byte alignment
EMIT_BYTE(rt, code,0);
EMIT_BYTE(rt, code,0);

//how many elements
EMIT_INT(rt, code, result);

return 1; //leaves only 1 value on the stack
}
else {
fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid AST compound flag found\n" TOY_CC_RESET);
exit(-1);
Expand All @@ -297,6 +311,10 @@ static unsigned int writeInstructionAggregate(Toy_Routine** rt, Toy_AstAggregate
//collections are handled above
return result;
}
else if (ast.flag == TOY_AST_FLAG_PAIR) {
//pairs are handled above
return result;
}
else if (ast.flag == TOY_AST_FLAG_INDEX) {
//value[index, length]
EMIT_BYTE(rt, code, TOY_OPCODE_INDEX);
Expand Down
2 changes: 1 addition & 1 deletion source/toy_scope.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ Toy_Value* Toy_accessScopeAsPointer(Toy_Scope* scope, Toy_String* key) {
char buffer[key->info.length + 256];
sprintf(buffer, "Undefined variable: %s\n", key->name.data);
Toy_error(buffer);
NULL;
return NULL;
}

return &(entryPtr->value);
Expand Down
18 changes: 15 additions & 3 deletions source/toy_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ void Toy_insertTable(Toy_Table** tableHandle, Toy_Value key, Toy_Value value) {
probeAndInsert(tableHandle, key, value);
}

Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key) {
Toy_TableEntry* Toy_private_lookupTableEntryPtr(Toy_Table** tableHandle, Toy_Value key) {
if (TOY_VALUE_IS_NULL(key) || TOY_VALUE_IS_BOOLEAN(key)) { //TODO: disallow functions and opaques
Toy_error(TOY_CC_ERROR "ERROR: Bad table key\n" TOY_CC_RESET);
}
Expand All @@ -125,12 +125,12 @@ Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key) {
while (true) {
//found the entry
if (Toy_checkValuesAreEqual((*tableHandle)->data[probe].key, key)) {
return (*tableHandle)->data[probe].value;
return (*tableHandle)->data + probe;
}

//if its an empty slot
if (TOY_VALUE_IS_NULL((*tableHandle)->data[probe].key)) {
return TOY_VALUE_FROM_NULL();
return NULL;
}

//adjust and continue
Expand All @@ -139,6 +139,18 @@ Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key) {
}
}

Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key) {
//TODO: I hacked this in at a moment's notice, clean it up
Toy_TableEntry* entry = Toy_private_lookupTableEntryPtr(tableHandle, key);

if (entry == NULL) {
return TOY_VALUE_FROM_NULL();
}
else {
return entry->value;
}
}

void Toy_removeTable(Toy_Table** tableHandle, Toy_Value key) {
if (TOY_VALUE_IS_NULL(key) || TOY_VALUE_IS_BOOLEAN(key)) { //TODO: disallow functions and opaques
Toy_error(TOY_CC_ERROR "ERROR: Bad table key\n" TOY_CC_RESET);
Expand Down
5 changes: 3 additions & 2 deletions source/toy_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ typedef struct Toy_TableEntry { //32 | 64 BITNESS
unsigned int psl; //4 | 4
} Toy_TableEntry; //20 | 20

//key-value table (contains = count + tombstones)
//key-value table
typedef struct Toy_Table { //32 | 64 BITNESS
unsigned int capacity; //4 | 4
unsigned int count; //4 | 4
Expand All @@ -26,7 +26,8 @@ TOY_API Toy_Value Toy_lookupTable(Toy_Table** tableHandle, Toy_Value key);
TOY_API void Toy_removeTable(Toy_Table** tableHandle, Toy_Value key);

//NOTE: exposed to skip unnecessary allocations within Toy_Scope
TOY_API Toy_Table* Toy_private_adjustTableCapacity(Toy_Table* oldTable, unsigned int newCapacity);
TOY_API Toy_Table* Toy_private_adjustTableCapacity(Toy_Table* oldTable, unsigned int newCapacity); //TODO: make it public
TOY_API Toy_TableEntry* Toy_private_lookupTableEntryPtr(Toy_Table** tableHandle, Toy_Value key); //TODO: make it public?

//some useful sizes, could be swapped out as needed
#ifndef TOY_TABLE_INITIAL_CAPACITY
Expand Down
Loading

0 comments on commit b092b8c

Please sign in to comment.