started expanding type system

generics
cosmonaut 2021-04-24 12:59:30 -07:00
parent c4c916a2de
commit b00cde2193
5 changed files with 87 additions and 33 deletions

50
ast.c
View File

@ -25,6 +25,7 @@ const char* SyntaxKindString(SyntaxKind syntaxKind)
case Assignment: return "Assignment"; case Assignment: return "Assignment";
case BinaryExpression: return "BinaryExpression"; case BinaryExpression: return "BinaryExpression";
case Comment: return "Comment"; case Comment: return "Comment";
case CustomTypeNode: return "CustomTypeNode";
case Declaration: return "Declaration"; case Declaration: return "Declaration";
case DeclarationSequence: return "DeclarationSequence"; case DeclarationSequence: return "DeclarationSequence";
case FunctionArgumentSequence: return "FunctionArgumentSequence"; case FunctionArgumentSequence: return "FunctionArgumentSequence";
@ -35,6 +36,8 @@ const char* SyntaxKindString(SyntaxKind syntaxKind)
case FunctionSignatureArguments: return "FunctionSignatureArguments"; case FunctionSignatureArguments: return "FunctionSignatureArguments";
case Identifier: return "Identifier"; case Identifier: return "Identifier";
case Number: return "Number"; case Number: return "Number";
case PrimitiveTypeNode: return "PrimitiveTypeNode";
case ReferenceTypeNode: return "ReferenceTypeNode";
case Return: return "Return"; case Return: return "Return";
case StatementSequence: return "StatementSequence"; case StatementSequence: return "StatementSequence";
case StaticModifier: return "StaticModifier"; 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 PrimitiveType type
) { ) {
Node* node = (Node*) malloc(sizeof(Node)); Node* node = (Node*) malloc(sizeof(Node));
node->syntaxKind = Type; node->syntaxKind = PrimitiveTypeNode;
node->type = type; node->primitiveType = type;
node->childCount = 0; node->childCount = 0;
return node; return node;
} }
Node* MakeCustomTypeNode( 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* node = (Node*) malloc(sizeof(Node));
node->syntaxKind = Type; node->syntaxKind = Type;
node->type = CustomType;
node->childCount = 1; node->childCount = 1;
node->children = (Node**) malloc(sizeof(Node*)); node->children = (Node**) malloc(sizeof(Node*));
node->children[0] = identifierNode; node->children[0] = typeNode;
return node; return node;
} }
@ -344,7 +373,6 @@ static const char* PrimitiveTypeToString(PrimitiveType type)
case UInt: return "UInt"; case UInt: return "UInt";
case Bool: return "Bool"; case Bool: return "Bool";
case Void: return "Void"; case Void: return "Void";
case CustomType: return "CustomType";
} }
return "Unknown"; return "Unknown";
@ -386,8 +414,12 @@ static void PrintNode(Node *node, int tabCount)
case Declaration: case Declaration:
break; break;
case Type: case CustomTypeNode:
printf("%s", PrimitiveTypeToString(node->type)); printf("%s", node->value.string);
break;
case PrimitiveTypeNode:
printf("%s", PrimitiveTypeToString(node->primitiveType));
break; break;
case Identifier: case Identifier:

19
ast.h
View File

