@sizeof (foo) should work now

This commit is contained in:
Bill Currie 2002-08-18 04:08:02 +00:00
parent d796f9ea5a
commit a94bdb199f
4 changed files with 50 additions and 13 deletions

View file

@ -177,5 +177,6 @@ expr_t *selector_expr (struct keywordarg_s *selector);
expr_t *protocol_expr (const char *protocol);
expr_t *encode_expr (struct type_s *type);
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

View file

@ -2185,3 +2185,18 @@ message_expr (expr_t *receiver, keywordarg_t *message)
call->e.block.result->e.def->type = rec_type;
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;
}

View file

@ -301,6 +301,7 @@ static keyword_t keywords[] = {
{"@argv", ARGV, 0, 0, PROG_VERSION},
{"@extern", EXTERN, 0, 0, PROG_VERSION},
{"@static", STATIC, 0, 0, PROG_VERSION},
{"@sizeof", SIZEOF, 0, 0, PROG_VERSION},
};
static const char *
@ -315,6 +316,7 @@ type_or_name (char *token)
static hashtab_t *keyword_tab;
keyword_t *keyword;
type_t *type;
class_t *class;
if (!keyword_tab) {
int i;
@ -338,6 +340,10 @@ type_or_name (char *token)
yylval.type = type;
return TYPE;
}
if ((class = get_class (token, 0))) {
yylval.string_val = save_string (token);
return CLASS_NAME;
}
yylval.string_val = save_string (token);
return NAME;
}

View file

@ -119,7 +119,7 @@ void free_local_inits (hashtab_t *def_list);
%right '(' '['
%left '.'
%token <string_val> NAME STRING_VAL
%token <string_val> CLASS_NAME NAME STRING_VAL
%token <integer_val> INT_VAL
%token <float_val> FLOAT_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 IFBE IFB IFAE IFA
%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 <type> TYPE
%token CLASS DEFS ENCODE END IMPLEMENTATION INTERFACE PRIVATE PROTECTED
%token PROTOCOL PUBLIC SELECTOR
@ -148,7 +147,7 @@ void free_local_inits (hashtab_t *def_list);
%type <def_list> save_inits
%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 <method> methodproto methoddecl
%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 <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 { $$ = $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
@ -805,6 +812,8 @@ expr
| ARGV { $$ = new_name_expr (".argv"); }
| SELF { $$ = new_self_expr (); }
| THIS { $$ = new_this_expr (); }
| SIZEOF '(' expr ')' { $$ = sizeof_expr ($3, 0); }
| SIZEOF '(' type ')' { $$ = sizeof_expr (0, $3); }
| const { $$ = $1; }
| '(' expr ')' { $$ = $2; $$->paren = 1; }
;
@ -907,8 +916,13 @@ classdecl
}
;
class_name
maybe_class
: NAME
| CLASS_NAME
;
class_name
: maybe_class
{
$$ = get_class ($1, 0);
if (!$$) {
@ -919,7 +933,7 @@ class_name
;
new_class_name
: NAME
: maybe_class
{
$$ = get_class ($1, 1);
if ($$->defined) {
@ -950,7 +964,7 @@ new_class_with_super
;
category_name
: NAME '(' NAME ')'
: maybe_class '(' maybe_class ')'
{
$$ = get_category ($1, $3, 0);
if (!$$) {
@ -961,7 +975,7 @@ category_name
;
new_category_name
: NAME '(' NAME ')'
: maybe_class '(' maybe_class ')'
{
$$ = get_category ($1, $3, 1);
if ($$->defined) {
@ -973,7 +987,7 @@ new_category_name
;
protocol_name
: NAME
: maybe_class
{
$$ = get_protocol ($1, 0);
if ($$) {
@ -1208,7 +1222,7 @@ keywordselector
;
selector
: NAME
: maybe_class
| TYPE { $$ = save_string (yytext); }
| reserved_word
;
@ -1248,7 +1262,7 @@ keyworddecl
obj_expr
: obj_messageexpr
| SELECTOR '(' selectorarg ')' { $$ = selector_expr ($3); }
| PROTOCOL '(' NAME ')' { $$ = protocol_expr ($3); }
| PROTOCOL '(' maybe_class ')' { $$ = protocol_expr ($3); }
| ENCODE '(' type ')' { $$ = encode_expr ($3); }
| obj_string /* FIXME string object? */
;
@ -1259,6 +1273,7 @@ obj_messageexpr
receiver
: expr
| CLASS_NAME { $$ = new_name_expr ($1); }
| SUPER { $$ = new_name_expr ("super"); }
;