From 7d5f5997120c1b91d6e7b5306c8888bd475c041f Mon Sep 17 00:00:00 2001 From: venko Date: Sat, 29 May 2021 18:27:13 -0700 Subject: [PATCH] Lots of bug fixes for id lookup --- src/ast.c | 315 +++++++++++++++++++++++++++++++++++++++++++++++------ src/ast.h | 4 +- src/main.c | 21 +--- 3 files changed, 291 insertions(+), 49 deletions(-) diff --git a/src/ast.c b/src/ast.c index f34fc61..51f416c 100644 --- a/src/ast.c +++ b/src/ast.c @@ -937,9 +937,16 @@ TypeTag *MakeTypeTag(Node *node) tag = MakeTypeTag(node->allocExpression.type); break; + case GenericArgument: + tag->type = Generic; + tag->value.genericType = strdup(node->genericArgument.identifier + ->identifier.name); + break; + case GenericTypeNode: tag->type = Generic; tag->value.genericType = strdup(node->genericType.name); + break; default: fprintf( @@ -949,6 +956,7 @@ TypeTag *MakeTypeTag(Node *node) SyntaxKindString(node->syntaxKind)); return NULL; } + return tag; } @@ -991,19 +999,167 @@ char *TypeTagToString(TypeTag *tag) } } -void LinkParentPointers(Node *node) +void LinkParentPointers(Node *node, Node *prev) { - static Node *parent = NULL; + if (node == NULL) return; - if (node == NULL) + node->parent = prev; + + uint32_t i; + switch (node->syntaxKind) { - fprintf(stderr, "wraith: Encountered NULL node while linking parent pointers.\n"); + case AccessExpression: + LinkParentPointers(node->accessExpression.accessee, node); + LinkParentPointers(node->accessExpression.accessor, node); + return; + + case AllocExpression: + LinkParentPointers(node->allocExpression.type, node); + return; + + case Assignment: + LinkParentPointers(node->assignmentStatement.left, node); + LinkParentPointers(node->assignmentStatement.right, node); + return; + + case BinaryExpression: + LinkParentPointers(node->binaryExpression.left, node); + LinkParentPointers(node->binaryExpression.right, node); + return; + + case Comment: + return; + + case CustomTypeNode: + return; + + case Declaration: + LinkParentPointers(node->declaration.type, node); + LinkParentPointers(node->declaration.identifier, node); + return; + + case DeclarationSequence: + for (i = 0; i < node->declarationSequence.count; i += 1) { + LinkParentPointers(node->declarationSequence.sequence[i], node); + } + return; + + case ForLoop: + LinkParentPointers(node->forLoop.declaration, node); + LinkParentPointers(node->forLoop.startNumber, node); + LinkParentPointers(node->forLoop.endNumber, node); + LinkParentPointers(node->forLoop.statementSequence, node); + return; + + case FunctionArgumentSequence: + for (i = 0; i < node->functionArgumentSequence.count; i += 1) { + LinkParentPointers(node->functionArgumentSequence.sequence[i], node); + } + return; + + case FunctionCallExpression: + LinkParentPointers(node->functionCallExpression.identifier, node); + LinkParentPointers(node->functionCallExpression.argumentSequence, node); + return; + + case FunctionDeclaration: + LinkParentPointers(node->functionDeclaration.functionSignature, node); + LinkParentPointers(node->functionDeclaration.functionBody, node); + return; + + case FunctionModifiers: + for (i = 0; i < node->functionModifiers.count; i += 1) { + LinkParentPointers(node->functionModifiers.sequence[i], node); + } + return; + + case FunctionSignature: + LinkParentPointers(node->functionSignature.identifier, node); + LinkParentPointers(node->functionSignature.type, node); + LinkParentPointers(node->functionSignature.arguments, node); + LinkParentPointers(node->functionSignature.modifiers, node); + LinkParentPointers(node->functionSignature.genericArguments, node); + return; + + case FunctionSignatureArguments: + for (i = 0; i < node->functionSignatureArguments.count; i += 1) { + LinkParentPointers(node->functionSignatureArguments.sequence[i], node); + } + return; + + case GenericArgument: + LinkParentPointers(node->genericArgument.identifier, node); + LinkParentPointers(node->genericArgument.constraint, node); + return; + + case GenericArguments: + for (i = 0; i < node->genericArguments.count; i += 1) { + LinkParentPointers(node->genericArguments.arguments[i], node); + } + return; + + case GenericTypeNode: + return; + + case Identifier: + return; + + case IfStatement: + LinkParentPointers(node->ifStatement.expression, node); + LinkParentPointers(node->ifStatement.statementSequence, node); + return; + + case IfElseStatement: + LinkParentPointers(node->ifElseStatement.ifStatement, node); + LinkParentPointers(node->ifElseStatement.elseStatement, node); + return; + + case Number: + return; + + case PrimitiveTypeNode: + return; + + case ReferenceTypeNode: + LinkParentPointers(node->referenceType.type, node); + return; + + case Return: + LinkParentPointers(node->returnStatement.expression, node); + return; + + case ReturnVoid: + return; + + case StatementSequence: + for (i = 0; i < node->statementSequence.count; i += 1) { + LinkParentPointers(node->statementSequence.sequence[i], node); + } + return; + + case StaticModifier: + return; + + case StringLiteral: + return; + + case StructDeclaration: + LinkParentPointers(node->structDeclaration.identifier, node); + LinkParentPointers(node->structDeclaration.declarationSequence, node); + return; + + case Type: + return; + + case UnaryExpression: + LinkParentPointers(node->unaryExpression.child, node); + return; + + default: + fprintf(stderr, "wraith: Unhandled SyntaxKind %s in recurse function.\n", + SyntaxKindString(node->syntaxKind)); return; } - - node->parent = parent; - parent = node; - Recurse(node, *LinkParentPointers); } Node *GetIdFromStruct(Node *structDecl) @@ -1082,12 +1238,14 @@ Node *TryGetId(Node *node) { switch (node->syntaxKind) { - case StructDeclaration: - return GetIdFromStruct(node); - case FunctionDeclaration: - return GetIdFromFunction(node); + case Assignment: + return GetIdFromAssignment(node); case Declaration: return GetIdFromDeclaration(node); + case FunctionDeclaration: + return GetIdFromFunction(node); + case StructDeclaration: + return GetIdFromStruct(node); default: return NULL; } @@ -1120,36 +1278,69 @@ Node *LookupFunctionArgId(Node *funcDecl, char *target) return NULL; } -Node *LookupIdNode(Node *current, Node *prev, char *target) +Node *LookupStructInternalId(Node *structDecl, char *target) { - if (current == NULL) return NULL; + Node *decls = structDecl->structDeclaration.declarationSequence; + uint32_t i; + for (i = 0; i < decls->declarationSequence.count; i += 1) + { + Node *match = TryGetId(decls->declarationSequence.sequence[i]); + if (match != NULL && strcmp(target, match->identifier.name) == 0) + return match; + } + + return NULL; +} + +Node *InspectNode(Node *node, char *target) +{ /* If this node may have an identifier declaration inside it, attempt to look up the identifier * node itself, returning it if it matches the given target name. */ - if (NodeMayHaveId(current)) + if (NodeMayHaveId(node)) { - Node *candidateId = TryGetId(current); + Node *candidateId = TryGetId(node); if (candidateId != NULL && strcmp(target, candidateId->identifier.name) == 0) { return candidateId; } - - /* If the candidate node was not the one we wanted, but the current node is a function - * declaration, it's possible that the identifier we want is one of the function's - * parameters rather than the function's name itself. */ - if (current->syntaxKind == FunctionDeclaration) - { - Node *match = LookupFunctionArgId(current, target); - if (match != NULL) return match; - } } + /* If the candidate node was not the one we wanted, but the node node is a function + * declaration, it's possible that the identifier we want is one of the function's + * parameters rather than the function's name itself. */ + if (node->syntaxKind == FunctionDeclaration) + { + Node *match = LookupFunctionArgId(node, target); + if (match != NULL) return match; + } + + /* Likewise if the node node is a struct declaration, inspect the struct's internals + * to see if a top-level definition is the one we're looking for. */ + if (node->syntaxKind == StructDeclaration) + { + Node *match = LookupStructInternalId(node, target); + if (match != NULL) return match; + } + + return NULL; +} + +Node *LookupIdNode(Node *current, Node *prev, char *target) +{ + if (current == NULL) return NULL; + Node *match; + + /* First inspect the current node to see if it contains the target identifier. */ + match = InspectNode(current, target); + if (match != NULL) return match; + /* If this is the start of our search, we should not attempt to look at * child nodes. Only looking up the AST is valid at this point. * * This has the notable side-effect that this function will return NULL if * you attempt to look up a struct's internals starting from the node - * representing the struct itself. */ + * representing the struct itself. The same is true for functions. */ if (prev == NULL) { return LookupIdNode(current->parent, current, target); @@ -1163,8 +1354,11 @@ Node *LookupIdNode(Node *current, Node *prev, char *target) for (i = 0; i < current->declarationSequence.count; i += 1) { Node *decl = current->declarationSequence.sequence[i]; - Node *declId = TryGetId(decl); - if (declId != NULL) return declId; + match = InspectNode(decl, target); + if (match != NULL) return match; + /*Node *declId = TryGetId(decl); + if (declId != NULL && strcmp(target, declId->identifier.name) == 0) + return declId;*/ } break; case StatementSequence: @@ -1183,16 +1377,73 @@ Node *LookupIdNode(Node *current, Node *prev, char *target) Node *stmt = current->statementSequence.sequence[i]; if (stmt == prev) continue; - if (NodeMayHaveId(stmt)) + if (strcmp(target, "g") == 0) { + printf("info: %s\n", SyntaxKindString(stmt->syntaxKind)); + } + + match = InspectNode(stmt, target); + if (match != NULL) return match; + /*if (NodeMayHaveId(stmt)) { Node *candidateId = TryGetId(current); if (candidateId != NULL && strcmp(target, candidateId->identifier.name) == 0) - { return candidateId; - } - } + }*/ } break; } + return LookupIdNode(current->parent, current, target); } + +void IdentifierPass(Node *node) +{ + if (node == NULL) return; + + switch (node->syntaxKind) + { + case AllocExpression: + node->typeTag = MakeTypeTag(node); + break; + + case Declaration: + node->declaration.identifier->typeTag = MakeTypeTag(node); + break; + + case FunctionDeclaration: + node->functionDeclaration.functionSignature + ->functionSignature.identifier->typeTag = MakeTypeTag(node); + break;; + + case StructDeclaration: + node->structDeclaration.identifier->typeTag = MakeTypeTag(node); + break; + + case GenericArgument: + node->genericArgument.identifier->typeTag = MakeTypeTag(node); + break; + + case Identifier: + { + if (node->typeTag != NULL) return; + + char *name = node->identifier.name; + Node *declaration = LookupIdNode(node, NULL, name); + if (declaration == NULL) + { + /* FIXME: Express this case as an error with AST information. */ + fprintf(stderr, "wraith: Could not find definition of identifier %s.\n", name); + TypeTag *tag = (TypeTag *)malloc(sizeof(TypeTag)); + tag->type = Unknown; + node->typeTag = tag; + } + else + { + node->typeTag = declaration->typeTag; + } + break; + } + } + + Recurse(node, *IdentifierPass); +} \ No newline at end of file diff --git a/src/ast.h b/src/ast.h index 967cbe5..251f0f6 100644 --- a/src/ast.h +++ b/src/ast.h @@ -373,10 +373,12 @@ const char *SyntaxKindString(SyntaxKind syntaxKind); * function in all other cases. */ void Recurse(Node *node, void (*func)(Node*)); -void LinkParentPointers(Node *node); +void LinkParentPointers(Node *node, Node *prev); TypeTag *MakeTypeTag(Node *node); char *TypeTagToString(TypeTag *tag); Node *LookupIdNode(Node *current, Node *prev, char *target); + +void IdentifierPass(Node *node); #endif /* WRAITH_AST_H */ diff --git a/src/main.c b/src/main.c index 044210c..1b7c70b 100644 --- a/src/main.c +++ b/src/main.c @@ -86,23 +86,12 @@ int main(int argc, char *argv[]) } else { - LinkParentPointers(rootNode); - { - IdNode *idTree = MakeIdTree(rootNode, NULL); - printf("\n"); - PrintIdTree(idTree, /*tabCount=*/0); + LinkParentPointers(rootNode, NULL); + IdentifierPass(rootNode); + /*ConvertASTCustomsToGenerics(rootNode);*/ + PrintNode(rootNode, 0); - printf("\nConverting custom types in the ID-tree.\n"); - ConvertIdCustomsToGenerics(idTree); - printf("\n"); - PrintIdTree(idTree, /*tabCount=*/0); - - printf("\nConverting custom type nodes in the AST.\n"); - ConvertASTCustomsToGenerics(rootNode); - printf("\n"); - PrintNode(rootNode, /*tabCount=*/0); - - } + printf("Beginning codegen.\n"); exitCode = Codegen(rootNode, optimizationLevel); } }