@ -9,6 +9,7 @@ typedef enum
Assignment, Assignment,
BinaryExpression, BinaryExpression,
Comment, Comment,
CustomTypeNode,
Declaration, Declaration,
DeclarationSequence, DeclarationSequence,
Expression, Expression,
@ -21,6 +22,8 @@ typedef enum
FunctionSignatureArguments, FunctionSignatureArguments,
Identifier, Identifier,
Number, Number,
PrimitiveTypeNode,
ReferenceTypeNode,
Return, Return,
ReturnVoid, ReturnVoid,
StatementSequence, StatementSequence,
@ -51,8 +54,7 @@ typedef enum
UInt, UInt,
Float, Float,
Double, Double,
String, String
CustomType
} PrimitiveType; } PrimitiveType;
typedef union typedef union
@ -76,17 +78,24 @@ typedef struct Node
char *string; char *string;
uint64_t number; uint64_t number;
} value; } value;
PrimitiveType type; PrimitiveType primitiveType;
} Node; } Node;
char* strdup (const char* s); char* strdup (const char* s);
const char* SyntaxKindString(SyntaxKind syntaxKind); const char* SyntaxKindString(SyntaxKind syntaxKind);
Node* MakeTypeNode( uint8_t IsPrimitiveType(Node *typeNode);
Node* MakePrimitiveTypeNode(
PrimitiveType type PrimitiveType type
); );
Node* MakeCustomTypeNode( Node* MakeCustomTypeNode(
Node *identifierNode char *string
);
Node* MakeReferenceTypeNode(
Node *typeNode
);
Node* MakeTypeNode(
Node *typeNode /* can be primitive, custom, or reference */
); );
Node* MakeIdentifierNode( Node* MakeIdentifierNode(
const char *id const char *id

View File

@ -580,6 +580,7 @@ static void CompileAssignment(LLVMBuilderRef builder, Node *assignmentStatement)
LLVMBuildStore(builder, result, identifier); LLVMBuildStore(builder, result, identifier);
} }
/* FIXME: path for reference types */
static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *variableDeclaration) static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *variableDeclaration)
{ {
LLVMValueRef variable; LLVMValueRef variable;
@ -587,14 +588,14 @@ static void CompileFunctionVariableDeclaration(LLVMBuilderRef builder, Node *var
char *ptrName = strdup(variableName); char *ptrName = strdup(variableName);
strcat(ptrName, "_ptr"); 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, WraithTypeToLLVMType(variableDeclaration->children[0]->children[0]->primitiveType), ptrName);
variable = LLVMBuildAlloca(builder, LookupCustomType(customTypeName), ptrName);
} }
else 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); free(ptrName);
@ -668,13 +669,14 @@ static void CompileFunction(
PushScopeFrame(scope); PushScopeFrame(scope);
/* FIXME: should work for non-primitive types */
for (i = 0; i < functionSignature->children[2]->childCount; i += 1) 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; 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); LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, paramIndex, 0);
char *functionName = strdup(parentStructName); char *functionName = strdup(parentStructName);
@ -749,7 +751,7 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
switch (currentDeclarationNode->syntaxKind) switch (currentDeclarationNode->syntaxKind)
{ {
case Declaration: /* this is badly named */ 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; fieldDeclarations[fieldCount] = currentDeclarationNode;
fieldCount += 1; fieldCount += 1;
break; break;

View File

@ -15,6 +15,7 @@
"struct" return STRUCT; "struct" return STRUCT;
"return" return RETURN; "return" return RETURN;
"static" return STATIC; "static" return STATIC;
"Reference" return REFERENCE;
[0-9]+ return NUMBER; [0-9]+ return NUMBER;
[a-zA-Z][a-zA-Z0-9]* return ID; [a-zA-Z][a-zA-Z0-9]* return ID;
\"[a-zA-Z][a-zA-Z0-9]*\" return STRING_LITERAL; \"[a-zA-Z][a-zA-Z0-9]*\" return STRING_LITERAL;

View File

@ -31,6 +31,7 @@ extern Node *rootNode;
%token STRUCT %token STRUCT
%token RETURN %token RETURN
%token STATIC %token STATIC
%token REFERENCE
%token NUMBER %token NUMBER
%token ID %token ID
%token STRING_LITERAL %token STRING_LITERAL
@ -83,36 +84,49 @@ Program : TopLevelDeclarations
rootNode = declarationSequence; rootNode = declarationSequence;
} }
Type : VOID BaseType : VOID
{ {
$$ = MakeTypeNode(Void); $$ = MakePrimitiveTypeNode(Void);
} }
| INT | INT
{ {
$$ = MakeTypeNode(Int); $$ = MakePrimitiveTypeNode(Int);
} }
| UINT | UINT
{ {
$$ = MakeTypeNode(UInt); $$ = MakePrimitiveTypeNode(UInt);
} }
| FLOAT | FLOAT
{ {
$$ = MakeTypeNode(Float); $$ = MakePrimitiveTypeNode(Float);
} }
| DOUBLE | DOUBLE
{ {
$$ = MakeTypeNode(Double); $$ = MakePrimitiveTypeNode(Double);
} }
| STRING | STRING
{ {
$$ = MakeTypeNode(String); $$ = MakePrimitiveTypeNode(String);
} }
| BOOL | BOOL
{ {
$$ = MakeTypeNode(Bool); $$ = MakePrimitiveTypeNode(Bool);
}
| Identifier
{
$$ = MakeCustomTypeNode(yytext);
}
| REFERENCE LESS_THAN Type GREATER_THAN
{
$$ = MakeReferenceTypeNode($3);
} }
; ;
Type : BaseType
{
$$ = MakeTypeNode($1);
}
Identifier : ID Identifier : ID
{ {
$$ = MakeIdentifierNode(yytext); $$ = MakeIdentifierNode(yytext);
@ -170,10 +184,6 @@ VariableDeclaration : Identifier COLON Type
{ {
$$ = MakeDeclarationNode($3, $1); $$ = MakeDeclarationNode($3, $1);
} }
| Identifier COLON Identifier
{
$$ = MakeDeclarationNode(MakeCustomTypeNode($3), $1);
}
AssignmentStatement : VariableDeclaration EQUAL Expression AssignmentStatement : VariableDeclaration EQUAL Expression
{ {