diff --git a/generic.w b/generic.w index fcf1c93..127490d 100644 --- a/generic.w +++ b/generic.w @@ -51,6 +51,11 @@ struct Array { return memoryBlock.Get(index); } + + Set(index: uint, value: T): void + { + memoryBlock.Set(index, value); + } } interface Iterable @@ -64,21 +69,12 @@ struct Program { array: Array = Array.Init(4); x: int = 4; y: int = Foo.Func(x); - block: MemoryBlock = MemoryBlock - { - capacity: y, - start: @malloc(y * @sizeof()) - }; - 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; } } diff --git a/src/codegen.c b/src/codegen.c index 15b5f11..12683d1 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -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( diff --git a/src/validation.c b/src/validation.c index c74c0e8..05a3b7b 100644 --- a/src/validation.c +++ b/src/validation.c @@ -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;