[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.
- Re: [Tinycc-devel] _Generic or __builtin_choose_expr, uso ewin, 2017/07/03
- Re: [Tinycc-devel] _Generic or __builtin_choose_expr,
Michael Matz <=
- Re: [Tinycc-devel] _Generic or __builtin_choose_expr, grischka, 2017/07/04
- Re: [Tinycc-devel] _Generic or __builtin_choose_expr, Michael Matz, 2017/07/04
- Re: [Tinycc-devel] _Generic or __builtin_choose_expr, Michael Matz, 2017/07/04
- Re: [Tinycc-devel] _Generic or __builtin_choose_expr, uso ewin, 2017/07/04
- Re: [Tinycc-devel] _Generic or __builtin_choose_expr, uso ewin, 2017/07/04
- Re: [Tinycc-devel] _Generic or __builtin_choose_expr, uso ewin, 2017/07/04
- Re: [Tinycc-devel] _Generic or __builtin_choose_expr, Michael Matz, 2017/07/05
- Re: [Tinycc-devel] _Generic or __builtin_choose_expr, uso ewin, 2017/07/05
- Re: [Tinycc-devel] _Generic or __builtin_choose_expr, Christian Jullien, 2017/07/06
- Re: [Tinycc-devel] _Generic or __builtin_choose_expr, uso ewin, 2017/07/06