mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Types are being read into the variable declaration, not yet used
This commit is contained in:
@@ -1,2 +1 @@
|
||||
print [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
|
||||
print [["foo":1]:["bar":2]];
|
||||
var a : int const = 42;
|
||||
@@ -128,6 +128,35 @@ static int writeNodeCompoundToCache(Compiler* compiler, Node* node) {
|
||||
return index;
|
||||
}
|
||||
|
||||
static int writeLiteralTypeToCache(Compiler* compiler, Literal literal) {
|
||||
int index = -1;
|
||||
|
||||
//for now, stored as an array
|
||||
LiteralArray* store = ALLOCATE(LiteralArray, 1);
|
||||
initLiteralArray(store);
|
||||
|
||||
//save the mask to the store
|
||||
int maskIndex = findLiteralIndex(store, TO_INTEGER_LITERAL(AS_TYPE(literal).mask));
|
||||
if (maskIndex < 0) {
|
||||
maskIndex = pushLiteralArray(store, TO_INTEGER_LITERAL(AS_TYPE(literal).mask));
|
||||
}
|
||||
|
||||
pushLiteralArray(store, TO_INTEGER_LITERAL(maskIndex));
|
||||
|
||||
//if it's a compound type, recurse
|
||||
if (AS_TYPE(literal).mask & (MASK_ARRAY|MASK_DICTIONARY)) {
|
||||
for (int i = 0; i < AS_TYPE(literal).count; i++) {
|
||||
int subIndex = writeLiteralTypeToCache(compiler, ((Literal*)(AS_TYPE(literal).subtypes))[i]);
|
||||
pushLiteralArray(store, TO_INTEGER_LITERAL(subIndex));
|
||||
}
|
||||
}
|
||||
|
||||
//push the store to the compiler
|
||||
index = pushLiteralArray(&compiler->literalCache, TO_ARRAY_LITERAL(store));
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void writeCompiler(Compiler* compiler, Node* node) {
|
||||
//grow if the bytecode space is too small
|
||||
if (compiler->capacity < compiler->count + 1) {
|
||||
@@ -221,17 +250,28 @@ void writeCompiler(Compiler* compiler, Node* node) {
|
||||
fprintf(stderr, "[Internal] NODE_PAIR encountered in writeCompiler()");
|
||||
break;
|
||||
|
||||
// case NODE_VAR_TYPES:
|
||||
// //TODO: OP_TYPE_DECL
|
||||
case NODE_VAR_TYPES: {
|
||||
int index = writeLiteralTypeToCache(compiler, node->varTypes.typeLiteral);
|
||||
|
||||
// //find the type declaration in the cache, or create it if it doesn't exist
|
||||
// break;
|
||||
//embed the info into the bytecode
|
||||
if (index >= 256) {
|
||||
//push a "long" index
|
||||
compiler->bytecode[compiler->count++] = OP_TYPE_DECL_LONG; //1 byte
|
||||
*((unsigned short*)(compiler->bytecode + compiler->count)) = (unsigned short)index; //2 bytes
|
||||
|
||||
compiler->count += sizeof(unsigned short);
|
||||
}
|
||||
else {
|
||||
//push the index
|
||||
compiler->bytecode[compiler->count++] = OP_TYPE_DECL; //1 byte
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)index; //1 byte
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// case NODE_VAR_DECL:
|
||||
// //TODO: OP_VAR_DECL + OP_VAR_ASSIGN
|
||||
// break;
|
||||
|
||||
//TODO: more
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,7 +411,7 @@ unsigned char* collateCompiler(Compiler* compiler, int* size) {
|
||||
}
|
||||
break;
|
||||
|
||||
case LITERAL_DICTIONARY:
|
||||
case LITERAL_DICTIONARY: {
|
||||
emitByte(&collation, &capacity, &count, LITERAL_DICTIONARY);
|
||||
|
||||
LiteralArray* ptr = AS_ARRAY(compiler->literalCache.literals[i]); //used an array for storage above
|
||||
@@ -385,6 +425,24 @@ unsigned char* collateCompiler(Compiler* compiler, int* size) {
|
||||
}
|
||||
|
||||
freeLiteralArray(ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case LITERAL_TYPE: {
|
||||
emitByte(&collation, &capacity, &count, LITERAL_TYPE);
|
||||
|
||||
LiteralArray* ptr = AS_ARRAY(compiler->literalCache.literals[i]); //used an array for storage above
|
||||
|
||||
//length of the array, as a short
|
||||
emitShort(&collation, &capacity, &count, ptr->count); //count is the array size
|
||||
|
||||
//each element of the array
|
||||
for (int i = 0; i < ptr->count; i++) {
|
||||
emitShort(&collation, &capacity, &count, (unsigned short)AS_INTEGER(ptr->literals[i])); //shorts representing the indexes of the values
|
||||
}
|
||||
|
||||
freeLiteralArray(ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -210,6 +210,12 @@ void printLiteralCustom(Literal literal, void (printFn)(const char*)) {
|
||||
}
|
||||
|
||||
for (int i = 1; i < 8; i ++) { //0th bit is const
|
||||
//zero mask = any type, anys can't be const
|
||||
if (AS_TYPE(literal).mask == 0) {
|
||||
printToBuffer("any");
|
||||
break;
|
||||
}
|
||||
|
||||
if (AS_TYPE(literal).mask & MASK(i)) {
|
||||
//pretty print
|
||||
if (iterations++ > 0) {
|
||||
|
||||
@@ -97,7 +97,7 @@ typedef struct {
|
||||
#define MASK_ARRAY (MASK(TYPE_ARRAY))
|
||||
#define MASK_DICTIONARY (MASK(TYPE_DICTIONARY))
|
||||
#define MASK_FUNCTION (MASK(TYPE_FUNCTION))
|
||||
#define MASK_ANY (MASK_BOOLEAN|MASK_INTEGER|MASK_FLOAT|MASK_STRING|MASK_ARRAY|MASK_DICTIONARY|MASK_FUNCTION)
|
||||
#define MASK_ANY 0
|
||||
|
||||
//utils
|
||||
void printLiteral(Literal literal);
|
||||
|
||||
@@ -53,15 +53,12 @@ void freeNode(Node* node) {
|
||||
break;
|
||||
|
||||
case NODE_VAR_TYPES:
|
||||
for (int i = 0; i < node->varTypes.count; i++) {
|
||||
freeNode(node->varTypes.nodes + 1);
|
||||
}
|
||||
FREE_ARRAY(Node, node->varTypes.nodes, node->varTypes.capacity);
|
||||
freeLiteral(node->varTypes.typeLiteral);
|
||||
break;
|
||||
|
||||
case NODE_VAR_DECL:
|
||||
freeLiteral(node->varDecl.identifier);
|
||||
freeNode(node->varDecl.varType);
|
||||
freeLiteral(node->varDecl.typeLiteral);
|
||||
freeNode(node->varDecl.expression);
|
||||
break;
|
||||
}
|
||||
@@ -137,24 +134,21 @@ void emitNodePair(Node** nodeHandle, Node* left, Node* right) {
|
||||
*nodeHandle = tmp;
|
||||
}
|
||||
|
||||
void emitNodeVarTypes(Node** nodeHandle, unsigned char mask) {
|
||||
void emitNodeVarTypes(Node** nodeHandle, Literal literal) {
|
||||
Node* tmp = ALLOCATE(Node, 1);
|
||||
|
||||
tmp->type = NODE_VAR_TYPES;
|
||||
tmp->varTypes.mask = mask;
|
||||
tmp->varTypes.nodes = NULL;
|
||||
tmp->varTypes.capacity = 0;
|
||||
tmp->varTypes.count = 0;
|
||||
tmp->varTypes.typeLiteral = literal;
|
||||
|
||||
*nodeHandle = tmp;
|
||||
}
|
||||
|
||||
void emitNodeVarDecl(Node** nodeHandle, Literal identifier, Node* varType, Node* expression) {
|
||||
void emitNodeVarDecl(Node** nodeHandle, Literal identifier, Literal type, Node* expression) {
|
||||
Node* tmp = ALLOCATE(Node, 1);
|
||||
|
||||
tmp->type = NODE_VAR_DECL;
|
||||
tmp->varDecl.identifier = identifier;
|
||||
tmp->varDecl.varType = varType;
|
||||
tmp->varDecl.typeLiteral = type;
|
||||
tmp->varDecl.expression = expression;
|
||||
|
||||
*nodeHandle = tmp;
|
||||
@@ -223,20 +217,14 @@ void printNode(Node* node) {
|
||||
break;
|
||||
|
||||
case NODE_VAR_TYPES:
|
||||
printf("type[\n");
|
||||
|
||||
for (int i = 0; i < node->varTypes.count; i++) {
|
||||
printNode(&(node->varTypes.nodes[i]));
|
||||
}
|
||||
|
||||
printf("]\n");
|
||||
printLiteral(node->varTypes.typeLiteral);
|
||||
break;
|
||||
|
||||
case NODE_VAR_DECL:
|
||||
printf("vardecl(");
|
||||
printLiteral(node->varDecl.identifier);
|
||||
printf("; ");
|
||||
printNode(node->varDecl.varType);
|
||||
printLiteral(node->varDecl.typeLiteral);
|
||||
printf("; ");
|
||||
printNode(node->varDecl.expression);
|
||||
printf(")");
|
||||
|
||||
@@ -66,16 +66,13 @@ typedef struct NodePair {
|
||||
|
||||
typedef struct NodeVarTypes {
|
||||
NodeType type;
|
||||
unsigned char mask; //the type mask
|
||||
Node* nodes;
|
||||
int capacity;
|
||||
int count;
|
||||
Literal typeLiteral;
|
||||
} NodeVarTypes;
|
||||
|
||||
typedef struct NodeVarDecl {
|
||||
NodeType type;
|
||||
Literal identifier;
|
||||
Node* varType;
|
||||
Literal typeLiteral;
|
||||
Node* expression;
|
||||
} NodeVarDecl;
|
||||
|
||||
@@ -100,8 +97,8 @@ void emitNodeGrouping(Node** nodeHandle);
|
||||
void emitNodeBlock(Node** nodeHandle);
|
||||
void emitNodeCompound(Node** nodeHandle, LiteralType literalType);
|
||||
void emitNodePair(Node** nodeHandle, Node* left, Node* right);
|
||||
void emitNodeVarTypes(Node** nodeHandle, unsigned char mask);
|
||||
void emitNodeVarDecl(Node** nodeHandle, Literal identifier, Node* varType, Node* expression);
|
||||
void emitNodeVarTypes(Node** nodeHandle, Literal literal);
|
||||
void emitNodeVarDecl(Node** nodeHandle, Literal identifier, Literal type, Node* expression);
|
||||
|
||||
void printNode(Node* node);
|
||||
|
||||
|
||||
@@ -25,9 +25,11 @@ typedef enum Opcode {
|
||||
OP_SCOPE_BEGIN,
|
||||
OP_SCOPE_END,
|
||||
|
||||
OP_TYPE_DECL, //declare a type to be used
|
||||
OP_VAR_DECL, //stack: literal name, literal type (referenced by array index)
|
||||
OP_VAR_ASSIGN, //stack: literal name, literal value
|
||||
OP_TYPE_DECL, //declare a type to be used (as a literal)
|
||||
OP_TYPE_DECL_LONG, //declare a type to be used (as a long literal)
|
||||
|
||||
// OP_VAR_DECL, //stack: literal name, literal type (referenced by array index)
|
||||
// OP_VAR_ASSIGN, //stack: literal name, literal value
|
||||
|
||||
//meta
|
||||
OP_SECTION_END,
|
||||
|
||||
@@ -731,83 +731,76 @@ static void statement(Parser* parser, Node* node) {
|
||||
}
|
||||
|
||||
//declarations and definitions
|
||||
static void readVarType(Parser* parser, Node** nodeHandle) {
|
||||
//TODO: custom types with the "type" keyword
|
||||
static Literal readTypeToLiteral(Parser* parser) {
|
||||
advance(parser);
|
||||
|
||||
unsigned char typeMask = 0;
|
||||
|
||||
Node* left = NULL;
|
||||
Node* right = NULL;
|
||||
Literal literal = TO_TYPE_LITERAL(MASK_ANY);
|
||||
|
||||
switch(parser->previous.type) {
|
||||
case TOKEN_BOOLEAN:
|
||||
typeMask |= MASK_BOOLEAN;
|
||||
AS_TYPE(literal).mask |= MASK_BOOLEAN;
|
||||
break;
|
||||
|
||||
case TOKEN_INTEGER:
|
||||
typeMask |= MASK_INTEGER;
|
||||
AS_TYPE(literal).mask |= MASK_INTEGER;
|
||||
break;
|
||||
|
||||
case TOKEN_FLOAT:
|
||||
typeMask |= MASK_FLOAT;
|
||||
AS_TYPE(literal).mask |= MASK_FLOAT;
|
||||
break;
|
||||
|
||||
case TOKEN_STRING:
|
||||
typeMask |= MASK_STRING;
|
||||
AS_TYPE(literal).mask |= MASK_STRING;
|
||||
break;
|
||||
|
||||
//array, dictionary - read the sub-types
|
||||
case TOKEN_BRACKET_LEFT:
|
||||
//at least 1 type required
|
||||
readVarType(parser, &left);
|
||||
case TOKEN_BRACKET_LEFT: {
|
||||
Literal l = readTypeToLiteral(parser);
|
||||
|
||||
if (match(parser, TOKEN_COMMA)) {
|
||||
//if there's 2 types, it's a dictionary
|
||||
readVarType(parser, &right);
|
||||
typeMask |= MASK_DICTIONARY;
|
||||
Literal r = readTypeToLiteral(parser);
|
||||
|
||||
//dictionary
|
||||
Literal* dict = TYPE_PUSH_SUBTYPE(&literal, MASK_DICTIONARY);
|
||||
|
||||
((Literal*)(AS_TYPE(*dict).subtypes))[0] = l;
|
||||
((Literal*)(AS_TYPE(*dict).subtypes))[1] = r;
|
||||
}
|
||||
else {
|
||||
//else it's just an array
|
||||
typeMask |= MASK_ARRAY;
|
||||
}
|
||||
consume(parser, TOKEN_BRACKET_RIGHT, "Expected ']' at end of type definition");
|
||||
break;
|
||||
//array
|
||||
Literal* arr = TYPE_PUSH_SUBTYPE(&literal, MASK_ARRAY);
|
||||
|
||||
case TOKEN_ANY:
|
||||
typeMask |= MASK_ANY;
|
||||
//append the "l" literal
|
||||
((Literal*)(AS_TYPE(*arr).subtypes))[0] = l;
|
||||
}
|
||||
|
||||
consume(parser, TOKEN_BRACKET_RIGHT, "Expected ']' at end of type definition");
|
||||
}
|
||||
break;
|
||||
|
||||
//TODO: function
|
||||
|
||||
default:
|
||||
error(parser, parser->previous, "Bad type");
|
||||
return;
|
||||
error(parser, parser->previous, "Bad type signature");
|
||||
return TO_NULL_LITERAL;
|
||||
}
|
||||
|
||||
//const follows the type
|
||||
if (match(parser, TOKEN_CONST)) {
|
||||
typeMask |= MASK_CONST;
|
||||
AS_TYPE(literal).mask |= MASK_CONST;
|
||||
}
|
||||
|
||||
return literal;
|
||||
}
|
||||
|
||||
static void readVarType(Parser* parser, Node** nodeHandle) {
|
||||
//TODO: custom types with the "type" keyword
|
||||
|
||||
//get the type literal
|
||||
Literal type = readTypeToLiteral(parser);
|
||||
|
||||
//generate the node
|
||||
emitNodeVarTypes(nodeHandle, typeMask);
|
||||
|
||||
//check for sub-nodes
|
||||
if (left) {
|
||||
int oldCapacity = (*nodeHandle)->varTypes.capacity;
|
||||
|
||||
(*nodeHandle)->varTypes.capacity = GROW_CAPACITY(oldCapacity);
|
||||
(*nodeHandle)->varTypes.nodes = GROW_ARRAY(Node, (*nodeHandle)->varTypes.nodes, oldCapacity, (*nodeHandle)->varTypes.capacity);
|
||||
|
||||
//push left to the array
|
||||
*((*nodeHandle)->varTypes.nodes) = *left;
|
||||
|
||||
//append the other one too
|
||||
if (right) {
|
||||
*((*nodeHandle)->varTypes.nodes + 1) = *right;
|
||||
}
|
||||
}
|
||||
emitNodeVarTypes(nodeHandle, type);
|
||||
}
|
||||
|
||||
static void varDecl(Parser* parser, Node** nodeHandle) {
|
||||
@@ -827,10 +820,10 @@ static void varDecl(Parser* parser, Node** nodeHandle) {
|
||||
expression(parser, &expressionNode);
|
||||
}
|
||||
|
||||
//TODO: compile-time static type check?
|
||||
//TODO: static type checking?
|
||||
|
||||
//finally
|
||||
emitNodeVarDecl(nodeHandle, TO_IDENTIFIER_LITERAL(identifierToken.lexeme), typeNode, expressionNode);
|
||||
// emitNodeVarDecl(nodeHandle, TO_IDENTIFIER_LITERAL(identifierToken.lexeme), typeNode, expressionNode);
|
||||
|
||||
consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of var declaration");
|
||||
}
|
||||
|
||||
@@ -247,27 +247,34 @@ int main(int argc, const char* argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// repl();
|
||||
repl();
|
||||
|
||||
//testing the types, improving on them as I go
|
||||
Literal root = TO_TYPE_LITERAL( MASK_ARRAY | MASK_DICTIONARY );
|
||||
Literal* arr = TYPE_PUSH_SUBTYPE(&root, MASK_ARRAY );
|
||||
Literal* dict = TYPE_PUSH_SUBTYPE(&root, MASK_DICTIONARY );
|
||||
// //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(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_BOOLEAN );
|
||||
// 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 );
|
||||
|
||||
printLiteral(root);
|
||||
printf("\n");
|
||||
// TYPE_PUSH_SUBTYPE(dict, MASK_STRING | MASK_CONST );
|
||||
// TYPE_PUSH_SUBTYPE(dict, MASK_INTEGER | MASK_FLOAT );
|
||||
|
||||
//output: <[int] | [float] | [int | float] | [string const:bool] | [string const:int]>
|
||||
// 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user