History

add C11's _Generic

Simple implementation, I'm not even sure to respect C standart here, but it should work with most use case. This add an case in unary(), and generate TokString depending of _Generic controlling exression, use begin_macro to "push" the generated TokString, then call unary() again before exiting the switch so the just add token are reevaluate again.

Matthias Gatto committed 9 years ago

Commit 157bad51 parent 9ed8b542 files · +74 −1Browse files

Unified · Split

2 files
  1. tccgen.c +71 −0
  2. tcctok.h +3 −1
tccgen.c+71−0
@@ -92,6 +92,7 @@ ST_FUNC void vpush(CType *type); · 91 unmodified lines
9292 ST_FUNC int gvtst(int inv, int t);
9393 ST_FUNC int is_btype_size(int bt);
9494 static void gen_inline_functions(TCCState *s);
95+static void skip_or_save_block(TokenString **str);
9596
9697 ST_INLN int is_float(int t)
9798 {
@@ -4689,6 +4690,76 @@ ST_FUNC void unary(void) · 4591 unmodified lines
46894690 next();
46904691 break;
46914692
4693+ case TOK_GENERIC:
4694+ {
4695+ CType controlling_type;
4696+ int has_default = 0;
4697+ int has_match = 0;
4698+ CType cur_type;
4699+ AttributeDef ad_tmp;
4700+ int learn = 0;
4701+ TokenString *str = NULL;
4702+ ParseState saved_parse_state;
4703+
4704+ next();
4705+ skip('(');
4706+ expr_type(&controlling_type, 1);
4707+ if (controlling_type.t & VT_ARRAY)
4708+ controlling_type.t = VT_PTR;
4709+ controlling_type.t &= ~VT_CONSTANT;
4710+ for (;;) {
4711+ learn = 0;
4712+ skip(',');
4713+ if (tok == TOK_DEFAULT) {
4714+ if (has_default)
4715+ tcc_error("too many 'default'");
4716+ if (!has_match) {
4717+ has_default = 1;
4718+ learn = 1;
4719+ }
4720+ next();
4721+ } else {
4722+ int itmp;
4723+
4724+ parse_btype(&cur_type, &ad_tmp);
4725+ type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
4726+ if (compare_types(&controlling_type, &cur_type, 0)) {
4727+ if (has_match) {
4728+ tcc_error("type march twice");
4729+ }
4730+ if (has_default)
4731+ tok_str_free(str);
4732+ has_match = 1;
4733+ learn = 1;
4734+ }
4735+ }
4736+ skip(':');
4737+ if (learn) {
4738+ skip_or_save_block(&str);
4739+ } else {
4740+ skip_or_save_block(NULL);
4741+ }
4742+ if (tok == ',')
4743+ continue;
4744+ else if (tok == ')')
4745+ break;
4746+ }
4747+ if (!has_match && !has_default) {
4748+ char buf[256];
4749+
4750+ type_to_str(buf, 256, &controlling_type, NULL);
4751+ tcc_error("_Generic sellector of type '%s' is not compatible with any assosiation",
4752+ buf);
4753+ }
4754+ skip(')');
4755+ save_parse_state(&saved_parse_state);
4756+ begin_macro(str, 1);
4757+ next();
4758+ expr_eq();
4759+ end_macro();
4760+ restore_parse_state(&saved_parse_state);
4761+ break;
4762+ }
46924763 // special qnan , snan and infinity values
46934764 case TOK___NAN__:
46944765 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
tcctok.h+3−1
@@ -36,7 +36,9 @@ · 35 unmodified lines
3636 DEF(TOK_RESTRICT2, "__restrict")
3737 DEF(TOK_RESTRICT3, "__restrict__")
3838 DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
39−
39+
40+ DEF(TOK_GENERIC, "_Generic")
41+
4042 DEF(TOK_FLOAT, "float")
4143 DEF(TOK_DOUBLE, "double")
4244 DEF(TOK_BOOL, "_Bool")

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t