Restricted syntactical variances in the implementation of the external_functions statement.

issue#70
Houtan Bastani 2010-02-24 15:10:11 +01:00
parent e24c9c5ad1
commit 46e56b59c0
3 changed files with 70 additions and 18 deletions

View File

@ -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;
}

View File

@ -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();
}

View File

@ -157,7 +157,7 @@ private:
//! Temporary storage for argument list of external function
stack<vector<NodeID> > 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