groundwork for struct generics

pull/11/head
cosmonaut 2021-06-02 19:03:58 -07:00
parent a571edcf6d
commit f3435f8659
4 changed files with 115 additions and 11 deletions

View File

@ -113,9 +113,13 @@ BaseType : VOID
{
$$ = MakePrimitiveTypeNode(MemoryAddress);
}
| Identifier GenericArgumentClauseNonEmpty
{
$$ = MakeConcreteGenericTypeNode($1, $2);
}
| Identifier
{
$$ = MakeCustomTypeNode(yytext);
$$ = MakeCustomTypeNode($1);
}
| REFERENCE LESS_THAN Type GREATER_THAN
{
@ -359,11 +363,13 @@ GenericArguments : GenericArgument
$$ = AddGenericArgument($1, $3);
}
GenericArgumentClause : LESS_THAN GenericArguments GREATER_THAN
GenericArgumentClauseNonEmpty : LESS_THAN GenericArguments GREATER_THAN
{
$$ = $2;
}
;
GenericArgumentClause : GenericArgumentClauseNonEmpty
|
{
$$ = MakeEmptyGenericArgumentsNode();

View File

@ -24,6 +24,7 @@ struct Program {
static Main(): int {
x: int = 4;
y: int = Foo.Func(x);
block: MemoryBlock<int>;
addr: MemoryAddress = @malloc(y);
@free(addr);
return x;

View File

@ -19,6 +19,8 @@ const char *SyntaxKindString(SyntaxKind syntaxKind)
return "BinaryExpression";
case Comment:
return "Comment";
case ConcreteGenericTypeNode:
return "ConcreteGenericTypeNode";
case CustomTypeNode:
return "CustomTypeNode";
case Declaration:
@ -95,11 +97,12 @@ Node *MakePrimitiveTypeNode(PrimitiveType type)
return node;
}
Node *MakeCustomTypeNode(char *name)
Node *MakeCustomTypeNode(Node *identifierNode)
{
Node *node = (Node *)malloc(sizeof(Node));
node->syntaxKind = CustomTypeNode;
node->customType.name = strdup(name);
node->customType.name = strdup(identifierNode->identifier.name);
free(identifierNode);
return node;
}
@ -111,6 +114,18 @@ Node *MakeReferenceTypeNode(Node *typeNode)
return node;
}
Node *MakeConcreteGenericTypeNode(
Node *identifierNode,
Node *genericArgumentsNode)
{
Node *node = (Node *)malloc(sizeof(Node));
node->syntaxKind = ConcreteGenericTypeNode;
node->concreteGenericType.name = strdup(identifierNode->identifier.name);
node->concreteGenericType.genericArguments = genericArgumentsNode;
free(identifierNode);
return node;
}
Node *MakeTypeNode(Node *typeNode)
{
Node *node = (Node *)malloc(sizeof(Node));
@ -624,6 +639,11 @@ void PrintNode(Node *node, uint32_t tabCount)
PrintNode(node->binaryExpression.right, tabCount + 1);
return;
case ConcreteGenericTypeNode:
printf("%s\n", node->concreteGenericType.name);
PrintNode(node->concreteGenericType.genericArguments, tabCount + 1);
return;
case CustomTypeNode:
printf("%s\n", node->customType.name);
return;
@ -843,6 +863,10 @@ void Recurse(Node *node, void (*func)(Node *))
case Comment:
return;
case ConcreteGenericTypeNode:
func(node->concreteGenericType.genericArguments);
return;
case CustomTypeNode:
return;
@ -1004,6 +1028,8 @@ void Recurse(Node *node, void (*func)(Node *))
TypeTag *MakeTypeTag(Node *node)
{
uint32_t i;
if (node == NULL)
{
fprintf(
@ -1034,6 +1060,28 @@ TypeTag *MakeTypeTag(Node *node)
tag->value.customType = strdup(node->customType.name);
break;
case ConcreteGenericTypeNode:
tag->type = ConcreteGeneric;
tag->value.concreteGenericType.name =
strdup(node->concreteGenericType.name);
tag->value.concreteGenericType.genericArgumentCount =
node->concreteGenericType.genericArguments->genericArguments.count;
tag->value.concreteGenericType.genericArguments = malloc(
sizeof(TypeTag *) *
tag->value.concreteGenericType.genericArgumentCount);
for (i = 0;
i <
node->concreteGenericType.genericArguments->genericArguments.count;
i += 1)
{
tag->value.concreteGenericType.genericArguments[i] = MakeTypeTag(
node->concreteGenericType.genericArguments->genericArguments
.arguments[i]
->genericArgument.type);
}
break;
case Declaration:
tag = MakeTypeTag(node->declaration.type);
break;
@ -1078,6 +1126,8 @@ TypeTag *MakeTypeTag(Node *node)
char *TypeTagToString(TypeTag *tag)
{
uint32_t i;
if (tag == NULL)
{
fprintf(
@ -1114,6 +1164,31 @@ char *TypeTagToString(TypeTag *tag)
sprintf(result, "Generic<%s>", tag->value.genericType);
return result;
}
case ConcreteGeneric:
{
char *result = strdup(tag->value.concreteGenericType.name);
uint32_t len = strlen(result);
result = realloc(result, len + 2);
strcat(result, "<");
for (i = 0; i < tag->value.concreteGenericType.genericArgumentCount;
i += 1)
{
char *inner = TypeTagToString(
tag->value.concreteGenericType.genericArguments[i]);
len += strlen(inner);
result = realloc(result, sizeof(char) * (len + 3));
if (i != tag->value.concreteGenericType.genericArgumentCount - 1)
{
strcat(result, ", ");
}
strcat(result, inner);
}
result = realloc(result, sizeof(char) * (len + 2));
strcat(result, ">");
return result;
}
}
}

View File

@ -19,6 +19,7 @@ typedef enum
Assignment,
BinaryExpression,
Comment,
ConcreteGenericTypeNode,
CustomTypeNode,
Declaration,
DeclarationSequence,
@ -86,7 +87,16 @@ typedef union
BinaryOperator binaryOperator;
} Operator;
typedef struct TypeTag
typedef struct TypeTag TypeTag;
typedef struct ConcreteGenericTypeTag
{
char *name;
TypeTag **genericArguments;
uint32_t genericArgumentCount;
} ConcreteGenericTypeTag;
struct TypeTag
{
enum Type
{
@ -94,7 +104,8 @@ typedef struct TypeTag
Primitive,
Reference,
Custom,
Generic
Generic,
ConcreteGeneric
} type;
union
{
@ -106,8 +117,10 @@ typedef struct TypeTag
char *customType;
/* Valid when type = Generic. */
char *genericType;
/* Valid when type = ConcreteGeneric */
ConcreteGenericTypeTag concreteGenericType;
} value;
} TypeTag;
};
typedef struct Node Node;
@ -146,6 +159,12 @@ struct Node
} comment;
struct
{
char *name;
Node *genericArguments;
} concreteGenericType;
struct
{
char *name;
@ -329,8 +348,11 @@ const char *SyntaxKindString(SyntaxKind syntaxKind);
uint8_t IsPrimitiveType(Node *typeNode);
Node *MakePrimitiveTypeNode(PrimitiveType type);
Node *MakeCustomTypeNode(char *string);
Node *MakeCustomTypeNode(Node *identifierNode);
Node *MakeReferenceTypeNode(Node *typeNode);
Node *MakeConcreteGenericTypeNode(
Node *identifierNode,
Node *genericArgumentsNode);
Node *MakeTypeNode(Node *typeNode);
Node *MakeIdentifierNode(const char *id);
Node *MakeNumberNode(const char *numberString);