mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-08-23 10:33:50 -04:00
eval: implement the C ? : operator
Add the C ternary conditional ? : operator. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
1722fcf81c
commit
099cc17739
56
asm/eval.c
56
asm/eval.c
@ -271,11 +271,12 @@ static int scan(void)
|
|||||||
* Grammar parsed is:
|
* Grammar parsed is:
|
||||||
*
|
*
|
||||||
* expr : bexpr [ WRT expr6 ]
|
* expr : bexpr [ WRT expr6 ]
|
||||||
* bexpr : rexp0
|
* bexpr : cexpr
|
||||||
|
* cexpr : rexp0 [ {?} bexpr {:} cexpr ]
|
||||||
* rexp0 : rexp1 [ {||} rexp1...]
|
* rexp0 : rexp1 [ {||} rexp1...]
|
||||||
* rexp1 : rexp2 [ {^^} rexp2...]
|
* rexp1 : rexp2 [ {^^} rexp2...]
|
||||||
* rexp2 : rexp3 [ {&&} rexp3...]
|
* rexp2 : rexp3 [ {&&} rexp3...]
|
||||||
* rexp3 : expr0 [ {=,==,<>,!=,<,>,<=,>=,<=>} expr0 ]
|
* rexp3 : expr0 [ {=,==,<>,!=,<,>,<=,>=,<=>} expr0... ]
|
||||||
* expr0 : expr1 [ {|} expr1...]
|
* expr0 : expr1 [ {|} expr1...]
|
||||||
* expr1 : expr2 [ {^} expr2...]
|
* expr1 : expr2 [ {^} expr2...]
|
||||||
* expr2 : expr3 [ {&} expr3...]
|
* expr2 : expr3 [ {&} expr3...]
|
||||||
@ -289,6 +290,7 @@ static int scan(void)
|
|||||||
* | number
|
* | number
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static expr *cexpr(void);
|
||||||
static expr *rexp0(void), *rexp1(void), *rexp2(void), *rexp3(void);
|
static expr *rexp0(void), *rexp1(void), *rexp2(void), *rexp3(void);
|
||||||
|
|
||||||
static expr *expr0(void), *expr1(void), *expr2(void), *expr3(void);
|
static expr *expr0(void), *expr1(void), *expr2(void), *expr3(void);
|
||||||
@ -297,7 +299,44 @@ static expr *expr4(void), *expr5(void), *expr6(void);
|
|||||||
/* This inline is a placeholder for the root of the basic expression */
|
/* This inline is a placeholder for the root of the basic expression */
|
||||||
static inline expr *bexpr(void)
|
static inline expr *bexpr(void)
|
||||||
{
|
{
|
||||||
return rexp0();
|
return cexpr();
|
||||||
|
}
|
||||||
|
|
||||||
|
static expr *cexpr(void)
|
||||||
|
{
|
||||||
|
expr *e, *f, *g;
|
||||||
|
|
||||||
|
e = rexp0();
|
||||||
|
if (!e)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (tt == '?') {
|
||||||
|
scan();
|
||||||
|
f = bexpr();
|
||||||
|
if (!f)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (tt != ':') {
|
||||||
|
nasm_error(ERR_NONFATAL, "`?' without matching `:'");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
scan();
|
||||||
|
g = cexpr();
|
||||||
|
if (!g)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (is_simple(e)) {
|
||||||
|
e = reloc_value(e) ? f : g;
|
||||||
|
} else if (is_just_unknown(e)) {
|
||||||
|
e = unknown_expr();
|
||||||
|
} else {
|
||||||
|
nasm_error(ERR_NONFATAL, "the left-hand side of `?' must be "
|
||||||
|
"a scalar value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static expr *rexp0(void)
|
static expr *rexp0(void)
|
||||||
@ -987,7 +1026,7 @@ expr *evaluate(scanner sc, void *scprivate, struct tokenval *tv,
|
|||||||
expr *f = NULL;
|
expr *f = NULL;
|
||||||
|
|
||||||
deadman = 0;
|
deadman = 0;
|
||||||
|
|
||||||
hint = hints;
|
hint = hints;
|
||||||
if (hint)
|
if (hint)
|
||||||
hint->type = EAH_NOHINT;
|
hint->type = EAH_NOHINT;
|
||||||
@ -998,14 +1037,13 @@ expr *evaluate(scanner sc, void *scprivate, struct tokenval *tv,
|
|||||||
tokval = tv;
|
tokval = tv;
|
||||||
opflags = fwref;
|
opflags = fwref;
|
||||||
|
|
||||||
if (tokval->t_type == TOKEN_INVALID)
|
|
||||||
scan();
|
|
||||||
else
|
|
||||||
tt = tokval->t_type;
|
|
||||||
|
|
||||||
while (ntempexprs) /* initialize temporary storage */
|
while (ntempexprs) /* initialize temporary storage */
|
||||||
nasm_free(tempexprs[--ntempexprs]);
|
nasm_free(tempexprs[--ntempexprs]);
|
||||||
|
|
||||||
|
tt = tokval->t_type;
|
||||||
|
if (tt == TOKEN_INVALID)
|
||||||
|
scan();
|
||||||
|
|
||||||
e = bexpr();
|
e = bexpr();
|
||||||
if (!e)
|
if (!e)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user