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) {...@@ -170,6 +170,13 @@ static AstNode *create_char_lit_node(Context *c, uint8_t value) {
170 return node;170 return node;
171}171}
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
173static AstNode *create_num_lit_unsigned(Context *c, uint64_t x) {180static AstNode *create_num_lit_unsigned(Context *c, uint64_t x) {
174 AstNode *node = create_node(c, NodeTypeNumberLiteral);181 AstNode *node = create_node(c, NodeTypeNumberLiteral);
175 node->data.number_literal.kind = NumLitUInt;182 node->data.number_literal.kind = NumLitUInt;
...@@ -1255,6 +1262,97 @@ static bool is_simple_symbol(Buf *buf) {...@@ -1255,6 +1262,97 @@ static bool is_simple_symbol(Buf *buf) {
1255 return true;1262 return true;
1256}1263}
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
1258static void process_macro(Context *c, Buf *name, Buf *value) {1356static void process_macro(Context *c, Buf *name, Buf *value) {
1259 //fprintf(stderr, "macro '%s' = '%s'\n", buf_ptr(name), buf_ptr(value));1357 //fprintf(stderr, "macro '%s' = '%s'\n", buf_ptr(name), buf_ptr(value));
1260 if (is_zig_keyword(name)) {1358 if (is_zig_keyword(name)) {
...@@ -1269,7 +1367,12 @@ static void process_macro(Context *c, Buf *name, Buf *value) {...@@ -1269,7 +1367,12 @@ static void process_macro(Context *c, Buf *name, Buf *value) {
1269 return;1367 return;
1270 }1368 }
1271 // maybe it's a string literal1369 // maybe it's a string literal
1272 // TODO1370 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
1274 // maybe it's an unsigned integer1377 // maybe it's an unsigned integer
1275 uint64_t uint;1378 uint64_t uint;
test/run_tests.cpp+5
...@@ -2185,6 +2185,11 @@ extern void (*fn_ptr)(void);...@@ -2185,6 +2185,11 @@ extern void (*fn_ptr)(void);
2185 R"SOURCE(pub inline fn foo() {2185 R"SOURCE(pub inline fn foo() {
2186 (??fn_ptr)()2186 (??fn_ptr)()
2187})SOURCE");2187})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\";");
2188}2193}
21892194
2190static void run_self_hosted_test(void) {2195static void run_self_hosted_test(void) {