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
92ST_FUNC int gvtst(int inv, int t);92ST_FUNC int gvtst(int inv, int t);
93ST_FUNC int is_btype_size(int bt);93ST_FUNC int is_btype_size(int bt);
94static void gen_inline_functions(TCCState *s);94static void gen_inline_functions(TCCState *s);
95static void skip_or_save_block(TokenString **str);
95 96
96ST_INLN int is_float(int t)97ST_INLN int is_float(int t)
97{98{
@@ -4689,6 +4690,76 @@ ST_FUNC void unary(void) · 4591 unmodified lines
4689 next();4690 next();
4690 break;4691 break;
4691 4692
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 }
4692 // special qnan , snan and infinity values4763 // special qnan , snan and infinity values
4693 case TOK___NAN__:4764 case TOK___NAN__:
4694 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);4765 vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
tcctok.h+3−1
@@ -36,7 +36,9 @@ · 35 unmodified lines
36 DEF(TOK_RESTRICT2, "__restrict")36 DEF(TOK_RESTRICT2, "__restrict")
37 DEF(TOK_RESTRICT3, "__restrict__")37 DEF(TOK_RESTRICT3, "__restrict__")
38 DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */38 DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
39 39
40 DEF(TOK_GENERIC, "_Generic")
41
40 DEF(TOK_FLOAT, "float")42 DEF(TOK_FLOAT, "float")
41 DEF(TOK_DOUBLE, "double")43 DEF(TOK_DOUBLE, "double")
42 DEF(TOK_BOOL, "_Bool")44 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