[qfcc] Implement ulong, long and uint constants

Finally :P
This commit is contained in:
Bill Currie 2022-04-29 15:38:55 +09:00
parent 9c8e13aa4c
commit 9cccb7a4d4
6 changed files with 52 additions and 9 deletions

View file

@ -633,6 +633,9 @@ int expr_int (expr_t *e) __attribute__((pure));
expr_t *new_uint_expr (unsigned uint_val);
unsigned expr_uint (expr_t *e) __attribute__((pure));
expr_t *new_long_expr (pr_long_t long_val);
expr_t *new_ulong_expr (pr_ulong_t ulong_val);
/** Create a new short constant expression node.
\param short_val The short constant being represented.

View file

@ -56,6 +56,8 @@ struct ex_value_s *new_pointer_val (int val, struct type_s *type,
struct ex_value_s *new_quaternion_val (const float *quaternion_val);
struct ex_value_s *new_int_val (int int_val);
struct ex_value_s *new_uint_val (int uint_val);
struct ex_value_s *new_long_val (pr_long_t long_val);
struct ex_value_s *new_ulong_val (pr_ulong_t ulong_val);
struct ex_value_s *new_short_val (short short_val);
struct ex_value_s *new_nil_val (struct type_s *type);
struct ex_value_s *new_type_value (const struct type_s *type,

View file

@ -752,6 +752,18 @@ new_uint_expr (unsigned uint_val)
return new_value_expr (new_uint_val (uint_val));
}
expr_t *
new_long_expr (pr_long_t long_val)
{
return new_value_expr (new_long_val (long_val));
}
expr_t *
new_ulong_expr (pr_ulong_t ulong_val)
{
return new_value_expr (new_ulong_val (ulong_val));
}
expr_t *
new_short_expr (short short_val)
{

View file

@ -131,17 +131,25 @@ STRING \"(\\.|[^"\\])*\"
{INT}+{UL}? {
const char *c = yytext + yyleng - 1;
int i;
pr_long_t i;
if (yytext[0] == '0' && tolower (yytext[1] == 'b'))
i = strtol (yytext + 2, 0, 2);
else
i = strtol (yytext, 0, 0);
if (*c == 'u' || *c == 'U') {
qc_yylval.expr = new_int_expr (i);//FIXME
if (tolower (*c) == 'u') {
if (tolower (c[1]) == 'l') {
qc_yylval.expr = new_ulong_expr (i);
} else {
qc_yylval.expr = new_uint_expr (i);
}
} else {
qc_yylval.expr = new_int_expr (i);
qc_yylval.expr->implicit = 1;
if (tolower (c[1]) == 'l') {
qc_yylval.expr = new_long_expr (i);
} else {
qc_yylval.expr = new_int_expr (i);
qc_yylval.expr->implicit = 1;
}
}
return VALUE;
}

View file

@ -94,7 +94,7 @@ int yylex (void);
%union {
int op;
int size;
unsigned size;
specifier_t spec;
void *pointer; // for ensuring pointer values are null
struct type_s *type;
@ -1131,11 +1131,13 @@ abs_decl
array_decl
: '[' expr ']'
{
if (!is_int_val ($2) || expr_int ($2) < 1) {
if (is_int_val ($2) && expr_int ($2) > 0) {
$$ = expr_int ($2);
} else if (is_uint_val ($2) && expr_uint ($2) > 0) {
$$ = expr_uint ($2);
} else {
error (0, "invalid array size");
$$ = 0;
} else {
$$ = expr_int ($2);
}
}
| '[' ']' { $$ = 0; }

View file

@ -240,6 +240,22 @@ new_uint_val (int uint_val)
return find_value (&val);
}
ex_value_t *
new_long_val (pr_long_t long_val)
{
ex_value_t val = { .v = { .long_val = long_val } };
set_val_type (&val, &type_long);
return find_value (&val);
}
ex_value_t *
new_ulong_val (pr_ulong_t ulong_val)
{
ex_value_t val = { .v = { .ulong_val = ulong_val } };
set_val_type (&val, &type_ulong);
return find_value (&val);
}
ex_value_t *
new_short_val (short short_val)
{