| ... | @@ -31,6 +31,7 @@ struct Context { | ... | @@ -31,6 +31,7 @@ struct Context { |
| 31 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> struct_type_table; | 31 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> struct_type_table; |
| 32 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> enum_type_table; | 32 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> enum_type_table; |
| 33 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table; | 33 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table; |
| | 34 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> macro_table; |
| 34 | SourceManager *source_manager; | 35 | SourceManager *source_manager; |
| 35 | ZigList<AstNode *> aliases; | 36 | ZigList<AstNode *> aliases; |
| 36 | }; | 37 | }; |
| ... | @@ -132,12 +133,17 @@ static AstNode *create_param_decl_node(Context *c, const char *name, AstNode *ty | ... | @@ -132,12 +133,17 @@ static AstNode *create_param_decl_node(Context *c, const char *name, AstNode *ty |
| 132 | return node; | 133 | return node; |
| 133 | } | 134 | } |
| 134 | | 135 | |
| | 136 | static AstNode *create_char_lit_node(Context *c, uint8_t value) { |
| | 137 | AstNode *node = create_node(c, NodeTypeCharLiteral); |
| | 138 | node->data.char_literal.value = value; |
| | 139 | return node; |
| | 140 | } |
| | 141 | |
| 135 | static AstNode *create_num_lit_unsigned(Context *c, uint64_t x) { | 142 | static AstNode *create_num_lit_unsigned(Context *c, uint64_t x) { |
| 136 | AstNode *node = create_node(c, NodeTypeNumberLiteral); | 143 | AstNode *node = create_node(c, NodeTypeNumberLiteral); |
| 137 | node->data.number_literal.kind = NumLitUInt; | 144 | node->data.number_literal.kind = NumLitUInt; |
| 138 | node->data.number_literal.data.x_uint = x; | 145 | node->data.number_literal.data.x_uint = x; |
| 139 | | 146 | |
| 140 | normalize_parent_ptrs(node); | | |
| 141 | return node; | 147 | return node; |
| 142 | } | 148 | } |
| 143 | | 149 | |
| ... | @@ -713,6 +719,69 @@ static void render_aliases(Context *c) { | ... | @@ -713,6 +719,69 @@ static void render_aliases(Context *c) { |
| 713 | } | 719 | } |
| 714 | } | 720 | } |
| 715 | | 721 | |
| | 722 | static int parse_c_char_lit(Buf *value, uint8_t *out_c) { |
| | 723 | enum State { |
| | 724 | StateExpectStartQuot, |
| | 725 | StateExpectChar, |
| | 726 | StateExpectEndQuot, |
| | 727 | StateExpectEnd, |
| | 728 | }; |
| | 729 | State state = StateExpectStartQuot; |
| | 730 | for (int i = 0; i < buf_len(value); i += 1) { |
| | 731 | uint8_t c = buf_ptr(value)[i]; |
| | 732 | switch (state) { |
| | 733 | case StateExpectStartQuot: |
| | 734 | switch (c) { |
| | 735 | case '\'': |
| | 736 | state = StateExpectChar; |
| | 737 | break; |
| | 738 | default: |
| | 739 | return -1; |
| | 740 | } |
| | 741 | break; |
| | 742 | case StateExpectChar: |
| | 743 | switch (c) { |
| | 744 | case '\\': |
| | 745 | case '\'': |
| | 746 | return -1; |
| | 747 | default: |
| | 748 | *out_c = c; |
| | 749 | state = StateExpectEndQuot; |
| | 750 | } |
| | 751 | break; |
| | 752 | case StateExpectEndQuot: |
| | 753 | switch (c) { |
| | 754 | case '\'': |
| | 755 | state = StateExpectEnd; |
| | 756 | break; |
| | 757 | default: |
| | 758 | return -1; |
| | 759 | } |
| | 760 | break; |
| | 761 | case StateExpectEnd: |
| | 762 | return -1; |
| | 763 | } |
| | 764 | } |
| | 765 | return (state == StateExpectEnd) ? 0 : -1; |
| | 766 | } |
| | 767 | |
| | 768 | static void process_macro(Context *c, Buf *name, Buf *value) { |
| | 769 | // maybe it's a character literal |
| | 770 | uint8_t ch; |
| | 771 | if (!parse_c_char_lit(value, &ch)) { |
| | 772 | c->macro_table.put(name, true); |
| | 773 | AstNode *var_node = create_var_decl_node(c, buf_ptr(name), create_char_lit_node(c, ch)); |
| | 774 | c->root->data.root.top_level_decls.append(var_node); |
| | 775 | return; |
| | 776 | } |
| | 777 | // maybe it's a string literal |
| | 778 | // TODO |
| | 779 | // maybe it's a number literal |
| | 780 | // TODO |
| | 781 | // maybe it's a symbol |
| | 782 | // TODO |
| | 783 | } |
| | 784 | |
| 716 | static void process_preprocessor_entities(Context *c, ASTUnit &unit) { | 785 | static void process_preprocessor_entities(Context *c, ASTUnit &unit) { |
| 717 | for (PreprocessedEntity *entity : unit.getLocalPreprocessingEntities()) { | 786 | for (PreprocessedEntity *entity : unit.getLocalPreprocessingEntities()) { |
| 718 | switch (entity->getKind()) { | 787 | switch (entity->getKind()) { |
| ... | @@ -724,14 +793,27 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) { | ... | @@ -724,14 +793,27 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) { |
| 724 | { | 793 | { |
| 725 | MacroDefinitionRecord *macro = static_cast<MacroDefinitionRecord *>(entity); | 794 | MacroDefinitionRecord *macro = static_cast<MacroDefinitionRecord *>(entity); |
| 726 | const char *name = macro->getName()->getNameStart(); | 795 | const char *name = macro->getName()->getNameStart(); |
| 727 | fprintf(stderr, "definition macro: %s\n", name); | | |
| 728 | SourceRange range = macro->getSourceRange(); | 796 | SourceRange range = macro->getSourceRange(); |
| 729 | SourceLocation begin_loc = range.getBegin(); | 797 | SourceLocation begin_loc = range.getBegin(); |
| 730 | SourceLocation end_loc = range.getEnd(); | 798 | SourceLocation end_loc = range.getEnd(); |
| 731 | | 799 | |
| 732 | const char *start_c = c->source_manager->getCharacterData(begin_loc); | 800 | if (begin_loc == end_loc) { |
| | 801 | // this means it is a macro without a value |
| | 802 | // we don't care about such things |
| | 803 | continue; |
| | 804 | } |
| | 805 | |
| 733 | const char *end_c = c->source_manager->getCharacterData(end_loc); | 806 | const char *end_c = c->source_manager->getCharacterData(end_loc); |
| 734 | fprintf(stderr, "source: '%.*s'\n", (int)(end_c - start_c), start_c); | 807 | Buf *value = buf_alloc(); |
| | 808 | while (*end_c && *end_c != '\n') { |
| | 809 | buf_append_char(value, *end_c); |
| | 810 | if (end_c[0] == '\\' && end_c[1] == '\n') { |
| | 811 | end_c += 2; |
| | 812 | } else { |
| | 813 | end_c += 1; |
| | 814 | } |
| | 815 | } |
| | 816 | process_macro(c, buf_create_from_str(name), value); |
| 735 | } | 817 | } |
| 736 | } | 818 | } |
| 737 | } | 819 | } |
| ... | @@ -771,10 +853,11 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, | ... | @@ -771,10 +853,11 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, |
| 771 | c->import = import; | 853 | c->import = import; |
| 772 | c->errors = errors; | 854 | c->errors = errors; |
| 773 | c->visib_mod = VisibModPub; | 855 | c->visib_mod = VisibModPub; |
| 774 | c->root_type_table.init(16); | 856 | c->root_type_table.init(8); |
| 775 | c->enum_type_table.init(16); | 857 | c->enum_type_table.init(8); |
| 776 | c->struct_type_table.init(16); | 858 | c->struct_type_table.init(8); |
| 777 | c->fn_table.init(16); | 859 | c->fn_table.init(8); |
| | 860 | c->macro_table.init(8); |
| 778 | | 861 | |
| 779 | char *ZIG_PARSEH_CFLAGS = getenv("ZIG_PARSEH_CFLAGS"); | 862 | char *ZIG_PARSEH_CFLAGS = getenv("ZIG_PARSEH_CFLAGS"); |
| 780 | if (ZIG_PARSEH_CFLAGS) { | 863 | if (ZIG_PARSEH_CFLAGS) { |