Compare commits

...

3 Commits

Author SHA1 Message Date
cosmonaut a0efcf548d more generic stuff 2021-05-15 12:47:38 -07:00
cosmonaut e5e5397e7e start on generic codegen 2021-05-14 11:55:44 -07:00
cosmonaut a529bb6e4f started work on generics 2021-05-14 11:55:44 -07:00
6 changed files with 239 additions and 18 deletions

View File

@ -1,6 +1,16 @@
interface Increments
{
Increment(): void;
}
struct YourStruct struct YourStruct
{ {
yourInt: int; yourInt: int;
IncrementOther<T: Increments>(other: T): void
{
other.Increment();
}
} }
struct MyStruct struct MyStruct

View File

@ -13,6 +13,7 @@
"string" return STRING; "string" return STRING;
"bool" return BOOL; "bool" return BOOL;
"struct" return STRUCT; "struct" return STRUCT;
"interface" return INTERFACE;
"return" return RETURN; "return" return RETURN;
"static" return STATIC; "static" return STATIC;
"Reference" return REFERENCE; "Reference" return REFERENCE;

View File

@ -26,6 +26,7 @@ extern FILE *yyin;
%token STRING %token STRING
%token BOOL %token BOOL
%token STRUCT %token STRUCT
%token INTERFACE
%token RETURN %token RETURN
%token STATIC %token STATIC
%token REFERENCE %token REFERENCE
@ -307,14 +308,40 @@ Body : LEFT_BRACE Statements RIGHT_BRACE
$$ = $2; $$ = $2;
} }
FunctionSignature : Identifier LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type GenericConstraint : Identifier COLON Identifier
{ {
$$ = MakeFunctionSignatureNode($1, $6, $3, MakeFunctionModifiersNode(NULL, 0)); $$ = MakeGenericConstraintNode($1, $3);
}
GenericConstraints : GenericConstraint
{
$$ = StartGenericConstraintsNode($1);
}
| GenericConstraints COMMA GenericConstraint
{
$$ = AddGenericConstraint($1, $3);
}
;
GenericConstraintClause : LESS_THAN GenericConstraints GREATER_THAN
{
$$ = $2;
}
|
{
$$ = MakeEmptyGenericConstraintsNode();
}
;
/* FIXME: modifiers should be recursive */
FunctionSignature : Identifier GenericConstraintClause LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type
{
$$ = MakeFunctionSignatureNode($1, $7, $4, MakeFunctionModifiersNode(NULL, 0), $2);
} }
| STATIC Identifier LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type | STATIC Identifier LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type
{ {
Node *modifier = MakeStaticNode(); Node *modifier = MakeStaticNode();
$$ = MakeFunctionSignatureNode($2, $7, $4, MakeFunctionModifiersNode(&modifier, 1)); $$ = MakeFunctionSignatureNode($2, $7, $4, MakeFunctionModifiersNode(&modifier, 1), MakeEmptyGenericConstraintsNode());
} }
FunctionDeclaration : FunctionSignature Body FunctionDeclaration : FunctionSignature Body
@ -327,6 +354,24 @@ StructDeclaration : STRUCT Identifier LEFT_BRACE Declarations RIGHT_BRACE
$$ = MakeStructDeclarationNode($2, $4); $$ = MakeStructDeclarationNode($2, $4);
} }
InterfaceDeclaration : INTERFACE Identifier LEFT_BRACE InterfaceChildren RIGHT_BRACE
{
$$ = MakeInterfaceDeclarationNode($2, $4);
}
InterfaceChild : FunctionSignature SEMICOLON
;
InterfaceChildren : InterfaceChild
{
$$ = StartDeclarationSequenceNode($1);
}
| InterfaceChildren InterfaceChild
{
$$ = AddDeclarationNode($1, $2);
}
;
Declaration : FunctionDeclaration Declaration : FunctionDeclaration
| VariableDeclaration SEMICOLON | VariableDeclaration SEMICOLON
; ;
@ -340,7 +385,9 @@ Declarations : Declaration
$$ = AddDeclarationNode($1, $2); $$ = AddDeclarationNode($1, $2);
} }
TopLevelDeclaration : StructDeclaration; TopLevelDeclaration : StructDeclaration
| InterfaceDeclaration
;
TopLevelDeclarations : TopLevelDeclaration TopLevelDeclarations : TopLevelDeclaration
{ {

View File

@ -276,20 +276,59 @@ Node *MakeEmptyFunctionSignatureArgumentsNode()
return node; return node;
} }
Node* MakeGenericConstraintNode(Node *identifierNode, Node *interfaceNode)
{
Node* node = (Node*) malloc(sizeof(Node));
node->syntaxKind = GenericConstraint;
node->childCount = 2;
node->children = (Node**) malloc(sizeof(Node*) * 2);
node->children[0] = identifierNode;
node->children[1] = interfaceNode; /* can be NULL */
return node;
}
Node* StartGenericConstraintsNode(Node *genericNode)
{
Node* node = (Node*) malloc(sizeof(Node));
node->syntaxKind = GenericConstraints;
node->childCount = 1;
node->children = (Node**) malloc(sizeof(Node*));
node->children[0] = genericNode;
return node;
}
Node* AddGenericConstraint(Node *genericsNode, Node *genericNode)
{
genericsNode->children = realloc(genericsNode->children, sizeof(Node*) * (genericsNode->childCount + 1));
genericsNode->children[genericsNode->childCount] = genericNode;
genericsNode->childCount += 1;
return genericsNode;
}
Node* MakeEmptyGenericConstraintsNode()
{
Node* node = (Node*) malloc(sizeof(Node));
node->syntaxKind = GenericConstraints;
node->childCount = 0;
return node;
}
Node* MakeFunctionSignatureNode( Node* MakeFunctionSignatureNode(
Node *identifierNode, Node *identifierNode,
Node* typeNode, Node* typeNode,
Node* arguments, Node* arguments,
Node* modifiersNode Node* modifiersNode,
Node* genericConstraintsNode
) { ) {
Node* node = (Node*) malloc(sizeof(Node)); Node* node = (Node*) malloc(sizeof(Node));
node->syntaxKind = FunctionSignature; node->syntaxKind = FunctionSignature;
node->childCount = 4; node->childCount = 5;
node->children = (Node**) malloc(sizeof(Node*) * (node->childCount)); node->children = (Node**) malloc(sizeof(Node*) * (node->childCount));
node->children[0] = identifierNode; node->children[0] = identifierNode;
node->children[1] = typeNode; node->children[1] = typeNode;
node->children[2] = arguments; node->children[2] = arguments;
node->children[3] = modifiersNode; node->children[3] = modifiersNode;
node->children[4] = genericConstraintsNode;
return node; return node;
} }
@ -319,6 +358,19 @@ Node* MakeStructDeclarationNode(
return node; return node;
} }
Node* MakeInterfaceDeclarationNode(
Node *identifierNode,
Node *declarationSequenceNode
) {
Node* node = (Node*) malloc(sizeof(Node));
node->syntaxKind = InterfaceDeclaration;
node->childCount = 2;
node->children = (Node**) malloc(sizeof(Node*) * 2);
node->children[0] = identifierNode;
node->children[1] = declarationSequenceNode;
return node;
}
Node* StartDeclarationSequenceNode( Node* StartDeclarationSequenceNode(
Node *declarationNode Node *declarationNode
) { ) {

View File

@ -22,9 +22,12 @@ typedef enum
FunctionModifiers, FunctionModifiers,
FunctionSignature, FunctionSignature,
FunctionSignatureArguments, FunctionSignatureArguments,
GenericConstraint,
GenericConstraints,
Identifier, Identifier,
IfStatement, IfStatement,
IfElseStatement, IfElseStatement,
InterfaceDeclaration,
Number, Number,
PrimitiveTypeNode, PrimitiveTypeNode,
ReferenceTypeNode, ReferenceTypeNode,
@ -177,11 +180,22 @@ Node* AddFunctionSignatureArgumentNode(
Node *argumentNode Node *argumentNode
); );
Node* MakeEmptyFunctionSignatureArgumentsNode(); Node* MakeEmptyFunctionSignatureArgumentsNode();
Node* MakeGenericConstraintNode(
Node *identifierNode,
Node *interfaceNode
);
Node* StartGenericConstraintsNode(Node *genericNode);
Node* AddGenericConstraint(
Node *genericsNode,
Node *genericNode
);
Node* MakeEmptyGenericConstraintsNode();
Node* MakeFunctionSignatureNode( Node* MakeFunctionSignatureNode(
Node *identifierNode, Node *identifierNode,
Node *typeNode, Node *typeNode,
Node *argumentsNode, Node *argumentsNode,
Node* modifiersNode Node *modifiersNode,
Node *genericConstraintsNode
); );
Node* MakeFunctionDeclarationNode( Node* MakeFunctionDeclarationNode(
Node *functionSignatureNode, Node *functionSignatureNode,
@ -191,6 +205,10 @@ Node* MakeStructDeclarationNode(
Node *identifierNode, Node *identifierNode,
Node *declarationSequenceNode Node *declarationSequenceNode
); );
Node* MakeInterfaceDeclarationNode(
Node *identifierNode,
Node *declarationSequenceNode
);
Node* StartDeclarationSequenceNode( Node* StartDeclarationSequenceNode(
Node *declarationNode Node *declarationNode
); );

View File

@ -56,6 +56,24 @@ typedef struct StructTypeFunction
uint8_t isStatic; uint8_t isStatic;
} StructTypeFunction; } StructTypeFunction;
typedef struct MonomorphizedGenericStructFunction
{
TypeTag **typeTags;
LLVMValueRef functionReference;
} MonomorphizedGenericStructFunction;
typedef struct GenericStructFunction
{
char *name;
Node *functionDeclaration;
char **genericTypeNames;
uint32_t genericTypeCount;
MonomorphizedGenericStructFunction *monomorphizedFunctions;
uint32_t monomorphizedFunctionCount;
} GenericStructFunction;
typedef struct StructTypeDeclaration typedef struct StructTypeDeclaration
{ {
char *name; char *name;
@ -66,6 +84,9 @@ typedef struct StructTypeDeclaration
StructTypeFunction *functions; StructTypeFunction *functions;
uint32_t functionCount; uint32_t functionCount;
GenericStructFunction *genericFunctions;
uint32_t genericFunctionCount;
} StructTypeDeclaration; } StructTypeDeclaration;
StructTypeDeclaration *structTypeDeclarations; StructTypeDeclaration *structTypeDeclarations;
@ -299,6 +320,32 @@ static void DeclareStructFunction(
fprintf(stderr, "Could not find struct type for function!\n"); fprintf(stderr, "Could not find struct type for function!\n");
} }
static void DeclareGenericFunction(
LLVMTypeRef structPointerType,
Node *functionDeclaration
) {
uint32_t i, j, index;
for (i = 0; i < structTypeDeclarationCount; i += 1)
{
if (structTypeDeclarations[i].structPointerType == structPointerType)
{
index = structTypeDeclarations[i].genericFunctionCount;
structTypeDeclarations[i].genericFunctions = realloc(structTypeDeclarations[i].genericFunctions, sizeof(GenericStructFunction) * (structTypeDeclarations[i].genericFunctionCount + 1));
structTypeDeclarations[i].genericFunctions[index].name = strdup(functionDeclaration->children[0]->children[0]->value.string);
structTypeDeclarations[i].genericFunctions[index].functionDeclaration = functionDeclaration;
structTypeDeclarations[i].genericFunctions[index].genericTypeCount = functionDeclaration->children[0]->children[4]->childCount;
for (j = 0; j < structTypeDeclarations[i].genericFunctions[index].genericTypeCount; j += 1)
{
structTypeDeclarations[i].genericFunctions[index].genericTypeNames[j] = strdup(functionDeclaration->children[0]->children[4]->children[j]->children[0]->value.string);
}
structTypeDeclarations[i].genericFunctionCount += 1;
return;
}
}
}
static LLVMTypeRef LookupCustomType(char *name) static LLVMTypeRef LookupCustomType(char *name)
{ {
uint32_t i; uint32_t i;
@ -337,6 +384,20 @@ static LLVMTypeRef ResolveType(Node* typeNode)
} }
} }
static LLVMValueRef LookupGenericFunction(
StructTypeDeclaration *structDeclaration,
GenericStructFunction *genericFunction,
TypeTag **argTypes,
uint32_t argCount
) {
uint32_t i;
for (i = 0; i < argCount; i += 1)
{
}
}
/* FIXME: add generics */
static LLVMValueRef LookupFunctionByType( static LLVMValueRef LookupFunctionByType(
LLVMTypeRef structType, LLVMTypeRef structType,
char *name, char *name,
@ -369,7 +430,9 @@ static LLVMValueRef LookupFunctionByPointerType(
LLVMTypeRef structPointerType, LLVMTypeRef structPointerType,
char *name, char *name,
LLVMTypeRef *pReturnType, LLVMTypeRef *pReturnType,
uint8_t *pStatic uint8_t *pStatic,
TypeTag **argTypes,
uint32_t argCount
) { ) {
uint32_t i, j; uint32_t i, j;
@ -386,6 +449,14 @@ static LLVMValueRef LookupFunctionByPointerType(
return structTypeDeclarations[i].functions[j].function; return structTypeDeclarations[i].functions[j].function;
} }
} }
for (j = 0; j < structTypeDeclarations[i].genericFunctionCount; j += 1)
{
if (strcmp(structTypeDeclarations[i].genericFunctions[j].name, name) == 0)
{
return LookupGenericFunction()
}
}
} }
} }
@ -397,9 +468,10 @@ static LLVMValueRef LookupFunctionByInstance(
LLVMValueRef structPointer, LLVMValueRef structPointer,
char *name, char *name,
LLVMTypeRef *pReturnType, LLVMTypeRef *pReturnType,
uint8_t *pStatic uint8_t *pStatic,
TypeTag **argTypes
) { ) {
return LookupFunctionByPointerType(LLVMTypeOf(structPointer), name, pReturnType, pStatic); return LookupFunctionByPointerType(LLVMTypeOf(structPointer), name, pReturnType, pStatic, argTypes);
} }
static void AddStructVariablesToScope( static void AddStructVariablesToScope(
@ -498,6 +570,7 @@ static LLVMValueRef CompileFunctionCallExpression(
) { ) {
uint32_t i; uint32_t i;
uint32_t argumentCount = 0; uint32_t argumentCount = 0;
TypeTag *argTypes[expression->children[1]->childCount + 1];
LLVMValueRef args[expression->children[1]->childCount + 1]; LLVMValueRef args[expression->children[1]->childCount + 1];
LLVMValueRef function; LLVMValueRef function;
uint8_t isStatic; uint8_t isStatic;
@ -505,6 +578,11 @@ static LLVMValueRef CompileFunctionCallExpression(
LLVMTypeRef functionReturnType; LLVMTypeRef functionReturnType;
char *returnName = ""; char *returnName = "";
for (i = 0; i < expression->children[1]->childCount; i += 1)
{
argTypes[i] = expression->children[1]->children[i]->typeTag;
}
/* FIXME: this needs to be recursive on access chains */ /* FIXME: this needs to be recursive on access chains */
if (expression->children[0]->syntaxKind == AccessExpression) if (expression->children[0]->syntaxKind == AccessExpression)
{ {
@ -524,7 +602,7 @@ static LLVMValueRef CompileFunctionCallExpression(
else else
{ {
structInstance = FindVariablePointer(expression->children[0]->children[0]->value.string); structInstance = FindVariablePointer(expression->children[0]->children[0]->value.string);
function = LookupFunctionByInstance(structInstance, expression->children[0]->children[1]->value.string, &functionReturnType, &isStatic); function = LookupFunctionByInstance(structInstance, expression->children[0]->children[1]->value.string, &functionReturnType, &isStatic, argTypes);
} }
} }
else else
@ -872,6 +950,12 @@ static void CompileFunction(
paramIndex += 1; paramIndex += 1;
} }
if (functionSignature->children[4]->childCount > 0)
{
DeclareGenericFunction(wStructPointerType, functionDeclaration);
return;
}
PushScopeFrame(scope); PushScopeFrame(scope);
/* FIXME: should work for non-primitive types */ /* FIXME: should work for non-primitive types */
@ -984,6 +1068,11 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
PopScopeFrame(scope); PopScopeFrame(scope);
} }
static void CompileInterface(LLVMModuleRef module, LLVMContextRef context, Node *node)
{
}
static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node) static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node)
{ {
uint32_t i; uint32_t i;
@ -994,9 +1083,13 @@ static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node)
{ {
CompileStruct(module, context, node->children[i]); CompileStruct(module, context, node->children[i]);
} }
else if (node->children[i]->syntaxKind == InterfaceDeclaration)
{
CompileInterface(module, context, node->children[i]);
}
else else
{ {
fprintf(stderr, "top level declarations that are not structs are forbidden!\n"); fprintf(stderr, "Top-level declarations that are not structs or interfaces are forbidden!\n");
} }
} }
} }