mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 12:00:11 -05:00
Update linemap filename before location in both parsers. Rely on parser to update linemap. Lexer maintains location. Various small syntax corrections and extensions. PR cobol/120772 PR cobol/120779 PR cobol/120790 PR cobol/120791 PR cobol/120794 gcc/cobol/ChangeLog: * gcobc: Supply -fPIC for shared objects. * genapi.cc (linemap_add): Delete empty macro. (parser_enter_file): Do not call linemap_add. (parser_leave_file): Same. * gengen.cc (location_from_lineno): Remove function. * lexio.cc (parse_replacing_term): Allow empty term. (cdftext::process_file): Always append to output. (cdftext::segment_line): Output #line directives. * lexio.h (struct span_t): Count lines in span. * parse.y: Revamp REPOSITORY, and minor syntax extensions. * parse_ante.h (input_file_status_notify): Update linemap filename before location. (intrinsic_token_of): Declare. (parser_move_carefully): Support MOVE pointer. * parse_util.h (intrinsic_token_of): New function. * scan.l: New EOF logic, accept NOT=, own yylloc and yylineno. * scan_ante.h (class enter_leave_t): Do not store newline count. (cdf_location_set): Remove declaration. (ydfltype_of): New function. (update_location): Accept location parameter. (reset_location): New function. (YY_USER_ACTION): Use update_location(). (YY_USER_INIT): Update CDF location. (verify_ws): New function. (wait_for_the_child): Removed. * symbols.h (cobol_fileline_set): return line number. * util.cc (valid_move): Use range-based for loop. (struct input_file_t): Remove line_map pointer. (class unique_stack): New peek() member function. (cobol_lineno_save): Rename to overload cobol_lineno(). (cobol_lineno): Replaces cobol_lineno_save(). (cobol_filename): Return void. (location_from_lineno): New function used by genapi.cc. (cdf_location_set): Remove. (matched_length): No change. (cobol_fileline_set): Return line number. (fisspace): Remove extra semicolon. (fisprint): Same. * util.h (cobol_filename_restore): Return void. (cobol_lineno_save): Remove declaration. (cobol_lineno): Declare.
488 lines
22 KiB
C++
488 lines
22 KiB
C++
/*
|
|
* Copyright (c) 2021-2025 Symas Corporation
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following disclaimer
|
|
* in the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* * Neither the name of the Symas Corporation nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
// This file is included only by parse.y
|
|
|
|
#include <map>
|
|
|
|
/*
|
|
* Intrinsics
|
|
* types are:
|
|
* A Alphabetic
|
|
* D DBCS
|
|
* I Integer
|
|
* K Keyword
|
|
* N Numeric
|
|
* O Other
|
|
* U National
|
|
* 8 UTF-8
|
|
* X Alphanumeric
|
|
* n variadic
|
|
* We use just A, I, N, or X, choosing the most general for each parameter.
|
|
*/
|
|
static const function_descr_t function_descrs[] = {
|
|
{ ABS, "ABS",
|
|
"__gg__abs", "N", {}, FldNumericBin5 },
|
|
{ ACOS, "ACOS",
|
|
"__gg__acos", "N", {}, FldNumericBin5 },
|
|
{ ANNUITY, "ANNUITY",
|
|
"__gg__annuity", "NI", {}, FldNumericBin5 },
|
|
{ ASIN, "ASIN",
|
|
"__gg__asin", "N", {}, FldNumericBin5 },
|
|
{ ATAN, "ATAN",
|
|
"__gg__atan", "N", {}, FldNumericBin5 },
|
|
{ BASECONVERT, "BASECONVERT",
|
|
"__gg__baseconvert", "XII", {}, FldNumericBin5 },
|
|
{ BIT_OF, "BIT-OF",
|
|
"__gg__bit_of", "X", {}, FldAlphanumeric },
|
|
{ BIT_TO_CHAR, "BIT-TO-CHAR",
|
|
"__gg__bit_to_char", "X", {}, FldAlphanumeric },
|
|
// BOOLEAN-OF-INTEGER requires FldBoolean
|
|
{ BOOLEAN_OF_INTEGER, "BOOLEAN-OF-INTEGER",
|
|
"__gg__boolean_of_integer", "II", {}, FldNumericBin5 },
|
|
{ BYTE_LENGTH, "BYTE-LENGTH",
|
|
"__gg__byte_length", "X", {}, FldNumericBin5 },
|
|
{ CHAR, "CHAR",
|
|
"__gg__char", "I", {}, FldAlphanumeric },
|
|
{ CHAR_NATIONAL, "CHAR-NATIONAL",
|
|
"__gg__char_national", "I", {}, FldAlphanumeric },
|
|
{ COMBINED_DATETIME, "COMBINED-DATETIME",
|
|
"__gg__combined_datetime", "IN", {}, FldNumericBin5 },
|
|
{ CONCAT, "CONCAT",
|
|
"__gg__concat", "n", {}, FldAlphanumeric },
|
|
{ CONVERT, "CONVERT",
|
|
"__gg__convert", "XII", {}, FldAlphanumeric },
|
|
{ COS, "COS",
|
|
"__gg__cos", "N", {}, FldNumericBin5 },
|
|
{ CURRENT_DATE, "CURRENT-DATE",
|
|
"__gg__current_date", "", {}, FldAlphanumeric },
|
|
{ DATE_OF_INTEGER, "DATE-OF-INTEGER",
|
|
"__gg__date_of_integer", "I", {}, FldNumericBin5 },
|
|
{ DATE_TO_YYYYMMDD, "DATE-TO-YYYYMMDD",
|
|
"__gg__date_to_yyyymmdd", "III", {}, FldNumericBin5 },
|
|
{ DAY_OF_INTEGER, "DAY-OF-INTEGER",
|
|
"__gg__day_of_integer", "I", {}, FldNumericBin5 },
|
|
{ DAY_TO_YYYYDDD, "DAY-TO-YYYYDDD",
|
|
"__gg__day_to_yyyyddd", "III", {}, FldNumericBin5 },
|
|
{ DISPLAY_OF, "DISPLAY-OF",
|
|
"__gg__display_of", "UUI", {}, FldAlphanumeric },
|
|
{ E, "E",
|
|
"__gg_e", "", {}, FldNumericBin5 },
|
|
|
|
{ EXCEPTION_FILE, "EXCEPTION-FILE",
|
|
"__gg__func_exception_file", "", {}, FldAlphanumeric },
|
|
{ EXCEPTION_FILE_N, "EXCEPTION-FILE-N",
|
|
"__gg__func_exception_file_n", "", {}, FldAlphanumeric },
|
|
{ EXCEPTION_LOCATION, "EXCEPTION-LOCATION",
|
|
"__gg__func_exception_location", "", {}, FldAlphanumeric },
|
|
{ EXCEPTION_LOCATION_N, "EXCEPTION-LOCATION-N",
|
|
"__gg__func_exception_location_n", "", {}, FldAlphanumeric },
|
|
{ EXCEPTION_STATEMENT, "EXCEPTION-STATEMENT",
|
|
"__gg__func_exception_statement", "", {}, FldAlphanumeric },
|
|
{ EXCEPTION_STATUS, "EXCEPTION-STATUS",
|
|
"__gg__func_exception_status", "", {}, FldAlphanumeric },
|
|
|
|
{ EXP, "EXP",
|
|
"__gg__exp", "N", {}, FldNumericBin5 },
|
|
{ EXP10, "EXP10",
|
|
"__gg__exp10", "N", {}, FldNumericBin5 },
|
|
{ FACTORIAL, "FACTORIAL",
|
|
"__gg__factorial", "I", {}, FldNumericBin5 },
|
|
{ FIND_STRING, "FIND-STRING",
|
|
"__gg__find_string", "AXI", {}, FldNumericBin5 },
|
|
{ FORMATTED_CURRENT_DATE, "FORMATTED-CURRENT-DATE",
|
|
"__gg__formatted_current_date", "X", {}, FldAlphanumeric },
|
|
{ FORMATTED_DATE, "FORMATTED-DATE",
|
|
"__gg__formatted_date", "XX", {}, FldAlphanumeric },
|
|
{ FORMATTED_DATETIME, "FORMATTED-DATETIME",
|
|
"__gg__formatted_datetime", "XINI", {}, FldAlphanumeric },
|
|
{ FORMATTED_TIME, "FORMATTED-TIME",
|
|
"__gg__formatted_time", "INI", {}, FldNumericBin5 },
|
|
{ FRACTION_PART, "FRACTION-PART",
|
|
"__gg__fraction_part", "N", {}, FldNumericBin5 },
|
|
{ HEX_OF, "HEX-OF",
|
|
"__gg__hex_of", "X", {}, FldAlphanumeric },
|
|
{ HEX_TO_CHAR, "HEX-TO-CHAR",
|
|
"__gg__hex_to_char", "X", {}, FldAlphanumeric },
|
|
{ HIGHEST_ALGEBRAIC, "HIGHEST-ALGEBRAIC",
|
|
"__gg__highest_algebraic", "N", {}, FldNumericBin5 },
|
|
{ INTEGER, "INTEGER",
|
|
"__gg__integer", "N", {}, FldNumericBin5 },
|
|
// requires FldBoolean
|
|
{ INTEGER_OF_BOOLEAN, "INTEGER-OF-BOOLEAN",
|
|
"__gg__integer_of_boolean", "B", {}, FldNumericBin5 },
|
|
{ INTEGER_OF_DATE, "INTEGER-OF-DATE",
|
|
"__gg__integer_of_date", "I", {}, FldNumericBin5 },
|
|
{ INTEGER_OF_DAY, "INTEGER-OF-DAY",
|
|
"__gg__integer_of_day", "I", {}, FldNumericBin5 },
|
|
{ INTEGER_OF_FORMATTED_DATE, "INTEGER-OF-FORMATTED-DATE",
|
|
"__gg__integer_of_formatted_date", "XX", {}, FldAlphanumeric },
|
|
{ INTEGER_PART, "INTEGER-PART",
|
|
"__gg__integer_part", "N", {}, FldNumericBin5 },
|
|
{ LENGTH, "LENGTH",
|
|
"__gg__length", "X", {}, FldNumericBin5 },
|
|
{ LOCALE_COMPARE, "LOCALE-COMPARE",
|
|
"__gg__locale_compare", "XXX", {}, FldNumericBin5 },
|
|
{ LOCALE_DATE, "LOCALE-DATE",
|
|
"__gg__locale_date", "XX", {}, FldNumericBin5 },
|
|
{ LOCALE_TIME, "LOCALE-TIME",
|
|
"__gg__locale_time", "XX", {}, FldNumericBin5 },
|
|
{ LOCALE_TIME_FROM_SECONDS, "LOCALE-TIME-FROM-SECONDS",
|
|
"__gg__locale_time_from_seconds", "NX", {}, FldNumericBin5 },
|
|
|
|
{ LOG, "LOG",
|
|
"__gg__log", "N", {}, FldNumericBin5 },
|
|
{ LOG10, "LOG10",
|
|
"__gg__log10", "N", {}, FldNumericBin5 },
|
|
{ LOWER_CASE, "LOWER-CASE",
|
|
"__gg__lower_case", "X", {}, FldAlphanumeric },
|
|
{ LOWEST_ALGEBRAIC, "LOWEST-ALGEBRAIC",
|
|
"__gg__lowest_algebraic", "N", {}, FldNumericBin5 },
|
|
|
|
{ MAXX, "MAX",
|
|
"__gg__max", "n", {}, FldAlphanumeric },
|
|
{ MEAN, "MEAN",
|
|
"__gg__mean", "n", {}, FldNumericBin5 },
|
|
{ MEDIAN, "MEDIAN",
|
|
"__gg__median", "n", {}, FldNumericBin5 },
|
|
{ MIDRANGE, "MIDRANGE",
|
|
"__gg__midrange", "n", {}, FldNumericBin5 },
|
|
{ MINN, "MIN",
|
|
"__gg__min", "n", {}, FldAlphanumeric },
|
|
{ MOD, "MOD",
|
|
"__gg__mod", "IN", {}, FldNumericBin5 },
|
|
{ MODULE_NAME, "MODULE-NAME",
|
|
"__gg__module_name", "I", {}, FldAlphanumeric },
|
|
{ NATIONAL_OF, "NATIONAL-OF",
|
|
"__gg__national_of", "XX", {}, FldAlphanumeric },
|
|
{ NUMVAL, "NUMVAL",
|
|
"__gg__numval", "X", {}, FldNumericBin5 },
|
|
{ NUMVAL_C, "NUMVAL-C",
|
|
"__gg__numval_c", "XXU", {}, FldNumericBin5 },
|
|
{ NUMVAL_F, "NUMVAL-F",
|
|
"__gg__numval_f", "X", {}, FldNumericBin5 },
|
|
{ ORD, "ORD",
|
|
"__gg__ord", "X", {}, FldNumericBin5 },
|
|
{ ORD_MAX, "ORD-MAX",
|
|
"__gg__ord_max", "n", {}, FldNumericBin5 },
|
|
{ ORD_MIN, "ORD-MIN",
|
|
"__gg__ord_min", "n", {}, FldNumericBin5 },
|
|
{ PI, "PI",
|
|
"__gg__pi", "", {}, FldNumericBin5 },
|
|
{ PRESENT_VALUE, "PRESENT-VALUE",
|
|
"__gg__present_value", "n", {}, FldNumericBin5 },
|
|
{ RANDOM, "RANDOM",
|
|
"__gg__random", "I", {}, FldNumericBin5 },
|
|
{ RANGE, "RANGE",
|
|
"__gg__range", "n", {}, FldNumericBin5 },
|
|
{ REM, "REM",
|
|
"__gg__rem", "NN", {}, FldNumericBin5 },
|
|
{ REVERSE, "REVERSE",
|
|
"__gg__reverse", "X", {}, FldAlphanumeric },
|
|
{ SECONDS_FROM_FORMATTED_TIME, "SECONDS-FROM-FORMATTED-TIME",
|
|
"__gg__seconds_from_formatted_time", "XX", {}, FldAlphanumeric },
|
|
{ SECONDS_PAST_MIDNIGHT, "SECONDS_PAST_MIDNIGHT",
|
|
"__gg__seconds_past_midnight", "", {}, FldAlphanumeric },
|
|
{ SIGN, "SIGN",
|
|
"__gg__sign", "N", {}, FldNumericBin5 },
|
|
{ SIN, "SIN",
|
|
"__gg__sin", "N", {}, FldNumericBin5 },
|
|
{ SMALLEST_ALGEBRAIC, "SMALLEST-ALGEBRAIC",
|
|
"__gg__smallest_algebraic", "N", {}, FldNumericBin5 },
|
|
{ SQRT, "SQRT",
|
|
"__gg__sqrt", "N", {}, FldNumericBin5 },
|
|
{ STANDARD_COMPARE, "STANDARD-COMPARE",
|
|
"__gg__standard_compare", "XXXI", {}, FldAlphanumeric },
|
|
{ STANDARD_DEVIATION, "STANDARD-DEVIATION",
|
|
"__gg__standard_deviation", "n", {}, FldNumericBin5 },
|
|
{ SUBSTITUTE, "SUBSTITUTE",
|
|
"__gg__substitute", "XXX", {}, FldAlphanumeric },
|
|
{ SUM, "SUM",
|
|
"__gg__sum", "n", {}, FldNumericBin5 },
|
|
{ TAN, "TAN",
|
|
"__gg__tan", "N", {}, FldNumericBin5 },
|
|
{ TEST_DATE_YYYYMMDD, "TEST-DATE-YYYYMMDD",
|
|
"__gg__test_date_yyyymmdd", "I", {}, FldNumericBin5 },
|
|
{ TEST_DAY_YYYYDDD, "TEST-DAY-YYYYDDD",
|
|
"__gg__test_day_yyyyddd", "I", {}, FldNumericBin5 },
|
|
{ TEST_FORMATTED_DATETIME, "TEST-FORMATTED-DATETIME",
|
|
"__gg__test_formatted_datetime", "XX", {}, FldNumericBin5 },
|
|
{ TEST_NUMVAL, "TEST-NUMVAL",
|
|
"__gg__test_numval", "X", {}, FldNumericBin5 },
|
|
{ TEST_NUMVAL_C, "TEST-NUMVAL-C",
|
|
"__gg__test_numval_c", "XXU", {}, FldNumericBin5 },
|
|
{ TEST_NUMVAL_F, "TEST-NUMVAL-F",
|
|
"__gg__test_numval_f", "X", {}, FldNumericBin5 },
|
|
{ TRIM, "TRIM",
|
|
"__gg__trim", "XI", {}, FldNumericBin5 },
|
|
{ ULENGTH, "ULENGTH",
|
|
"__gg__ulength", "X", {}, FldAlphanumeric },
|
|
{ UPOS, "UPOS",
|
|
"__gg__upos", "XI", {}, FldAlphanumeric },
|
|
{ UPPER_CASE, "UPPER-CASE",
|
|
"__gg__upper_case", "X", {}, FldAlphanumeric },
|
|
{ USUBSTR, "USUBSTR",
|
|
"__gg__usubstr", "XII", {}, FldAlphanumeric },
|
|
{ USUPPLEMENTARY, "USUPPLEMENTARY",
|
|
"__gg__usupplementary", "X", {}, FldAlphanumeric },
|
|
{ UUID4, "UUID4",
|
|
"__gg_uuid4", "", {}, FldAlphanumeric },
|
|
{ UVALID, "UVALID",
|
|
"__gg__uvalid", "X", {}, FldAlphanumeric },
|
|
{ UWIDTH, "UWIDTH",
|
|
"__gg__uwidth", "XI", {}, FldAlphanumeric },
|
|
{ VARIANCE, "VARIANCE",
|
|
"__gg__variance", "n", {}, FldNumericBin5 },
|
|
{ WHEN_COMPILED, "WHEN-COMPILED",
|
|
"__gg__when_compiled", "", {}, FldAlphanumeric },
|
|
{ YEAR_TO_YYYY, "YEAR-TO-YYYY",
|
|
"__gg__year_to_yyyy", "III", {}, FldNumericBin5 },
|
|
};
|
|
|
|
static const
|
|
function_descr_t *function_descrs_end = function_descrs + COUNT_OF(function_descrs);
|
|
|
|
class cname_cmp {
|
|
const char *cname;
|
|
public:
|
|
explicit cname_cmp( const char *cname ) : cname(cname) {}
|
|
|
|
bool operator()( const function_descr_t& descr ) {
|
|
return strlen(cname) == strlen(descr.cname) &&
|
|
0 == strcmp(cname, descr.cname);
|
|
}
|
|
bool operator()( const char that[] ) {
|
|
return strlen(cname) == strlen(that) &&
|
|
0 == strcmp(cname, that);
|
|
}
|
|
};
|
|
|
|
static int
|
|
intrinsic_token_of( const char name[] ) {
|
|
auto pdescr = std::find_if( function_descrs, function_descrs_end,
|
|
[name]( const function_descr_t& descr ) {
|
|
return 0 == strcmp(name, descr.name);
|
|
} );
|
|
return pdescr == function_descrs_end? 0 : pdescr->token;
|
|
}
|
|
|
|
/*
|
|
* For variadic intrinsic functions, ensure all parameters are commensurate.
|
|
* Return pointer in 1st inconsistent parameter type.
|
|
* Return NULL to indicate success.
|
|
*/
|
|
static cbl_refer_t *
|
|
intrinsic_inconsistent_parameter( size_t n, cbl_refer_t *args ) {
|
|
class commensurate_type {
|
|
cbl_refer_t first;
|
|
public:
|
|
explicit commensurate_type( const cbl_refer_t& first ) : first(first) {}
|
|
bool operator()( const cbl_refer_t& arg ) const {
|
|
return is_numeric(first.field) == is_numeric(arg.field);
|
|
}
|
|
};
|
|
|
|
auto p = std::find_if_not(args, args + n, commensurate_type(args[0]));
|
|
return p == args + n? NULL : p;
|
|
}
|
|
|
|
static cbl_field_type_t
|
|
intrinsic_return_type( int token ) {
|
|
auto p = std::find_if( function_descrs,
|
|
function_descrs_end,
|
|
[token]( const auto& descr ) {
|
|
return token == descr.token;
|
|
} );
|
|
return p == function_descrs_end? FldAlphanumeric : p->ret_type;
|
|
}
|
|
|
|
static const char *
|
|
intrinsic_cname( int token ) {
|
|
auto p = std::find_if( function_descrs,
|
|
function_descrs_end,
|
|
[token]( const auto& descr ) {
|
|
return token == descr.token;
|
|
} );
|
|
return p == function_descrs_end? NULL : p->cname;
|
|
}
|
|
|
|
const char *
|
|
intrinsic_function_name( int token ) {
|
|
auto p = std::find_if( function_descrs,
|
|
function_descrs_end,
|
|
[token]( const auto& descr ) {
|
|
return token == descr.token;
|
|
} );
|
|
return p == function_descrs_end? NULL : p->name;
|
|
}
|
|
|
|
/*
|
|
* Provide supplied function parameters.
|
|
* Return index to 1st invalid parameter type.
|
|
* Return N to indicate success.
|
|
*/
|
|
static size_t
|
|
intrinsic_invalid_parameter( int token,
|
|
const std::vector<cbl_refer_t>& args )
|
|
{
|
|
auto p = std::find_if( function_descrs,
|
|
function_descrs_end,
|
|
[token]( const auto& descr ) {
|
|
return token == descr.token;
|
|
} );
|
|
if( p == function_descrs_end ) {
|
|
cbl_internal_error( "%s: intrinsic function %qs not found",
|
|
__func__, keyword_str(token) );
|
|
}
|
|
|
|
gcc_assert(!args.empty());
|
|
gcc_assert(p < function_descrs_end);
|
|
|
|
const function_descr_t& descr = *p;
|
|
|
|
size_t i = 0;
|
|
for( auto arg : args ) {
|
|
if( arg.field == NULL ) {
|
|
i++;
|
|
continue;
|
|
}
|
|
assert(i < strlen(descr.types));
|
|
|
|
switch(descr.types[i]) {
|
|
case 'A' : //Alphabetic
|
|
case 'I' : //Integer
|
|
case 'N' : //Numeric
|
|
case 'X' : //Alphanumeric
|
|
break;
|
|
case 'n' : //variadic
|
|
return args.size();
|
|
break;
|
|
case 'D' : //DBCS
|
|
case 'K' : //Keyword
|
|
case 'O' : //Other
|
|
case 'U' : //National
|
|
case '8' : //UTF-8
|
|
default:
|
|
cbl_internal_error( "%s: invalid function descr type '%c'",
|
|
__func__, descr.types[i]);
|
|
}
|
|
|
|
static std::map<char, const char*> typenames
|
|
{
|
|
{ 'A', "Alphabetic" },
|
|
{ 'I', "Integer" },
|
|
{ 'N', "Numeric" },
|
|
{ 'X', "Alphanumeric" },
|
|
};
|
|
|
|
switch( arg.field->type ) {
|
|
case FldInvalid:
|
|
case FldClass:
|
|
case FldConditional:
|
|
case FldForward:
|
|
case FldIndex:
|
|
yyerror("%s: field '%s' (%s) invalid for %s parameter",
|
|
descr.name,
|
|
arg.field->name, cbl_field_type_str(arg.field->type),
|
|
typenames[descr.types[i]]);
|
|
return i;
|
|
break;
|
|
case FldGroup:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if( is_numeric(arg.field) || is_integer_literal(arg.field)) {
|
|
if( strchr("A", descr.types[i]) != NULL ) {
|
|
yyerror("%s: numeric field '%s' (%s) invalid for %s parameter",
|
|
descr.name,
|
|
arg.field->name, cbl_field_type_str(arg.field->type),
|
|
typenames[descr.types[i]]);
|
|
return i;
|
|
}
|
|
} else { // string field
|
|
if( strchr("IN", descr.types[i]) != NULL ) {
|
|
if( data_category_of(arg.field) == data_alphabetic_e ) {
|
|
yyerror("%s: non-numeric field '%s' (%s) invalid for %s parameter",
|
|
descr.name,
|
|
arg.field->name, cbl_field_type_str(arg.field->type),
|
|
typenames[descr.types[i]]);
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
i++;
|
|
} // end loop
|
|
|
|
return args.size();
|
|
}
|
|
|
|
/*
|
|
* Functions used by code gen
|
|
*/
|
|
|
|
size_t
|
|
intrinsic_parameter_count( const char cname[] ) {
|
|
const function_descr_t *descr = std::find_if(function_descrs,
|
|
function_descrs_end, cname_cmp(cname));
|
|
return descr == function_descrs_end || descr->types[0] == 'n'?
|
|
size_t(-1) : strlen(descr->types);
|
|
}
|
|
|
|
#if 0
|
|
static int
|
|
yyreport_syntax_error (const yypcontext_t *ctx)
|
|
{
|
|
int res = 0;
|
|
YYLOCATION_PRINT (stderr, yypcontext_location (ctx));
|
|
fprintf (stderr, ": syntax error");
|
|
// Report the tokens expected at this point.
|
|
{
|
|
enum { TOKENMAX = 5 };
|
|
yysymbol_kind_t expected[TOKENMAX];
|
|
int n = yypcontext_expected_tokens (ctx, expected, TOKENMAX);
|
|
if (n < 0)
|
|
// Forward errors to yyparse.
|
|
res = n;
|
|
else
|
|
for (int i = 0; i < n; ++i)
|
|
fprintf (stderr, "%s %s",
|
|
i == 0 ? ": expected" : " or", yysymbol_name (expected[i]));
|
|
}
|
|
// Report the unexpected token.
|
|
{
|
|
yysymbol_kind_t lookahead = yypcontext_token (ctx);
|
|
if (lookahead != YYSYMBOL_YYEMPTY)
|
|
fprintf (stderr, " before %s", yysymbol_name (lookahead));
|
|
}
|
|
fprintf (stderr, "\n");
|
|
return res;
|
|
}
|
|
#endif
|