From 46e56b59c073e05f08d553386ee24c6e2e426430 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 24 Feb 2010 15:10:11 +0100 Subject: [PATCH] Restricted syntactical variances in the implementation of the external_functions statement. --- ExternalFunctionsTable.cc | 69 +++++++++++++++++++++++++++++++++------ ParsingDriver.cc | 17 ++++++---- ParsingDriver.hh | 2 +- 3 files changed, 70 insertions(+), 18 deletions(-) diff --git a/ExternalFunctionsTable.cc b/ExternalFunctionsTable.cc index 28044a6d..83c03f60 100644 --- a/ExternalFunctionsTable.cc +++ b/ExternalFunctionsTable.cc @@ -35,17 +35,9 @@ ExternalFunctionsTable::addExternalFunction(int symb_id, const external_function { assert(symb_id >= 0); - if (external_function_options_arg.secondDerivSymbID > eExtFunNotSet && - external_function_options_arg.firstDerivSymbID == eExtFunNotSet) - { - cerr << "ERROR: If the second derivative is provided to the external_function() command," - << "the first derivative must also be provided" << endl; - exit(EXIT_FAILURE); - } - if (external_function_options_arg.nargs <= 0) { - cerr << "ERROR: The number of arguments passed to an external function must be > 0" << endl; + cerr << "ERROR: The number of arguments passed to an external function must be > 0." << endl; exit(EXIT_FAILURE); } @@ -56,5 +48,62 @@ ExternalFunctionsTable::addExternalFunction(int symb_id, const external_function if (external_function_options_arg.secondDerivSymbID == eExtFunSetButNoNameProvided) external_function_options_chng.secondDerivSymbID = symb_id; - externalFunctionTable[symb_id] = external_function_options_chng; + if (external_function_options_chng.secondDerivSymbID == symb_id && + external_function_options_chng.firstDerivSymbID != symb_id) + { + cerr << "ERROR: If the second derivative is provided by the top-level function " + << "the first derivative must also be provided by the same function." << endl; + exit(EXIT_FAILURE); + } + + if ((external_function_options_chng.secondDerivSymbID != symb_id && + external_function_options_chng.firstDerivSymbID == symb_id) && + external_function_options_chng.secondDerivSymbID != eExtFunNotSet) + { + cerr << "ERROR: If the first derivative is provided by the top-level function, the " + << "second derivative cannot be provided by any other external function." << endl; + exit(EXIT_FAILURE); + } + + if (external_function_options_chng.secondDerivSymbID != eExtFunNotSet&& + external_function_options_chng.firstDerivSymbID == eExtFunNotSet) + { + cerr << "ERROR: If the second derivative is provided, the first derivative must also be provided." << endl; + exit(EXIT_FAILURE); + } + + if (external_function_options_chng.secondDerivSymbID == external_function_options_chng.firstDerivSymbID && + external_function_options_chng.firstDerivSymbID != symb_id && + external_function_options_chng.firstDerivSymbID != eExtFunNotSet) + { + cerr << "ERROR: If the Jacobian and Hessian are provided by the same function, that " + << "function must be the top-level function." << endl; + exit(EXIT_FAILURE); + } + + if (exists(symb_id)) + { + if (external_function_options_arg.nargs != getNargs(symb_id)) + { + cerr << "ERROR: The number of arguments passed to the external_function() statement do not " + << "match the number of arguments passed to a previous call or declaration of the top-level function."<< endl; + exit(EXIT_FAILURE); + } + + if (external_function_options_chng.firstDerivSymbID != getFirstDerivSymbID(symb_id)) + { + cerr << "ERROR: The first derivative function passed to the external_function() statement does not " + << "match the first derivative function passed to a previous call or declaration of the top-level function."<< endl; + exit(EXIT_FAILURE); + } + + if (external_function_options_chng.secondDerivSymbID != getSecondDerivSymbID(symb_id)) + { + cerr << "ERROR: The second derivative function passed to the external_function() statement does not " + << "match the second derivative function passed to a previous call or declaration of the top-level function."<< endl; + exit(EXIT_FAILURE); + } + } + else + externalFunctionTable[symb_id] = external_function_options_chng; } diff --git a/ParsingDriver.cc b/ParsingDriver.cc index a07298bc..0f890e22 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -64,7 +64,7 @@ ParsingDriver::reset_current_external_function_options() current_external_function_options.nargs = eExtFunSetDefaultNargs; current_external_function_options.firstDerivSymbID = eExtFunNotSet; current_external_function_options.secondDerivSymbID = eExtFunNotSet; - current_external_function_name.clear(); + current_external_function_id = eExtFunNotSet; } ModFile * @@ -1638,7 +1638,7 @@ ParsingDriver::external_function_option(const string &name_option, const string if (opt.empty()) error("An argument must be passed to the 'name' option of the external_function() statement."); declare_symbol(&opt, eExternalFunction, NULL); - current_external_function_name = opt; + current_external_function_id = mod_file->symbol_table.getID(opt); } else if (name_option == "first_deriv_provided") { @@ -1669,15 +1669,18 @@ ParsingDriver::external_function_option(const string &name_option, const string void ParsingDriver::external_function() { - if (current_external_function_name.empty()) + if (current_external_function_id == eExtFunNotSet) error("The 'name' option must be passed to external_function()."); - int function_symb_id = mod_file->symbol_table.getID(current_external_function_name); - if (current_external_function_options.secondDerivSymbID > eExtFunNotSet && - current_external_function_options.firstDerivSymbID == eExtFunNotSet) + if (current_external_function_options.secondDerivSymbID >= 0 && + current_external_function_options.firstDerivSymbID == eExtFunNotSet) error("If the second derivative is provided to the external_function command, the first derivative must also be provided."); - mod_file->external_functions_table.addExternalFunction(function_symb_id, current_external_function_options); + if (current_external_function_options.secondDerivSymbID == eExtFunSetButNoNameProvided && + current_external_function_options.firstDerivSymbID != eExtFunSetButNoNameProvided) + error("If the second derivative is provided in the top-level function, the first derivative must also be provided in that function."); + + mod_file->external_functions_table.addExternalFunction(current_external_function_id, current_external_function_options); reset_current_external_function_options(); } diff --git a/ParsingDriver.hh b/ParsingDriver.hh index 20e92508..55d26602 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -157,7 +157,7 @@ private: //! Temporary storage for argument list of external function stack > stack_external_function_args; //! Temporary storage for the symb_id associated with the "name" symbol of the current external_function statement - string current_external_function_name; + int current_external_function_id; //! Temporary storage for option list provided to external_function() ExternalFunctionsTable::external_function_options current_external_function_options; //! reset the values for temporary storage