| ... | ... | @@ -170,6 +170,13 @@ static AstNode *create_char_lit_node(Context *c, uint8_t value) { |
| 170 | 170 | return node; |
| 171 | 171 | } |
| 172 | 172 | |
| 173 | static 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 | |
| 173 | 180 | static AstNode *create_num_lit_unsigned(Context *c, uint64_t x) { |
| 174 | 181 | AstNode *node = create_node(c, NodeTypeNumberLiteral); |
| 175 | 182 | node->data.number_literal.kind = NumLitUInt; |
| ... | ... | @@ -1255,6 +1262,97 @@ static bool is_simple_symbol(Buf *buf) { |
| 1255 | 1262 | return true; |
| 1256 | 1263 | } |
| 1257 | 1264 | |
| 1265 | enum ParseCStrState { |
| 1266 | ParseCStrStateExpectQuot, |
| 1267 | ParseCStrStateNormal, |
| 1268 | ParseCStrStateEscape, |
| 1269 | }; |
| 1270 | |
| 1271 | static 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 | |
| 1258 | 1356 | static void process_macro(Context *c, Buf *name, Buf *value) { |
| 1259 | 1357 | //fprintf(stderr, "macro '%s' = '%s'\n", buf_ptr(name), buf_ptr(value)); |
| 1260 | 1358 | if (is_zig_keyword(name)) { |
| ... | ... | @@ -1269,7 +1367,12 @@ static void process_macro(Context *c, Buf *name, Buf *value) { |
| 1269 | 1367 | return; |
| 1270 | 1368 | } |
| 1271 | 1369 | // 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 | } |
| 1273 | 1376 | |
| 1274 | 1377 | // maybe it's an unsigned integer |
| 1275 | 1378 | uint64_t uint; |