diff --git a/modcc/errorvisitor.cpp b/modcc/errorvisitor.cpp index 225ec97d1f79972b32746f82606e5279f3112ff2..eddf59b854379ba372056af904444c4ece1c406e 100644 --- a/modcc/errorvisitor.cpp +++ b/modcc/errorvisitor.cpp @@ -14,7 +14,6 @@ void ErrorVisitor::visit(ProcedureExpression *e) { for(auto& expression : e->args()) { expression->accept(this); } - e->body()->accept(this); print_error(e); } @@ -24,18 +23,17 @@ void ErrorVisitor::visit(FunctionExpression *e) { for(auto& expression : e->args()) { expression->accept(this); } - e->body()->accept(this); print_error(e); } // an if statement void ErrorVisitor::visit(IfExpression *e) { + e->condition()->accept(this); e->true_branch()->accept(this); if(e->false_branch()) { e->false_branch()->accept(this); } - print_error(e); } @@ -43,7 +41,6 @@ void ErrorVisitor::visit(BlockExpression* e) { for(auto& expression : e->statements()) { expression->accept(this); } - print_error(e); } @@ -51,7 +48,6 @@ void ErrorVisitor::visit(InitialBlock* e) { for(auto& expression : e->statements()) { expression->accept(this); } - print_error(e); } @@ -68,7 +64,7 @@ void ErrorVisitor::visit(BinaryExpression *e) { print_error(e); } -// binary expresssion +// call expresssion void ErrorVisitor::visit(CallExpression *e) { for(auto& expression: e->args()) { expression->accept(this); @@ -76,3 +72,42 @@ void ErrorVisitor::visit(CallExpression *e) { print_error(e); } +// reaction expresssion +void ErrorVisitor::visit(ReactionExpression *e) { + e->lhs()->accept(this); + e->rhs()->accept(this); + e->fwd_rate()->accept(this); + e->rev_rate()->accept(this); + print_error(e); +} + +// stoich expresssion +void ErrorVisitor::visit(StoichExpression *e) { + for (auto& expression: e->terms()) { + expression->accept(this); + } + print_error(e); +} + +// stoich term expresssion +void ErrorVisitor::visit(StoichTermExpression *e) { + e->ident()->accept(this); + e->coeff()->accept(this); + print_error(e); +} + +// compartment expresssion +void ErrorVisitor::visit(CompartmentExpression *e) { + e->scale_factor()->accept(this); + for (auto& expression: e->state_vars()) { + expression->accept(this); + } + print_error(e); +} + +// pdiff expresssion +void ErrorVisitor::visit(PDiffExpression *e) { + e->var()->accept(this); + e->arg()->accept(this); + print_error(e); +} \ No newline at end of file diff --git a/modcc/errorvisitor.hpp b/modcc/errorvisitor.hpp index 39afad2be75f998ce855a31cf3bb27147c694332..c9b633857bd0e9c8ca44db8e6f0fd44ae97da07e 100644 --- a/modcc/errorvisitor.hpp +++ b/modcc/errorvisitor.hpp @@ -10,16 +10,21 @@ public: : module_name_(m) {} - void visit(Expression *e) override; - void visit(ProcedureExpression *e) override; - void visit(FunctionExpression *e) override; - void visit(UnaryExpression *e) override; - void visit(BinaryExpression *e) override; - void visit(CallExpression *e) override; + void visit(Expression *e) override; + void visit(ProcedureExpression *e) override; + void visit(FunctionExpression *e) override; + void visit(UnaryExpression *e) override; + void visit(BinaryExpression *e) override; + void visit(CallExpression *e) override; + void visit(ReactionExpression *e) override; + void visit(StoichExpression *e) override; + void visit(StoichTermExpression *e) override; + void visit(CompartmentExpression *e) override; + void visit(PDiffExpression *e) override; - void visit(BlockExpression *e) override; - void visit(InitialBlock *e) override; - void visit(IfExpression *e) override; + void visit(BlockExpression *e) override; + void visit(InitialBlock *e) override; + void visit(IfExpression *e) override; int num_errors() {return num_errors_;} int num_warnings() {return num_warnings_;} diff --git a/modcc/expression.cpp b/modcc/expression.cpp index 74f50ef142e0c151fe1e41e6a6d381471f835e83..8cb81f7106e592d85570e8964260a305b8ddb36d 100644 --- a/modcc/expression.cpp +++ b/modcc/expression.cpp @@ -148,6 +148,9 @@ void DerivativeExpression::semantic(scope_ptr scp) { error_ = false; IdentifierExpression::semantic(scp); + if (has_error()) { + return; + } auto v = symbol_->is_variable(); if (!v || !v->is_state()) { error( pprintf("the variable '%' must be a state variable to be differentiated", @@ -323,17 +326,8 @@ void ReactionExpression::semantic(scope_ptr scp) { fwd_rate()->semantic(scp); rev_rate()->semantic(scp); - std::string msg = lhs_->has_error() ? lhs_->error_message() : - rhs_->has_error() ? rhs_->error_message() : - fwd_rate_->has_error() ? fwd_rate_->error_message() : - rev_rate_->has_error() ? rev_rate_->error_message() : ""; - - if (!msg.empty()) { - error(msg); - return; - } - - if(fwd_rate_->is_procedure_call() || rev_rate_->is_procedure_call()) { + if((!fwd_rate_->has_error() && fwd_rate_->is_procedure_call()) || + (!rev_rate_->has_error() && rev_rate_->is_procedure_call())) { error("procedure calls can't be made in an expression"); } } @@ -350,11 +344,7 @@ expression_ptr StoichTermExpression::clone() const { void StoichTermExpression::semantic(scope_ptr scp) { error_ = false; scope_ = scp; - ident()->semantic(scp); - if(ident()->has_error()) { - error(ident()->error_message()); - } } /******************************************************************************* @@ -387,9 +377,6 @@ void StoichExpression::semantic(scope_ptr scp) { for(auto& e: terms()) { e->semantic(scp); - if(e->has_error()) { - error(e->error_message()); - } } } @@ -423,10 +410,9 @@ std::string CompartmentExpression::to_string() const { void CompartmentExpression::semantic(scope_ptr scp) { error_ = false; scope_ = scp; - scale_factor()->semantic(scp); - if(scale_factor()->has_error()) { - error(scale_factor()->error_message()); + for (auto& e: state_vars_) { + e->semantic(scp); } } @@ -446,14 +432,7 @@ void LinearExpression::semantic(scope_ptr scp) { lhs_->semantic(scp); rhs_->semantic(scp); - std::string msg = lhs_->has_error() ? lhs_->error_message() : - rhs_->has_error() ? rhs_->error_message() : ""; - - if (!msg.empty()) { - error(msg); - return; - } - if(rhs_->is_procedure_call()) { + if(!rhs_->has_error() && rhs_->is_procedure_call()) { error("procedure calls can't be made in an expression"); } } @@ -474,14 +453,7 @@ void ConserveExpression::semantic(scope_ptr scp) { lhs_->semantic(scp); rhs_->semantic(scp); - std::string msg = lhs_->has_error() ? lhs_->error_message() : - rhs_->has_error() ? rhs_->error_message() : ""; - - if (!msg.empty()) { - error(msg); - return; - } - if(rhs_->is_procedure_call()) { + if(!rhs_->has_error() && rhs_->is_procedure_call()) { error("procedure calls can't be made in an expression"); } } @@ -539,9 +511,6 @@ void CallExpression::semantic(scope_ptr scp) { // perform semantic analysis on the arguments for(auto& a : args_) { a->semantic(scp); - if(a->has_error()) { - error(a->error_message()); - } } } @@ -587,9 +556,6 @@ void ProcedureExpression::semantic(scope_ptr scp) { // add the argumemts to the list of local variables for(auto& a : args_) { a->semantic(scope_); - if(a->has_error()) { - error(a->error_message()); - } } // this loop could be used to then check the types of statements in the body @@ -600,9 +566,6 @@ void ProcedureExpression::semantic(scope_ptr scp) { // perform semantic analysis for each expression in the body body_->semantic(scope_); - if(body_->has_error()) { - error(body_->error_message()); - } // the symbol for this expression is itself symbol_ = scope_->find_global(name()); @@ -697,16 +660,10 @@ void NetReceiveExpression::semantic(scope_type::symbol_map &global_symbols) { // add the argumemts to the list of local variables for(auto& a : args_) { a->semantic(scope_); - if(a->has_error()) { - error(a->error_message()); - } } // perform semantic analysis for each expression in the body body_->semantic(scope_); - if(body_->has_error()) { - error(body_->error_message()); - } // this loop could be used to then check the types of statements in the body for(auto& e : *(body_->is_block())) { @@ -746,16 +703,10 @@ void PostEventExpression::semantic(scope_type::symbol_map &global_symbols) { // add the argumemts to the list of local variables for(auto& a : args_) { a->semantic(scope_); - if(a->has_error()) { - error(a->error_message()); - } } // perform semantic analysis for each expression in the body body_->semantic(scope_); - if(body_->has_error()) { - error(body_->error_message()); - } symbol_ = scope_->find_global(name()); } @@ -792,9 +743,6 @@ void FunctionExpression::semantic(scope_type::symbol_map &global_symbols) { // add the argumemts to the list of local variables for(auto& a : args_) { a->semantic(scope_); - if(a->has_error()) { - error(a->error_message()); - } } // Add a variable that has the same name as the function, @@ -808,12 +756,12 @@ void FunctionExpression::semantic(scope_type::symbol_map &global_symbols) { // perform semantic analysis for each expression in the body body_->semantic(scope_); - if(body_->has_error()) { - error(body_->error_message()); - } + // this loop could be used to then check the types of statements in the body for(auto& e : *(body())) { - if(e->is_initial_block()) error("INITIAL block not allowed inside FUNCTION definition"); + if(e->is_initial_block()) { + error("INITIAL block not allowed inside FUNCTION definition"); + } } // the symbol for this expression is itself @@ -829,11 +777,7 @@ void UnaryExpression::semantic(scope_ptr scp) { scope_ = scp; expression_->semantic(scp); - if(expression_->has_error()) { - error(expression_->error_message()); - return; - } - if(expression_->is_procedure_call()) { + if(!expression_->has_error() && expression_->is_procedure_call()) { error("a procedure call can't be part of an expression"); } } @@ -856,14 +800,8 @@ void BinaryExpression::semantic(scope_ptr scp) { lhs_->semantic(scp); rhs_->semantic(scp); - std::string msg = lhs_->has_error() ? lhs_->error_message() : - rhs_->has_error() ? rhs_->error_message() : ""; - - if (!msg.empty()) { - error(msg); - return; - } - if(rhs_->is_procedure_call() || lhs_->is_procedure_call()) { + if((!rhs_->has_error() && rhs_->is_procedure_call()) || + (!lhs_->has_error() && lhs_->is_procedure_call())) { error("procedure calls can't be made in an expression"); } } @@ -896,14 +834,6 @@ void AssignmentExpression::semantic(scope_ptr scp) { lhs_->semantic(scp); rhs_->semantic(scp); - std::string msg = lhs_->has_error() ? lhs_->error_message() : - rhs_->has_error() ? rhs_->error_message() : ""; - - if (!msg.empty()) { - error(msg); - return; - } - // only flag an lvalue error if there was no error in the lhs expression // this ensures that we don't print redundant error messages when trying // to write to an undeclared variable @@ -986,9 +916,6 @@ void BlockExpression::semantic(scope_ptr scp) { scope_ = scp; for(auto& e : statements_) { e->semantic(scope_); - if(e->has_error()) { - error(e->error_message()); - } } } @@ -1021,24 +948,12 @@ void IfExpression::semantic(scope_ptr scp) { scope_ = scp; condition_->semantic(scp); - if(condition_->has_error()) { - error(condition()->error_message()); - } - - if(!condition_->is_conditional()) { + if(!condition_->has_error() && !condition_->is_conditional()) { error("not a valid conditional expression"); } - true_branch_->semantic(scp); - if(true_branch_->has_error()) { - error(true_branch_->error_message()); - } - if(false_branch_) { false_branch_->semantic(scp); - if(false_branch_->has_error()) { - error(false_branch_->error_message()); - } } } @@ -1072,13 +987,7 @@ void PDiffExpression::semantic(scope_ptr scp) { "an identifier, but instead %", yellow(var_->to_string()))); } var_->semantic(scp); - if(var_->has_error()) { - error(var_->error_message()); - } arg_->semantic(scp); - if(arg_->has_error()) { - error(arg_->error_message()); - } } expression_ptr PDiffExpression::clone() const { diff --git a/modcc/expression.hpp b/modcc/expression.hpp index f12b429dd4fde2180d5059b98ac6933b028594f8..fc7c3dac06afd59169140c26c6db0bfe86bf30fc 100644 --- a/modcc/expression.hpp +++ b/modcc/expression.hpp @@ -45,7 +45,6 @@ class Symbol; class ConductanceExpression; class PDiffExpression; class VariableExpression; -class ProcedureExpression; class NetReceiveExpression; class PostEventExpression; class APIMethod;