nested and static generic compilation
parent
05b3707258
commit
f59be30791
26
generic.w
26
generic.w
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue