groundwork for struct generics
parent
a571edcf6d
commit
f3435f8659
|
@ -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);
|
||||
}
|
||||
|
||||
GenericArgumentClauseNonEmpty : LESS_THAN GenericArguments GREATER_THAN
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
GenericArgumentClause : LESS_THAN GenericArguments GREATER_THAN
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
GenericArgumentClause : GenericArgumentClauseNonEmpty
|
||||
|
|
||||
{
|
||||
$$ = MakeEmptyGenericArgumentsNode();
|
||||
|
|
|
@ -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;
|
||||
|
|
79
src/ast.c
79
src/ast.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
30
src/ast.h
30
src/ast.h
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue