authorgravatar for pfudke@gmail.comjean-dao <pfudke@gmail.com> 2017-09-10 22:35:56+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-10 16:35:56-04:00
log373785ae8d49d0ae3785020f05573763268ee9e1
treeae0e5a368c68b65c7b18bfa36503e30f31809a5b
parent4f44d49925f2a1f6e4f34732dd10c431ddcdb379

c macros: support hex chars (#459)

* c macros: remove add_char redundancies * c macros: support hex chars * c macros: add test for hex chars

3 files changed, 66 insertions(+), 19 deletions(-)

src/c_tokenizer.cpp+53-19
...@@ -598,7 +598,8 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {...@@ -598,7 +598,8 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
598 ctok->octal_index = 1;598 ctok->octal_index = 1;
599 break;599 break;
600 case 'x':600 case 'x':
601 zig_panic("TODO hex");601 ctok->state = CTokStateStrHex;
602 ctok->cur_char = 0;
602 break;603 break;
603 case 'u':604 case 'u':
604 zig_panic("TODO unicode");605 zig_panic("TODO unicode");
...@@ -610,6 +611,54 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {...@@ -610,6 +611,54 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
610 return mark_error(ctok);611 return mark_error(ctok);
611 }612 }
612 break;613 break;
614 case CTokStateStrHex: {
615 uint8_t value = 0;
616 switch (*c) {
617 case '0':
618 case '1':
619 case '2':
620 case '3':
621 case '4':
622 case '5':
623 case '6':
624 case '7':
625 case '8':
626 case '9':
627 value = *c - '0';
628 break;
629 case 'a':
630 case 'b':
631 case 'c':
632 case 'd':
633 case 'e':
634 case 'f':
635 value = (*c - 'a') + 10;
636 break;
637 case 'A':
638 case 'B':
639 case 'C':
640 case 'D':
641 case 'E':
642 case 'F':
643 value = (*c - 'A') + 10;
644 break;
645 default:
646 c -= 1;
647 add_char(ctok, ctok->cur_char);
648 continue;
649 }
650 // TODO @mul_with_overflow
651 if (((long)ctok->cur_char) * 16 >= 256) {
652 zig_panic("TODO str hex mul overflow");
653 }
654 ctok->cur_char = (uint8_t)(ctok->cur_char * (uint8_t)16);
655 // TODO @add_with_overflow
656 if (((long)ctok->cur_char) + (long)(value) >= 256) {
657 zig_panic("TODO str hex add overflow");
658 }
659 ctok->cur_char = (uint8_t)(ctok->cur_char + value);
660 break;
661 }
613 case CTokStateStrOctal:662 case CTokStateStrOctal:
614 switch (*c) {663 switch (*c) {
615 case '0':664 case '0':
...@@ -632,28 +681,12 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {...@@ -632,28 +681,12 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
632 ctok->cur_char = (uint8_t)(ctok->cur_char + (uint8_t)(*c - '0'));681 ctok->cur_char = (uint8_t)(ctok->cur_char + (uint8_t)(*c - '0'));
633 ctok->octal_index += 1;682 ctok->octal_index += 1;
634 if (ctok->octal_index == 3) {683 if (ctok->octal_index == 3) {
635 if (ctok->cur_tok->id == CTokIdStrLit) {684 add_char(ctok, ctok->cur_char);
636 add_char(ctok, ctok->cur_char);
637 ctok->state = CTokStateString;
638 } else if (ctok->cur_tok->id == CTokIdCharLit) {
639 ctok->cur_tok->data.char_lit = ctok->cur_char;
640 ctok->state = CTokStateExpectEndQuot;
641 } else {
642 zig_unreachable();
643 }
644 }685 }
645 break;686 break;
646 default:687 default:
647 c -= 1;688 c -= 1;
648 if (ctok->cur_tok->id == CTokIdStrLit) {689 add_char(ctok, ctok->cur_char);
649 add_char(ctok, ctok->cur_char);
650 ctok->state = CTokStateString;
651 } else if (ctok->cur_tok->id == CTokIdCharLit) {
652 ctok->cur_tok->data.char_lit = ctok->cur_char;
653 ctok->state = CTokStateExpectEndQuot;
654 } else {
655 zig_unreachable();
656 }
657 continue;690 continue;
658 }691 }
659 break;692 break;
...@@ -748,6 +781,7 @@ found_end_of_macro:...@@ -748,6 +781,7 @@ found_end_of_macro:
748 case CTokStateString:781 case CTokStateString:
749 case CTokStateExpSign:782 case CTokStateExpSign:
750 case CTokStateFloatExpFirst:783 case CTokStateFloatExpFirst:
784 case CTokStateStrHex:
751 case CTokStateStrOctal:785 case CTokStateStrOctal:
752 return mark_error(ctok);786 return mark_error(ctok);
753 }787 }
src/c_tokenizer.hpp+1
...@@ -68,6 +68,7 @@ enum CTokState {...@@ -68,6 +68,7 @@ enum CTokState {
68 CTokStateExpSign,68 CTokStateExpSign,
69 CTokStateFloatExp,69 CTokStateFloatExp,
70 CTokStateFloatExpFirst,70 CTokStateFloatExpFirst,
71 CTokStateStrHex,
71 CTokStateStrOctal,72 CTokStateStrOctal,
72 CTokStateNumLitIntSuffixU,73 CTokStateNumLitIntSuffixU,
73 CTokStateNumLitIntSuffixL,74 CTokStateNumLitIntSuffixL,
test/parsec.zig+12
...@@ -285,6 +285,18 @@ pub fn addCases(cases: &tests.ParseCContext) {...@@ -285,6 +285,18 @@ pub fn addCases(cases: &tests.ParseCContext) {
285 \\pub const @"comptime" = struct_comptime;285 \\pub const @"comptime" = struct_comptime;
286 );286 );
287287
288 cases.add("macro defines string literal with hex",
289 \\#define FOO "aoeu\xab derp"
290 \\#define FOO2 "aoeu\x0007a derp"
291 \\#define FOO_CHAR '\xfF'
292 ,
293 \\pub const FOO = c"aoeu\xab derp";
294 ,
295 \\pub const FOO2 = c"aoeuz derp";
296 ,
297 \\pub const FOO_CHAR = 255;
298 );
299
288 cases.add("macro defines string literal with octal",300 cases.add("macro defines string literal with octal",
289 \\#define FOO "aoeu\023 derp"301 \\#define FOO "aoeu\023 derp"
290 \\#define FOO2 "aoeu\0234 derp"302 \\#define FOO2 "aoeu\0234 derp"