@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 *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

View file

@ -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;
}

View file

@ -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;
} }

View file

@ -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"); }
; ;