From 70a0d2ab0aeb819874e2ccb99a82046d4c52e660 Mon Sep 17 00:00:00 2001 From: ZhuangYumin Date: Wed, 14 Aug 2024 15:54:02 +0000 Subject: [PATCH] add error message --- include/ast/scope.hpp | 12 +++--- src/ast/semanticvisitor.cpp | 82 ++++++++++++++++++------------------- src/semantic/visitor.cpp | 8 ++-- 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/include/ast/scope.hpp b/include/ast/scope.hpp index 3bb26c8..6a1cf45 100644 --- a/include/ast/scope.hpp +++ b/include/ast/scope.hpp @@ -35,11 +35,11 @@ class LocalScope : public ScopeBase { return false; } if (std::holds_alternative(type) && std::get(type) == "void") { - throw SemanticError("Variable cannot be void", 1); + throw SemanticError("Invalid Type", 1); } if (std::holds_alternative(type) && std::get(type).has_base_type && std::get(type).basetype == "void") { - throw SemanticError("Variable cannot be void", 1); + throw SemanticError("Invalid Type", 1); } local_variables[name] = type; return true; @@ -109,11 +109,11 @@ class ClassDefScope : public ScopeBase { return false; } if (std::holds_alternative(type) && std::get(type) == "void") { - throw SemanticError("Variable cannot be void", 1); + throw SemanticError("Invalid Type", 1); } if (std::holds_alternative(type) && std::get(type).has_base_type && std::get(type).basetype == "void") { - throw SemanticError("Variable cannot be void", 1); + throw SemanticError("Invalid Type", 1); } member_variables[name] = type; return true; @@ -218,11 +218,11 @@ class GlobalScope : public ScopeBase { return false; } if (std::holds_alternative(type) && std::get(type) == "void") { - throw SemanticError("Variable cannot be void", 1); + throw SemanticError("Invalid Type", 1); } if (std::holds_alternative(type) && std::get(type).has_base_type && std::get(type).basetype == "void") { - throw SemanticError("Variable cannot be void", 1); + throw SemanticError("Invalid Type", 1); } global_variables[name] = type; return true; diff --git a/src/ast/semanticvisitor.cpp b/src/ast/semanticvisitor.cpp index 23f17f9..24c2415 100644 --- a/src/ast/semanticvisitor.cpp +++ b/src/ast/semanticvisitor.cpp @@ -13,7 +13,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(FuncDef_ASTNode *node) { node->func_body->accept(this); if (!has_return && std::holds_alternative(cur_func_schema.return_type) && std::get(cur_func_schema.return_type) != "void" && node->func_name != "main") { - throw SemanticError("Non-void function must have a return value", 1); + throw SemanticError("Missing Return Statement", 1); } std::cerr << "leave function " << node->func_name << std::endl; is_in_func_def = false; @@ -69,7 +69,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(DefinitionStatement_ASTNode *node) { var.second->accept(this); } if (!cur_scope->add_variable(var.first, node->var_type)) { - throw SemanticError("Variable redefinition for " + var.first, 1); + throw SemanticError("Multiple Definitions", 1); } if (var.second) { if (node->var_type != var.second->expr_type_info) { @@ -85,7 +85,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(IfStatement_ASTNode *node) { node->condition->accept(this); const static ExprTypeInfo standard = "bool"; if (node->condition->expr_type_info != standard) { - throw SemanticError("If condition must be bool", 1); + throw SemanticError("Invalid Type", 1); } node->if_clause->accept(this); if (node->has_else_clause) { @@ -97,7 +97,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(WhileStatement_ASTNode *node) { node->condition->accept(this); const static ExprTypeInfo standard = "bool"; if (node->condition->expr_type_info != standard) { - throw SemanticError("While condition must be bool", 1); + throw SemanticError("Invalid Type", 1); } loop_level++; node->loop_body->accept(this); @@ -112,7 +112,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(ForStatement_ASTNode *node) { node->condition->accept(this); const static ExprTypeInfo standard = "bool"; if (node->condition->expr_type_info != standard) { - throw SemanticError("For condition must be bool", 1); + throw SemanticError("Invalid Type", 1); } } if (node->update) { @@ -124,7 +124,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(ForStatement_ASTNode *node) { } void ASTSemanticCheckVisitor::ActuralVisit(JmpStatement_ASTNode *node) { - if (loop_level == 0 && node->jmp_type > 0) throw SemanticError("Jump statement outside loop", 1); + if (loop_level == 0 && node->jmp_type > 0) throw SemanticError("Invalid Control Flow", 1); if (node->jmp_type == 0) { if (node->return_value) { has_return = true; @@ -149,34 +149,34 @@ void ASTSemanticCheckVisitor::ActuralVisit(SuiteStatement_ASTNode *node) { // Expression AST Nodes void ASTSemanticCheckVisitor::ActuralVisit(NewArrayExpr_ASTNode *node) { if (std::get(node->expr_type_info).basetype == "void") { - throw SemanticError("Array base type cannot be void", 1); + throw SemanticError("Invalid Type", 1); } for (size_t i = 0; i < node->dim_size.size(); i++) { if (node->dim_size[i]) { node->dim_size[i]->accept(this); const static ExprTypeInfo standard = "int"; if (node->dim_size[i]->expr_type_info != standard) { - throw SemanticError("Array dimension must be int", 1); + throw SemanticError("Type Mismatch", 1); } } } if (node->has_initial_value) { node->initial_value->accept(this); if (node->expr_type_info != node->initial_value->expr_type_info) { - throw SemanticError("Array type mismatch", 1); + throw SemanticError("Type Mismatch", 1); } } } void ASTSemanticCheckVisitor::ActuralVisit(NewConstructExpr_ASTNode *node) { if (std::get(node->expr_type_info) == "void") { - throw SemanticError("Cannot construct void", 1); + throw SemanticError("Invalid Type", 1); } } void ASTSemanticCheckVisitor::ActuralVisit(NewExpr_ASTNode *node) { if (std::get(node->expr_type_info) == "void") { - throw SemanticError("Cannot construct void", 1); + throw SemanticError("Invalid Type", 1); } } @@ -188,23 +188,23 @@ void ASTSemanticCheckVisitor::ActuralVisit(AccessExpr_ASTNode *node) { node->expr_type_info = "int"; return; } - throw SemanticError("Access on non-class", 1); + throw SemanticError("Type Mismatch", 1); } std::string base_type; try { base_type = std::get(node->base->expr_type_info); } catch (...) { - throw SemanticError("Access on non-class", 1); + throw SemanticError("Type Mismatch", 1); } if (node->is_function) { auto schema = global_scope->FetchClassMemberFunction(base_type, node->member); if (schema.arguments.size() != node->arguments.size()) { - throw SemanticError("Argument number mismatch", 1); + throw SemanticError("Type Mismatch", 1); } for (auto &arg : node->arguments) { arg->accept(this); if (arg->expr_type_info != schema.arguments[&arg - &node->arguments[0]].first) { - throw SemanticError("Argument type mismatch", 1); + throw SemanticError("Type Mismatch", 1); } } node->expr_type_info = schema.return_type; @@ -223,17 +223,17 @@ void ASTSemanticCheckVisitor::ActuralVisit(IndexExpr_ASTNode *node) { // TODO: Implement this method node->base->accept(this); if (std::holds_alternative(node->base->expr_type_info)) { - throw SemanticError("Indexing on non-array", 1); + throw SemanticError("Type Mismatch", 1); } const auto &tp = std::get(node->base->expr_type_info); if (tp.level < node->indices.size()) { - throw SemanticError("Indexing on non-array", 1); + throw SemanticError("Dimension Out Of Bound", 1); } for (auto idx : node->indices) { idx->accept(this); const static ExprTypeInfo standard = "int"; if (idx->expr_type_info != standard) { - throw SemanticError("Index must be int", 1); + throw SemanticError("Type Mismatch", 1); } } if (tp.level == node->indices.size()) { @@ -248,11 +248,11 @@ void ASTSemanticCheckVisitor::ActuralVisit(SuffixExpr_ASTNode *node) { // TODO: Implement this method node->base->accept(this); if (!node->base->assignable) { - throw SemanticError("Suffix operation on non-assignable", 1); + throw SemanticError("Type Mismatch", 1); } const static ExprTypeInfo standard = "int"; if (node->base->expr_type_info != standard) { - throw SemanticError("Suffix operation on non-int", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; } @@ -261,11 +261,11 @@ void ASTSemanticCheckVisitor::ActuralVisit(PrefixExpr_ASTNode *node) { // TODO: Implement this method node->base->accept(this); if (!node->base->assignable) { - throw SemanticError("Prefix operation on non-assignable", 1); + throw SemanticError("Type Mismatch", 1); } const static ExprTypeInfo standard = "int"; if (node->base->expr_type_info != standard) { - throw SemanticError("Prefix operation on non-int", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; node->assignable = true; @@ -276,7 +276,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(OppositeExpr_ASTNode *node) { node->base->accept(this); const static ExprTypeInfo standard = "int"; if (node->base->expr_type_info != standard) { - throw SemanticError("Opposite operation on non-int", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; } @@ -286,7 +286,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(LNotExpr_ASTNode *node) { node->base->accept(this); const static ExprTypeInfo standard = "bool"; if (node->base->expr_type_info != standard) { - throw SemanticError("Logical not operation on non-bool", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; } @@ -296,7 +296,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(BNotExpr_ASTNode *node) { node->base->accept(this); const static ExprTypeInfo standard = "int"; if (node->base->expr_type_info != standard) { - throw SemanticError("Bitwise not operation on non-int", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; } @@ -307,7 +307,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(MDMExpr_ASTNode *node) { node->right->accept(this); const static ExprTypeInfo standard = "int"; if (node->left->expr_type_info != standard || node->right->expr_type_info != standard) { - throw SemanticError("MDM operation on non-int", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; } @@ -323,7 +323,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(PMExpr_ASTNode *node) { } const static ExprTypeInfo standard = "int"; if (node->left->expr_type_info != standard || node->right->expr_type_info != standard) { - throw SemanticError("PM operation on non-int", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; } @@ -334,7 +334,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(RLExpr_ASTNode *node) { node->right->accept(this); const static ExprTypeInfo standard = "int"; if (node->left->expr_type_info != standard || node->right->expr_type_info != standard) { - throw SemanticError("RL operation on non-int", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; } @@ -350,7 +350,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(GGLLExpr_ASTNode *node) { } const static ExprTypeInfo standard = "int"; if (node->left->expr_type_info != standard || node->right->expr_type_info != standard) { - throw SemanticError("GGLL operation on non-int", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = "bool"; } @@ -369,7 +369,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(BAndExpr_ASTNode *node) { node->right->accept(this); const static ExprTypeInfo standard = "int"; if (node->left->expr_type_info != standard || node->right->expr_type_info != standard) { - throw SemanticError("BAnd operation on non-int", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; } @@ -380,7 +380,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(BXorExpr_ASTNode *node) { node->right->accept(this); const static ExprTypeInfo standard = "int"; if (node->left->expr_type_info != standard || node->right->expr_type_info != standard) { - throw SemanticError("BXor operation on non-int", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; } @@ -391,7 +391,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(BOrExpr_ASTNode *node) { node->right->accept(this); const static ExprTypeInfo standard = "int"; if (node->left->expr_type_info != standard || node->right->expr_type_info != standard) { - throw SemanticError("BOr operation on non-int", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; } @@ -402,7 +402,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(LAndExpr_ASTNode *node) { node->right->accept(this); const static ExprTypeInfo standard = "bool"; if (node->left->expr_type_info != standard || node->right->expr_type_info != standard) { - throw SemanticError("LAnd operation on non-bool", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; } @@ -413,7 +413,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(LOrExpr_ASTNode *node) { node->right->accept(this); const static ExprTypeInfo standard = "bool"; if (node->left->expr_type_info != standard || node->right->expr_type_info != standard) { - throw SemanticError("LOr operation on non-bool", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = standard; } @@ -426,7 +426,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(TernaryExpr_ASTNode *node) { node->src2->accept(this); if (node->src1->expr_type_info != node->src2->expr_type_info && node->src2->expr_type_info != node->src1->expr_type_info) { - throw SemanticError("Ternary operation on different type", 1); + throw SemanticError("Type Mismatch", 1); } node->expr_type_info = node->src1->expr_type_info; } @@ -435,11 +435,11 @@ void ASTSemanticCheckVisitor::ActuralVisit(AssignExpr_ASTNode *node) { // TODO: Implement this method node->dest->accept(this); if (!node->dest->assignable) { - throw SemanticError("Assign operation on non-assignable", 1); + throw SemanticError("Type Mismatch", 1); } node->src->accept(this); if (node->dest->expr_type_info != node->src->expr_type_info) { - throw SemanticError("Assign operation on different type", 1); + throw SemanticError("Type Mismatch", 1); } } @@ -478,13 +478,13 @@ void ASTSemanticCheckVisitor::ActuralVisit(FunctionCallExpr_ASTNode *node) { } std::cerr << "function to call is " << node->func_name << std::endl; if (schema.arguments.size() != node->arguments.size()) { - throw SemanticError("Argument number mismatch", 1); + throw SemanticError("Type Mismatch", 1); } for (auto &arg : node->arguments) { arg->accept(this); int idx = &arg - &node->arguments[0]; // for debug; if (schema.arguments[&arg - &node->arguments[0]].first != arg->expr_type_info) { - throw SemanticError("Argument type mismatch", 1); + throw SemanticError("Type Mismatch", 1); } } node->expr_type_info = schema.return_type; @@ -502,7 +502,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(FormattedStringExpr_ASTNode *node) { const static ExprTypeInfo valid_types[] = {"int", "bool", "string"}; if (arg->expr_type_info != valid_types[0] && arg->expr_type_info != valid_types[1] && arg->expr_type_info != valid_types[2]) { - throw SemanticError("Invalid type in formatted string", 1); + throw SemanticError("Type Mismatch", 1); } } node->expr_type_info = "string"; @@ -525,7 +525,7 @@ void ASTSemanticCheckVisitor::ActuralVisit(ConstantExpr_ASTNode *node) { found_level = depth; } else { if (base_type != std::get(node->expr_type_info) || found_level != depth) { - throw SemanticError("Invalid const array type", 1); + throw SemanticError("Type Mismatch", 1); } } } else { diff --git a/src/semantic/visitor.cpp b/src/semantic/visitor.cpp index 9688acd..8bffd84 100644 --- a/src/semantic/visitor.cpp +++ b/src/semantic/visitor.cpp @@ -130,11 +130,11 @@ std::any Visitor::visitFunction_def(MXParser::Function_defContext *context) { } if (ClassDefScope *cparent = dynamic_cast(cur_scope->parent)) { if (!cparent->add_function(func->func_name, cur_scope)) { - throw SemanticError("Function name " + func->func_name + " is not available", 1); + throw SemanticError("Multiple Definitions", 1); } } else if (GlobalScope *gparent = dynamic_cast(cur_scope->parent)) { if (!gparent->add_function(func->func_name, cur_scope)) { - throw SemanticError("Function name " + func->func_name + " is not available", 1); + throw SemanticError("Multiple Definitions", 1); } } else throw std::runtime_error("unknown parent scope type"); @@ -156,7 +156,7 @@ std::any Visitor::visitClass_def(MXParser::Class_defContext *context) { GlobalScope *gparent = dynamic_cast(cur_scope->parent); assert(gparent != nullptr); if (!gparent->add_class(context->ID()->getText(), cur_scope)) { - throw SemanticError("Class name " + context->ID()->getText() + " is not available", 1); + throw SemanticError("Multiple Definitions", 1); } nodetype_stk.push_back({ASTNodeType::ClassDef, class_def->current_scope}); @@ -239,7 +239,7 @@ std::any Visitor::visitClass_var_def(MXParser::Class_var_defContext *context) { std::cerr << std::string(nodetype_stk.size() * 2, ' ') << "recorded member variable name is " << id->getText() << std::endl; if (!member_var_def->current_scope->add_variable(id->getText(), member_var_def->var_type)) { - throw SemanticError("Variable name " + id->getText() + " is not available", 1); + throw SemanticError("Multiple Definitions", 1); } }