progress on nested generic compile
parent
45004f83e0
commit
ff5011b813
|
@ -151,6 +151,11 @@ AccessExpression : Identifier POINT AccessExpression
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
|
| BaseType POINT AccessExpression
|
||||||
|
{
|
||||||
|
$$ = MakeAccessExpressionNode($1, $3);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
SystemCallExpression : AT Identifier
|
SystemCallExpression : AT Identifier
|
||||||
{
|
{
|
||||||
|
@ -452,9 +457,9 @@ InterfaceMembers : InterfaceMember
|
||||||
$$ = AddInterfaceMemberNode($1, $2);
|
$$ = 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
|
TopLevelDeclaration : StructDeclaration
|
||||||
|
|
25
generic.w
25
generic.w
|
@ -35,8 +35,33 @@ struct MemoryBlock<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Array<T>
|
||||||
|
{
|
||||||
|
memoryBlock: MemoryBlock<T>;
|
||||||
|
|
||||||
|
static Init(capacity: uint): Array<T>
|
||||||
|
{
|
||||||
|
return Array<T>
|
||||||
|
{
|
||||||
|
memoryBlock: MemoryBlock<T> { capacity: capacity, start: @malloc(capacity * @sizeof<T>()) }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Get(index: uint): T
|
||||||
|
{
|
||||||
|
return memoryBlock.Get(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Iterable<T>
|
||||||
|
{
|
||||||
|
HasNext(): bool;
|
||||||
|
Next(): T;
|
||||||
|
}
|
||||||
|
|
||||||
struct Program {
|
struct Program {
|
||||||
static Main(): int {
|
static Main(): int {
|
||||||
|
array: Array<int> = Array<int>.Init(4);
|
||||||
x: int = 4;
|
x: int = 4;
|
||||||
y: int = Foo.Func(x);
|
y: int = Foo.Func(x);
|
||||||
block: MemoryBlock<int> = MemoryBlock<int>
|
block: MemoryBlock<int> = MemoryBlock<int>
|
||||||
|
|
15
src/ast.c
15
src/ast.c
|
@ -614,12 +614,14 @@ Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode)
|
||||||
|
|
||||||
Node *MakeInterfaceDeclarationNode(
|
Node *MakeInterfaceDeclarationNode(
|
||||||
Node *identifierNode,
|
Node *identifierNode,
|
||||||
Node *interfaceMembersNode)
|
Node *interfaceMembersNode,
|
||||||
|
Node *genericDeclarationsNode)
|
||||||
{
|
{
|
||||||
Node *node = (Node *)malloc(sizeof(Node));
|
Node *node = (Node *)malloc(sizeof(Node));
|
||||||
node->syntaxKind = Interface;
|
node->syntaxKind = Interface;
|
||||||
node->interface.identifier = identifierNode;
|
node->interface.identifier = identifierNode;
|
||||||
node->interface.interfaceMembers = interfaceMembersNode;
|
node->interface.interfaceMembers = interfaceMembersNode;
|
||||||
|
node->interface.genericDeclarations = genericDeclarationsNode;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1384,6 +1386,10 @@ void LinkParentPointers(Node *node, Node *prev)
|
||||||
case Comment:
|
case Comment:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case ConcreteGenericTypeNode:
|
||||||
|
LinkParentPointers(node->concreteGenericType.genericArguments, node);
|
||||||
|
return;
|
||||||
|
|
||||||
case CustomTypeNode:
|
case CustomTypeNode:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1423,6 +1429,7 @@ void LinkParentPointers(Node *node, Node *prev)
|
||||||
case FunctionCallExpression:
|
case FunctionCallExpression:
|
||||||
LinkParentPointers(node->functionCallExpression.identifier, node);
|
LinkParentPointers(node->functionCallExpression.identifier, node);
|
||||||
LinkParentPointers(node->functionCallExpression.argumentSequence, node);
|
LinkParentPointers(node->functionCallExpression.argumentSequence, node);
|
||||||
|
LinkParentPointers(node->functionCallExpression.genericArguments, node);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case FunctionDeclaration:
|
case FunctionDeclaration:
|
||||||
|
@ -1493,6 +1500,11 @@ void LinkParentPointers(Node *node, Node *prev)
|
||||||
LinkParentPointers(node->ifElseStatement.elseStatement, node);
|
LinkParentPointers(node->ifElseStatement.elseStatement, node);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case Interface:
|
||||||
|
LinkParentPointers(node->interface.genericDeclarations, node);
|
||||||
|
LinkParentPointers(node->interface.interfaceMembers, node);
|
||||||
|
return;
|
||||||
|
|
||||||
case Number:
|
case Number:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1547,6 +1559,7 @@ void LinkParentPointers(Node *node, Node *prev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Type:
|
case Type:
|
||||||
|
LinkParentPointers(node->type.typeNode, node);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case UnaryExpression:
|
case UnaryExpression:
|
||||||
|
|
|
@ -290,6 +290,7 @@ struct Node
|
||||||
{
|
{
|
||||||
Node *identifier;
|
Node *identifier;
|
||||||
Node *interfaceMembers;
|
Node *interfaceMembers;
|
||||||
|
Node *genericDeclarations;
|
||||||
} interface;
|
} interface;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|
@ -461,7 +462,8 @@ Node *MakeEmptyFieldInitNode();
|
||||||
Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode);
|
Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode);
|
||||||
Node *MakeInterfaceDeclarationNode(
|
Node *MakeInterfaceDeclarationNode(
|
||||||
Node *identifierNode,
|
Node *identifierNode,
|
||||||
Node *interfaceMembersNode);
|
Node *interfaceMembersNode,
|
||||||
|
Node *genericDeclarationsNode);
|
||||||
Node *StartInterfaceMembersNode(Node *interfaceMemberNode);
|
Node *StartInterfaceMembersNode(Node *interfaceMemberNode);
|
||||||
Node *AddInterfaceMemberNode(
|
Node *AddInterfaceMemberNode(
|
||||||
Node *interfaceMembersNode,
|
Node *interfaceMembersNode,
|
||||||
|
|
|
@ -1370,36 +1370,62 @@ static LLVMValueRef CompileFunctionCallExpression(
|
||||||
if (functionCallExpression->functionCallExpression.identifier->syntaxKind ==
|
if (functionCallExpression->functionCallExpression.identifier->syntaxKind ==
|
||||||
AccessExpression)
|
AccessExpression)
|
||||||
{
|
{
|
||||||
LLVMTypeRef typeReference = LookupStructTypeByName(
|
if (functionCallExpression->functionCallExpression.identifier->accessExpression.accessee->syntaxKind ==
|
||||||
functionCallExpression->functionCallExpression.identifier
|
ConcreteGenericTypeNode)
|
||||||
->accessExpression.accessee->identifier.name);
|
{
|
||||||
|
TypeTag *typeTag =
|
||||||
|
MakeTypeTag(
|
||||||
|
functionCallExpression->functionCallExpression.identifier->accessExpression.accessee
|
||||||
|
);
|
||||||
|
LLVMTypeRef typeReference = ResolveType(typeTag);
|
||||||
|
|
||||||
char *functionName =
|
char *functionName =
|
||||||
functionCallExpression->functionCallExpression.identifier
|
functionCallExpression->functionCallExpression.identifier
|
||||||
->accessExpression.accessor->identifier.name;
|
->accessExpression.accessor->identifier.name;
|
||||||
|
|
||||||
if (typeReference != NULL)
|
function = LookupFunctionByType(
|
||||||
{
|
typeReference,
|
||||||
function = LookupFunctionByType(
|
functionName,
|
||||||
typeReference,
|
functionCallExpression,
|
||||||
functionName,
|
&functionReturnType,
|
||||||
functionCallExpression,
|
&isStatic
|
||||||
&functionReturnType,
|
);
|
||||||
&isStatic);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
structInstance = FindVariablePointer(
|
|
||||||
functionCallExpression->functionCallExpression.identifier
|
|
||||||
->accessExpression.accessee->identifier.name);
|
|
||||||
|
|
||||||
function = LookupFunctionByInstance(
|
free(typeTag);
|
||||||
structInstance,
|
}
|
||||||
functionName,
|
else
|
||||||
functionCallExpression,
|
{
|
||||||
&functionReturnType,
|
LLVMTypeRef typeReference = LookupStructTypeByName(
|
||||||
&isStatic);
|
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 (
|
else if (
|
||||||
functionCallExpression->functionCallExpression.identifier->syntaxKind ==
|
functionCallExpression->functionCallExpression.identifier->syntaxKind ==
|
||||||
|
|
|
@ -449,6 +449,22 @@ void ConvertCustomsToGenerics(Node *node)
|
||||||
MakeGenericTypeNode(id->typeTag->value.genericType);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,6 +485,22 @@ void ConvertCustomsToGenerics(Node *node)
|
||||||
MakeGenericTypeNode(id->typeTag->value.genericType);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue