c macros: support hex chars (#459)

* c macros: remove add_char redundancies

* c macros: support hex chars

* c macros: add test for hex chars
master
jean-dao 2017-09-10 22:35:56 +02:00 committed by Andrew Kelley
parent 4f44d49925
commit 373785ae8d
3 changed files with 66 additions and 19 deletions

View File

@ -598,7 +598,8 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
ctok->octal_index = 1;
break;
case 'x':
zig_panic("TODO hex");
ctok->state = CTokStateStrHex;
ctok->cur_char = 0;
break;
case 'u':
zig_panic("TODO unicode");
@ -610,6 +611,54 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
return mark_error(ctok);
}
break;
case CTokStateStrHex: {
uint8_t value = 0;
switch (*c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
value = *c - '0';
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
value = (*c - 'a') + 10;
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
value = (*c - 'A') + 10;
break;
default:
c -= 1;
add_char(ctok, ctok->cur_char);
continue;
}
// TODO @mul_with_overflow
if (((long)ctok->cur_char) * 16 >= 256) {
zig_panic("TODO str hex mul overflow");
}
ctok->cur_char = (uint8_t)(ctok->cur_char * (uint8_t)16);
// TODO @add_with_overflow
if (((long)ctok->cur_char) + (long)(value) >= 256) {
zig_panic("TODO str hex add overflow");
}
ctok->cur_char = (uint8_t)(ctok->cur_char + value);
break;
}
case CTokStateStrOctal:
switch (*c) {
case '0':
@ -632,28 +681,12 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
ctok->cur_char = (uint8_t)(ctok->cur_char + (uint8_t)(*c - '0'));
ctok->octal_index += 1;
if (ctok->octal_index == 3) {
if (ctok->cur_tok->id == CTokIdStrLit) {
add_char(ctok, ctok->cur_char);
ctok->state = CTokStateString;
} else if (ctok->cur_tok->id == CTokIdCharLit) {
ctok->cur_tok->data.char_lit = ctok->cur_char;
ctok->state = CTokStateExpectEndQuot;
} else {
zig_unreachable();
}
add_char(ctok, ctok->cur_char);
}
break;
default:
c -= 1;
if (ctok->cur_tok->id == CTokIdStrLit) {
add_char(ctok, ctok->cur_char);
ctok->state = CTokStateString;
} else if (ctok->cur_tok->id == CTokIdCharLit) {
ctok->cur_tok->data.char_lit = ctok->cur_char;
ctok->state = CTokStateExpectEndQuot;
} else {
zig_unreachable();
}
add_char(ctok, ctok->cur_char);
continue;
}
break;
@ -748,6 +781,7 @@ found_end_of_macro:
case CTokStateString:
case CTokStateExpSign:
case CTokStateFloatExpFirst:
case CTokStateStrHex:
case CTokStateStrOctal:
return mark_error(ctok);
}

View File

@ -68,6 +68,7 @@ enum CTokState {
CTokStateExpSign,
CTokStateFloatExp,
CTokStateFloatExpFirst,
CTokStateStrHex,
CTokStateStrOctal,
CTokStateNumLitIntSuffixU,
CTokStateNumLitIntSuffixL,

View File

@ -285,6 +285,18 @@ pub fn addCases(cases: &tests.ParseCContext) {
\\pub const @"comptime" = struct_comptime;
);
cases.add("macro defines string literal with hex",
\\#define FOO "aoeu\xab derp"
\\#define FOO2 "aoeu\x0007a derp"
\\#define FOO_CHAR '\xfF'
,
\\pub const FOO = c"aoeu\xab derp";
,
\\pub const FOO2 = c"aoeuz derp";
,
\\pub const FOO_CHAR = 255;
);
cases.add("macro defines string literal with octal",
\\#define FOO "aoeu\023 derp"
\\#define FOO2 "aoeu\0234 derp"