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 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:

19
ast.h
View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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
{