mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
I think var declarations are working correctly; no type checking yet
This commit is contained in:
@@ -1 +1,2 @@
|
|||||||
var name : [string const, int] = ["foo" : 42];
|
var name : [string const, int] = ["foo" : 42];
|
||||||
|
var something = 0;
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ static int writeNodeCompoundToCache(Compiler* compiler, Node* node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//push the store to the cache, with instructions about how pack it
|
//push the store to the cache, with instructions about how pack it
|
||||||
index = pushLiteralArray(&compiler->literalCache, TO_DICTIONARY_LITERAL(store)); //pushed as an array, so below can recognize it
|
index = pushLiteralArray(&compiler->literalCache, TO_ARRAY_LITERAL(store)); //WARNING: pushed as a dictionary, so below can recognize it
|
||||||
}
|
}
|
||||||
else if (node->compound.literalType == LITERAL_ARRAY) {
|
else if (node->compound.literalType == LITERAL_ARRAY) {
|
||||||
//ensure each literal value is in the cache, individually
|
//ensure each literal value is in the cache, individually
|
||||||
@@ -135,24 +135,25 @@ static int writeLiteralTypeToCache(LiteralArray* parent, Literal literal) {
|
|||||||
LiteralArray* store = ALLOCATE(LiteralArray, 1);
|
LiteralArray* store = ALLOCATE(LiteralArray, 1);
|
||||||
initLiteralArray(store);
|
initLiteralArray(store);
|
||||||
|
|
||||||
//save the mask to the store
|
//save the mask to the store, at index 0
|
||||||
int maskIndex = findLiteralIndex(parent, TO_INTEGER_LITERAL(AS_TYPE(literal).mask));
|
int maskIndex = findLiteralIndex(store, TO_INTEGER_LITERAL(AS_TYPE(literal).mask));
|
||||||
if (maskIndex < 0) {
|
if (maskIndex < 0) {
|
||||||
maskIndex = pushLiteralArray(parent, TO_INTEGER_LITERAL(AS_TYPE(literal).mask));
|
maskIndex = pushLiteralArray(store, TO_INTEGER_LITERAL(AS_TYPE(literal).mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
pushLiteralArray(store, TO_INTEGER_LITERAL(maskIndex));
|
|
||||||
|
|
||||||
//if it's a compound type, recurse
|
//if it's a compound type, recurse
|
||||||
if (AS_TYPE(literal).mask & (MASK_ARRAY|MASK_DICTIONARY)) {
|
if (AS_TYPE(literal).mask & (MASK_ARRAY|MASK_DICTIONARY)) {
|
||||||
for (int i = 0; i < AS_TYPE(literal).count; i++) {
|
for (int i = 0; i < AS_TYPE(literal).count; i++) {
|
||||||
|
//write the values to the cache, and the indexes to the store
|
||||||
int subIndex = writeLiteralTypeToCache(parent, ((Literal*)(AS_TYPE(literal).subtypes))[i]);
|
int subIndex = writeLiteralTypeToCache(parent, ((Literal*)(AS_TYPE(literal).subtypes))[i]);
|
||||||
pushLiteralArray(store, TO_INTEGER_LITERAL(subIndex));
|
pushLiteralArray(store, TO_INTEGER_LITERAL(subIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//push the store to the parent
|
//push the store to the cache, tweaking the type
|
||||||
index = pushLiteralArray(parent, TO_ARRAY_LITERAL(store));
|
Literal lit = TO_ARRAY_LITERAL(store);
|
||||||
|
lit.type = LITERAL_TYPE; //TODO: tweaking the type isn't a good idea
|
||||||
|
index = pushLiteralArray(parent, lit);
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,14 +80,14 @@ static char* readString(unsigned char* tb, int* count) {
|
|||||||
|
|
||||||
static void consumeByte(unsigned char byte, unsigned char* tb, int* count) {
|
static void consumeByte(unsigned char byte, unsigned char* tb, int* count) {
|
||||||
if (byte != tb[*count]) {
|
if (byte != tb[*count]) {
|
||||||
printf("[internal] Failed to consume the correct byte\n");
|
printf("[internal] Failed to consume the correct byte (expected %u, found %u)\n", byte, tb[*count]);
|
||||||
}
|
}
|
||||||
*count += 1;
|
*count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void consumeShort(unsigned short bytes, unsigned char* tb, int* count) {
|
static void consumeShort(unsigned short bytes, unsigned char* tb, int* count) {
|
||||||
if (bytes != *(unsigned short*)(tb + *count)) {
|
if (bytes != *(unsigned short*)(tb + *count)) {
|
||||||
printf("[internal] Failed to consume the correct bytes\n");
|
printf("[internal] Failed to consume the correct bytes (expected %u, found %u)\n", bytes, *(unsigned short*)(tb + *count));
|
||||||
}
|
}
|
||||||
*count += 2;
|
*count += 2;
|
||||||
}
|
}
|
||||||
@@ -497,7 +497,7 @@ void runInterpreter(Interpreter* interpreter) {
|
|||||||
pushLiteralArray(&interpreter->literalCache, identifier);
|
pushLiteralArray(&interpreter->literalCache, identifier);
|
||||||
|
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(identifier %s)\n", AS_IDENTIFIER(identifier));
|
printf("(identifier %s (%d))\n", AS_IDENTIFIER(identifier), identifier.as.identifier.hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -505,22 +505,36 @@ void runInterpreter(Interpreter* interpreter) {
|
|||||||
case LITERAL_TYPE: {
|
case LITERAL_TYPE: {
|
||||||
Literal typeLiteral;
|
Literal typeLiteral;
|
||||||
|
|
||||||
// read the mask
|
//read the array count (subtract 1, because mask is always present)
|
||||||
unsigned char mask = readByte(interpreter->bytecode, &interpreter->count);
|
unsigned short count = readShort(interpreter->bytecode, &interpreter->count) - 1;
|
||||||
|
|
||||||
|
// read the mask
|
||||||
|
unsigned char mask = readShort(interpreter->bytecode, &interpreter->count);
|
||||||
|
|
||||||
|
//create the literal
|
||||||
typeLiteral = TO_TYPE_LITERAL(mask);
|
typeLiteral = TO_TYPE_LITERAL(mask);
|
||||||
|
|
||||||
AS_TYPE(typeLiteral).count = readShort(interpreter->bytecode, &interpreter->count);
|
|
||||||
|
|
||||||
//if it's got subtypes, grab them from the existing cache
|
//if it's got subtypes, grab them from the existing cache
|
||||||
if (AS_TYPE(typeLiteral).count > 0) {
|
if (count > 0) {
|
||||||
AS_TYPE(typeLiteral).subtypes = ALLOCATE(Literal, AS_TYPE(typeLiteral).count);
|
AS_TYPE(typeLiteral).subtypes = ALLOCATE(Literal, count);
|
||||||
|
AS_TYPE(typeLiteral).capacity = count;
|
||||||
|
AS_TYPE(typeLiteral).count = count;
|
||||||
|
|
||||||
for (int i = 0; i < AS_TYPE(typeLiteral).count; i++) {
|
for (int i = 0; i < AS_TYPE(typeLiteral).count; i++) {
|
||||||
//read each index
|
//read each index
|
||||||
int index = readShort(interpreter->bytecode, &interpreter->count);
|
int index = readShort(interpreter->bytecode, &interpreter->count);
|
||||||
((Literal*)(AS_TYPE(typeLiteral).subtypes))[i] = interpreter->literalCache.literals[index];
|
((Literal*)(AS_TYPE(typeLiteral).subtypes))[i] = interpreter->literalCache.literals[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//save the type
|
||||||
|
pushLiteralArray(&interpreter->literalCache, typeLiteral);
|
||||||
|
|
||||||
|
if (command.verbose) {
|
||||||
|
printf("(type ");
|
||||||
|
printLiteral(typeLiteral);
|
||||||
|
printf(")\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) {
|
|||||||
int delimCount = 0;
|
int delimCount = 0;
|
||||||
printToBuffer("[");
|
printToBuffer("[");
|
||||||
for (int i = 0; i < ptr->capacity; i++) {
|
for (int i = 0; i < ptr->capacity; i++) {
|
||||||
if (ptr->entries[i].key.type == LITERAL_NULL) {
|
if (IS_NULL(ptr->entries[i].key)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) {
|
|||||||
|
|
||||||
for (int i = 1; i < 8; i ++) { //0th bit is const
|
for (int i = 1; i < 8; i ++) { //0th bit is const
|
||||||
//zero mask = any type, anys can't be const
|
//zero mask = any type, anys can't be const
|
||||||
if (AS_TYPE(literal).mask == 0) {
|
if (AS_TYPE(literal).mask == MASK_ANY) {
|
||||||
printToBuffer("any");
|
printToBuffer("any");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) {
|
|||||||
printToBuffer(" | ");
|
printToBuffer(" | ");
|
||||||
}
|
}
|
||||||
|
|
||||||
//special case for array & dictionary
|
//special case for array AND dictionary
|
||||||
if (i == TYPE_ARRAY) {
|
if (i == TYPE_ARRAY) {
|
||||||
if ((AS_TYPE(literal).mask & (MASK_ARRAY|MASK_DICTIONARY)) == (MASK_ARRAY|MASK_DICTIONARY)) {
|
if ((AS_TYPE(literal).mask & (MASK_ARRAY|MASK_DICTIONARY)) == (MASK_ARRAY|MASK_DICTIONARY)) {
|
||||||
int pCache = printTypeMarker;
|
int pCache = printTypeMarker;
|
||||||
@@ -357,8 +357,8 @@ Literal _toStringLiteral(char* str) {
|
|||||||
return ((Literal){LITERAL_STRING, {.string.ptr = (char*)str, .string.length = strlen((char*)str)}});
|
return ((Literal){LITERAL_STRING, {.string.ptr = (char*)str, .string.length = strlen((char*)str)}});
|
||||||
}
|
}
|
||||||
|
|
||||||
Literal _toIdentifierLiteral(char* str) {
|
Literal _toIdentifierLiteral(char* str, int length) {
|
||||||
return ((Literal){LITERAL_IDENTIFIER,{.identifier.ptr = (char*)str,.identifier.length = strlen((char*)str), .identifier.hash=hashString(str, strlen((char*)str))}});
|
return ((Literal){LITERAL_IDENTIFIER,{.identifier.ptr = (char*)str,.identifier.length = length, .identifier.hash = hashString(str, length)}});
|
||||||
}
|
}
|
||||||
|
|
||||||
Literal* _typePushSubtype(Literal* lit, unsigned char submask) {
|
Literal* _typePushSubtype(Literal* lit, unsigned char submask) {
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ typedef struct {
|
|||||||
#define TO_ARRAY_LITERAL(value) ((Literal){LITERAL_ARRAY, { .array = value }})
|
#define TO_ARRAY_LITERAL(value) ((Literal){LITERAL_ARRAY, { .array = value }})
|
||||||
#define TO_DICTIONARY_LITERAL(value) ((Literal){LITERAL_DICTIONARY, { .dictionary = value }})
|
#define TO_DICTIONARY_LITERAL(value) ((Literal){LITERAL_DICTIONARY, { .dictionary = value }})
|
||||||
// #define TO_FUNCTION_LITERAL
|
// #define TO_FUNCTION_LITERAL
|
||||||
#define TO_IDENTIFIER_LITERAL(value) _toIdentifierLiteral(value)
|
#define TO_IDENTIFIER_LITERAL(value) _toIdentifierLiteral(value, strlen(value))
|
||||||
#define TO_TYPE_LITERAL(value) ((Literal){ LITERAL_TYPE, { .type.mask = value, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }})
|
#define TO_TYPE_LITERAL(value) ((Literal){ LITERAL_TYPE, { .type.mask = value, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }})
|
||||||
|
|
||||||
#define MASK(x) (1 << (x))
|
#define MASK(x) (1 << (x))
|
||||||
@@ -114,7 +114,7 @@ void freeLiteral(Literal literal);
|
|||||||
//BUGFIX: macros are not functions
|
//BUGFIX: macros are not functions
|
||||||
bool _isTruthy(Literal x);
|
bool _isTruthy(Literal x);
|
||||||
Literal _toStringLiteral(char* str);
|
Literal _toStringLiteral(char* str);
|
||||||
Literal _toIdentifierLiteral(char* str);
|
Literal _toIdentifierLiteral(char* str, int length);
|
||||||
Literal* _typePushSubtype(Literal* lit, unsigned char submask);
|
Literal* _typePushSubtype(Literal* lit, unsigned char submask);
|
||||||
|
|
||||||
//utils
|
//utils
|
||||||
|
|||||||
@@ -20,10 +20,13 @@ int pushLiteralArray(LiteralArray* array, Literal literal) {
|
|||||||
array->literals = GROW_ARRAY(Literal, array->literals, oldCapacity, array->capacity);
|
array->literals = GROW_ARRAY(Literal, array->literals, oldCapacity, array->capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if it's a string, make a local copy
|
//if it's a string or an identifier, make a local copy
|
||||||
if (IS_STRING(literal)) {
|
if (IS_STRING(literal)) {
|
||||||
literal = TO_STRING_LITERAL(copyString(AS_STRING(literal), STRLEN(literal)));
|
literal = TO_STRING_LITERAL(copyString(AS_STRING(literal), STRLEN(literal)));
|
||||||
}
|
}
|
||||||
|
if (IS_IDENTIFIER(literal)) {
|
||||||
|
literal = TO_IDENTIFIER_LITERAL(copyString(AS_IDENTIFIER(literal), STRLEN_I(literal)));
|
||||||
|
}
|
||||||
|
|
||||||
array->literals[array->count] = literal;
|
array->literals[array->count] = literal;
|
||||||
return array->count++;
|
return array->count++;
|
||||||
@@ -58,45 +61,9 @@ int findLiteralIndex(LiteralArray* array, Literal literal) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//matching type, compare values
|
//types match?
|
||||||
switch(array->literals[i].type) {
|
if (literalsAreEqual(array->literals[i], literal)) {
|
||||||
case LITERAL_NULL:
|
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
case LITERAL_BOOLEAN:
|
|
||||||
if (AS_BOOLEAN(array->literals[i]) == AS_BOOLEAN(literal)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case LITERAL_INTEGER:
|
|
||||||
if (AS_INTEGER(array->literals[i]) == AS_INTEGER(literal)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case LITERAL_FLOAT:
|
|
||||||
if (AS_FLOAT(array->literals[i]) == AS_FLOAT(literal)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case LITERAL_STRING:
|
|
||||||
if (strncmp(AS_STRING(array->literals[i]), AS_STRING(literal), STRLEN(literal)) == 0) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// case LITERAL_ARRAY:
|
|
||||||
// //
|
|
||||||
// continue;
|
|
||||||
|
|
||||||
// case LITERAL_DICTIONARY:
|
|
||||||
// //
|
|
||||||
// continue;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "[Internal] Unexpected literal type in findLiteralIndex(): %d\n", literal.type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
#include "literal.h"
|
#include "literal.h"
|
||||||
|
|
||||||
typedef struct LiteralArray {
|
typedef struct LiteralArray {
|
||||||
|
Literal* literals;
|
||||||
int capacity;
|
int capacity;
|
||||||
int count;
|
int count;
|
||||||
Literal* literals;
|
|
||||||
} LiteralArray;
|
} LiteralArray;
|
||||||
|
|
||||||
void initLiteralArray(LiteralArray* array);
|
void initLiteralArray(LiteralArray* array);
|
||||||
|
|||||||
@@ -107,6 +107,21 @@ static bool setEntryArray(_entry** dictionaryHandle, int* capacityPtr, int count
|
|||||||
|
|
||||||
_entry* entry = getEntryArray(*dictionaryHandle, *capacityPtr, key, hash, false);
|
_entry* entry = getEntryArray(*dictionaryHandle, *capacityPtr, key, hash, false);
|
||||||
|
|
||||||
|
//if it's a string or an identifier, make a local copy
|
||||||
|
if (IS_STRING(key)) {
|
||||||
|
key = TO_STRING_LITERAL(copyString(AS_STRING(key), STRLEN(key)));
|
||||||
|
}
|
||||||
|
if (IS_IDENTIFIER(key)) {
|
||||||
|
key = TO_IDENTIFIER_LITERAL(copyString(AS_IDENTIFIER(key), STRLEN_I(key)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_STRING(value)) {
|
||||||
|
value = TO_STRING_LITERAL(copyString(AS_STRING(value), STRLEN(value)));
|
||||||
|
}
|
||||||
|
if (IS_IDENTIFIER(value)) {
|
||||||
|
value = TO_IDENTIFIER_LITERAL(copyString(AS_IDENTIFIER(value), STRLEN_I(value)));
|
||||||
|
}
|
||||||
|
|
||||||
//true = count increase
|
//true = count increase
|
||||||
if (IS_NULL(entry->key)) {
|
if (IS_NULL(entry->key)) {
|
||||||
setEntryValues(entry, key, value);
|
setEntryValues(entry, key, value);
|
||||||
|
|||||||
@@ -760,26 +760,24 @@ static Literal readTypeToLiteral(Parser* parser) {
|
|||||||
if (match(parser, TOKEN_COMMA)) {
|
if (match(parser, TOKEN_COMMA)) {
|
||||||
Literal r = readTypeToLiteral(parser);
|
Literal r = readTypeToLiteral(parser);
|
||||||
|
|
||||||
//dictionary
|
AS_TYPE(literal).subtypes = ALLOCATE(Literal, 2);
|
||||||
Literal* dict = TYPE_PUSH_SUBTYPE(&literal, MASK_DICTIONARY);
|
AS_TYPE(literal).capacity = 2;
|
||||||
|
AS_TYPE(literal).count = 2;
|
||||||
|
|
||||||
AS_TYPE(*dict).subtypes = ALLOCATE(Literal, 2);
|
((Literal*)(AS_TYPE(literal).subtypes))[0] = l;
|
||||||
AS_TYPE(*dict).capacity = 2;
|
((Literal*)(AS_TYPE(literal).subtypes))[1] = r;
|
||||||
AS_TYPE(*dict).count = 2;
|
|
||||||
|
|
||||||
((Literal*)(AS_TYPE(*dict).subtypes))[0] = l;
|
AS_TYPE(literal).mask |= MASK_DICTIONARY;
|
||||||
((Literal*)(AS_TYPE(*dict).subtypes))[1] = r;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//array
|
AS_TYPE(literal).subtypes = ALLOCATE(Literal, 1);
|
||||||
Literal* arr = TYPE_PUSH_SUBTYPE(&literal, MASK_ARRAY);
|
AS_TYPE(literal).capacity = 1;
|
||||||
|
AS_TYPE(literal).count = 1;
|
||||||
AS_TYPE(*arr).subtypes = ALLOCATE(Literal, 1);
|
|
||||||
AS_TYPE(*arr).capacity = 1;
|
|
||||||
AS_TYPE(*arr).count = 1;
|
|
||||||
|
|
||||||
//append the "l" literal
|
//append the "l" literal
|
||||||
((Literal*)(AS_TYPE(*arr).subtypes))[0] = l;
|
((Literal*)(AS_TYPE(literal).subtypes))[0] = l;
|
||||||
|
|
||||||
|
AS_TYPE(literal).mask |= MASK_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
consume(parser, TOKEN_BRACKET_RIGHT, "Expected ']' at end of type definition");
|
consume(parser, TOKEN_BRACKET_RIGHT, "Expected ']' at end of type definition");
|
||||||
@@ -806,14 +804,17 @@ static void varDecl(Parser* parser, Node** nodeHandle) {
|
|||||||
consume(parser, TOKEN_IDENTIFIER, "Expected identifier after var keyword");
|
consume(parser, TOKEN_IDENTIFIER, "Expected identifier after var keyword");
|
||||||
Token identifierToken = parser->previous;
|
Token identifierToken = parser->previous;
|
||||||
|
|
||||||
Literal identifier = TO_IDENTIFIER_LITERAL(identifierToken.lexeme);
|
char* cpy = copyString(identifierToken.lexeme, identifierToken.length);
|
||||||
identifier.as.identifier.length = identifierToken.length; //BUGFIX
|
Literal identifier = _toIdentifierLiteral(cpy, strlen(cpy)); //BUGFIX: use this instead of the macro
|
||||||
|
|
||||||
//read the type, if present
|
//read the type, if present
|
||||||
Literal typeLiteral;
|
Literal typeLiteral;
|
||||||
if (match(parser, TOKEN_COLON)) {
|
if (match(parser, TOKEN_COLON)) {
|
||||||
typeLiteral = readTypeToLiteral(parser);
|
typeLiteral = readTypeToLiteral(parser);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
typeLiteral = TO_TYPE_LITERAL(MASK_ANY);
|
||||||
|
}
|
||||||
|
|
||||||
//variable definition is an expression
|
//variable definition is an expression
|
||||||
Node* expressionNode = NULL;
|
Node* expressionNode = NULL;
|
||||||
|
|||||||
@@ -106,17 +106,40 @@ void runBinary(unsigned char* tb, size_t size) {
|
|||||||
initInterpreter(&interpreter, tb, size);
|
initInterpreter(&interpreter, tb, size);
|
||||||
runInterpreter(&interpreter);
|
runInterpreter(&interpreter);
|
||||||
|
|
||||||
//DEBUG
|
// //DEBUG
|
||||||
Literal lit;
|
// {
|
||||||
|
// printf("testing name\n");
|
||||||
|
// Literal lit;
|
||||||
|
|
||||||
printf("DEBUG> ");
|
// printf("VALUE: ");
|
||||||
if (getScopeVariable(interpreter.scope, TO_IDENTIFIER_LITERAL("name"), &lit)) {
|
// if (getScopeVariable(interpreter.scope, TO_IDENTIFIER_LITERAL("name"), &lit)) {
|
||||||
printLiteral(lit);
|
// printLiteral(lit);
|
||||||
}
|
|
||||||
else {
|
// printf("\nTYPE: ");
|
||||||
printf("Failed");
|
// printLiteral(getLiteralDictionary(&interpreter.scope->types, TO_IDENTIFIER_LITERAL("name")));
|
||||||
}
|
// }
|
||||||
printf("\n");
|
// else {
|
||||||
|
// printf("Failed");
|
||||||
|
// }
|
||||||
|
// printf("\n\n");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// {
|
||||||
|
// printf("testing something\n");
|
||||||
|
// Literal lit;
|
||||||
|
|
||||||
|
// printf("VALUE: ");
|
||||||
|
// if (getScopeVariable(interpreter.scope, TO_IDENTIFIER_LITERAL("something"), &lit)) {
|
||||||
|
// printLiteral(lit);
|
||||||
|
|
||||||
|
// printf("\nTYPE: ");
|
||||||
|
// printLiteral(getLiteralDictionary(&interpreter.scope->types, TO_IDENTIFIER_LITERAL("something")));
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// printf("Failed");
|
||||||
|
// }
|
||||||
|
// printf("\n\n");
|
||||||
|
// }
|
||||||
|
|
||||||
freeInterpreter(&interpreter);
|
freeInterpreter(&interpreter);
|
||||||
}
|
}
|
||||||
@@ -262,32 +285,5 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
repl();
|
repl();
|
||||||
|
|
||||||
// //testing the types, improving on them as I go
|
|
||||||
// Literal root = TO_TYPE_LITERAL( MASK_ARRAY | MASK_DICTIONARY | MASK_INTEGER | MASK_FLOAT );
|
|
||||||
// Literal* arr = TYPE_PUSH_SUBTYPE(&root, MASK_ARRAY );
|
|
||||||
// Literal* dict = TYPE_PUSH_SUBTYPE(&root, MASK_DICTIONARY );
|
|
||||||
|
|
||||||
// TYPE_PUSH_SUBTYPE(arr, MASK_INTEGER );
|
|
||||||
// TYPE_PUSH_SUBTYPE(arr, MASK_FLOAT );
|
|
||||||
// TYPE_PUSH_SUBTYPE(arr, MASK_INTEGER | MASK_FLOAT );
|
|
||||||
|
|
||||||
// TYPE_PUSH_SUBTYPE(dict, MASK_STRING | MASK_CONST );
|
|
||||||
// TYPE_PUSH_SUBTYPE(dict, MASK_FLOAT );
|
|
||||||
|
|
||||||
// TYPE_PUSH_SUBTYPE(dict, MASK_STRING | MASK_CONST );
|
|
||||||
// TYPE_PUSH_SUBTYPE(dict, MASK_INTEGER );
|
|
||||||
|
|
||||||
// TYPE_PUSH_SUBTYPE(dict, MASK_STRING | MASK_CONST );
|
|
||||||
// TYPE_PUSH_SUBTYPE(dict, MASK_INTEGER | MASK_FLOAT );
|
|
||||||
|
|
||||||
// printLiteral(root);
|
|
||||||
// printf("\n");
|
|
||||||
|
|
||||||
// Literal any = TO_TYPE_LITERAL(MASK_ANY);
|
|
||||||
|
|
||||||
// printLiteral(any);
|
|
||||||
|
|
||||||
//output: <int | float | [int] | [float] | [int | float] | [string const:float] | [string const:int] | [string const:int | float]>
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ static void freeAncestorChain(Scope* scope) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
freeLiteralDictionary(&scope->variables);
|
freeLiteralDictionary(&scope->variables);
|
||||||
|
freeLiteralDictionary(&scope->types);
|
||||||
|
|
||||||
FREE(Scope, scope);
|
FREE(Scope, scope);
|
||||||
}
|
}
|
||||||
@@ -25,6 +26,7 @@ Scope* pushScope(Scope* ancestor) {
|
|||||||
Scope* scope = ALLOCATE(Scope, 1);
|
Scope* scope = ALLOCATE(Scope, 1);
|
||||||
scope->ancestor = ancestor;
|
scope->ancestor = ancestor;
|
||||||
initLiteralDictionary(&scope->variables);
|
initLiteralDictionary(&scope->variables);
|
||||||
|
initLiteralDictionary(&scope->types);
|
||||||
|
|
||||||
//tick up all scope reference counts
|
//tick up all scope reference counts
|
||||||
scope->references = 0;
|
scope->references = 0;
|
||||||
@@ -46,7 +48,7 @@ Scope* popScope(Scope* scope) {
|
|||||||
//returns false if error
|
//returns false if error
|
||||||
bool declareScopeVariable(Scope* scope, Literal key, Literal type) {
|
bool declareScopeVariable(Scope* scope, Literal key, Literal type) {
|
||||||
//store the type, for later checking on assignment
|
//store the type, for later checking on assignment
|
||||||
//TODO
|
setLiteralDictionary(&scope->types, key, type);
|
||||||
|
|
||||||
//don't redefine a variable within this scope
|
//don't redefine a variable within this scope
|
||||||
if (existsLiteralDictionary(&scope->variables, key)) {
|
if (existsLiteralDictionary(&scope->variables, key)) {
|
||||||
@@ -64,6 +66,8 @@ bool setScopeVariable(Scope* scope, Literal key, Literal value) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: type checking
|
||||||
|
|
||||||
//if it's not in this scope, keep searching up the chain
|
//if it's not in this scope, keep searching up the chain
|
||||||
if (!existsLiteralDictionary(&scope->variables, key)) {
|
if (!existsLiteralDictionary(&scope->variables, key)) {
|
||||||
return setScopeVariable(scope->ancestor, key, value);
|
return setScopeVariable(scope->ancestor, key, value);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
typedef struct Scope {
|
typedef struct Scope {
|
||||||
LiteralDictionary variables; //only allow identifiers as the keys
|
LiteralDictionary variables; //only allow identifiers as the keys
|
||||||
|
LiteralDictionary types; //the types, indexed by identifiers
|
||||||
struct Scope* ancestor;
|
struct Scope* ancestor;
|
||||||
int references; //how many scopes point here
|
int references; //how many scopes point here
|
||||||
} Scope;
|
} Scope;
|
||||||
|
|||||||
Reference in New Issue
Block a user