Commit 373785ae8d
Changed files (3)
src/c_tokenizer.cpp
@@ -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);
}
src/c_tokenizer.hpp
@@ -68,6 +68,7 @@ enum CTokState {
CTokStateExpSign,
CTokStateFloatExp,
CTokStateFloatExpFirst,
+ CTokStateStrHex,
CTokStateStrOctal,
CTokStateNumLitIntSuffixU,
CTokStateNumLitIntSuffixL,
test/parsec.zig
@@ -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"