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); return memoryBlock.Get(index);
} }
Set(index: uint, value: T): void
{
memoryBlock.Set(index, value);
}
} }
interface Iterable<T> interface Iterable<T>
@ -64,21 +69,12 @@ struct Program {
array: Array<int> = Array<int>.Init(4); 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> array.Set(0, 2);
{ array.Set(1, 0);
capacity: y, array.Set(2, 5);
start: @malloc(y * @sizeof<int>()) array.Set(3, 9);
}; Console.PrintLine("%i", array.Get(0));
block.Set(0, 5); Console.PrintLine("%i", array.Get(3));
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();
return 0; return 0;
} }
} }

View File

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

View File

@ -504,6 +504,42 @@ void ConvertCustomsToGenerics(Node *node)
break; 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: case GenericArgument:
{ {
Node *typeNode = node->genericArgument.type; Node *typeNode = node->genericArgument.type;