started work on generics

generics
cosmonaut 2021-05-03 00:06:54 -07:00
parent cbeb8d3ce2
commit f46630b0ab
6 changed files with 150 additions and 13 deletions

View File

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

View File

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

View File

@ -26,6 +26,7 @@ extern FILE *yyin;
%token STRING
%token BOOL
%token STRUCT
%token INTERFACE
%token RETURN
%token STATIC
%token REFERENCE
@ -307,14 +308,40 @@ Body : LEFT_BRACE Statements RIGHT_BRACE
$$ = $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
{
Node *modifier = MakeStaticNode();
$$ = MakeFunctionSignatureNode($2, $7, $4, MakeFunctionModifiersNode(&modifier, 1));
$$ = MakeFunctionSignatureNode($2, $7, $4, MakeFunctionModifiersNode(&modifier, 1), MakeEmptyGenericConstraintsNode());
}
FunctionDeclaration : FunctionSignature Body
@ -327,6 +354,24 @@ StructDeclaration : STRUCT Identifier LEFT_BRACE Declarations RIGHT_BRACE
$$ = 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
| VariableDeclaration SEMICOLON
;
@ -340,7 +385,9 @@ Declarations : Declaration
$$ = AddDeclarationNode($1, $2);
}
TopLevelDeclaration : StructDeclaration;
TopLevelDeclaration : StructDeclaration
| InterfaceDeclaration
;
TopLevelDeclarations : TopLevelDeclaration
{

View File

@ -286,20 +286,59 @@ Node *MakeEmptyFunctionSignatureArgumentsNode()
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;
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 *identifierNode,
Node* typeNode,
Node* arguments,
Node* modifiersNode
Node* modifiersNode,
Node* genericConstraintsNode
) {
Node* node = (Node*) malloc(sizeof(Node));
node->syntaxKind = FunctionSignature;
node->childCount = 4;
node->childCount = 5;
node->children = (Node**) malloc(sizeof(Node*) * (node->childCount));
node->children[0] = identifierNode;
node->children[1] = typeNode;
node->children[2] = arguments;
node->children[3] = modifiersNode;
node->children[4] = genericConstraintsNode;
return node;
}
@ -329,6 +368,19 @@ Node* MakeStructDeclarationNode(
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 *declarationNode
) {

View File

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

View File

@ -984,6 +984,11 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
PopScopeFrame(scope);
}
static void CompileInterface(LLVMModuleRef module, LLVMContextRef context, Node *node)
{
}
static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node)
{
uint32_t i;
@ -994,9 +999,13 @@ static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node)
{
CompileStruct(module, context, node->children[i]);
}
else if (node->children[i]->syntaxKind == InterfaceDeclaration)
{
CompileInterface(module, context, node->children[i]);
}
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");
}
}
}