diff --git a/generators/wraith.lex b/generators/wraith.lex index e6ed085..da3b65b 100644 --- a/generators/wraith.lex +++ b/generators/wraith.lex @@ -14,6 +14,7 @@ "bool" return BOOL; "MemoryAddress" return MEMORYADDRESS; "struct" return STRUCT; +"interface" return INTERFACE; "return" return RETURN; "static" return STATIC; "Reference" return REFERENCE; diff --git a/generators/wraith.y b/generators/wraith.y index d9a637f..758e625 100644 --- a/generators/wraith.y +++ b/generators/wraith.y @@ -27,6 +27,7 @@ extern FILE *yyin; %token BOOL %token MEMORYADDRESS %token STRUCT +%token INTERFACE %token RETURN %token STATIC %token REFERENCE @@ -355,6 +356,10 @@ GenericDeclaration : Identifier { $$ = MakeGenericDeclarationNode($1, NULL); } + | Identifier COLON Type + { + $$ = MakeGenericDeclarationNode($1, $3); + } GenericDeclarations : GenericDeclaration { @@ -433,7 +438,28 @@ Declarations : Declaration $$ = AddDeclarationNode($1, $2); } -TopLevelDeclaration : StructDeclaration; +InterfaceMember : FunctionSignature SEMICOLON + { + $$ = $1; + } + +InterfaceMembers : InterfaceMember + { + $$ = StartInterfaceMembersNode($1); + } + | InterfaceMembers InterfaceMember + { + $$ = AddInterfaceMemberNode($1, $2); + } + +InterfaceDeclaration : INTERFACE Identifier LEFT_BRACE InterfaceMembers RIGHT_BRACE + { + $$ = MakeInterfaceDeclarationNode($2, $4); + } + +TopLevelDeclaration : StructDeclaration + | InterfaceDeclaration + ; TopLevelDeclarations : TopLevelDeclaration { diff --git a/interface.w b/interface.w new file mode 100644 index 0000000..aaa6c44 --- /dev/null +++ b/interface.w @@ -0,0 +1,30 @@ +struct Ass +{ + Fart(): void + { + Console.PrintLine("Poot!"); + } +} + +interface Farter +{ + Fart(): void; +} + +struct FartDispatcher +{ + static Fart(farter: T): void + { + farter.Fart(); + } +} + +struct Program { + static Main(): int { + ass: Ass; + + FartDispatcher.Fart(ass); + + return 0; + } +} diff --git a/src/ast.c b/src/ast.c index a4cd091..731ba0e 100644 --- a/src/ast.c +++ b/src/ast.c @@ -612,6 +612,41 @@ Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode) return node; } +Node *MakeInterfaceDeclarationNode( + Node *identifierNode, + Node *interfaceMembersNode) +{ + Node *node = (Node *)malloc(sizeof(Node)); + node->syntaxKind = Interface; + node->interface.identifier = identifierNode; + node->interface.interfaceMembers = interfaceMembersNode; + return node; +} + +Node *StartInterfaceMembersNode(Node *interfaceMemberNode) +{ + Node *node = (Node *)malloc(sizeof(Node)); + node->syntaxKind = InterfaceMembers; + node->interfaceMembers.members = (Node **)malloc(sizeof(Node *)); + node->interfaceMembers.members[0] = interfaceMemberNode; + node->interfaceMembers.count = 1; + return node; +} + +Node *AddInterfaceMemberNode( + Node *interfaceMembersNode, + Node *interfaceMemberNode) +{ + interfaceMembersNode->interfaceMembers.members = realloc( + interfaceMembersNode->interfaceMembers.members, + sizeof(Node *) * (interfaceMembersNode->interfaceMembers.count + 1)); + interfaceMembersNode->interfaceMembers + .members[interfaceMembersNode->interfaceMembers.count] = + interfaceMemberNode; + interfaceMembersNode->interfaceMembers.count += 1; + return interfaceMembersNode; +} + static const char *PrimitiveTypeToString(PrimitiveType type) { switch (type) diff --git a/src/ast.h b/src/ast.h index 3fdedf9..c499932 100644 --- a/src/ast.h +++ b/src/ast.h @@ -39,6 +39,8 @@ typedef enum Identifier, IfStatement, IfElseStatement, + Interface, + InterfaceMembers, Number, PrimitiveTypeNode, ReferenceTypeNode, @@ -284,6 +286,18 @@ struct Node Node *elseStatement; } ifElseStatement; + struct + { + Node *identifier; + Node *interfaceMembers; + } interface; + + struct + { + Node **members; + uint32_t count; + } interfaceMembers; + struct { uint64_t value; @@ -445,6 +459,13 @@ Node *StartStructInitFieldsNode(Node *fieldInitNode); Node *AddFieldInitNode(Node *structInitFieldsNode, Node *fieldInitNode); Node *MakeEmptyFieldInitNode(); Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode); +Node *MakeInterfaceDeclarationNode( + Node *identifierNode, + Node *interfaceMembersNode); +Node *StartInterfaceMembersNode(Node *interfaceMemberNode); +Node *AddInterfaceMemberNode( + Node *interfaceMembersNode, + Node *interfaceMemberNode); void PrintNode(Node *node, uint32_t tabCount); const char *SyntaxKindString(SyntaxKind syntaxKind); diff --git a/src/codegen.c b/src/codegen.c index b2421f9..a8ca29e 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -2334,11 +2334,17 @@ static void Compile( context, declarationSequenceNode->declarationSequence.sequence[i]); } + else if ( + declarationSequenceNode->declarationSequence.sequence[i] + ->syntaxKind == Interface) + { + /* Interfaces don't need to compile! */ + } else { fprintf( stderr, - "top level declarations that are not structs are " + "top level declarations that are not structs or interfaces are " "forbidden!\n"); } }