c macros: support hex chars (#459)
* c macros: remove add_char redundancies * c macros: support hex chars * c macros: add test for hex charsmaster
parent
4f44d49925
commit
373785ae8d
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ enum CTokState {
|
|||
CTokStateExpSign,
|
||||
CTokStateFloatExp,
|
||||
CTokStateFloatExpFirst,
|
||||
CTokStateStrHex,
|
||||
CTokStateStrOctal,
|
||||
CTokStateNumLitIntSuffixU,
|
||||
CTokStateNumLitIntSuffixL,
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue