From ff5011b81326ac6754b6cf2a83047a1afb5a0584 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Mon, 6 Sep 2021 23:59:43 -0700 Subject: [PATCH] progress on nested generic compile --- generators/wraith.y | 9 +++-- generic.w | 25 ++++++++++++++ src/ast.c | 15 ++++++++- src/ast.h | 4 ++- src/codegen.c | 80 ++++++++++++++++++++++++++++++--------------- src/validation.c | 32 ++++++++++++++++++ 6 files changed, 134 insertions(+), 31 deletions(-) diff --git a/generators/wraith.y b/generators/wraith.y index 758e625..7d52b4b 100644 --- a/generators/wraith.y +++ b/generators/wraith.y @@ -151,6 +151,11 @@ AccessExpression : Identifier POINT AccessExpression { $$ = $1; } + | BaseType POINT AccessExpression + { + $$ = MakeAccessExpressionNode($1, $3); + } + ; SystemCallExpression : AT Identifier { @@ -452,9 +457,9 @@ InterfaceMembers : InterfaceMember $$ = AddInterfaceMemberNode($1, $2); } -InterfaceDeclaration : INTERFACE Identifier LEFT_BRACE InterfaceMembers RIGHT_BRACE +InterfaceDeclaration : INTERFACE Identifier GenericDeclarationClause LEFT_BRACE InterfaceMembers RIGHT_BRACE { - $$ = MakeInterfaceDeclarationNode($2, $4); + $$ = MakeInterfaceDeclarationNode($2, $5, $3); } TopLevelDeclaration : StructDeclaration diff --git a/generic.w b/generic.w index b85d7e8..fcf1c93 100644 --- a/generic.w +++ b/generic.w @@ -35,8 +35,33 @@ struct MemoryBlock } } +struct Array +{ + memoryBlock: MemoryBlock; + + static Init(capacity: uint): Array + { + return Array + { + memoryBlock: MemoryBlock { capacity: capacity, start: @malloc(capacity * @sizeof()) } + }; + } + + Get(index: uint): T + { + return memoryBlock.Get(index); + } +} + +interface Iterable +{ + HasNext(): bool; + Next(): T; +} + struct Program { static Main(): int { + array: Array = Array.Init(4); x: int = 4; y: int = Foo.Func(x); block: MemoryBlock = MemoryBlock diff --git a/src/ast.c b/src/ast.c index 731ba0e..c3e9847 100644 --- a/src/ast.c +++ b/src/ast.c @@ -614,12 +614,14 @@ Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode) Node *MakeInterfaceDeclarationNode( Node *identifierNode, - Node *interfaceMembersNode) + Node *interfaceMembersNode, + Node *genericDeclarationsNode) { Node *node = (Node *)malloc(sizeof(Node)); node->syntaxKind = Interface; node->interface.identifier = identifierNode; node->interface.interfaceMembers = interfaceMembersNode; + node->interface.genericDeclarations = genericDeclarationsNode; return node; } @@ -1384,6 +1386,10 @@ void LinkParentPointers(Node *node, Node *prev) case Comment: return; + case ConcreteGenericTypeNode: + LinkParentPointers(node->concreteGenericType.genericArguments, node); + return; + case CustomTypeNode: return; @@ -1423,6 +1429,7 @@ void LinkParentPointers(Node *node, Node *prev) case FunctionCallExpression: LinkParentPointers(node->functionCallExpression.identifier, node); LinkParentPointers(node->functionCallExpression.argumentSequence, node); + LinkParentPointers(node->functionCallExpression.genericArguments, node); return; case FunctionDeclaration: @@ -1493,6 +1500,11 @@ void LinkParentPointers(Node *node, Node *prev) LinkParentPointers(node->ifElseStatement.elseStatement, node); return; + case Interface: + LinkParentPointers(node->interface.genericDeclarations, node); + LinkParentPointers(node->interface.interfaceMembers, node); + return; + case Number: return; @@ -1547,6 +1559,7 @@ void LinkParentPointers(Node *node, Node *prev) return; case Type: + LinkParentPointers(node->type.typeNode, node); return; case UnaryExpression: diff --git a/src/ast.h b/src/ast.h index c499932..5e31cd7 100644 --- a/src/ast.h +++ b/src/ast.h @@ -290,6 +290,7 @@ struct Node { Node *identifier; Node *interfaceMembers; + Node *genericDeclarations; } interface; struct @@ -461,7 +462,8 @@ Node *MakeEmptyFieldInitNode(); Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode); Node *MakeInterfaceDeclarationNode( Node *identifierNode, - Node *interfaceMembersNode); + Node *interfaceMembersNode, + Node *genericDeclarationsNode); Node *StartInterfaceMembersNode(Node *interfaceMemberNode); Node *AddInterfaceMemberNode( Node *interfaceMembersNode, diff --git a/src/codegen.c b/src/codegen.c index a8ca29e..c4fee87 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1370,36 +1370,62 @@ static LLVMValueRef CompileFunctionCallExpression( if (functionCallExpression->functionCallExpression.identifier->syntaxKind == AccessExpression) { - LLVMTypeRef typeReference = LookupStructTypeByName( - functionCallExpression->functionCallExpression.identifier - ->accessExpression.accessee->identifier.name); + if (functionCallExpression->functionCallExpression.identifier->accessExpression.accessee->syntaxKind == + ConcreteGenericTypeNode) + { + TypeTag *typeTag = + MakeTypeTag( + functionCallExpression->functionCallExpression.identifier->accessExpression.accessee + ); + LLVMTypeRef typeReference = ResolveType(typeTag); - char *functionName = - functionCallExpression->functionCallExpression.identifier - ->accessExpression.accessor->identifier.name; + char *functionName = + functionCallExpression->functionCallExpression.identifier + ->accessExpression.accessor->identifier.name; - if (typeReference != NULL) - { - function = LookupFunctionByType( - typeReference, - functionName, - functionCallExpression, - &functionReturnType, - &isStatic); - } - else - { - structInstance = FindVariablePointer( - functionCallExpression->functionCallExpression.identifier - ->accessExpression.accessee->identifier.name); + function = LookupFunctionByType( + typeReference, + functionName, + functionCallExpression, + &functionReturnType, + &isStatic + ); - function = LookupFunctionByInstance( - structInstance, - functionName, - functionCallExpression, - &functionReturnType, - &isStatic); - } + free(typeTag); + } + else + { + LLVMTypeRef typeReference = LookupStructTypeByName( + functionCallExpression->functionCallExpression.identifier + ->accessExpression.accessee->identifier.name); + + char *functionName = + functionCallExpression->functionCallExpression.identifier + ->accessExpression.accessor->identifier.name; + + if (typeReference != NULL) + { + function = LookupFunctionByType( + typeReference, + functionName, + functionCallExpression, + &functionReturnType, + &isStatic); + } + else + { + structInstance = FindVariablePointer( + functionCallExpression->functionCallExpression.identifier + ->accessExpression.accessee->identifier.name); + + function = LookupFunctionByInstance( + structInstance, + functionName, + functionCallExpression, + &functionReturnType, + &isStatic); + } + } } else if ( functionCallExpression->functionCallExpression.identifier->syntaxKind == diff --git a/src/validation.c b/src/validation.c index d80e052..c74c0e8 100644 --- a/src/validation.c +++ b/src/validation.c @@ -449,6 +449,22 @@ void ConvertCustomsToGenerics(Node *node) MakeGenericTypeNode(id->typeTag->value.genericType); } } + else if (type->syntaxKind == ConcreteGenericTypeNode) + { + for (int32_t i = 0; i < id->typeTag->value.concreteGenericType.genericArgumentCount; i += 1) + { + if (id->typeTag->value.concreteGenericType.genericArguments[i]->type == Custom) + { + char *target = id->typeTag->value.concreteGenericType.genericArguments[i]->value.customType; + Node *typeLookup = LookupType(node, target); + if (typeLookup != NULL && + typeLookup->syntaxKind == GenericDeclaration) + { + id->typeTag->value.concreteGenericType.genericArguments[i]->type = Generic; + } + } + } + } break; } @@ -469,6 +485,22 @@ void ConvertCustomsToGenerics(Node *node) MakeGenericTypeNode(id->typeTag->value.genericType); } } + else if (type->syntaxKind == ConcreteGenericTypeNode) + { + for (int32_t i = 0; i < id->typeTag->value.concreteGenericType.genericArgumentCount; i += 1) + { + if (id->typeTag->value.concreteGenericType.genericArguments[i]->type == Custom) + { + char *target = id->typeTag->value.concreteGenericType.genericArguments[i]->value.customType; + Node *typeLookup = LookupType(node, target); + if (typeLookup != NULL && + typeLookup->syntaxKind == GenericDeclaration) + { + id->typeTag->value.concreteGenericType.genericArguments[i]->type = Generic; + } + } + } + } break; }