authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-06 21:44:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-06 21:44:22-07:00
logf19fa590e550975fcd821338923785335c9f393a
tree171f28f151e922a092fc9347935e5b73715c599e
parent4c8f26e9f68367f18a19852d468e514e41f1e0d2

parseh understands simple string literal macros


2 files changed, 109 insertions(+), 1 deletions(-)

src/parseh.cpp+104-1
......@@ -170,6 +170,13 @@ static AstNode *create_char_lit_node(Context *c, uint8_t value) {
170170 return node;
171171}
172172
173static AstNode *create_str_lit_node(Context *c, Buf *buf) {
174 AstNode *node = create_node(c, NodeTypeStringLiteral);
175 buf_init_from_buf(&node->data.string_literal.buf, buf);
176 node->data.string_literal.c = true;
177 return node;
178}
179
173180static AstNode *create_num_lit_unsigned(Context *c, uint64_t x) {
174181 AstNode *node = create_node(c, NodeTypeNumberLiteral);
175182 node->data.number_literal.kind = NumLitUInt;
......@@ -1255,6 +1262,97 @@ static bool is_simple_symbol(Buf *buf) {
12551262 return true;
12561263}
12571264
1265enum ParseCStrState {
1266 ParseCStrStateExpectQuot,
1267 ParseCStrStateNormal,
1268 ParseCStrStateEscape,
1269};
1270
1271static int parse_c_str_lit(Buf *buf, Buf *out_str) {
1272 ParseCStrState state = ParseCStrStateExpectQuot;
1273 buf_resize(out_str, 0);
1274
1275 for (int i = 0; i < buf_len(buf); i += 1) {
1276 uint8_t c = buf_ptr(buf)[i];
1277 switch (state) {
1278 case ParseCStrStateExpectQuot:
1279 if (c == '"') {
1280 state = ParseCStrStateNormal;
1281 } else {
1282 return -1;
1283 }
1284 break;
1285 case ParseCStrStateNormal:
1286 switch (c) {
1287 case '\\':
1288 state = ParseCStrStateEscape;
1289 break;
1290 case '\n':
1291 return -1;
1292 case '"':
1293 return 0;
1294 default:
1295 buf_append_char(out_str, c);
1296 }
1297 break;
1298 case ParseCStrStateEscape:
1299 switch (c) {
1300 case '\'':
1301 buf_append_char(out_str, '\'');
1302 state = ParseCStrStateNormal;
1303 break;
1304 case '"':
1305 buf_append_char(out_str, '"');
1306 state = ParseCStrStateNormal;
1307 break;
1308 case '?':
1309 buf_append_char(out_str, '\?');
1310 state = ParseCStrStateNormal;
1311 break;
1312 case '\\':
1313 buf_append_char(out_str, '\\');
1314 state = ParseCStrStateNormal;
1315 break;
1316 case 'a':
1317 buf_append_char(out_str, '\a');
1318 state = ParseCStrStateNormal;
1319 break;
1320 case 'b':
1321 buf_append_char(out_str, '\b');
1322 state = ParseCStrStateNormal;
1323 break;
1324 case 'f':
1325 buf_append_char(out_str, '\f');
1326 state = ParseCStrStateNormal;
1327 break;
1328 case 'n':
1329 buf_append_char(out_str, '\n');
1330 state = ParseCStrStateNormal;
1331 break;
1332 case 'r':
1333 buf_append_char(out_str, '\r');
1334 state = ParseCStrStateNormal;
1335 break;
1336 case 't':
1337 buf_append_char(out_str, '\t');
1338 state = ParseCStrStateNormal;
1339 break;
1340 case 'v':
1341 buf_append_char(out_str, '\v');
1342 state = ParseCStrStateNormal;
1343 break;
1344 default:
1345 // TODO octal escape sequence, hexadecimal escape sequence, and
1346 // universal character name
1347 return -1;
1348 }
1349 break;
1350 }
1351 }
1352
1353 return -1;
1354}
1355
12581356static void process_macro(Context *c, Buf *name, Buf *value) {
12591357 //fprintf(stderr, "macro '%s' = '%s'\n", buf_ptr(name), buf_ptr(value));
12601358 if (is_zig_keyword(name)) {
......@@ -1269,7 +1367,12 @@ static void process_macro(Context *c, Buf *name, Buf *value) {
12691367 return;
12701368 }
12711369 // maybe it's a string literal
1272 // TODO
1370 Buf str_lit = BUF_INIT;
1371 if (!parse_c_str_lit(value, &str_lit)) {
1372 AstNode *var_node = create_var_decl_node(c, buf_ptr(name), create_str_lit_node(c, &str_lit));
1373 c->macro_table.put(name, var_node);
1374 return;
1375 }
12731376
12741377 // maybe it's an unsigned integer
12751378 uint64_t uint;
test/run_tests.cpp+5
......@@ -2185,6 +2185,11 @@ extern void (*fn_ptr)(void);
21852185 R"SOURCE(pub inline fn foo() {
21862186 (??fn_ptr)()
21872187})SOURCE");
2188
2189
2190 add_parseh_case("#define string", R"SOURCE(
2191#define foo "a string"
2192 )SOURCE", 1, "pub const foo = c\"a string\";");
21882193}
21892194
21902195static void run_self_hosted_test(void) {