tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] _Generic or __builtin_choose_expr


From: Michael Matz
Subject: Re: [Tinycc-devel] _Generic or __builtin_choose_expr
Date: Mon, 3 Jul 2017 19:48:46 +0200 (CEST)
User-agent: Alpine 2.20 (LSU 67 2015-01-07)

Hi,

On Mon, 3 Jul 2017, uso ewin wrote:

> I've try to use skip_or_save_block but using this function would ask me to
> completely refactor it,
> so I've made a skip_or_save_block2
> (code here: 
> https://github.com/cosmo-ray/tcc/commit/48e16cb2e33ea39b5051992ab23b006523fd14b4
> ),
> it work mostly like skip_or_save_block but, don't allocate TokString,
> and ignore braces, as brace should not be take into account inside
> a generic expression (I'm not sure here).

The braces are necessary for the GNU extension of statement expressions:

  ({ int i = 42; i; })

is a valid expression (in GNU C).  Anyway, I've just pushed some changes 
to mob which should simplify your life a bit.  First string literals are 
now always const char, so your hack with is_str and overriding the type 
shouldn't be needed anymore.  Second skip_or_save_block should now be 
directly usable for you (if called on non-'{' it collects the tokens until 
comma or ')'; or semicolon or '}' but those latter are syntax errors which 
will be diagnosed when actually parsing that token string).

In your patch you have also this after the loop:

  +    skip(')'); 
  +    tok_str_add_tok(&str); 
  +    tok_str_add(&str, 0); 
  +    begin_macro(&str, 2);
  +    next();
  +    expr_eq();

That doesn't seem right.  You add the token after the ')' that 
closes the _Generic expression to the token string that you evaluate 
afterwards.  That is you'd parse "_Generic(x,default:1 + 2) * 2" as
"1 + 2 * 3", but it should be parsed as "(1 + 2) * 3" (note operator 
precedence).  The correct idiom for parsing a saved string of tokens as 
expression would be something like this:

            ParseState saved_parse_state;
            ...
            // assume str contains the token string
            skip(')');
            save_parse_state(&saved_parse_state);
            begin_macro(str, 1);
            next();
            expr_eq();
            end_macro();
            restore_parse_state(&saved_parse_state);

(note also the '1' in begin_macro).  The above sequence relies on TOK_EOF 
being part of str (like skip_or_save_block does), but without such 
separator you'd always run into the 1+2*3 problem from above, and the 
above is still only one line longer than your sequence :)

You have to take care to not create leaks inside the loop if you see a 
matching type after a default association, the str needs to be freed 
appropriately (you have a similar leak in there, str is a local variable 
but the contents (the ->str member) is simply overwritten and leaks).

So, can you re-try implementing your _Generic parsing with the new 
skip_or_save_block from mob and with the above remarks taken into account?  
Sorry for the back and forth, but let's try to create a tiny change with 
the largest impact and avoid code duplication ;)


Ciao,
Michael.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]