#include "typeutils.h" #include #include #include 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; } }