Compare commits
No commits in common. "interfaces" and "main" have entirely different histories.
interfaces
...
main
|
@ -14,7 +14,6 @@
|
||||||
"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;
|
||||||
|
|
|
@ -27,7 +27,6 @@ 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
|
||||||
|
@ -151,11 +150,6 @@ AccessExpression : Identifier POINT AccessExpression
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| BaseType POINT AccessExpression
|
|
||||||
{
|
|
||||||
$$ = MakeAccessExpressionNode($1, $3);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
SystemCallExpression : AT Identifier
|
SystemCallExpression : AT Identifier
|
||||||
{
|
{
|
||||||
|
@ -361,10 +355,6 @@ GenericDeclaration : Identifier
|
||||||
{
|
{
|
||||||
$$ = MakeGenericDeclarationNode($1, NULL);
|
$$ = MakeGenericDeclarationNode($1, NULL);
|
||||||
}
|
}
|
||||||
| Identifier COLON Type
|
|
||||||
{
|
|
||||||
$$ = MakeGenericDeclarationNode($1, $3);
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericDeclarations : GenericDeclaration
|
GenericDeclarations : GenericDeclaration
|
||||||
{
|
{
|
||||||
|
@ -443,28 +433,7 @@ Declarations : Declaration
|
||||||
$$ = AddDeclarationNode($1, $2);
|
$$ = AddDeclarationNode($1, $2);
|
||||||
}
|
}
|
||||||
|
|
||||||
InterfaceMember : FunctionSignature SEMICOLON
|
TopLevelDeclaration : StructDeclaration;
|
||||||
{
|
|
||||||
$$ = $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
|
||||||
{
|
{
|
||||||
|
|
54
generic.w
54
generic.w
|
@ -14,15 +14,6 @@ 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>());
|
||||||
|
@ -44,40 +35,25 @@ 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);
|
||||||
array.Set(0, 2);
|
block: MemoryBlock<int> = MemoryBlock<int>
|
||||||
array.Set(1, 0);
|
{
|
||||||
array.Set(2, 5);
|
capacity: y,
|
||||||
array.Set(3, 9);
|
start: @malloc(y * @sizeof<int>())
|
||||||
Console.PrintLine("%i", array.Get(0));
|
};
|
||||||
Console.PrintLine("%i", array.Get(3));
|
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();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
30
interface.w
30
interface.w
|
@ -1,30 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
48
src/ast.c
48
src/ast.c
|
@ -612,43 +612,6 @@ 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)
|
||||||
|
@ -1386,10 +1349,6 @@ 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;
|
||||||
|
|
||||||
|
@ -1429,7 +1388,6 @@ 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:
|
||||||
|
@ -1500,11 +1458,6 @@ 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;
|
||||||
|
|
||||||
|
@ -1559,7 +1512,6 @@ void LinkParentPointers(Node *node, Node *prev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Type:
|
case Type:
|
||||||
LinkParentPointers(node->type.typeNode, node);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case UnaryExpression:
|
case UnaryExpression:
|
||||||
|
|
23
src/ast.h
23
src/ast.h
|
@ -39,8 +39,6 @@ typedef enum
|
||||||
Identifier,
|
Identifier,
|
||||||
IfStatement,
|
IfStatement,
|
||||||
IfElseStatement,
|
IfElseStatement,
|
||||||
Interface,
|
|
||||||
InterfaceMembers,
|
|
||||||
Number,
|
Number,
|
||||||
PrimitiveTypeNode,
|
PrimitiveTypeNode,
|
||||||
ReferenceTypeNode,
|
ReferenceTypeNode,
|
||||||
|
@ -286,19 +284,6 @@ 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;
|
||||||
|
@ -460,14 +445,6 @@ 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);
|
||||||
|
|
204
src/codegen.c
204
src/codegen.c
|
@ -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,30 +420,27 @@ 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] = malloc(sizeof(StructTypeDeclaration));
|
structTypeDeclarations[index].module = module;
|
||||||
structTypeDeclarations[index]->module = module;
|
structTypeDeclarations[index].structType = wStructType;
|
||||||
structTypeDeclarations[index]->structType = wStructType;
|
structTypeDeclarations[index].structPointerType = wStructPointerType;
|
||||||
structTypeDeclarations[index]->structPointerType = wStructPointerType;
|
structTypeDeclarations[index].name = strdup(name);
|
||||||
structTypeDeclarations[index]->name = strdup(name);
|
structTypeDeclarations[index].fields = NULL;
|
||||||
structTypeDeclarations[index]->fields = NULL;
|
structTypeDeclarations[index].fieldCount = 0;
|
||||||
structTypeDeclarations[index]->fieldCount = 0;
|
structTypeDeclarations[index].functions = NULL;
|
||||||
structTypeDeclarations[index]->functions = NULL;
|
structTypeDeclarations[index].functionCount = 0;
|
||||||
structTypeDeclarations[index]->functionCount = 0;
|
structTypeDeclarations[index].genericFunctions = NULL;
|
||||||
structTypeDeclarations[index]->genericFunctions = NULL;
|
structTypeDeclarations[index].genericFunctionCount = 0;
|
||||||
structTypeDeclarations[index]->genericFunctionCount = 0;
|
|
||||||
|
|
||||||
structTypeDeclarationCount += 1;
|
structTypeDeclarationCount += 1;
|
||||||
|
|
||||||
return structTypeDeclarations[index];
|
return &structTypeDeclarations[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
static MonomorphizedGenericStructHashEntry *CompileMonomorphizedGenericStruct(
|
static StructTypeDeclaration *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;
|
||||||
|
@ -489,25 +486,6 @@ static MonomorphizedGenericStructHashEntry *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)
|
||||||
{
|
{
|
||||||
|
@ -550,7 +528,7 @@ static MonomorphizedGenericStructHashEntry *CompileMonomorphizedGenericStruct(
|
||||||
|
|
||||||
PopScopeFrame(scope);
|
PopScopeFrame(scope);
|
||||||
|
|
||||||
return &hashArray->elements[hashArray->count - 1];;
|
return declaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
static StructTypeDeclaration *LookupGenericStructType(
|
static StructTypeDeclaration *LookupGenericStructType(
|
||||||
|
@ -600,20 +578,38 @@ static StructTypeDeclaration *LookupGenericStructType(
|
||||||
|
|
||||||
if (match)
|
if (match)
|
||||||
{
|
{
|
||||||
hashEntry = &hashArray->elements[j];
|
hashEntry = &hashArray->elements[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hashEntry == NULL)
|
if (hashEntry == NULL)
|
||||||
{
|
{
|
||||||
hashEntry =
|
StructTypeDeclaration *structTypeDeclaration =
|
||||||
CompileMonomorphizedGenericStruct(
|
CompileMonomorphizedGenericStruct(
|
||||||
&genericStructTypeDeclarations[i],
|
&genericStructTypeDeclarations[i],
|
||||||
genericTypeTags,
|
genericTypeTags,
|
||||||
typeTag->genericArgumentCount,
|
typeTag->genericArgumentCount);
|
||||||
hashArray,
|
|
||||||
typeHash);
|
hashArray->elements = realloc(
|
||||||
|
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;
|
||||||
|
@ -692,9 +688,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,9 +703,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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,18 +724,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);
|
||||||
}
|
}
|
||||||
|
@ -1179,29 +1175,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);
|
||||||
|
@ -1225,29 +1221,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);
|
||||||
|
@ -1373,31 +1369,6 @@ static LLVMValueRef CompileFunctionCallExpression(
|
||||||
*/
|
*/
|
||||||
if (functionCallExpression->functionCallExpression.identifier->syntaxKind ==
|
if (functionCallExpression->functionCallExpression.identifier->syntaxKind ==
|
||||||
AccessExpression)
|
AccessExpression)
|
||||||
{
|
|
||||||
if (functionCallExpression->functionCallExpression.identifier->accessExpression.accessee->syntaxKind ==
|
|
||||||
ConcreteGenericTypeNode)
|
|
||||||
{
|
|
||||||
TypeTag *typeTag =
|
|
||||||
MakeTypeTag(
|
|
||||||
functionCallExpression->functionCallExpression.identifier->accessExpression.accessee
|
|
||||||
);
|
|
||||||
LLVMTypeRef typeReference = ResolveType(typeTag);
|
|
||||||
|
|
||||||
char *functionName =
|
|
||||||
functionCallExpression->functionCallExpression.identifier
|
|
||||||
->accessExpression.accessor->identifier.name;
|
|
||||||
|
|
||||||
function = LookupFunctionByType(
|
|
||||||
typeReference,
|
|
||||||
functionName,
|
|
||||||
functionCallExpression,
|
|
||||||
&functionReturnType,
|
|
||||||
&isStatic
|
|
||||||
);
|
|
||||||
|
|
||||||
free(typeTag);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
LLVMTypeRef typeReference = LookupStructTypeByName(
|
LLVMTypeRef typeReference = LookupStructTypeByName(
|
||||||
functionCallExpression->functionCallExpression.identifier
|
functionCallExpression->functionCallExpression.identifier
|
||||||
|
@ -1430,7 +1401,6 @@ static LLVMValueRef CompileFunctionCallExpression(
|
||||||
&isStatic);
|
&isStatic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (
|
else if (
|
||||||
functionCallExpression->functionCallExpression.identifier->syntaxKind ==
|
functionCallExpression->functionCallExpression.identifier->syntaxKind ==
|
||||||
Identifier)
|
Identifier)
|
||||||
|
@ -1643,7 +1613,6 @@ 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");
|
||||||
|
|
||||||
|
@ -1659,40 +1628,19 @@ static LLVMValueRef CompileStructInitExpression(
|
||||||
.fieldInits[i]
|
.fieldInits[i]
|
||||||
->fieldInit.identifier->identifier.name);
|
->fieldInit.identifier->identifier.name);
|
||||||
|
|
||||||
LLVMValueRef fieldExpressionResult = CompileExpression(
|
LLVMBuildStore(
|
||||||
|
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 LLVMBuildLoad(
|
return structPointer;
|
||||||
builder,
|
|
||||||
structPointer,
|
|
||||||
"struct"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMValueRef CompileExpression(
|
static LLVMValueRef CompileExpression(
|
||||||
|
@ -2386,17 +2334,11 @@ 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 or interfaces are "
|
"top level declarations that are not structs are "
|
||||||
"forbidden!\n");
|
"forbidden!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
103
src/validation.c
103
src/validation.c
|
@ -432,41 +432,6 @@ 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;
|
||||||
|
@ -484,22 +449,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,58 +468,6 @@ void ConvertCustomsToGenerics(Node *node)
|
||||||
node->functionSignature.type =
|
node->functionSignature.type =
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue