From 5b82ed8e455406e7b2f213925fad077d727f7c7f Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 22 Aug 2022 14:27:41 +0100 Subject: [PATCH] Must force a type when dealing with compound types --- docs/TODO.txt | 1 + docs/spec.md | 10 ++++++++++ source/parser.c | 21 +++++++++++---------- test/types.toy | 7 ++++--- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/docs/TODO.txt b/docs/TODO.txt index 38a5656..21b7831 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -24,6 +24,7 @@ TODO: functions are first-class citizens TODO: functions last argument can be a rest parameter TODO: && and || operators +TODO: += -= *= /= %= operators TODO: A way to check the type of a variable (typeOf keyword) TODO: a = b = c = 1; ? TODO: are compounds shallow or deep copies? diff --git a/docs/spec.md b/docs/spec.md index c986ba3..798cd4f 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -118,6 +118,16 @@ var t: type = int; var u: t = 42; ``` +To force a type instead of an array, use the `type` keyword: + +``` +var a = [type type]; //array of types +var b = type [type]; //type of array of types +var c = [type]; //error! + +var d = b; //types can be re-assigned to other variables +``` + ## 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. diff --git a/source/parser.c b/source/parser.c index f45511b..44d5d14 100644 --- a/source/parser.c +++ b/source/parser.c @@ -78,7 +78,6 @@ static void synchronize(Parser* parser) { case TOKEN_IMPORT: case TOKEN_PRINT: case TOKEN_RETURN: - case TOKEN_TYPE: case TOKEN_VAR: case TOKEN_WHILE: parser->panic = false; @@ -119,8 +118,17 @@ ParseRule parseRules[]; //forward declarations static void declaration(Parser* parser, Node** nodeHandle); static void parsePrecedence(Parser* parser, Node** nodeHandle, PrecedenceRule rule); +static Literal readTypeToLiteral(Parser* parser); //the expression rules +static Opcode forceType(Parser* parser, Node** nodeHandle) { + Literal literal = readTypeToLiteral(parser); + + emitNodeLiteral(nodeHandle, literal); + + return OP_EOF; +} + static Opcode compound(Parser* parser, Node** nodeHandle) { //read either an array or a dictionary into a literal node @@ -615,7 +623,7 @@ ParseRule parseRules[] = { //must match the token types {NULL, NULL, PREC_NONE},// TOKEN_OF, {NULL, NULL, PREC_NONE},// TOKEN_PRINT, {NULL, NULL, PREC_NONE},// TOKEN_RETURN, - {NULL, NULL, PREC_NONE},// TOKEN_USING, + {forceType, NULL, PREC_PRIMARY},// TOKEN_TYPE, {NULL, NULL, PREC_NONE},// TOKEN_VAR, {NULL, NULL, PREC_NONE},// TOKEN_WHILE, @@ -1231,14 +1239,7 @@ static void varDecl(Parser* parser, Node** nodeHandle) { //variable definition is an expression Node* expressionNode = NULL; if (match(parser, TOKEN_ASSIGN)) { - //BUGFIX: if reading into a "type" variable, expect a type value - if (AS_TYPE(typeLiteral).typeOf == LITERAL_TYPE) { //This may cause issues when reading function returns - Literal val = readTypeToLiteral(parser); - - emitNodeLiteral(&expressionNode, val); - } else { - expression(parser, &expressionNode); - } + expression(parser, &expressionNode); } else { //values are null by default diff --git a/test/types.toy b/test/types.toy index 767aad9..5875a5f 100644 --- a/test/types.toy +++ b/test/types.toy @@ -7,14 +7,15 @@ assert u == 42, "first-class types are screwing with values"; //differentiate by the "type" value -var v: type = [int]; //TODO: still can't check for this +var v: type = type [int]; var w = [int]; +var x = v; assert w == [int], "defining an array of types failed"; - +assert x == type [int], "re-assigning a type value failed"; //complex type -var complex: type = [string, [int]]; +var complex: type = type [string, [int]]; var dict: complex = [ "first array": [1, 2, 3], "second array": [4, 5, 6],