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 [];
|
||||||
print [:];
|
print [:];
|
||||||
|
|
||||||
|
//recursive
|
||||||
|
print [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
|
||||||
|
|
||||||
//var arr : [int] = [1, 2, 3, 42];
|
//var arr : [int] = [1, 2, 3, 42];
|
||||||
//var dict : [string, int] = ["hello": 1, "world":2];
|
//var dict : [string, int] = ["hello": 1, "world":2];
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
print ["foo", "bar"];
|
print [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
|
||||||
print ["foo":1, "bar":2];
|
print [["foo":1]:["bar":2]];
|
||||||
|
|||||||
@@ -24,6 +24,110 @@ void initCompiler(Compiler* compiler) {
|
|||||||
pushLiteralArray(&compiler->literalCache, f);
|
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) {
|
void writeCompiler(Compiler* compiler, Node* node) {
|
||||||
//grow if the bytecode space is too small
|
//grow if the bytecode space is too small
|
||||||
if (compiler->capacity < compiler->count + 1) {
|
if (compiler->capacity < compiler->count + 1) {
|
||||||
@@ -95,53 +199,7 @@ void writeCompiler(Compiler* compiler, Node* node) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_COMPOUND: {
|
case NODE_COMPOUND: {
|
||||||
int index = -1;
|
int index = writeNodeCompoundToCache(compiler, node);
|
||||||
|
|
||||||
//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()");
|
|
||||||
}
|
|
||||||
|
|
||||||
//push the node opcode to the bytecode
|
//push the node opcode to the bytecode
|
||||||
if (index >= 256) {
|
if (index >= 256) {
|
||||||
|
|||||||
@@ -271,6 +271,23 @@ int hashLiteral(Literal lit) {
|
|||||||
case LITERAL_STRING:
|
case LITERAL_STRING:
|
||||||
return hashString(AS_STRING(lit), STRLEN(lit));
|
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:
|
case LITERAL_IDENTIFIER:
|
||||||
return hashString(AS_IDENTIFIER(lit), STRLEN_I(lit));
|
return hashString(AS_IDENTIFIER(lit), STRLEN_I(lit));
|
||||||
|
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ typedef struct {
|
|||||||
#define AS_INTEGER(value) ((value).as.integer)
|
#define AS_INTEGER(value) ((value).as.integer)
|
||||||
#define AS_FLOAT(value) ((value).as.number)
|
#define AS_FLOAT(value) ((value).as.number)
|
||||||
#define AS_STRING(value) ((value).as.string.ptr)
|
#define AS_STRING(value) ((value).as.string.ptr)
|
||||||
#define AS_ARRAY(value) ((value).as.array)
|
#define AS_ARRAY(value) ((LiteralArray*)((value).as.array))
|
||||||
#define AS_DICTIONARY(value) ((value).as.dictionary)
|
#define AS_DICTIONARY(value) ((LiteralDictionary*)((value).as.dictionary))
|
||||||
// #define AS_FUNCTION(value)
|
// #define AS_FUNCTION(value)
|
||||||
#define AS_IDENTIFIER(value) ((value).as.identifier.ptr)
|
#define AS_IDENTIFIER(value) ((value).as.identifier.ptr)
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,14 @@ int findLiteralIndex(LiteralArray* array, Literal literal) {
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// case LITERAL_ARRAY:
|
||||||
|
// //
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
// case LITERAL_DICTIONARY:
|
||||||
|
// //
|
||||||
|
// continue;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "[Internal] Unexpected literal type in findLiteralIndex(): %d\n", literal.type);
|
fprintf(stderr, "[Internal] Unexpected literal type in findLiteralIndex(): %d\n", literal.type);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user