mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Recursive arrays and dictionaries!
This commit is contained in:
@@ -35,6 +35,9 @@ print ["key":"value"];
|
||||
print [];
|
||||
print [:];
|
||||
|
||||
//recursive
|
||||
print [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
|
||||
|
||||
//var arr : [int] = [1, 2, 3, 42];
|
||||
//var dict : [string, int] = ["hello": 1, "world":2];
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
print ["foo", "bar"];
|
||||
print ["foo":1, "bar":2];
|
||||
print [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
|
||||
print [["foo":1]:["bar":2]];
|
||||
|
||||
@@ -24,6 +24,110 @@ void initCompiler(Compiler* compiler) {
|
||||
pushLiteralArray(&compiler->literalCache, f);
|
||||
}
|
||||
|
||||
//separated out, so it can be recursive
|
||||
static int writeNodeCompoundToCache(Compiler* compiler, Node* node) {
|
||||
int index = -1;
|
||||
|
||||
//for both, stored as an array
|
||||
LiteralArray* store = ALLOCATE(LiteralArray, 1);
|
||||
initLiteralArray(store);
|
||||
|
||||
//emit an array or a dictionary definition
|
||||
if (node->compound.literalType == LITERAL_DICTIONARY) {
|
||||
//ensure each literal key and value are in the cache, individually
|
||||
for (int i = 0; i < node->compound.count; i++) {
|
||||
//keys
|
||||
switch(node->compound.nodes[i].pair.left->type) {
|
||||
case NODE_LITERAL: {
|
||||
//keys are literals
|
||||
int key = findLiteralIndex(&compiler->literalCache, node->compound.nodes[i].pair.left->atomic.literal);
|
||||
if (key < 0) {
|
||||
key = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].pair.left->atomic.literal);
|
||||
}
|
||||
|
||||
pushLiteralArray(store, TO_INTEGER_LITERAL(key));
|
||||
}
|
||||
break;
|
||||
|
||||
case NODE_COMPOUND: {
|
||||
int key = writeNodeCompoundToCache(compiler, node->compound.nodes[i].pair.left);
|
||||
|
||||
pushLiteralArray(store, TO_INTEGER_LITERAL(key));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "[Internal] Unrecognized key node type in writeNodeCompoundToCache()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//values
|
||||
switch(node->compound.nodes[i].pair.right->type) {
|
||||
case NODE_LITERAL: {
|
||||
//values are literals
|
||||
int val = findLiteralIndex(&compiler->literalCache, node->compound.nodes[i].pair.right->atomic.literal);
|
||||
if (val < 0) {
|
||||
val = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].pair.right->atomic.literal);
|
||||
}
|
||||
|
||||
pushLiteralArray(store, TO_INTEGER_LITERAL(val));
|
||||
}
|
||||
break;
|
||||
|
||||
case NODE_COMPOUND: {
|
||||
int val = writeNodeCompoundToCache(compiler, node->compound.nodes[i].pair.right);
|
||||
|
||||
pushLiteralArray(store, TO_INTEGER_LITERAL(val));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "[Internal] Unrecognized value node type in writeNodeCompoundToCache()");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//push the store to the cache, with instructions about how pack it
|
||||
index = pushLiteralArray(&compiler->literalCache, TO_DICTIONARY_LITERAL(store));
|
||||
}
|
||||
else if (node->compound.literalType == LITERAL_ARRAY) {
|
||||
//ensure each literal value is in the cache, individually
|
||||
for (int i = 0; i < node->compound.count; i++) {
|
||||
switch(node->compound.nodes[i].type) {
|
||||
case NODE_LITERAL: {
|
||||
//values
|
||||
int val = findLiteralIndex(&compiler->literalCache, node->compound.nodes[i].atomic.literal);
|
||||
if (val < 0) {
|
||||
val = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].atomic.literal);
|
||||
}
|
||||
|
||||
pushLiteralArray(store, TO_INTEGER_LITERAL(val));
|
||||
}
|
||||
break;
|
||||
|
||||
case NODE_COMPOUND: {
|
||||
int val = writeNodeCompoundToCache(compiler, &node->compound.nodes[i]);
|
||||
|
||||
index = pushLiteralArray(store, TO_INTEGER_LITERAL(val));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "[Internal] Unrecognized node type in writeNodeCompoundToCache()");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//push the store to the cache, with instructions about how pack it
|
||||
index = pushLiteralArray(&compiler->literalCache, TO_ARRAY_LITERAL(store));
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "[Internal] Unrecognized compound type in writeNodeCompoundToCache()");
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void writeCompiler(Compiler* compiler, Node* node) {
|
||||
//grow if the bytecode space is too small
|
||||
if (compiler->capacity < compiler->count + 1) {
|
||||
@@ -95,53 +199,7 @@ void writeCompiler(Compiler* compiler, Node* node) {
|
||||
break;
|
||||
|
||||
case NODE_COMPOUND: {
|
||||
int index = -1;
|
||||
|
||||
//for both, stored as an array
|
||||
LiteralArray* store = ALLOCATE(LiteralArray, 1);
|
||||
initLiteralArray(store);
|
||||
|
||||
//emit an array or a dictionary definition
|
||||
if (node->compound.literalType == LITERAL_DICTIONARY) {
|
||||
//ensure each literal key and value are in the cache, individually
|
||||
for (int i = 0; i < node->compound.count; i++) {
|
||||
//keys
|
||||
int key = findLiteralIndex(&compiler->literalCache, node->compound.nodes[i].pair.left->atomic.literal);
|
||||
if (key < 0) {
|
||||
key = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].pair.left->atomic.literal);
|
||||
}
|
||||
|
||||
//values
|
||||
int val = findLiteralIndex(&compiler->literalCache, node->compound.nodes[i].pair.right->atomic.literal);
|
||||
if (val < 0) {
|
||||
val = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].pair.right->atomic.literal);
|
||||
}
|
||||
|
||||
pushLiteralArray(store, TO_INTEGER_LITERAL(key));
|
||||
pushLiteralArray(store, TO_INTEGER_LITERAL(val));
|
||||
}
|
||||
|
||||
//push the store to the cache, with instructions about how pack it
|
||||
index = pushLiteralArray(&compiler->literalCache, TO_DICTIONARY_LITERAL(store));
|
||||
}
|
||||
else if (node->compound.literalType == LITERAL_ARRAY) {
|
||||
//ensure each literal value is in the cache, individually
|
||||
for (int i = 0; i < node->compound.count; i++) {
|
||||
//values
|
||||
int val = findLiteralIndex(&compiler->literalCache, node->compound.nodes[i].atomic.literal);
|
||||
if (val < 0) {
|
||||
val = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].atomic.literal);
|
||||
}
|
||||
|
||||
pushLiteralArray(store, TO_INTEGER_LITERAL(val));
|
||||
}
|
||||
|
||||
//push the store to the cache, with instructions about how pack it
|
||||
index = pushLiteralArray(&compiler->literalCache, TO_ARRAY_LITERAL(store));
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "[Internal] Unrecognized compound type in writeCompiler()");
|
||||
}
|
||||
int index = writeNodeCompoundToCache(compiler, node);
|
||||
|
||||
//push the node opcode to the bytecode
|
||||
if (index >= 256) {
|
||||
|
||||
@@ -271,6 +271,23 @@ int hashLiteral(Literal lit) {
|
||||
case LITERAL_STRING:
|
||||
return hashString(AS_STRING(lit), STRLEN(lit));
|
||||
|
||||
case LITERAL_ARRAY: {
|
||||
unsigned int res = 0;
|
||||
for (int i = 0; i < AS_DICTIONARY(lit)->count; i++) {
|
||||
res += hashLiteral(AS_ARRAY(lit)->literals[i]);
|
||||
}
|
||||
return hash(res);
|
||||
}
|
||||
|
||||
case LITERAL_DICTIONARY: {
|
||||
unsigned int res = 0;
|
||||
for (int i = 0; i < AS_DICTIONARY(lit)->count; i++) {
|
||||
res += hashLiteral(AS_DICTIONARY(lit)->entries[i].key);
|
||||
res += hashLiteral(AS_DICTIONARY(lit)->entries[i].value);
|
||||
}
|
||||
return hash(res);
|
||||
}
|
||||
|
||||
case LITERAL_IDENTIFIER:
|
||||
return hashString(AS_IDENTIFIER(lit), STRLEN_I(lit));
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@ typedef struct {
|
||||
#define AS_INTEGER(value) ((value).as.integer)
|
||||
#define AS_FLOAT(value) ((value).as.number)
|
||||
#define AS_STRING(value) ((value).as.string.ptr)
|
||||
#define AS_ARRAY(value) ((value).as.array)
|
||||
#define AS_DICTIONARY(value) ((value).as.dictionary)
|
||||
#define AS_ARRAY(value) ((LiteralArray*)((value).as.array))
|
||||
#define AS_DICTIONARY(value) ((LiteralDictionary*)((value).as.dictionary))
|
||||
// #define AS_FUNCTION(value)
|
||||
#define AS_IDENTIFIER(value) ((value).as.identifier.ptr)
|
||||
|
||||
|
||||
@@ -87,6 +87,14 @@ int findLiteralIndex(LiteralArray* array, Literal literal) {
|
||||
}
|
||||
continue;
|
||||
|
||||
// case LITERAL_ARRAY:
|
||||
// //
|
||||
// continue;
|
||||
|
||||
// case LITERAL_DICTIONARY:
|
||||
// //
|
||||
// continue;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "[Internal] Unexpected literal type in findLiteralIndex(): %d\n", literal.type);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user