diff --git a/src/ast.c b/src/ast.c index 4c39ba0..3fb4869 100644 --- a/src/ast.c +++ b/src/ast.c @@ -526,3 +526,81 @@ void PrintTree(Node *node, uint32_t tabCount) PrintTree(node->children[i], tabCount + 1); } } + +TypeTag* MakeTypeTag(Node *node) { + if (node == NULL) { + fprintf(stderr, "wraith: Attempted to call MakeTypeTag on null value.\n"); + return NULL; + } + + TypeTag *tag = (TypeTag*)malloc(sizeof(TypeTag)); + switch (node->syntaxKind) { + case Type: + tag = MakeTypeTag(node->children[0]); + break; + + case PrimitiveTypeNode: + tag->type = Primitive; + tag->value.primitiveType = node->primitiveType; + break; + + case ReferenceTypeNode: + tag->type = Reference; + tag->value.referenceType = MakeTypeTag(node->children[0]); + break; + + case CustomTypeNode: + tag->type = Custom; + tag->value.customType = strdup(node->value.string); + break; + + case Declaration: + tag = MakeTypeTag(node->children[0]); + break; + + case StructDeclaration: + tag->type = Custom; + tag->value.customType = strdup(node->children[0]->value.string); + break; + + case FunctionDeclaration: + tag = MakeTypeTag(node->children[0]->children[1]); + break; + + default: + fprintf(stderr, + "wraith: Attempted to call MakeTypeTag on" + " node with unsupported SyntaxKind: %s\n", + SyntaxKindString(node->syntaxKind)); + return NULL; + } + return tag; +} + +char* TypeTagToString(TypeTag *tag) { + if (tag == NULL) { + fprintf(stderr, "wraith: Attempted to call TypeTagToString with null value\n"); + return NULL; + } + + switch (tag->type) { + case Unknown: + return "Unknown"; + case Primitive: + return PrimitiveTypeToString(tag->value.primitiveType); + case Reference: { + char *inner = TypeTagToString(tag->value.referenceType); + size_t innerStrLen = strlen(inner); + char *result = malloc(sizeof(char) * (innerStrLen + 5)); + sprintf(result, "Ref<%s>", inner); + return result; + } + case Custom: + return tag->value.customType; + } +} + +void AddTypeTags(Node *ast) +{ + fprintf(stderr, "wraith: AddTypeTags not implemented yet.\n"); +} \ No newline at end of file diff --git a/src/ast.h b/src/ast.h index 5c04d76..9c5d4fc 100644 --- a/src/ast.h +++ b/src/ast.h @@ -71,6 +71,26 @@ typedef union BinaryOperator binaryOperator; } Operator; +typedef struct TypeTag +{ + enum Type + { + Unknown, + Primitive, + Reference, + Custom + } type; + union + { + // Valid when type = Primitive. + PrimitiveType primitiveType; + // Valid when type = Reference. + struct TypeTag *referenceType; + // Valid when type = Custom. + char *customType; + } value; +} TypeTag; + typedef struct Node { SyntaxKind syntaxKind; @@ -87,6 +107,7 @@ typedef struct Node uint64_t number; } value; PrimitiveType primitiveType; + TypeTag *typeTag; } Node; const char* SyntaxKindString(SyntaxKind syntaxKind); @@ -211,4 +232,8 @@ Node* MakeForLoopNode( void PrintTree(Node *node, uint32_t tabCount); +TypeTag* MakeTypeTag(Node *node); +char* TypeTagToString(TypeTag *tag); +void AddTypeTags(Node *ast); + #endif /* WRAITH_AST_H */ diff --git a/src/identcheck.c b/src/identcheck.c index 75e966c..14c6175 100644 --- a/src/identcheck.c +++ b/src/identcheck.c @@ -76,13 +76,17 @@ IdNode* MakeIdTree(Node *astNode, IdNode *parent) { return loopNode; } - case Declaration: - return MakeIdNode(Variable, astNode->children[1]->value.string, parent); + case Declaration: { + IdNode *declNode = MakeIdNode(Variable, astNode->children[1]->value.string, parent); + declNode->typeTag = MakeTypeTag(astNode); + return declNode; + } case StructDeclaration: { Node *idNode = astNode->children[0]; Node *declsNode = astNode->children[1]; IdNode *structNode = MakeIdNode(Struct, idNode->value.string, parent); + structNode->typeTag = MakeTypeTag(astNode); for (i = 0; i < declsNode->childCount; i++) { AddChildToNode(structNode, MakeIdTree(declsNode->children[i], structNode)); } @@ -95,6 +99,7 @@ IdNode* MakeIdTree(Node *astNode, IdNode *parent) { Node *funcArgsNode = sigNode->children[2]; Node *bodyStatementsNode = astNode->children[1]; IdNode *funcNode = MakeIdNode(Function, funcNameNode->value.string, parent); + funcNode->typeTag = MakeTypeTag(astNode); for (i = 0; i < funcArgsNode->childCount; i++) { AddChildToNode(funcNode, MakeIdTree(funcArgsNode->children[i], funcNode)); } @@ -118,11 +123,24 @@ IdNode* MakeIdTree(Node *astNode, IdNode *parent) { } void PrintIdNode(IdNode *node) { + if (node == NULL) { + fprintf(stderr, "wraith: Attempted to call PrintIdNode with null value.\n"); + return; + } + switch(node->type) { - case LexicalScope: printf("Scope (%s)\n", node->name); break; - case Struct: printf("%s : Struct\n", node->name); break; - case Function: printf("%s : Function\n", node->name); break; - case Variable: printf("%s : Variable\n", node->name); break; + case LexicalScope: + printf("Scope (%s)\n", node->name); + break; + case Struct: + printf("%s : %s\n", node->name, TypeTagToString(node->typeTag)); + break; + case Function: + printf("%s : Function<%s>\n", node->name, TypeTagToString(node->typeTag)); + break; + case Variable: + printf("%s : %s\n", node->name, TypeTagToString(node->typeTag)); + break; } } diff --git a/src/identcheck.h b/src/identcheck.h index 0afa6ac..78feed9 100644 --- a/src/identcheck.h +++ b/src/identcheck.h @@ -16,6 +16,7 @@ typedef enum NodeType { typedef struct IdNode { NodeType type; char *name; + TypeTag *typeTag; struct IdNode *parent; struct IdNode **children; uint32_t childCount;