forked from cosmonaut/wraith-lang
203 lines
6.6 KiB
C
203 lines
6.6 KiB
C
|
#include "typeutils.h"
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
void ConvertIdCustomsToGenerics(IdNode *node) {
|
||
|
uint32_t i;
|
||
|
switch(node->type)
|
||
|
{
|
||
|
case UnorderedScope:
|
||
|
case OrderedScope:
|
||
|
case Struct:
|
||
|
/* FIXME: This case will need to be modified to handle type parameters over structs. */
|
||
|
for (i = 0; i < node->childCount; i += 1) {
|
||
|
ConvertIdCustomsToGenerics(node->children[i]);
|
||
|
}
|
||
|
return;
|
||
|
|
||
|
case Variable: {
|
||
|
TypeTag *varType = node->typeTag;
|
||
|
if (varType->type == Custom) {
|
||
|
IdNode *x = LookupId(node->parent, node, varType->value.customType);
|
||
|
if (x != NULL && x->type == GenericType) {
|
||
|
varType->type = Generic;
|
||
|
}
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
case Function: {
|
||
|
TypeTag *funcType = node->typeTag;
|
||
|
if (funcType->type == Custom) {
|
||
|
/* For functions we have to handle the type lookup manually since the generic type
|
||
|
* identifiers are declared as children of the function's IdNode. */
|
||
|
for (i = 0; i < node->childCount; i += 1) {
|
||
|
IdNode *child = node->children[i];
|
||
|
if (child->type == GenericType && strcmp(child->name, funcType->value.customType) == 0) {
|
||
|
funcType->type = Generic;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < node->childCount; i += 1) {
|
||
|
ConvertIdCustomsToGenerics(node->children[i]);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ConvertASTCustomsToGenerics(Node *node) {
|
||
|
uint32_t i;
|
||
|
switch (node->syntaxKind) {
|
||
|
case AccessExpression:
|
||
|
ConvertASTCustomsToGenerics(node->accessExpression.accessee);
|
||
|
ConvertASTCustomsToGenerics(node->accessExpression.accessor);
|
||
|
return;
|
||
|
|
||
|
case AllocExpression:
|
||
|
ConvertASTCustomsToGenerics(node->allocExpression.type);
|
||
|
return;
|
||
|
|
||
|
case Assignment:
|
||
|
ConvertASTCustomsToGenerics(node->assignmentStatement.left);
|
||
|
ConvertASTCustomsToGenerics(node->assignmentStatement.right);
|
||
|
return;
|
||
|
|
||
|
case BinaryExpression:
|
||
|
ConvertASTCustomsToGenerics(node->binaryExpression.left);
|
||
|
ConvertASTCustomsToGenerics(node->binaryExpression.right);
|
||
|
return;
|
||
|
|
||
|
case Comment:
|
||
|
return;
|
||
|
|
||
|
case CustomTypeNode:
|
||
|
return;
|
||
|
|
||
|
case Declaration: {
|
||
|
Node *type = node->declaration.type->type.typeNode;
|
||
|
Node *id = node->declaration.identifier;
|
||
|
if (id->typeTag->type == Generic && type->syntaxKind == CustomTypeNode) {
|
||
|
free(node->declaration.type);
|
||
|
node->declaration.type = MakeGenericTypeNode(id->typeTag->value.genericType);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
case DeclarationSequence:
|
||
|
for (i = 0; i < node->declarationSequence.count; i += 1) {
|
||
|
ConvertASTCustomsToGenerics(node->declarationSequence.sequence[i]);
|
||
|
}
|
||
|
return;
|
||
|
|
||
|
case ForLoop:
|
||
|
ConvertASTCustomsToGenerics(node->forLoop.declaration);
|
||
|
ConvertASTCustomsToGenerics(node->forLoop.startNumber);
|
||
|
ConvertASTCustomsToGenerics(node->forLoop.endNumber);
|
||
|
ConvertASTCustomsToGenerics(node->forLoop.statementSequence);
|
||
|
return;
|
||
|
|
||
|
case FunctionArgumentSequence:
|
||
|
for (i = 0; i < node->functionArgumentSequence.count; i += 1) {
|
||
|
ConvertASTCustomsToGenerics(node->functionArgumentSequence.sequence[i]);
|
||
|
}
|
||
|
return;
|
||
|
|
||
|
case FunctionCallExpression:
|
||
|
ConvertASTCustomsToGenerics(node->functionCallExpression.identifier);
|
||
|
ConvertASTCustomsToGenerics(node->functionCallExpression.argumentSequence);
|
||
|
return;
|
||
|
|
||
|
case FunctionDeclaration:
|
||
|
ConvertASTCustomsToGenerics(node->functionDeclaration.functionSignature);
|
||
|
ConvertASTCustomsToGenerics(node->functionDeclaration.functionBody);
|
||
|
return;
|
||
|
|
||
|
case FunctionModifiers:
|
||
|
return;
|
||
|
|
||
|
case FunctionSignature:{
|
||
|
Node *id = node->functionSignature.identifier;
|
||
|
Node *type = node->functionSignature.type;
|
||
|
if (id->typeTag->type == Generic && type->syntaxKind == CustomTypeNode) {
|
||
|
free(node->functionSignature.type);
|
||
|
node->functionSignature.type = MakeGenericTypeNode(id->typeTag->value.genericType);
|
||
|
}
|
||
|
ConvertASTCustomsToGenerics(node->functionSignature.arguments);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
case FunctionSignatureArguments:
|
||
|
for (i = 0; i < node->functionSignatureArguments.count; i += 1) {
|
||
|
ConvertASTCustomsToGenerics(node->functionSignatureArguments.sequence[i]);
|
||
|
}
|
||
|
return;
|
||
|
|
||
|
case GenericArgument:
|
||
|
return;
|
||
|
|
||
|
case GenericArguments:
|
||
|
return;
|
||
|
|
||
|
case GenericTypeNode:
|
||
|
return;
|
||
|
|
||
|
case Identifier:
|
||
|
return;
|
||
|
|
||
|
case IfStatement:
|
||
|
ConvertASTCustomsToGenerics(node->ifStatement.expression);
|
||
|
ConvertASTCustomsToGenerics(node->ifStatement.statementSequence);
|
||
|
return;
|
||
|
|
||
|
case IfElseStatement:
|
||
|
ConvertASTCustomsToGenerics(node->ifElseStatement.ifStatement);
|
||
|
ConvertASTCustomsToGenerics(node->ifElseStatement.elseStatement);
|
||
|
return;
|
||
|
|
||
|
case Number:
|
||
|
return;
|
||
|
|
||
|
case PrimitiveTypeNode:
|
||
|
return;
|
||
|
|
||
|
case ReferenceTypeNode:
|
||
|
return;
|
||
|
|
||
|
case Return:
|
||
|
ConvertASTCustomsToGenerics(node->returnStatement.expression);
|
||
|
return;
|
||
|
|
||
|
case ReturnVoid:
|
||
|
return;
|
||
|
|
||
|
case StatementSequence:
|
||
|
for (i = 0; i < node->statementSequence.count; i += 1) {
|
||
|
ConvertASTCustomsToGenerics(node->statementSequence.sequence[i]);
|
||
|
}
|
||
|
return;
|
||
|
|
||
|
case StaticModifier:
|
||
|
return;
|
||
|
|
||
|
case StringLiteral:
|
||
|
return;
|
||
|
|
||
|
case StructDeclaration:
|
||
|
/* FIXME: This case will need to be modified to handle type parameters over structs. */
|
||
|
ConvertASTCustomsToGenerics(node->structDeclaration.identifier);
|
||
|
ConvertASTCustomsToGenerics(node->structDeclaration.declarationSequence);
|
||
|
return;
|
||
|
|
||
|
case Type:
|
||
|
return;
|
||
|
|
||
|
case UnaryExpression:
|
||
|
ConvertASTCustomsToGenerics(node->unaryExpression.child);
|
||
|
return;
|
||
|
}
|
||
|
}
|