Compare commits

...

5 Commits

8 changed files with 435 additions and 117 deletions

View File

@ -14,6 +14,7 @@
"bool" return BOOL; "bool" return BOOL;
"MemoryAddress" return MEMORYADDRESS; "MemoryAddress" return MEMORYADDRESS;
"struct" return STRUCT; "struct" return STRUCT;
"interface" return INTERFACE;
"return" return RETURN; "return" return RETURN;
"static" return STATIC; "static" return STATIC;
"Reference" return REFERENCE; "Reference" return REFERENCE;

View File

@ -27,6 +27,7 @@ extern FILE *yyin;
%token BOOL %token BOOL
%token MEMORYADDRESS %token MEMORYADDRESS
%token STRUCT %token STRUCT
%token INTERFACE
%token RETURN %token RETURN
%token STATIC %token STATIC
%token REFERENCE %token REFERENCE
@ -150,6 +151,11 @@ AccessExpression : Identifier POINT AccessExpression
{ {
$$ = $1; $$ = $1;
} }
| BaseType POINT AccessExpression
{
$$ = MakeAccessExpressionNode($1, $3);
}
;
SystemCallExpression : AT Identifier SystemCallExpression : AT Identifier
{ {
@ -355,6 +361,10 @@ GenericDeclaration : Identifier
{ {
$$ = MakeGenericDeclarationNode($1, NULL); $$ = MakeGenericDeclarationNode($1, NULL);
} }
| Identifier COLON Type
{
$$ = MakeGenericDeclarationNode($1, $3);
}
GenericDeclarations : GenericDeclaration GenericDeclarations : GenericDeclaration
{ {
@ -433,7 +443,28 @@ Declarations : Declaration
$$ = AddDeclarationNode($1, $2); $$ = AddDeclarationNode($1, $2);
} }
TopLevelDeclaration : StructDeclaration; InterfaceMember : FunctionSignature SEMICOLON
{
$$ = $1;
}
InterfaceMembers : InterfaceMember
{
$$ = StartInterfaceMembersNode($1);
}
| InterfaceMembers InterfaceMember
{
$$ = AddInterfaceMemberNode($1, $2);
}
InterfaceDeclaration : INTERFACE Identifier GenericDeclarationClause LEFT_BRACE InterfaceMembers RIGHT_BRACE
{
$$ = MakeInterfaceDeclarationNode($2, $5, $3);
}
TopLevelDeclaration : StructDeclaration
| InterfaceDeclaration
;
TopLevelDeclarations : TopLevelDeclaration TopLevelDeclarations : TopLevelDeclaration
{ {

View File

@ -14,6 +14,15 @@ struct MemoryBlock<T>
start: MemoryAddress; start: MemoryAddress;
capacity: uint; capacity: uint;
static Init(capacity: uint): MemoryBlock<T>
{
return MemoryBlock<T>
{
capacity: capacity,
start: @malloc(capacity * @sizeof<T>())
};
}
AddressOf(index: uint): MemoryAddress AddressOf(index: uint): MemoryAddress
{ {
return start + (index * @sizeof<T>()); return start + (index * @sizeof<T>());
@ -35,25 +44,40 @@ struct MemoryBlock<T>
} }
} }
struct Array<T>
{
memoryBlock: MemoryBlock<T>;
static Init(capacity: uint): Array<T>
{
return Array<T>
{
memoryBlock: MemoryBlock<T>.Init(capacity)
};
}
Get(index: uint): T
{
return memoryBlock.Get(index);
}
Set(index: uint, value: T): void
{
memoryBlock.Set(index, value);
}
}
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> 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;
} }
} }

30
interface.w Normal file
View File

@ -0,0 +1,30 @@
struct Ass
{
Fart(): void
{
Console.PrintLine("Poot!");
}
}
interface Farter
{
Fart(): void;
}
struct FartDispatcher
{
static Fart<T : Farter>(farter: T): void
{
farter.Fart();
}
}
struct Program {
static Main(): int {
ass: Ass;
FartDispatcher.Fart(ass);
return 0;
}
}

View File

@ -612,6 +612,43 @@ Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode)
return node; return node;
} }
Node *MakeInterfaceDeclarationNode(
Node *identifierNode,
Node *interfaceMembersNode,
Node *genericDeclarationsNode)
{
Node *node = (Node *)malloc(sizeof(Node));
node->syntaxKind = Interface;
node->interface.identifier = identifierNode;
node->interface.interfaceMembers = interfaceMembersNode;
node->interface.genericDeclarations = genericDeclarationsNode;
return node;
}
Node *StartInterfaceMembersNode(Node *interfaceMemberNode)
{
Node *node = (Node *)malloc(sizeof(Node));
node->syntaxKind = InterfaceMembers;
node->interfaceMembers.members = (Node **)malloc(sizeof(Node *));
node->interfaceMembers.members[0] = interfaceMemberNode;
node->interfaceMembers.count = 1;
return node;
}
Node *AddInterfaceMemberNode(
Node *interfaceMembersNode,
Node *interfaceMemberNode)
{
interfaceMembersNode->interfaceMembers.members = realloc(
interfaceMembersNode->interfaceMembers.members,
sizeof(Node *) * (interfaceMembersNode->interfaceMembers.count + 1));
interfaceMembersNode->interfaceMembers
.members[interfaceMembersNode->interfaceMembers.count] =
interfaceMemberNode;
interfaceMembersNode->interfaceMembers.count += 1;
return interfaceMembersNode;
}
static const char *PrimitiveTypeToString(PrimitiveType type) static const char *PrimitiveTypeToString(PrimitiveType type)
{ {
switch (type) switch (type)
@ -1349,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;
@ -1388,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:
@ -1458,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;
@ -1512,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:

View File

@ -39,6 +39,8 @@ typedef enum
Identifier, Identifier,
IfStatement, IfStatement,
IfElseStatement, IfElseStatement,
Interface,
InterfaceMembers,
Number, Number,
PrimitiveTypeNode, PrimitiveTypeNode,
ReferenceTypeNode, ReferenceTypeNode,
@ -284,6 +286,19 @@ struct Node
Node *elseStatement; Node *elseStatement;
} ifElseStatement; } ifElseStatement;
struct
{
Node *identifier;
Node *interfaceMembers;
Node *genericDeclarations;
} interface;
struct
{
Node **members;
uint32_t count;
} interfaceMembers;
struct struct
{ {
uint64_t value; uint64_t value;
@ -445,6 +460,14 @@ Node *StartStructInitFieldsNode(Node *fieldInitNode);
Node *AddFieldInitNode(Node *structInitFieldsNode, Node *fieldInitNode); Node *AddFieldInitNode(Node *structInitFieldsNode, Node *fieldInitNode);
Node *MakeEmptyFieldInitNode(); Node *MakeEmptyFieldInitNode();
Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode); Node *MakeStructInitExpressionNode(Node *typeNode, Node *structInitFieldsNode);
Node *MakeInterfaceDeclarationNode(
Node *identifierNode,
Node *interfaceMembersNode,
Node *genericDeclarationsNode);
Node *StartInterfaceMembersNode(Node *interfaceMemberNode);
Node *AddInterfaceMemberNode(
Node *interfaceMembersNode,
Node *interfaceMemberNode);
void PrintNode(Node *node, uint32_t tabCount); void PrintNode(Node *node, uint32_t tabCount);
const char *SyntaxKindString(SyntaxKind syntaxKind); const char *SyntaxKindString(SyntaxKind syntaxKind);

View File

@ -111,7 +111,7 @@ struct StructTypeDeclaration
uint32_t genericFunctionCount; uint32_t genericFunctionCount;
}; };
StructTypeDeclaration *structTypeDeclarations; StructTypeDeclaration **structTypeDeclarations;
uint32_t structTypeDeclarationCount; uint32_t structTypeDeclarationCount;
typedef struct MonomorphizedGenericStructHashEntry typedef struct MonomorphizedGenericStructHashEntry
@ -401,9 +401,9 @@ static LLVMTypeRef LookupCustomType(char *name)
for (i = 0; i < structTypeDeclarationCount; i += 1) for (i = 0; i < structTypeDeclarationCount; i += 1)
{ {
if (strcmp(structTypeDeclarations[i].name, name) == 0) if (strcmp(structTypeDeclarations[i]->name, name) == 0)
{ {
return structTypeDeclarations[i].structType; return structTypeDeclarations[i]->structType;
} }
} }
@ -420,27 +420,30 @@ static StructTypeDeclaration *AddStructDeclaration(
uint32_t index = structTypeDeclarationCount; uint32_t index = structTypeDeclarationCount;
structTypeDeclarations = realloc( structTypeDeclarations = realloc(
structTypeDeclarations, structTypeDeclarations,
sizeof(StructTypeDeclaration) * (structTypeDeclarationCount + 1)); sizeof(StructTypeDeclaration*) * (structTypeDeclarationCount + 1));
structTypeDeclarations[index].module = module; structTypeDeclarations[index] = malloc(sizeof(StructTypeDeclaration));
structTypeDeclarations[index].structType = wStructType; structTypeDeclarations[index]->module = module;
structTypeDeclarations[index].structPointerType = wStructPointerType; structTypeDeclarations[index]->structType = wStructType;
structTypeDeclarations[index].name = strdup(name); structTypeDeclarations[index]->structPointerType = wStructPointerType;
structTypeDeclarations[index].fields = NULL; structTypeDeclarations[index]->name = strdup(name);
structTypeDeclarations[index].fieldCount = 0; structTypeDeclarations[index]->fields = NULL;
structTypeDeclarations[index].functions = NULL; structTypeDeclarations[index]->fieldCount = 0;
structTypeDeclarations[index].functionCount = 0; structTypeDeclarations[index]->functions = NULL;
structTypeDeclarations[index].genericFunctions = NULL; structTypeDeclarations[index]->functionCount = 0;
structTypeDeclarations[index].genericFunctionCount = 0; structTypeDeclarations[index]->genericFunctions = NULL;
structTypeDeclarations[index]->genericFunctionCount = 0;
structTypeDeclarationCount += 1; structTypeDeclarationCount += 1;
return &structTypeDeclarations[index]; return structTypeDeclarations[index];
} }
static StructTypeDeclaration *CompileMonomorphizedGenericStruct( static MonomorphizedGenericStructHashEntry *CompileMonomorphizedGenericStruct(
GenericStructTypeDeclaration *genericStructTypeDeclaration, GenericStructTypeDeclaration *genericStructTypeDeclaration,
TypeTag **genericArgumentTypes, TypeTag **genericArgumentTypes,
uint32_t genericArgumentTypeCount) uint32_t genericArgumentTypeCount,
MonomorphizedGenericStructHashArray *hashArray,
uint64_t typeHash)
{ {
uint32_t i = 0; uint32_t i = 0;
uint32_t fieldCount = 0; uint32_t fieldCount = 0;
@ -486,6 +489,25 @@ static StructTypeDeclaration *CompileMonomorphizedGenericStruct(
free(structName); free(structName);
/* add entry to the hash array here in case of recursion */
hashArray->elements = realloc(
hashArray->elements,
sizeof(MonomorphizedGenericStructHashEntry) *
(hashArray->count + 1));
hashArray->elements[hashArray->count].key = typeHash;
hashArray->elements[hashArray->count].types =
malloc(sizeof(TypeTag *) * genericArgumentTypeCount);
hashArray->elements[hashArray->count].typeCount =
genericArgumentTypeCount;
hashArray->elements[hashArray->count].structDeclaration =
declaration;
for (uint32_t j = 0; j < genericArgumentTypeCount; j += 1)
{
hashArray->elements[hashArray->count].types[j] =
genericArgumentTypes[j];
}
hashArray->count += 1;
/* first build the structure def */ /* first build the structure def */
for (i = 0; i < declarationCount; i += 1) for (i = 0; i < declarationCount; i += 1)
{ {
@ -528,7 +550,7 @@ static StructTypeDeclaration *CompileMonomorphizedGenericStruct(
PopScopeFrame(scope); PopScopeFrame(scope);
return declaration; return &hashArray->elements[hashArray->count - 1];;
} }
static StructTypeDeclaration *LookupGenericStructType( static StructTypeDeclaration *LookupGenericStructType(
@ -578,38 +600,20 @@ static StructTypeDeclaration *LookupGenericStructType(
if (match) if (match)
{ {
hashEntry = &hashArray->elements[i]; hashEntry = &hashArray->elements[j];
break; break;
} }
} }
if (hashEntry == NULL) if (hashEntry == NULL)
{ {
StructTypeDeclaration *structTypeDeclaration = hashEntry =
CompileMonomorphizedGenericStruct( CompileMonomorphizedGenericStruct(
&genericStructTypeDeclarations[i], &genericStructTypeDeclarations[i],
genericTypeTags, genericTypeTags,
typeTag->genericArgumentCount); typeTag->genericArgumentCount,
hashArray,
hashArray->elements = realloc( typeHash);
hashArray->elements,
sizeof(MonomorphizedGenericStructHashEntry) *
(hashArray->count + 1));
hashArray->elements[hashArray->count].key = typeHash;
hashArray->elements[hashArray->count].types =
malloc(sizeof(TypeTag *) * typeTag->genericArgumentCount);
hashArray->elements[hashArray->count].typeCount =
typeTag->genericArgumentCount;
hashArray->elements[hashArray->count].structDeclaration =
structTypeDeclaration;
for (j = 0; j < typeTag->genericArgumentCount; j += 1)
{
hashArray->elements[hashArray->count].types[j] =
genericTypeTags[j];
}
hashArray->count += 1;
hashEntry = &hashArray->elements[hashArray->count - 1];
} }
return hashEntry->structDeclaration; return hashEntry->structDeclaration;
@ -688,9 +692,9 @@ static LLVMTypeRef LookupStructTypeByName(char *name)
for (i = 0; i < structTypeDeclarationCount; i += 1) for (i = 0; i < structTypeDeclarationCount; i += 1)
{ {
if (strcmp(structTypeDeclarations[i].name, name) == 0) if (strcmp(structTypeDeclarations[i]->name, name) == 0)
{ {
return structTypeDeclarations[i].structType; return structTypeDeclarations[i]->structType;
} }
} }
@ -703,9 +707,9 @@ static StructTypeDeclaration *LookupStructDeclaration(LLVMTypeRef structType)
for (i = 0; i < structTypeDeclarationCount; i += 1) for (i = 0; i < structTypeDeclarationCount; i += 1)
{ {
if (structTypeDeclarations[i].structType == structType) if (structTypeDeclarations[i]->structType == structType)
{ {
return &structTypeDeclarations[i]; return structTypeDeclarations[i];
} }
} }
@ -724,18 +728,18 @@ static LLVMValueRef FindStructFieldPointer(
for (i = 0; i < structTypeDeclarationCount; i += 1) for (i = 0; i < structTypeDeclarationCount; i += 1)
{ {
if (structTypeDeclarations[i].structPointerType == structPointerType) if (structTypeDeclarations[i]->structPointerType == structPointerType)
{ {
for (j = 0; j < structTypeDeclarations[i].fieldCount; j += 1) for (j = 0; j < structTypeDeclarations[i]->fieldCount; j += 1)
{ {
if (strcmp(structTypeDeclarations[i].fields[j].name, name) == 0) if (strcmp(structTypeDeclarations[i]->fields[j].name, name) == 0)
{ {
char *ptrName = strdup(name); char *ptrName = strdup(name);
ptrName = w_strcat(ptrName, "_ptr"); ptrName = w_strcat(ptrName, "_ptr");
return LLVMBuildStructGEP( return LLVMBuildStructGEP(
builder, builder,
structPointer, structPointer,
structTypeDeclarations[i].fields[j].index, structTypeDeclarations[i]->fields[j].index,
ptrName); ptrName);
free(ptrName); free(ptrName);
} }
@ -1175,29 +1179,29 @@ static LLVMValueRef LookupFunctionByType(
for (i = 0; i < structTypeDeclarationCount; i += 1) for (i = 0; i < structTypeDeclarationCount; i += 1)
{ {
if (structTypeDeclarations[i].structType == structType) if (structTypeDeclarations[i]->structType == structType)
{ {
for (j = 0; j < structTypeDeclarations[i].functionCount; j += 1) for (j = 0; j < structTypeDeclarations[i]->functionCount; j += 1)
{ {
if (strcmp(structTypeDeclarations[i].functions[j].name, name) == if (strcmp(structTypeDeclarations[i]->functions[j].name, name) ==
0) 0)
{ {
*pReturnType = *pReturnType =
structTypeDeclarations[i].functions[j].returnType; structTypeDeclarations[i]->functions[j].returnType;
*pStatic = structTypeDeclarations[i].functions[j].isStatic; *pStatic = structTypeDeclarations[i]->functions[j].isStatic;
return structTypeDeclarations[i].functions[j].function; return structTypeDeclarations[i]->functions[j].function;
} }
} }
for (j = 0; j < structTypeDeclarations[i].genericFunctionCount; for (j = 0; j < structTypeDeclarations[i]->genericFunctionCount;
j += 1) j += 1)
{ {
if (strcmp( if (strcmp(
structTypeDeclarations[i].genericFunctions[j].name, structTypeDeclarations[i]->genericFunctions[j].name,
name) == 0) name) == 0)
{ {
return LookupGenericFunction( return LookupGenericFunction(
&structTypeDeclarations[i].genericFunctions[j], &structTypeDeclarations[i]->genericFunctions[j],
functionCallExpression, functionCallExpression,
pReturnType, pReturnType,
pStatic); pStatic);
@ -1221,29 +1225,29 @@ static LLVMValueRef LookupFunctionByPointerType(
for (i = 0; i < structTypeDeclarationCount; i += 1) for (i = 0; i < structTypeDeclarationCount; i += 1)
{ {
if (structTypeDeclarations[i].structPointerType == structPointerType) if (structTypeDeclarations[i]->structPointerType == structPointerType)
{ {
for (j = 0; j < structTypeDeclarations[i].functionCount; j += 1) for (j = 0; j < structTypeDeclarations[i]->functionCount; j += 1)
{ {
if (strcmp(structTypeDeclarations[i].functions[j].name, name) == if (strcmp(structTypeDeclarations[i]->functions[j].name, name) ==
0) 0)
{ {
*pReturnType = *pReturnType =
structTypeDeclarations[i].functions[j].returnType; structTypeDeclarations[i]->functions[j].returnType;
*pStatic = structTypeDeclarations[i].functions[j].isStatic; *pStatic = structTypeDeclarations[i]->functions[j].isStatic;
return structTypeDeclarations[i].functions[j].function; return structTypeDeclarations[i]->functions[j].function;
} }
} }
for (j = 0; j < structTypeDeclarations[i].genericFunctionCount; for (j = 0; j < structTypeDeclarations[i]->genericFunctionCount;
j += 1) j += 1)
{ {
if (strcmp( if (strcmp(
structTypeDeclarations[i].genericFunctions[j].name, structTypeDeclarations[i]->genericFunctions[j].name,
name) == 0) name) == 0)
{ {
return LookupGenericFunction( return LookupGenericFunction(
&structTypeDeclarations[i].genericFunctions[j], &structTypeDeclarations[i]->genericFunctions[j],
functionCallExpression, functionCallExpression,
pReturnType, pReturnType,
pStatic); pStatic);
@ -1370,36 +1374,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 ==
@ -1613,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");
@ -1628,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);
structFieldPointer);
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( static LLVMValueRef CompileExpression(
@ -2334,11 +2386,17 @@ static void Compile(
context, context,
declarationSequenceNode->declarationSequence.sequence[i]); declarationSequenceNode->declarationSequence.sequence[i]);
} }
else if (
declarationSequenceNode->declarationSequence.sequence[i]
->syntaxKind == Interface)
{
/* Interfaces don't need to compile! */
}
else else
{ {
fprintf( fprintf(
stderr, stderr,
"top level declarations that are not structs are " "top level declarations that are not structs or interfaces are "
"forbidden!\n"); "forbidden!\n");
} }
} }

View File

@ -432,6 +432,41 @@ void ConvertCustomsToGenerics(Node *node)
switch (node->syntaxKind) switch (node->syntaxKind)
{ {
case Type:
{
Node *type = node->type.typeNode;
if (type->syntaxKind == CustomTypeNode)
{
char *target = type->customType.name;
Node *typeLookup = LookupType(node, target);
if (typeLookup != NULL &&
typeLookup->syntaxKind == GenericDeclaration)
{
node->typeTag->type = Generic;
free(node->declaration.type);
node->declaration.type =
MakeGenericTypeNode(node->typeTag->value.genericType);
}
}
else if (type->syntaxKind == ConcreteGenericTypeNode)
{
for (int32_t i = 0; i < node->typeTag->value.concreteGenericType.genericArgumentCount; i += 1)
{
if (node->typeTag->value.concreteGenericType.genericArguments[i]->type == Custom)
{
char *target = node->typeTag->value.concreteGenericType.genericArguments[i]->value.customType;
Node *typeLookup = LookupType(node, target);
if (typeLookup != NULL &&
typeLookup->syntaxKind == GenericDeclaration)
{
node->typeTag->value.concreteGenericType.genericArguments[i]->type = Generic;
}
}
}
}
break;
}
case Declaration: case Declaration:
{ {
Node *id = node->declaration.identifier; Node *id = node->declaration.identifier;
@ -449,6 +484,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,9 +520,61 @@ 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;
} }
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;