forked from cosmonaut/wraith-lang
started expanding type system
parent
c4c916a2de
commit
b00cde2193
50
ast.c
50
ast.c
|
@ -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
19
ast.h
|
@ -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
|
||||||
|
|
16
compiler.c
16
compiler.c
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
34
wraith.y
34
wraith.y
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue