| ... | @@ -2469,6 +2469,74 @@ static void render_macros(Context *c) { | ... | @@ -2469,6 +2469,74 @@ static void render_macros(Context *c) { |
| 2469 | } | 2469 | } |
| 2470 | } | 2470 | } |
| 2471 | | 2471 | |
| | 2472 | static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, bool negate) { |
| | 2473 | CTok *tok = &ctok->tokens.at(*tok_i); |
| | 2474 | if (tok->id == CTokIdNumLitInt) { |
| | 2475 | *tok_i += 1; |
| | 2476 | switch (tok->data.num_lit_int.suffix) { |
| | 2477 | case CNumLitSuffixNone: |
| | 2478 | return trans_create_node_unsigned_negative(c, tok->data.num_lit_int.x, negate); |
| | 2479 | case CNumLitSuffixL: |
| | 2480 | return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_long"); |
| | 2481 | case CNumLitSuffixU: |
| | 2482 | return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_uint"); |
| | 2483 | case CNumLitSuffixLU: |
| | 2484 | return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_ulong"); |
| | 2485 | case CNumLitSuffixLL: |
| | 2486 | return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_longlong"); |
| | 2487 | case CNumLitSuffixLLU: |
| | 2488 | return trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, "c_ulonglong"); |
| | 2489 | } |
| | 2490 | zig_unreachable(); |
| | 2491 | } else if (tok->id == CTokIdNumLitFloat) { |
| | 2492 | *tok_i += 1; |
| | 2493 | double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float; |
| | 2494 | return trans_create_node_float_lit(c, value); |
| | 2495 | } |
| | 2496 | return nullptr; |
| | 2497 | } |
| | 2498 | |
| | 2499 | static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) { |
| | 2500 | CTok *tok = &ctok->tokens.at(*tok_i); |
| | 2501 | switch (tok->id) { |
| | 2502 | case CTokIdCharLit: |
| | 2503 | *tok_i += 1; |
| | 2504 | return trans_create_node_unsigned(c, tok->data.char_lit); |
| | 2505 | case CTokIdStrLit: |
| | 2506 | *tok_i += 1; |
| | 2507 | return trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit)); |
| | 2508 | case CTokIdMinus: |
| | 2509 | *tok_i += 1; |
| | 2510 | return parse_ctok_num_lit(c, ctok, tok_i, true); |
| | 2511 | case CTokIdNumLitInt: |
| | 2512 | case CTokIdNumLitFloat: |
| | 2513 | return parse_ctok_num_lit(c, ctok, tok_i, false); |
| | 2514 | case CTokIdSymbol: |
| | 2515 | { |
| | 2516 | *tok_i += 1; |
| | 2517 | Buf *symbol_name = buf_create_from_buf(&tok->data.symbol); |
| | 2518 | return trans_create_node_symbol(c, symbol_name); |
| | 2519 | } |
| | 2520 | case CTokIdLParen: |
| | 2521 | { |
| | 2522 | *tok_i += 1; |
| | 2523 | AstNode *inner_node = parse_ctok(c, ctok, tok_i); |
| | 2524 | |
| | 2525 | CTok *next_tok = &ctok->tokens.at(*tok_i); |
| | 2526 | if (next_tok->id != CTokIdRParen) { |
| | 2527 | return nullptr; |
| | 2528 | } |
| | 2529 | *tok_i += 1; |
| | 2530 | return inner_node; |
| | 2531 | } |
| | 2532 | case CTokIdEOF: |
| | 2533 | case CTokIdRParen: |
| | 2534 | // not able to make sense of this |
| | 2535 | return nullptr; |
| | 2536 | } |
| | 2537 | zig_unreachable(); |
| | 2538 | } |
| | 2539 | |
| 2472 | static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) { | 2540 | static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) { |
| 2473 | tokenize_c_macro(ctok, (const uint8_t *)char_ptr); | 2541 | tokenize_c_macro(ctok, (const uint8_t *)char_ptr); |
| 2474 | | 2542 | |
| ... | @@ -2476,81 +2544,29 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch | ... | @@ -2476,81 +2544,29 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch |
| 2476 | return; | 2544 | return; |
| 2477 | } | 2545 | } |
| 2478 | | 2546 | |
| 2479 | bool negate = false; | 2547 | size_t tok_i = 0; |
| 2480 | for (size_t i = 0; i < ctok->tokens.length; i += 1) { | 2548 | CTok *name_tok = &ctok->tokens.at(tok_i); |
| 2481 | bool is_first = (i == 0); | 2549 | assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name)); |
| 2482 | bool is_last = (i == ctok->tokens.length - 1); | 2550 | tok_i += 1; |
| 2483 | CTok *tok = &ctok->tokens.at(i); | 2551 | |
| 2484 | switch (tok->id) { | 2552 | AstNode *result_node = parse_ctok(c, ctok, &tok_i); |
| 2485 | case CTokIdCharLit: | 2553 | if (result_node == nullptr) { |
| 2486 | if (is_last && is_first) { | 2554 | return; |
| 2487 | AstNode *node = trans_create_node_unsigned(c, tok->data.char_lit); | 2555 | } |
| 2488 | c->macro_table.put(name, node); | 2556 | CTok *eof_tok = &ctok->tokens.at(tok_i); |
| 2489 | } | 2557 | if (eof_tok->id != CTokIdEOF) { |
| 2490 | return; | 2558 | return; |
| 2491 | case CTokIdStrLit: | 2559 | } |
| 2492 | if (is_last && is_first) { | 2560 | if (result_node->type == NodeTypeSymbol) { |
| 2493 | AstNode *node = trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit)); | 2561 | // if it equals itself, ignore. for example, from stdio.h: |
| 2494 | c->macro_table.put(name, node); | 2562 | // #define stdin stdin |
| 2495 | } | 2563 | Buf *symbol_name = result_node->data.symbol_expr.symbol; |
| 2496 | return; | 2564 | if (buf_eql_buf(name, symbol_name)) { |
| 2497 | case CTokIdNumLitInt: | 2565 | return; |
| 2498 | if (is_last) { | | |
| 2499 | AstNode *node; | | |
| 2500 | switch (tok->data.num_lit_int.suffix) { | | |
| 2501 | case CNumLitSuffixNone: | | |
| 2502 | node = trans_create_node_unsigned_negative(c, tok->data.num_lit_int.x, negate); | | |
| 2503 | break; | | |
| 2504 | case CNumLitSuffixL: | | |
| 2505 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, | | |
| 2506 | "c_long"); | | |
| 2507 | break; | | |
| 2508 | case CNumLitSuffixU: | | |
| 2509 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, | | |
| 2510 | "c_uint"); | | |
| 2511 | break; | | |
| 2512 | case CNumLitSuffixLU: | | |
| 2513 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, | | |
| 2514 | "c_ulong"); | | |
| 2515 | break; | | |
| 2516 | case CNumLitSuffixLL: | | |
| 2517 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, | | |
| 2518 | "c_longlong"); | | |
| 2519 | break; | | |
| 2520 | case CNumLitSuffixLLU: | | |
| 2521 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, | | |
| 2522 | "c_ulonglong"); | | |
| 2523 | break; | | |
| 2524 | } | | |
| 2525 | c->macro_table.put(name, node); | | |
| 2526 | } | | |
| 2527 | return; | | |
| 2528 | case CTokIdNumLitFloat: | | |
| 2529 | if (is_last) { | | |
| 2530 | double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float; | | |
| 2531 | AstNode *node = trans_create_node_float_lit(c, value); | | |
| 2532 | c->macro_table.put(name, node); | | |
| 2533 | } | | |
| 2534 | return; | | |
| 2535 | case CTokIdSymbol: | | |
| 2536 | if (is_last && is_first) { | | |
| 2537 | // if it equals itself, ignore. for example, from stdio.h: | | |
| 2538 | // #define stdin stdin | | |
| 2539 | Buf *symbol_name = buf_create_from_buf(&tok->data.symbol); | | |
| 2540 | if (buf_eql_buf(name, symbol_name)) { | | |
| 2541 | return; | | |
| 2542 | } | | |
| 2543 | c->macro_symbols.append({name, symbol_name}); | | |
| 2544 | return; | | |
| 2545 | } | | |
| 2546 | case CTokIdMinus: | | |
| 2547 | if (is_first) { | | |
| 2548 | negate = true; | | |
| 2549 | break; | | |
| 2550 | } else { | | |
| 2551 | return; | | |
| 2552 | } | | |
| 2553 | } | 2566 | } |
| | 2567 | c->macro_symbols.append({name, symbol_name}); |
| | 2568 | } else { |
| | 2569 | c->macro_table.put(name, result_node); |
| 2554 | } | 2570 | } |
| 2555 | } | 2571 | } |
| 2556 | | 2572 | |
| ... | @@ -2613,8 +2629,8 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) { | ... | @@ -2613,8 +2629,8 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) { |
| 2613 | continue; | 2629 | continue; |
| 2614 | } | 2630 | } |
| 2615 | | 2631 | |
| 2616 | const char *end_c = c->source_manager->getCharacterData(end_loc); | 2632 | const char *begin_c = c->source_manager->getCharacterData(begin_loc); |
| 2617 | process_macro(c, &ctok, name, end_c); | 2633 | process_macro(c, &ctok, name, begin_c); |
| 2618 | } | 2634 | } |
| 2619 | } | 2635 | } |
| 2620 | } | 2636 | } |