aboutsummaryrefslogtreecommitdiff
path: root/gcc/cobol/scan_ante.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cobol/scan_ante.h')
-rw-r--r--gcc/cobol/scan_ante.h97
1 files changed, 97 insertions, 0 deletions
diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h
index 784c9b0..c8c93ed 100644
--- a/gcc/cobol/scan_ante.h
+++ b/gcc/cobol/scan_ante.h
@@ -498,6 +498,10 @@ update_location_col( const char str[], int correction = 0) {
result = YY_NULL; \
}
+#define bcomputable(T, C) \
+ yylval.computational.type=T, \
+ yylval.computational.capacity=C, \
+ yylval.computational.signable=true, BINARY_INTEGER
#define scomputable(T, C) \
yylval.computational.type=T, \
yylval.computational.capacity=C, \
@@ -511,6 +515,99 @@ static char *tmpstring = NULL;
#define PROGRAM current_program_index()
+// map of alias => canonical
+static std::map <std::string, std::string> keyword_aliases;
+
+const std::string&
+keyword_alias_add( const std::string& keyword, const std::string& alias ) {
+ auto p = keyword_aliases.find(alias);
+ if( p != keyword_aliases.end() ) return p->second; // error: do not overwrite
+ return keyword_aliases[alias] = keyword;
+}
+
+/*
+ * Because numeric USAGE types don't have distinct tokens and may have aliases,
+ * we keep a table of their canonical names, which we use if we encounter an
+ * alias.
+ */
+struct bint_t {
+ int token;
+ cbl_field_type_t type;
+ uint32_t capacity;
+ bool signable;
+};
+static const std::map <std::string, bint_t > binary_integers {
+ { "COMP-X", { COMPUTATIONAL, FldNumericBin5, 0xFF, false } },
+ { "COMP-6", { COMPUTATIONAL, FldPacked, 0, false } },
+ { "COMP-5", { COMPUTATIONAL, FldNumericBin5, 0, false } },
+ { "COMP-4", { COMPUTATIONAL, FldNumericBinary, 0, true } },
+ { "COMP-2", { COMPUTATIONAL, FldFloat, 8, false } },
+ { "COMP-1", { COMPUTATIONAL, FldFloat, 4, false } },
+ { "COMP", { COMPUTATIONAL, FldNumericBinary, 0, false } },
+ { "COMPUTATIONAL-X", { COMPUTATIONAL, FldNumericBin5, 0xFF, false } },
+ { "COMPUTATIONAL-6", { COMPUTATIONAL, FldPacked, 0, false } },
+ { "COMPUTATIONAL-5", { COMPUTATIONAL, FldNumericBin5, 0, false } },
+ { "COMPUTATIONAL-4", { COMPUTATIONAL, FldNumericBinary, 0, true } },
+ { "COMPUTATIONAL-2", { COMPUTATIONAL, FldFloat, 8, false } },
+ { "COMPUTATIONAL-1", { COMPUTATIONAL, FldFloat, 4, false } },
+ { "COMPUTATIONAL", { COMPUTATIONAL, FldNumericBinary, 0, false } },
+ { "BINARY", { BINARY_INTEGER, FldNumericBinary, 0, true } },
+ { "BINARY-CHAR", { BINARY_INTEGER, FldNumericBin5, 1, true } },
+ { "BINARY-SHORT", { BINARY_INTEGER, FldNumericBin5, 2, true } },
+ { "BINARY-LONG", { BINARY_INTEGER, FldNumericBin5, 4, true } },
+ { "BINARY-DOUBLE", { BINARY_INTEGER, FldNumericBin5, 8, true } },
+ { "BINARY-LONG-LONG", { BINARY_INTEGER, FldNumericBin5, 8, true } },
+ { "FLOAT-BINARY-32", { COMPUTATIONAL, FldFloat, 4, false } },
+ { "FLOAT-BINARY-64", { COMPUTATIONAL, FldFloat, 8, false } },
+ { "FLOAT-BINARY-128", { COMPUTATIONAL, FldFloat, 16, false } },
+ { "FLOAT-EXTENDED", { COMPUTATIONAL, FldFloat, 16, false } },
+ { "FLOAT-LONG", { COMPUTATIONAL, FldFloat, 8, false } },
+ { "FLOAT-SHORT", { COMPUTATIONAL, FldFloat, 4, false } },
+};
+
+static int
+binary_integer_usage( const char name[]) {
+ cbl_name_t uname = {};
+ std::transform(name, name + strlen(name), uname, ftoupper);
+
+ dbgmsg("%s:%d: checking %s in %zu keyword_aliases",
+ __func__, __LINE__, uname, keyword_aliases.size() );
+
+ std::string key = uname;
+ auto alias = keyword_aliases.find(key);
+ if( alias != keyword_aliases.end() ) key = alias->second;
+
+ auto p = binary_integers.find(key);
+ if( p == binary_integers.end() ) return 0;
+
+ yylval.computational.type = p->second.type;
+ yylval.computational.capacity = p->second.capacity;
+ yylval.computational.signable = p->second.signable;
+ dbgmsg("%s:%d: %s has type %d", __func__, __LINE__,
+ uname, p->second.type );
+ return p->second.token;
+}
+
+int
+binary_integer_usage_of( const char name[] ) {
+ cbl_name_t uname = {};
+ std::transform(name, name + strlen(name), uname, ftoupper);
+
+ auto p = binary_integers.find(uname);
+ if( p != binary_integers.end() ) {
+ int token = p->second.token;
+ switch( token ) {
+ case COMPUTATIONAL:
+ case BINARY_INTEGER:
+ return token;
+ default:
+ gcc_unreachable();
+ assert(false);
+ }
+ }
+ return 0;
+}
+
static uint32_t
level_of( const char input[] ) {
unsigned int output = 0;