From b00cde219311b8329db791977dadd41d26613e57 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sat, 24 Apr 2021 12:59:30 -0700 Subject: [PATCH] started expanding type system --- ast.c | 50 +++++++++++++++++++++++++++++++++++++++++--------- ast.h | 19 ++++++++++++++----- compiler.c | 16 +++++++++------- wraith.lex | 1 + wraith.y | 34 ++++++++++++++++++++++------------ 5 files changed, 87 insertions(+), 33 deletions(-) diff --git a/ast.c b/ast.c index 03652d7..c239901 100644 --- a/ast.c +++ b/ast.c @@ -25,6 +25,7 @@ const char* SyntaxKindString(SyntaxKind syntaxKind) case Assignment: return "Assignment"; case BinaryExpression: return "BinaryExpression"; case Comment: return "Comment"; + case CustomTypeNode: return "CustomTypeNode"; case Declaration: return "Declaration"; case DeclarationSequence: return "DeclarationSequence"; case FunctionArgumentSequence: return "FunctionArgumentSequence"; @@ -35,6 +36,8 @@ const char* SyntaxKindString(SyntaxKind syntaxKind) case FunctionSignatureArguments: return "FunctionSignatureArguments"; case Identifier: return "Identifier"; case Number: return "Number"; + case PrimitiveTypeNode: return "PrimitiveTypeNode"; + case ReferenceTypeNode: return "ReferenceTypeNode"; case Return: return "Return"; case StatementSequence: return "StatementSequence"; case StaticModifier: return "StaticModifier"; @@ -46,25 +49,51 @@ const char* SyntaxKindString(SyntaxKind syntaxKind) } } -Node* MakeTypeNode( +uint8_t IsPrimitiveType( + Node *typeNode +) { + return typeNode->children[0]->syntaxKind == PrimitiveTypeNode; +} + +Node* MakePrimitiveTypeNode( PrimitiveType type ) { Node* node = (Node*) malloc(sizeof(Node)); - node->syntaxKind = Type; - node->type = type; + node->syntaxKind = PrimitiveTypeNode; + node->primitiveType = type; node->childCount = 0; return node; } Node* MakeCustomTypeNode( - Node *identifierNode + char *name +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = CustomTypeNode; + node->value.string = strdup(name); + node->childCount = 0; + return node; +} + +Node* MakeReferenceTypeNode( + Node *typeNode +) { + Node* node = (Node*) malloc(sizeof(Node)); + node->syntaxKind = ReferenceTypeNode; + node->childCount = 1; + node->children = (Node**) malloc(sizeof(Node*)); + node->children[0] = typeNode; + return node; +} + +Node* MakeTypeNode( + Node* typeNode ) { Node* node = (Node*) malloc(sizeof(Node)); node->syntaxKind = Type; - node->type = CustomType; node->childCount = 1; node->children = (Node**) malloc(sizeof(Node*)); - node->children[0] = identifierNode; + node->children[0] = typeNode; return node; } @@ -344,7 +373,6 @@ static const char* PrimitiveTypeToString(PrimitiveType type) case UInt: return "UInt"; case Bool: return "Bool"; case Void: return "Void"; - case CustomType: return "CustomType"; } return "Unknown"; @@ -386,8 +414,12 @@ static void PrintNode(Node *node, int tabCount) case Declaration: break; - case Type: - printf("%s", PrimitiveTypeToString(node->type)); + case CustomTypeNode: + printf("%s", node->value.string); + break; + + case PrimitiveTypeNode: + printf("%s", PrimitiveTypeToString(node->primitiveType)); break; case Identifier: diff --git a/ast.h b/ast.h index 148355d..6f46530 100644 --- a/ast.h +++ b/ast.h @@ -9,6 +9,7 @@ typedef enum Assignment, BinaryExpression, Comment, + CustomTypeNode, Declaration, DeclarationSequence, Expression, @@ -21,6 +22,8 @@ typedef enum FunctionSignatureArguments, Identifier, Number, + PrimitiveTypeNode, + ReferenceTypeNode, Return, ReturnVoid, StatementSequence, @@ -51,8 +54,7 @@ typedef enum UInt, Float, Double, - String, - CustomType + String } PrimitiveType; typedef union @@ -76,17 +78,24 @@ typedef struct Node char *string; uint64_t number; } value; - PrimitiveType type; + PrimitiveType primitiveType; } Node; char* strdup (const char* s); const char* SyntaxKindString(SyntaxKind syntaxKind); -Node* MakeTypeNode( +uint8_t IsPrimitiveType(Node *typeNode); +Node* MakePrimitiveTypeNode( PrimitiveType type ); Node* MakeCustomTypeNode( - Node *identifierNode + char *string +); +Node* MakeReferenceTypeNode( + Node *typeNode +); +Node* MakeTypeNode( + Node *typeNode /* can be primitive, custom, or reference */ ); Node* MakeIdentifierNode( const char *id diff --git a/compiler.c b/compiler.c index 9249fa6..8b93e39 100644 --- a/compiler.c +++ b/compiler.c @@ -580,6 +580,7 @@ static void CompileAssignment(LLVMBuilderRef builder, Node *assignmentStatement) LLVMBuildStore(builder, result, identifier); } +/* FIXME: path for reference types */ static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *variableDeclaration) { LLVMValueRef variable; @@ -587,14 +588,14 @@ static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *var char *ptrName = strdup(variableName); strcat(ptrName, "_ptr"); - if (variableDeclaration->children[0]->type == CustomType) + if (IsPrimitiveType(variableDeclaration->children[0])) { - char *customTypeName = variableDeclaration->children[0]->children[0]->value.string; - variable = LLVMBuildAlloca(builder, LookupCustomType(customTypeName), ptrName); + variable = LLVMBuildAlloca(builder, WraithTypeToLLVMType(variableDeclaration->children[0]->children[0]->primitiveType), ptrName); } else { - variable = LLVMBuildAlloca(builder, WraithTypeToLLVMType(variableDeclaration->children[0]->type), ptrName); + char *customTypeName = variableDeclaration->children[0]->children[0]->value.string; + variable = LLVMBuildAlloca(builder, LookupCustomType(customTypeName), ptrName); } free(ptrName); @@ -668,13 +669,14 @@ static void CompileFunction( PushScopeFrame(scope); + /* FIXME: should work for non-primitive types */ for (i = 0; i < functionSignature->children[2]->childCount; i += 1) { - paramTypes[paramIndex] = WraithTypeToLLVMType(functionSignature->children[2]->children[i]->children[0]->type); + paramTypes[paramIndex] = WraithTypeToLLVMType(functionSignature->children[2]->children[i]->children[0]->children[0]->primitiveType); paramIndex += 1; } - LLVMTypeRef returnType = WraithTypeToLLVMType(functionSignature->children[1]->type); + LLVMTypeRef returnType = WraithTypeToLLVMType(functionSignature->children[1]->children[0]->primitiveType); LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, paramIndex, 0); char *functionName = strdup(parentStructName); @@ -749,7 +751,7 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no switch (currentDeclarationNode->syntaxKind) { case Declaration: /* this is badly named */ - types[fieldCount] = WraithTypeToLLVMType(currentDeclarationNode->children[0]->type); + types[fieldCount] = WraithTypeToLLVMType(currentDeclarationNode->children[0]->children[0]->primitiveType); fieldDeclarations[fieldCount] = currentDeclarationNode; fieldCount += 1; break; diff --git a/wraith.lex b/wraith.lex index 2c7d539..5a446e2 100644 --- a/wraith.lex +++ b/wraith.lex @@ -15,6 +15,7 @@ "struct" return STRUCT; "return" return RETURN; "static" return STATIC; +"Reference" return REFERENCE; [0-9]+ return NUMBER; [a-zA-Z][a-zA-Z0-9]* return ID; \"[a-zA-Z][a-zA-Z0-9]*\" return STRING_LITERAL; diff --git a/wraith.y b/wraith.y index 2ae05aa..93315f2 100644 --- a/wraith.y +++ b/wraith.y @@ -31,6 +31,7 @@ extern Node *rootNode; %token STRUCT %token RETURN %token STATIC +%token REFERENCE %token NUMBER %token ID %token STRING_LITERAL @@ -83,36 +84,49 @@ Program : TopLevelDeclarations rootNode = declarationSequence; } -Type : VOID +BaseType : VOID { - $$ = MakeTypeNode(Void); + $$ = MakePrimitiveTypeNode(Void); } | INT { - $$ = MakeTypeNode(Int); + $$ = MakePrimitiveTypeNode(Int); } | UINT { - $$ = MakeTypeNode(UInt); + $$ = MakePrimitiveTypeNode(UInt); } | FLOAT { - $$ = MakeTypeNode(Float); + $$ = MakePrimitiveTypeNode(Float); } | DOUBLE { - $$ = MakeTypeNode(Double); + $$ = MakePrimitiveTypeNode(Double); } | STRING { - $$ = MakeTypeNode(String); + $$ = MakePrimitiveTypeNode(String); } | BOOL { - $$ = MakeTypeNode(Bool); + $$ = MakePrimitiveTypeNode(Bool); + } + | Identifier + { + $$ = MakeCustomTypeNode(yytext); + } + | REFERENCE LESS_THAN Type GREATER_THAN + { + $$ = MakeReferenceTypeNode($3); } ; +Type : BaseType + { + $$ = MakeTypeNode($1); + } + Identifier : ID { $$ = MakeIdentifierNode(yytext); @@ -170,10 +184,6 @@ VariableDeclaration : Identifier COLON Type { $$ = MakeDeclarationNode($3, $1); } - | Identifier COLON Identifier - { - $$ = MakeDeclarationNode(MakeCustomTypeNode($3), $1); - } AssignmentStatement : VariableDeclaration EQUAL Expression {