Skip to content

Commit

Permalink
Add the missing relational, bitwise, logical and remainder operators …
Browse files Browse the repository at this point in the history
…to HuCC's

const_expr() parser that Uli added.

Change HuCC to use the const_expr() parser for "case" values.
  • Loading branch information
jbrandwood committed Nov 20, 2024
1 parent a01ff21 commit 4254c01
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 41 deletions.
2 changes: 1 addition & 1 deletion src/hucc/const.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
193 changes: 165 additions & 28 deletions src/hucc/primary.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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 (;;) {
Expand All @@ -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 (;;) {
Expand All @@ -636,7 +640,7 @@ static int parse6 (int *num)
return (1);
}

if (!parse5(&num2))
if (!parse_const5(&num2))
return (0);

if (op == '-')
Expand All @@ -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 (;;) {
Expand All @@ -664,7 +668,7 @@ static int parse7 (int *num)
return (1);
}

if (!parse6(&num2))
if (!parse_const6(&num2))
return (0);

if (op == 'l')
Expand All @@ -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 (;;) {
Expand All @@ -692,7 +730,7 @@ static int parse9 (int *num)
return (1);
}

if (!parse7(&num2))
if (!parse_const8(&num2))
return (0);

if (op == '=')
Expand All @@ -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);
}
Expand All @@ -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;
Expand All @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions src/hucc/primary.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
12 changes: 4 additions & 8 deletions src/hucc/stmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
4 changes: 2 additions & 2 deletions src/hucc/sym.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}
Expand Down

0 comments on commit 4254c01

Please sign in to comment.