diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 5635141f2..0f460445d 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -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. diff --git a/tools/qfcc/include/value.h b/tools/qfcc/include/value.h index 197c31514..e8eb5a3a7 100644 --- a/tools/qfcc/include/value.h +++ b/tools/qfcc/include/value.h @@ -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, diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index fe6a10dd3..daea88014 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -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) { diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index ee63d6791..495d69aa9 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -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; } diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 29029e543..5355a7981 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -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; } diff --git a/tools/qfcc/source/value.c b/tools/qfcc/source/value.c index 8661a140b..bd8ac599e 100644 --- a/tools/qfcc/source/value.c +++ b/tools/qfcc/source/value.c @@ -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) {