mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
Types are first-class citizens
This commit is contained in:
11
docs/spec.md
11
docs/spec.md
@@ -87,6 +87,7 @@ Variable names in Toy may have a type. These types are:
|
||||
* dictionary - a collection of indexable key-value pairs
|
||||
* function - chunks of reusable code
|
||||
* any - any of the above
|
||||
* type - the type of types
|
||||
|
||||
Types are optional attachments to names - they can be specified as such:
|
||||
|
||||
@@ -102,13 +103,21 @@ Types are not interoperable, but in some cases they can be converted from one ty
|
||||
var y : float = (float)x;
|
||||
```
|
||||
|
||||
defining the type of a variable is not required - in such a case, the type is "any".
|
||||
Defining the type of a variable is not required - in such a case, the type is "any".
|
||||
|
||||
```
|
||||
//define the variable named "v" with any type
|
||||
var z = 1;
|
||||
```
|
||||
|
||||
Variables are first-class citizens, meaning they can be stored in and used from variables:
|
||||
|
||||
```
|
||||
//this was originally unintended, but interesting
|
||||
var t: type = int;
|
||||
var u: t = 42;
|
||||
```
|
||||
|
||||
## Const
|
||||
|
||||
The "const" keyword can be appended to the type of a variable to fix the value in place - constants, as they're known, can't be changed once they are given a value at declaration.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
|
||||
//BUG: this causes a strange error message
|
||||
if (true);
|
||||
else;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
print [
|
||||
var arr: [string] = [
|
||||
|
||||
"0",
|
||||
"1",
|
||||
@@ -335,3 +335,5 @@ print [
|
||||
"299"
|
||||
|
||||
];
|
||||
|
||||
print arr;
|
||||
@@ -1,2 +1,4 @@
|
||||
//NOTE: dictionaries are NOT stored in order
|
||||
print ["0":"0","1":"1","2":"2","3":"3","4":"4","5":"5","6":"6","7":"7","8":"8","9":"9","10":"10","11":"11","12":"12","13":"13","14":"14","15":"15","16":"16","17":"17","18":"18","19":"19","20":"20","21":"21","22":"22","23":"23","24":"24","25":"25","26":"26","27":"27","28":"28","29":"29","30":"30","31":"31","32":"32","33":"33","34":"34","35":"35","36":"36","37":"37","38":"38","39":"39","40":"40","41":"41","42":"42","43":"43","44":"44","45":"45","46":"46","47":"47","48":"48","49":"49","50":"50","51":"51","52":"52","53":"53","54":"54","55":"55","56":"56","57":"57","58":"58","59":"59","60":"60","61":"61","62":"62","63":"63","64":"64","65":"65","66":"66","67":"67","68":"68","69":"69","70":"70","71":"71","72":"72","73":"73","74":"74","75":"75","76":"76","77":"77","78":"78","79":"79","80":"80","81":"81","82":"82","83":"83","84":"84","85":"85","86":"86","87":"87","88":"88","89":"89","90":"90","91":"91","92":"92","93":"93","94":"94","95":"95","96":"96","97":"97","98":"98","99":"99","100":"100","101":"101","102":"102","103":"103","104":"104","105":"105","106":"106","107":"107","108":"108","109":"109","110":"110","111":"111","112":"112","113":"113","114":"114","115":"115","116":"116","117":"117","118":"118","119":"119","120":"120","121":"121","122":"122","123":"123","124":"124","125":"125","126":"126","127":"127","128":"128","129":"129","130":"130","131":"131","132":"132","133":"133","134":"134","135":"135","136":"136","137":"137","138":"138","139":"139","140":"140","141":"141","142":"142","143":"143","144":"144","145":"145","146":"146","147":"147","148":"148","149":"149","150":"150","151":"151","152":"152","153":"153","154":"154","155":"155","156":"156","157":"157","158":"158","159":"159","160":"160","161":"161","162":"162","163":"163","164":"164","165":"165","166":"166","167":"167","168":"168","169":"169","170":"170","171":"171","172":"172","173":"173","174":"174","175":"175","176":"176","177":"177","178":"178","179":"179","180":"180","181":"181","182":"182","183":"183","184":"184","185":"185","186":"186","187":"187","188":"188","189":"189","190":"190","191":"191","192":"192","193":"193","194":"194","195":"195","196":"196","197":"197","198":"198","199":"199","200":"200","201":"201","202":"202","203":"203","204":"204","205":"205","206":"206","207":"207","208":"208","209":"209","210":"210","211":"211","212":"212","213":"213","214":"214","215":"215","216":"216","217":"217","218":"218","219":"219","220":"220","221":"221","222":"222","223":"223","224":"224","225":"225","226":"226","227":"227","228":"228","229":"229","230":"230","231":"231","232":"232","233":"233","234":"234","235":"235","236":"236","237":"237","238":"238","239":"239","240":"240","241":"241","242":"242","243":"243","244":"244","245":"245","246":"246","247":"247","248":"248","249":"249","250":"250","251":"251","252":"252","253":"253","254":"254","255":"255","256":"256","257":"257","258":"258","259":"259","260":"260","261":"261","262":"262","263":"263","264":"264","265":"265","266":"266","267":"267","268":"268","269":"269","270":"270","271":"271","272":"272","273":"273","274":"274","275":"275","276":"276","277":"277","278":"278","279":"279","280":"280","281":"281","282":"282","283":"283","284":"284","285":"285","286":"286","287":"287","288":"288","289":"289","290":"290","291":"291","292":"292","293":"293","294":"294","295":"295","296":"296","297":"297","298":"298","299":"299"];
|
||||
var dict: [string, string] = ["0":"0","1":"1","2":"2","3":"3","4":"4","5":"5","6":"6","7":"7","8":"8","9":"9","10":"10","11":"11","12":"12","13":"13","14":"14","15":"15","16":"16","17":"17","18":"18","19":"19","20":"20","21":"21","22":"22","23":"23","24":"24","25":"25","26":"26","27":"27","28":"28","29":"29","30":"30","31":"31","32":"32","33":"33","34":"34","35":"35","36":"36","37":"37","38":"38","39":"39","40":"40","41":"41","42":"42","43":"43","44":"44","45":"45","46":"46","47":"47","48":"48","49":"49","50":"50","51":"51","52":"52","53":"53","54":"54","55":"55","56":"56","57":"57","58":"58","59":"59","60":"60","61":"61","62":"62","63":"63","64":"64","65":"65","66":"66","67":"67","68":"68","69":"69","70":"70","71":"71","72":"72","73":"73","74":"74","75":"75","76":"76","77":"77","78":"78","79":"79","80":"80","81":"81","82":"82","83":"83","84":"84","85":"85","86":"86","87":"87","88":"88","89":"89","90":"90","91":"91","92":"92","93":"93","94":"94","95":"95","96":"96","97":"97","98":"98","99":"99","100":"100","101":"101","102":"102","103":"103","104":"104","105":"105","106":"106","107":"107","108":"108","109":"109","110":"110","111":"111","112":"112","113":"113","114":"114","115":"115","116":"116","117":"117","118":"118","119":"119","120":"120","121":"121","122":"122","123":"123","124":"124","125":"125","126":"126","127":"127","128":"128","129":"129","130":"130","131":"131","132":"132","133":"133","134":"134","135":"135","136":"136","137":"137","138":"138","139":"139","140":"140","141":"141","142":"142","143":"143","144":"144","145":"145","146":"146","147":"147","148":"148","149":"149","150":"150","151":"151","152":"152","153":"153","154":"154","155":"155","156":"156","157":"157","158":"158","159":"159","160":"160","161":"161","162":"162","163":"163","164":"164","165":"165","166":"166","167":"167","168":"168","169":"169","170":"170","171":"171","172":"172","173":"173","174":"174","175":"175","176":"176","177":"177","178":"178","179":"179","180":"180","181":"181","182":"182","183":"183","184":"184","185":"185","186":"186","187":"187","188":"188","189":"189","190":"190","191":"191","192":"192","193":"193","194":"194","195":"195","196":"196","197":"197","198":"198","199":"199","200":"200","201":"201","202":"202","203":"203","204":"204","205":"205","206":"206","207":"207","208":"208","209":"209","210":"210","211":"211","212":"212","213":"213","214":"214","215":"215","216":"216","217":"217","218":"218","219":"219","220":"220","221":"221","222":"222","223":"223","224":"224","225":"225","226":"226","227":"227","228":"228","229":"229","230":"230","231":"231","232":"232","233":"233","234":"234","235":"235","236":"236","237":"237","238":"238","239":"239","240":"240","241":"241","242":"242","243":"243","244":"244","245":"245","246":"246","247":"247","248":"248","249":"249","250":"250","251":"251","252":"252","253":"253","254":"254","255":"255","256":"256","257":"257","258":"258","259":"259","260":"260","261":"261","262":"262","263":"263","264":"264","265":"265","266":"266","267":"267","268":"268","269":"269","270":"270","271":"271","272":"272","273":"273","274":"274","275":"275","276":"276","277":"277","278":"278","279":"279","280":"280","281":"281","282":"282","283":"283","284":"284","285":"285","286":"286","287":"287","288":"288","289":"289","290":"290","291":"291","292":"292","293":"293","294":"294","295":"295","296":"296","297":"297","298":"298","299":"299"];
|
||||
|
||||
print dict;
|
||||
7
test/type-type.toy
Normal file
7
test/type-type.toy
Normal file
@@ -0,0 +1,7 @@
|
||||
var t: type = int;
|
||||
var u: t = 42;
|
||||
|
||||
assert t == int, "types are not first class";
|
||||
assert u == 42, "first-class types are screwing with values";
|
||||
|
||||
print "All good";
|
||||
Reference in New Issue
Block a user