From 4254c013951759048b750518f9cedee580a71492 Mon Sep 17 00:00:00 2001 From: John Brandwood <john.brandwood@telzey.com> Date: Wed, 20 Nov 2024 11:01:47 -0500 Subject: [PATCH] Add the missing relational, bitwise, logical and remainder operators to HuCC's const_expr() parser that Uli added. Change HuCC to use the const_expr() parser for "case" values. --- src/hucc/const.c | 2 +- src/hucc/primary.c | 193 ++++++++++++++++++++++++++++++++++++++------- src/hucc/primary.h | 4 +- src/hucc/stmt.c | 12 +-- src/hucc/sym.c | 4 +- 5 files changed, 174 insertions(+), 41 deletions(-) diff --git a/src/hucc/const.c b/src/hucc/const.c index f02b89de..324ce932 100644 --- a/src/hucc/const.c +++ b/src/hucc/const.c @@ -161,7 +161,7 @@ int get_string_ptr (char typ) if (typ == CINT || typ == CUINT) error("incompatible pointer type"); - if (qstr(&num)) + if (quoted_str(&num)) return (-(num + 1024)); else return (-1); diff --git a/src/hucc/primary.c b/src/hucc/primary.c index fae91cc7..22c5a742 100644 --- a/src/hucc/primary.c +++ b/src/hucc/primary.c @@ -447,9 +447,9 @@ int constant (int *val) { if (number(val)) immed(T_VALUE, *val); - else if (pstr(val)) + else if (quoted_chr(val)) immed(T_VALUE, *val); - else if (qstr(val)) { + else if (quoted_str(val)) { immed(T_STRING, *val); return (2); } @@ -507,7 +507,7 @@ bool number (int *val) return (true); } -static int parse0 (int *num) +static int parse_const0 (int *num) { if (!const_expr(num, ")", NULL)) return (0); @@ -517,7 +517,7 @@ static int parse0 (int *num) return (1); } -static int parse3 (int *num) +static int parse_const3 (int *num) { int num2; struct type_type t; @@ -549,9 +549,9 @@ static int parse3 (int *num) else op = 0; - if (!(have_paren && parse0(&num2)) && + if (!(have_paren && parse_const0(&num2)) && !number(&num2) && - !pstr(&num2) && + !quoted_chr(&num2) && !(symname(n) && find_enum(n, &num2))) return (0); @@ -590,11 +590,11 @@ static int parse3 (int *num) return (1); } -static int parse5 (int *num) +static int parse_const5 (int *num) { int num1, num2; - if (!parse3(&num1)) + if (!parse_const3(&num1)) return (0); for (;;) { @@ -603,26 +603,30 @@ static int parse5 (int *num) op = '*'; else if (match("/")) op = '/'; + else if (match("%")) + op = '%'; else { *num = num1; return (1); } - if (!parse3(&num2)) + if (!parse_const3(&num2)) return (0); if (op == '*') num1 *= num2; - else + else if (op == '/') num1 /= num2; + else + num1 %= num2; } } -static int parse6 (int *num) +static int parse_const6 (int *num) { int num1, num2; - if (!parse5(&num1)) + if (!parse_const5(&num1)) return (0); for (;;) { @@ -636,7 +640,7 @@ static int parse6 (int *num) return (1); } - if (!parse5(&num2)) + if (!parse_const5(&num2)) return (0); if (op == '-') @@ -646,11 +650,11 @@ static int parse6 (int *num) } } -static int parse7 (int *num) +static int parse_const7 (int *num) { int num1, num2; - if (!parse6(&num1)) + if (!parse_const6(&num1)) return (0); for (;;) { @@ -664,7 +668,7 @@ static int parse7 (int *num) return (1); } - if (!parse6(&num2)) + if (!parse_const6(&num2)) return (0); if (op == 'l') @@ -674,11 +678,45 @@ static int parse7 (int *num) } } -static int parse9 (int *num) +static int parse_const8 (int *num) { int num1, num2; - if (!parse7(&num1)) + if (!parse_const7(&num1)) + return (0); + + for (;;) { + char op; + if (match("<=")) + op = 0; + else if (match(">=")) + op = 1; + else if (match("<")) + op = 2; + else if (match(">")) + op = 3; + else { + *num = num1; + return (1); + } + + if (!parse_const7(&num2)) + return (0); + + switch (op) { + case 0: num1 = (num1 <= num2); break; + case 1: num1 = (num1 >= num2); break; + case 2: num1 = (num1 < num2); break; + case 3: num1 = (num1 > num2); break; + } + } +} + +static int parse_const9 (int *num) +{ + int num1, num2; + + if (!parse_const8(&num1)) return (0); for (;;) { @@ -692,7 +730,7 @@ static int parse9 (int *num) return (1); } - if (!parse7(&num2)) + if (!parse_const8(&num2)) return (0); if (op == '=') @@ -702,9 +740,109 @@ static int parse9 (int *num) } } +static int parse_const10 (int *num) +{ + int num1, num2; + + if (!parse_const9(&num1)) + return (0); + + for (;;) { + if (!match("&")) { + *num = num1; + return (1); + } + + if (!parse_const9(&num2)) + return (0); + + num1 = num1 & num2; + } +} + +static int parse_const11 (int *num) +{ + int num1, num2; + + if (!parse_const10(&num1)) + return (0); + + for (;;) { + if (!match("^")) { + *num = num1; + return (1); + } + + if (!parse_const10(&num2)) + return (0); + + num1 = num1 ^ num2; + } +} + +static int parse_const12 (int *num) +{ + int num1, num2; + + if (!parse_const11(&num1)) + return (0); + + for (;;) { + if (!match("|")) { + *num = num1; + return (1); + } + + if (!parse_const11(&num2)) + return (0); + + num1 = num1 | num2; + } +} + +static int parse_const13 (int *num) +{ + int num1, num2; + + if (!parse_const12(&num1)) + return (0); + + for (;;) { + if (!match("&&")) { + *num = num1; + return (1); + } + + if (!parse_const12(&num2)) + return (0); + + num1 = num1 && num2; + } +} + +static int parse_const14 (int *num) +{ + int num1, num2; + + if (!parse_const13(&num1)) + return (0); + + for (;;) { + if (!match("||")) { + *num = num1; + return (1); + } + + if (!parse_const13(&num2)) + return (0); + + num1 = num1 || num2; + } +} + bool const_expr (int *num, char *end1, char *end2) { - if (!parse9(num)) { + if (!parse_const14(num)) { error("failed to evaluate constant expression"); return (false); } @@ -717,11 +855,10 @@ bool const_expr (int *num, char *end1, char *end2) } /* - * pstr - * pstr parses a character than can eventually be 'double' i.e. like 'a9' - * returns 0 in case of failure else 1 + * Test if we have one char enclosed in single quotes + * return 0 in case of failure else 1 */ -bool pstr (int *val) +bool quoted_chr (int *val) { int k; char c; @@ -739,11 +876,11 @@ bool pstr (int *val) } /* - * qstr - * qstr parses a double quoted string into litq - * return 0 in case of failure and 1 else + * Test if we have string enclosed in double quotes. e.g. "abc". + * Load the string into literal pool. + * return 0 in case of failure else 1 */ -bool qstr (int *val) +bool quoted_str (int *val) { char c; diff --git a/src/hucc/primary.h b/src/hucc/primary.h index 651b02c8..3fdb1368 100644 --- a/src/hucc/primary.h +++ b/src/hucc/primary.h @@ -12,8 +12,8 @@ void result (LVALUE lval[], LVALUE lval2[]); int constant (int *val); bool number (int *val); bool const_expr (int *num, char *, char *); -bool pstr (int *val); -bool qstr (int *val); +bool quoted_chr (int *val); +bool quoted_str (int *val); bool const_str (int *val, const char *str); bool readqstr (void); bool readstr (void); diff --git a/src/hucc/stmt.c b/src/hucc/stmt.c index 71a9ba32..a27c1341 100644 --- a/src/hucc/stmt.c +++ b/src/hucc/stmt.c @@ -406,15 +406,11 @@ void doswitch (void) */ void docase (void) { - int val; - char n[NAMESIZE]; - - val = 0; + int val = 0; if (readswitch()) { - if (!number(&val)) - if (!pstr(&val)) - if (!(symname(n) && find_enum(n, &val))) - error("bad case label"); + if (!const_expr(&val, ":", NULL)) { + error("case label must be constant"); + } addcase(val); if (!match(":")) error("missing colon"); diff --git a/src/hucc/sym.c b/src/hucc/sym.c index 4e2ae5c9..6bb216b7 100644 --- a/src/hucc/sym.c +++ b/src/hucc/sym.c @@ -43,7 +43,7 @@ static int init (char *symbol_name, int type, int identity, int *dim, TAG_SYMBOL return (0); } - if (qstr(&value)) { + if (quoted_str(&value)) { if ((identity == VARIABLE) || (type != CCHAR && type != CUCHAR)) error("found string: must assign to char pointer or array"); /* XXX: make this a warning? */ if (identity == POINTER) { @@ -65,7 +65,7 @@ static int init (char *symbol_name, int type, int identity, int *dim, TAG_SYMBOL add_data_initials(symbol_name, CINT, value, tag); *dim = *dim - 1; } - else if (qstr(&value)) { + else if (quoted_str(&value)) { add_data_initials(symbol_name, CCHAR, value, tag); *dim = *dim - 1; }