nested and static generic compilation

interfaces
cosmonaut 2021-09-07 11:54:31 -07:00
parent 05b3707258
commit f59be30791
3 changed files with 75 additions and 21 deletions

View File

@ -51,6 +51,11 @@ struct Array<T>
{
return memoryBlock.Get(index);
}
Set(index: uint, value: T): void
{
memoryBlock.Set(index, value);
}
}
interface Iterable<T>
@ -64,21 +69,12 @@ struct Program {
array: Array<int> = Array<int>.Init(4);
x: int = 4;
y: int = Foo.Func(x);
block: MemoryBlock<int> = MemoryBlock<int>
{
capacity: y,
start: @malloc(y * @sizeof<int>())
};
block.Set(0, 5);
block.Set(1, 3);
block.Set(2, 9);
block.Set(3, 100);
Console.PrintLine("%p", block.start);
Console.PrintLine("%i", block.Get(0));
Console.PrintLine("%i", block.Get(1));
Console.PrintLine("%i", block.Get(2));
Console.PrintLine("%i", block.Get(3));
block.Free();
array.Set(0, 2);
array.Set(1, 0);
array.Set(2, 5);
array.Set(3, 9);
Console.PrintLine("%i", array.Get(0));
Console.PrintLine("%i", array.Get(3));
return 0;
}
}

View File

@ -1643,6 +1643,7 @@ static LLVMValueRef CompileStructInitExpression(
LLVMTypeRef structType = ResolveType(
ConcretizeType(structInitExpression->structInit.type->typeTag));
/* FIXME: this can be given by struct instead of allocated */
LLVMValueRef structPointer =
LLVMBuildAlloca(builder, structType, "structInit");
@ -1658,19 +1659,40 @@ static LLVMValueRef CompileStructInitExpression(
.fieldInits[i]
->fieldInit.identifier->identifier.name);
LLVMBuildStore(
builder,
CompileExpression(
LLVMValueRef fieldExpressionResult = CompileExpression(
structTypeDeclaration,
selfParam,
builder,
structInitExpression->structInit.initFields->structInitFields
.fieldInits[i]
->fieldInit.expression),
structFieldPointer);
->fieldInit.expression);
LLVMTypeKind fieldExpressionTypeKind = LLVMGetTypeKind(LLVMTypeOf(fieldExpressionResult));
if (fieldExpressionTypeKind == LLVMPointerTypeKind)
{
LLVMBuildMemCpy(
builder,
structPointer,
LLVMGetAlignment(structPointer),
fieldExpressionResult,
LLVMGetAlignment(fieldExpressionResult),
LLVMSizeOf(LLVMTypeOf(fieldExpressionResult))
);
}
else
{
LLVMBuildStore(
builder,
fieldExpressionResult,
structFieldPointer);
}
}
return structPointer;
return LLVMBuildLoad(
builder,
structPointer,
"struct"
);
}
static LLVMValueRef CompileExpression(

View File

@ -504,6 +504,42 @@ void ConvertCustomsToGenerics(Node *node)
break;
}
case StructInit:
{
Node *type = node->structInit.type->type.typeNode;
TypeTag *typeTag = node->structInit.type->typeTag;
if (type->syntaxKind == CustomTypeNode)
{
char *target = typeTag->value.customType;
Node *typeLookup = LookupType(node, target);
if (typeLookup != NULL &&
typeLookup->syntaxKind == GenericDeclaration)
{
typeTag->type = Generic;
free(node->functionSignature.type);
node->functionSignature.type =
MakeGenericTypeNode(typeTag->value.genericType);
}
}
else if (type->syntaxKind == ConcreteGenericTypeNode)
{
for (int32_t i = 0; i < typeTag->value.concreteGenericType.genericArgumentCount; i += 1)
{
if (typeTag->value.concreteGenericType.genericArguments[i]->type == Custom)
{
char *target = typeTag->value.concreteGenericType.genericArguments[i]->value.customType;
Node *typeLookup = LookupType(node, target);
if (typeLookup != NULL &&
typeLookup->syntaxKind == GenericDeclaration)
{
typeTag->value.concreteGenericType.genericArguments[i]->type = Generic;
}
}
}
}
break;
}
case GenericArgument:
{
Node *typeNode = node->genericArgument.type;