mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-05-06 16:01:10 +00:00
@sizeof (foo) should work now
This commit is contained in:
parent
d796f9ea5a
commit
a94bdb199f
4 changed files with 50 additions and 13 deletions
|
@ -177,5 +177,6 @@ expr_t *selector_expr (struct keywordarg_s *selector);
|
||||||
expr_t *protocol_expr (const char *protocol);
|
expr_t *protocol_expr (const char *protocol);
|
||||||
expr_t *encode_expr (struct type_s *type);
|
expr_t *encode_expr (struct type_s *type);
|
||||||
expr_t *message_expr (expr_t *receiver, struct keywordarg_s *message);
|
expr_t *message_expr (expr_t *receiver, struct keywordarg_s *message);
|
||||||
|
expr_t *sizeof_expr (expr_t *expr, struct type_s *type);
|
||||||
|
|
||||||
#endif//__expr_h
|
#endif//__expr_h
|
||||||
|
|
|
@ -2185,3 +2185,18 @@ message_expr (expr_t *receiver, keywordarg_t *message)
|
||||||
call->e.block.result->e.def->type = rec_type;
|
call->e.block.result->e.def->type = rec_type;
|
||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_t *
|
||||||
|
sizeof_expr (expr_t *expr, struct type_s *type)
|
||||||
|
{
|
||||||
|
if (!((!expr) ^ (!expr))) {
|
||||||
|
error (0, "internal error");
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
if (!type)
|
||||||
|
type = get_type (expr);
|
||||||
|
expr = new_expr ();
|
||||||
|
expr->type = ex_integer;
|
||||||
|
expr->e.integer_val = type_size (type);
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
|
@ -301,6 +301,7 @@ static keyword_t keywords[] = {
|
||||||
{"@argv", ARGV, 0, 0, PROG_VERSION},
|
{"@argv", ARGV, 0, 0, PROG_VERSION},
|
||||||
{"@extern", EXTERN, 0, 0, PROG_VERSION},
|
{"@extern", EXTERN, 0, 0, PROG_VERSION},
|
||||||
{"@static", STATIC, 0, 0, PROG_VERSION},
|
{"@static", STATIC, 0, 0, PROG_VERSION},
|
||||||
|
{"@sizeof", SIZEOF, 0, 0, PROG_VERSION},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
@ -315,6 +316,7 @@ type_or_name (char *token)
|
||||||
static hashtab_t *keyword_tab;
|
static hashtab_t *keyword_tab;
|
||||||
keyword_t *keyword;
|
keyword_t *keyword;
|
||||||
type_t *type;
|
type_t *type;
|
||||||
|
class_t *class;
|
||||||
|
|
||||||
if (!keyword_tab) {
|
if (!keyword_tab) {
|
||||||
int i;
|
int i;
|
||||||
|
@ -338,6 +340,10 @@ type_or_name (char *token)
|
||||||
yylval.type = type;
|
yylval.type = type;
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
if ((class = get_class (token, 0))) {
|
||||||
|
yylval.string_val = save_string (token);
|
||||||
|
return CLASS_NAME;
|
||||||
|
}
|
||||||
yylval.string_val = save_string (token);
|
yylval.string_val = save_string (token);
|
||||||
return NAME;
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ void free_local_inits (hashtab_t *def_list);
|
||||||
%right '(' '['
|
%right '(' '['
|
||||||
%left '.'
|
%left '.'
|
||||||
|
|
||||||
%token <string_val> NAME STRING_VAL
|
%token <string_val> CLASS_NAME NAME STRING_VAL
|
||||||
%token <integer_val> INT_VAL
|
%token <integer_val> INT_VAL
|
||||||
%token <float_val> FLOAT_VAL
|
%token <float_val> FLOAT_VAL
|
||||||
%token <vector_val> VECTOR_VAL
|
%token <vector_val> VECTOR_VAL
|
||||||
|
@ -128,10 +128,9 @@ void free_local_inits (hashtab_t *def_list);
|
||||||
%token LOCAL RETURN WHILE DO IF ELSE FOR BREAK CONTINUE ELLIPSIS NIL
|
%token LOCAL RETURN WHILE DO IF ELSE FOR BREAK CONTINUE ELLIPSIS NIL
|
||||||
%token IFBE IFB IFAE IFA
|
%token IFBE IFB IFAE IFA
|
||||||
%token SWITCH CASE DEFAULT STRUCT UNION ENUM TYPEDEF SUPER SELF THIS
|
%token SWITCH CASE DEFAULT STRUCT UNION ENUM TYPEDEF SUPER SELF THIS
|
||||||
%token ARGC ARGV EXTERN STATIC
|
%token ARGC ARGV EXTERN STATIC SIZEOF
|
||||||
%token ELE_START
|
%token ELE_START
|
||||||
%token <type> TYPE
|
%token <type> TYPE
|
||||||
|
|
||||||
%token CLASS DEFS ENCODE END IMPLEMENTATION INTERFACE PRIVATE PROTECTED
|
%token CLASS DEFS ENCODE END IMPLEMENTATION INTERFACE PRIVATE PROTECTED
|
||||||
%token PROTOCOL PUBLIC SELECTOR
|
%token PROTOCOL PUBLIC SELECTOR
|
||||||
|
|
||||||
|
@ -148,7 +147,7 @@ void free_local_inits (hashtab_t *def_list);
|
||||||
%type <def_list> save_inits
|
%type <def_list> save_inits
|
||||||
%type <switch_block> switch_block
|
%type <switch_block> switch_block
|
||||||
|
|
||||||
%type <string_val> selector reserved_word
|
%type <string_val> selector reserved_word maybe_class
|
||||||
%type <param> optparmlist unaryselector keyworddecl keywordselector
|
%type <param> optparmlist unaryselector keyworddecl keywordselector
|
||||||
%type <method> methodproto methoddecl
|
%type <method> methodproto methoddecl
|
||||||
%type <expr> obj_expr identifier_list obj_messageexpr obj_string receiver
|
%type <expr> obj_expr identifier_list obj_messageexpr obj_string receiver
|
||||||
|
@ -161,7 +160,7 @@ void free_local_inits (hashtab_t *def_list);
|
||||||
%type <methodlist> methodprotolist methodprotolist2
|
%type <methodlist> methodprotolist methodprotolist2
|
||||||
%type <type> ivar_decl_list
|
%type <type> ivar_decl_list
|
||||||
|
|
||||||
%expect 2 // statement : if | if else, defs : defs def ';' | defs obj_def
|
%expect 3 // statement : if | if else, class_name : maybe_class | category_name : maybe_class '(' maybe_class ')', type_name : TYPE | expr : TYPE '(' expr ')'
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
|
||||||
|
@ -287,7 +286,15 @@ non_field_type
|
||||||
|
|
||||||
type_name
|
type_name
|
||||||
: TYPE { $$ = $1; }
|
: TYPE { $$ = $1; }
|
||||||
| class_name { $$ = $1->type; }
|
| CLASS_NAME
|
||||||
|
{
|
||||||
|
class_t *class = get_class ($1, 0);
|
||||||
|
if (!class) {
|
||||||
|
error (0, "undefined symbol `%s'", $1);
|
||||||
|
class = get_class (0, 1);
|
||||||
|
}
|
||||||
|
$$ = class->type;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
function_decl
|
function_decl
|
||||||
|
@ -805,6 +812,8 @@ expr
|
||||||
| ARGV { $$ = new_name_expr (".argv"); }
|
| ARGV { $$ = new_name_expr (".argv"); }
|
||||||
| SELF { $$ = new_self_expr (); }
|
| SELF { $$ = new_self_expr (); }
|
||||||
| THIS { $$ = new_this_expr (); }
|
| THIS { $$ = new_this_expr (); }
|
||||||
|
| SIZEOF '(' expr ')' { $$ = sizeof_expr ($3, 0); }
|
||||||
|
| SIZEOF '(' type ')' { $$ = sizeof_expr (0, $3); }
|
||||||
| const { $$ = $1; }
|
| const { $$ = $1; }
|
||||||
| '(' expr ')' { $$ = $2; $$->paren = 1; }
|
| '(' expr ')' { $$ = $2; $$->paren = 1; }
|
||||||
;
|
;
|
||||||
|
@ -907,8 +916,13 @@ classdecl
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
class_name
|
maybe_class
|
||||||
: NAME
|
: NAME
|
||||||
|
| CLASS_NAME
|
||||||
|
;
|
||||||
|
|
||||||
|
class_name
|
||||||
|
: maybe_class
|
||||||
{
|
{
|
||||||
$$ = get_class ($1, 0);
|
$$ = get_class ($1, 0);
|
||||||
if (!$$) {
|
if (!$$) {
|
||||||
|
@ -919,7 +933,7 @@ class_name
|
||||||
;
|
;
|
||||||
|
|
||||||
new_class_name
|
new_class_name
|
||||||
: NAME
|
: maybe_class
|
||||||
{
|
{
|
||||||
$$ = get_class ($1, 1);
|
$$ = get_class ($1, 1);
|
||||||
if ($$->defined) {
|
if ($$->defined) {
|
||||||
|
@ -950,7 +964,7 @@ new_class_with_super
|
||||||
;
|
;
|
||||||
|
|
||||||
category_name
|
category_name
|
||||||
: NAME '(' NAME ')'
|
: maybe_class '(' maybe_class ')'
|
||||||
{
|
{
|
||||||
$$ = get_category ($1, $3, 0);
|
$$ = get_category ($1, $3, 0);
|
||||||
if (!$$) {
|
if (!$$) {
|
||||||
|
@ -961,7 +975,7 @@ category_name
|
||||||
;
|
;
|
||||||
|
|
||||||
new_category_name
|
new_category_name
|
||||||
: NAME '(' NAME ')'
|
: maybe_class '(' maybe_class ')'
|
||||||
{
|
{
|
||||||
$$ = get_category ($1, $3, 1);
|
$$ = get_category ($1, $3, 1);
|
||||||
if ($$->defined) {
|
if ($$->defined) {
|
||||||
|
@ -973,7 +987,7 @@ new_category_name
|
||||||
;
|
;
|
||||||
|
|
||||||
protocol_name
|
protocol_name
|
||||||
: NAME
|
: maybe_class
|
||||||
{
|
{
|
||||||
$$ = get_protocol ($1, 0);
|
$$ = get_protocol ($1, 0);
|
||||||
if ($$) {
|
if ($$) {
|
||||||
|
@ -1208,7 +1222,7 @@ keywordselector
|
||||||
;
|
;
|
||||||
|
|
||||||
selector
|
selector
|
||||||
: NAME
|
: maybe_class
|
||||||
| TYPE { $$ = save_string (yytext); }
|
| TYPE { $$ = save_string (yytext); }
|
||||||
| reserved_word
|
| reserved_word
|
||||||
;
|
;
|
||||||
|
@ -1248,7 +1262,7 @@ keyworddecl
|
||||||
obj_expr
|
obj_expr
|
||||||
: obj_messageexpr
|
: obj_messageexpr
|
||||||
| SELECTOR '(' selectorarg ')' { $$ = selector_expr ($3); }
|
| SELECTOR '(' selectorarg ')' { $$ = selector_expr ($3); }
|
||||||
| PROTOCOL '(' NAME ')' { $$ = protocol_expr ($3); }
|
| PROTOCOL '(' maybe_class ')' { $$ = protocol_expr ($3); }
|
||||||
| ENCODE '(' type ')' { $$ = encode_expr ($3); }
|
| ENCODE '(' type ')' { $$ = encode_expr ($3); }
|
||||||
| obj_string /* FIXME string object? */
|
| obj_string /* FIXME string object? */
|
||||||
;
|
;
|
||||||
|
@ -1259,6 +1273,7 @@ obj_messageexpr
|
||||||
|
|
||||||
receiver
|
receiver
|
||||||
: expr
|
: expr
|
||||||
|
| CLASS_NAME { $$ = new_name_expr ($1); }
|
||||||
| SUPER { $$ = new_name_expr ("super"); }
|
| SUPER { $$ = new_name_expr ("super"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue