mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Types are first-class citizens
This commit is contained in:
@@ -125,30 +125,30 @@ static int writeNodeCompoundToCache(Compiler* compiler, Node* node) {
|
||||
}
|
||||
|
||||
static int writeLiteralTypeToCache(LiteralArray* literalCache, Literal literal) {
|
||||
//I don't like storing types in an array, but it's the easiest and most straight forward method
|
||||
LiteralArray* store = ALLOCATE(LiteralArray, 1);
|
||||
initLiteralArray(store);
|
||||
|
||||
//store the base literal in the store
|
||||
pushLiteralArray(store, literal);
|
||||
|
||||
//if it's a compound type, recurse and store the results
|
||||
if (AS_TYPE(literal).typeOf == LITERAL_ARRAY || AS_TYPE(literal).typeOf == LITERAL_DICTIONARY) {
|
||||
//I don't like storing types in an array, but it's the easiest and most straight forward method
|
||||
LiteralArray* store = ALLOCATE(LiteralArray, 1);
|
||||
initLiteralArray(store);
|
||||
|
||||
//store the base literal in the store
|
||||
pushLiteralArray(store, literal);
|
||||
|
||||
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(literalCache, ((Literal*)(AS_TYPE(literal).subtypes))[i]);
|
||||
pushLiteralArray(store, TO_INTEGER_LITERAL(subIndex));
|
||||
}
|
||||
|
||||
//push the store to the cache, tweaking the type
|
||||
literal = TO_ARRAY_LITERAL(store);
|
||||
literal.type = LITERAL_TYPE_INTERMEDIATE; //NOTE: tweaking the type usually isn't a good idea
|
||||
}
|
||||
|
||||
//push the store to the cache, tweaking the type
|
||||
Literal lit = TO_ARRAY_LITERAL(store);
|
||||
lit.type = LITERAL_TYPE_INTERMEDIATE; //NOTE: tweaking the type usually isn't a good idea
|
||||
|
||||
//BUGFIX: check if exactly this literal array exists
|
||||
int index = findLiteralIndex(literalCache, lit);
|
||||
int index = findLiteralIndex(literalCache, literal);
|
||||
if (index < 0) {
|
||||
index = pushLiteralArray(literalCache, lit);
|
||||
index = pushLiteralArray(literalCache, literal);
|
||||
}
|
||||
|
||||
return index;
|
||||
@@ -253,7 +253,7 @@ static void writeCompilerWithJumps(Compiler* compiler, Node* node, void* breakAd
|
||||
fprintf(stderr, ERROR "[Internal] NODE_PAIR encountered in writeCompilerWithJumps()\n" RESET);
|
||||
break;
|
||||
|
||||
case NODE_VAR_TYPES: { //TODO: the "type" keyword
|
||||
case NODE_VAR_TYPES: { //TODO: remove this
|
||||
int index = writeLiteralTypeToCache(&compiler->literalCache, node->varTypes.typeLiteral);
|
||||
|
||||
//embed the info into the bytecode
|
||||
|
||||
@@ -364,6 +364,8 @@ static bool execVarDecl(Interpreter* interpreter, bool lng) {
|
||||
Literal identifier = interpreter->literalCache.literals[identifierIndex];
|
||||
Literal type = interpreter->literalCache.literals[typeIndex];
|
||||
|
||||
parseIdentifierToValue(interpreter, &type);
|
||||
|
||||
if (!declareScopeVariable(interpreter->scope, identifier, type)) {
|
||||
printf("Can't redefine the variable \"");
|
||||
printLiteral(identifier);
|
||||
@@ -711,7 +713,7 @@ static void execInterpreter(Interpreter* interpreter) {
|
||||
|
||||
case OP_VAR_DECL:
|
||||
case OP_VAR_DECL_LONG:
|
||||
if (!execVarDecl(interpreter, opcode == OP_LITERAL_LONG)) {
|
||||
if (!execVarDecl(interpreter, opcode == OP_VAR_DECL_LONG)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -206,6 +206,10 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) {
|
||||
printToBuffer("<");
|
||||
|
||||
switch(AS_TYPE(literal).typeOf) {
|
||||
case LITERAL_NULL:
|
||||
printToBuffer("null");
|
||||
break;
|
||||
|
||||
case LITERAL_BOOLEAN:
|
||||
printToBuffer("bool");
|
||||
break;
|
||||
@@ -261,7 +265,7 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) {
|
||||
|
||||
default:
|
||||
//should never be seen
|
||||
fprintf(stderr, "[Internal] Unrecognized literal type in print type: %d\n", literal.type);
|
||||
fprintf(stderr, "[Internal] Unrecognized literal type in print type: %d\n", AS_TYPE(literal).typeOf);
|
||||
}
|
||||
|
||||
//const (printed last)
|
||||
|
||||
@@ -1130,7 +1130,7 @@ static void statement(Parser* parser, Node** nodeHandle) {
|
||||
static Literal readTypeToLiteral(Parser* parser) {
|
||||
advance(parser);
|
||||
|
||||
Literal literal = TO_NULL_LITERAL;
|
||||
Literal literal = TO_TYPE_LITERAL(LITERAL_NULL, false);
|
||||
|
||||
switch(parser->previous.type) {
|
||||
case TOKEN_BOOLEAN:
|
||||
@@ -1177,6 +1177,26 @@ static Literal readTypeToLiteral(Parser* parser) {
|
||||
AS_TYPE(literal).typeOf = LITERAL_ANY;
|
||||
break;
|
||||
|
||||
//wtf
|
||||
case TOKEN_IDENTIFIER: {
|
||||
//duplicated from identifier()
|
||||
Token identifierToken = parser->previous;
|
||||
int length = identifierToken.length;
|
||||
//for safety
|
||||
if (length > 256) {
|
||||
length = 256;
|
||||
error(parser, parser->previous, "Identifiers can only be a maximum of 256 characters long");
|
||||
}
|
||||
char* cpy = copyString(identifierToken.lexeme, length);
|
||||
literal = _toIdentifierLiteral(cpy, strlen(cpy)); //BUGFIX: use this instead of the macro
|
||||
}
|
||||
break;
|
||||
|
||||
//WTF
|
||||
case TOKEN_TYPE:
|
||||
AS_TYPE(literal).typeOf = LITERAL_TYPE;
|
||||
break;
|
||||
|
||||
default:
|
||||
error(parser, parser->previous, "Bad type signature");
|
||||
return TO_NULL_LITERAL;
|
||||
|
||||
@@ -28,6 +28,11 @@ static bool checkType(Literal typeLiteral, Literal value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//don't allow null types
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//for each type, if a mismatch is found, return false
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_BOOLEAN && !IS_BOOLEAN(value)) {
|
||||
return false;
|
||||
@@ -80,7 +85,11 @@ static bool checkType(Literal typeLiteral, Literal value) {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: functions
|
||||
//TODO: function type checking
|
||||
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_TYPE && !IS_TYPE(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user