#include "Sema/ReferenceResolver.h" void ReferenceResolver::visit(const SharedPtr &module) { pushScope(module->internalScope); ASTVisitor::visit(module); popScope(); } void ReferenceResolver::visit(const SharedPtr &varDecl) { if (getCurrentScope()->hasVariable(varDecl->name)) { reportSemanticError("Variable repeated definition: " + varDecl->name); } else { getCurrentScope()->addVariable(varDecl->name, varDecl); } ASTVisitor::visit(varDecl); } void ReferenceResolver::visit(const SharedPtr ¶mVarDecl) { if (getCurrentScope()->hasVariable(paramVarDecl->name)) { reportSemanticError("Repeated definition of function parameters: " + paramVarDecl->name); } else { getCurrentScope()->addVariable(paramVarDecl->name, paramVarDecl); } } void ReferenceResolver::visit(const SharedPtr &funcDecl) { const SharedPtr &topLevelScope = dynPtrCast(getCurrentScope()); if (topLevelScope->hasFunction(funcDecl->name)) { reportSemanticError("Function repeated definition: " + funcDecl->name); } else { topLevelScope->addFunction(funcDecl->name, funcDecl); } pushScope(funcDecl->internalScope); ASTVisitor::visit(funcDecl); popScope(); } void ReferenceResolver::visit(const SharedPtr &varExpr) { const SharedPtr &varDecl = resolveVariable(varExpr->name); if (varDecl) { varExpr->refVarDecl = varDecl; } else { reportSemanticError("Variable undefined: " + varExpr->name); } } void ReferenceResolver::visit(const SharedPtr &callExpr) { SharedPtr funcDecl = resolveFunction(callExpr->calleeName); if (funcDecl) { callExpr->refFuncDecl = funcDecl; } else { reportSemanticError("Function undefined: " + callExpr->calleeName); } ASTVisitor::visit(callExpr); } void ReferenceResolver::visit(const SharedPtr &compStmt) { pushScope(compStmt->internalScope); ASTVisitor::visit(compStmt); popScope(); } void ReferenceResolver::visit(const SharedPtr &forStmt) { pushScope(forStmt->internalScope); ASTVisitor::visit(forStmt); popScope(); } void ReferenceResolver::visit(const SharedPtr &continueStmt) { continueStmt->refIterationStmt = resolveRefIterationStmt(continueStmt); } void ReferenceResolver::visit(const SharedPtr &breakStmt) { breakStmt->refIterationStmt = resolveRefIterationStmt(breakStmt); } void ReferenceResolver::visit(const SharedPtr &returnStmt) { SharedPtr scope = returnStmt->scope->getParent(); SharedPtr funcDecl; while (scope) { funcDecl = dynPtrCast(scope->host); if (funcDecl) { break; } scope = scope->getParent(); } if (funcDecl) { returnStmt->refFuncDecl = funcDecl; funcDecl->refReturnStmt = returnStmt; } else { // 这里本应该是语义合法性检查器的责任, 但是类型检查器要使用到refFuncDecl信息,所以提前到这里做 reportSemanticError("The return statement muse be in a function"); } ASTVisitor::visit(returnStmt); } SharedPtr ReferenceResolver::resolveRefIterationStmt(const SharedPtr &node) { SharedPtr iterNode = node->parent; SharedPtr refWhileStmt = nullptr; SharedPtr refForStmt = nullptr; while (iterNode) { SharedPtr whileStmt = dynPtrCast(iterNode); if (whileStmt) { refWhileStmt = whileStmt; break; } SharedPtr forStmt = dynPtrCast(iterNode); if (forStmt) { refForStmt = forStmt; break; } iterNode = iterNode->parent; } if (refWhileStmt) { return refWhileStmt; } return refForStmt; }