|
1 | 1 | #ifndef RBS__PARSER_H |
2 | 2 | #define RBS__PARSER_H |
3 | 3 |
|
4 | | -#include "parserstate.h" |
| 4 | +#include "rbs/defines.h" |
| 5 | +#include "rbs/util/rbs_allocator.h" |
| 6 | +#include "rbs/util/rbs_constant_pool.h" |
| 7 | +#include "rbs/lexer.h" |
| 8 | +#include "rbs/ast.h" |
| 9 | + |
| 10 | +#include <stdbool.h> |
| 11 | +#include <stddef.h> |
| 12 | + |
| 13 | +/** |
| 14 | + * id_table represents a set of RBS constant IDs. |
| 15 | + * This is used to manage the set of bound variables. |
| 16 | + * */ |
| 17 | +typedef struct id_table { |
| 18 | + size_t size; |
| 19 | + size_t count; |
| 20 | + rbs_constant_id_t *ids; |
| 21 | + struct id_table *next; |
| 22 | +} id_table; |
| 23 | + |
| 24 | +/** |
| 25 | + * comment represents a sequence of comment lines. |
| 26 | + * |
| 27 | + * # Comment for the method. |
| 28 | + * # |
| 29 | + * # ```rb |
| 30 | + * # object.foo() # Do something |
| 31 | + * # ``` |
| 32 | + * # |
| 33 | + * def foo: () -> void |
| 34 | + * |
| 35 | + * A comment object represents the six lines of comments. |
| 36 | + * */ |
| 37 | +typedef struct comment { |
| 38 | + position start; |
| 39 | + position end; |
| 40 | + |
| 41 | + size_t line_size; |
| 42 | + size_t line_count; |
| 43 | + token *tokens; |
| 44 | + |
| 45 | + struct comment *next_comment; |
| 46 | +} comment; |
| 47 | + |
| 48 | +typedef struct error { |
| 49 | + char *message; |
| 50 | + token token; |
| 51 | + bool syntax_error; |
| 52 | +} error; |
| 53 | + |
| 54 | +/** |
| 55 | + * An RBS parser is a LL(3) parser. |
| 56 | + * */ |
| 57 | +typedef struct { |
| 58 | + lexstate *lexstate; |
| 59 | + |
| 60 | + token current_token; |
| 61 | + token next_token; /* The first lookahead token */ |
| 62 | + token next_token2; /* The second lookahead token */ |
| 63 | + token next_token3; /* The third lookahead token */ |
| 64 | + |
| 65 | + id_table *vars; /* Known type variables */ |
| 66 | + comment *last_comment; /* Last read comment */ |
| 67 | + |
| 68 | + rbs_constant_pool_t constant_pool; |
| 69 | + rbs_allocator_t allocator; |
| 70 | + error *error; |
| 71 | +} parserstate; |
| 72 | + |
| 73 | +/** |
| 74 | + * Insert new table entry. |
| 75 | + * Setting `reset` inserts a _reset_ entry, which stops searching. |
| 76 | + * |
| 77 | + * ``` |
| 78 | + * class Foo[A] |
| 79 | + * ^^^ <= push new table with reset |
| 80 | + * def foo: [B] () -> [A, B] |
| 81 | + * ^^^ <= push new table without reset |
| 82 | + * |
| 83 | + * class Baz[C] |
| 84 | + * ^^^ <= push new table with reset |
| 85 | + * end |
| 86 | + * end |
| 87 | + * ``` |
| 88 | + * */ |
| 89 | +id_table *parser_push_typevar_table(parserstate *state, bool reset); |
| 90 | + |
| 91 | +/** |
| 92 | + * Insert new type variable into the latest table. |
| 93 | + * */ |
| 94 | +NODISCARD bool parser_insert_typevar(parserstate *state, rbs_constant_id_t id); |
| 95 | + |
| 96 | +/** |
| 97 | + * Allocate new lexstate object. |
| 98 | + * |
| 99 | + * ``` |
| 100 | + * VALUE string = rb_funcall(buffer, rb_intern("content"), 0); |
| 101 | + * alloc_lexer(string, 0, 31) // New lexstate with buffer content |
| 102 | + * ``` |
| 103 | + * */ |
| 104 | +lexstate *alloc_lexer(rbs_allocator_t *, rbs_string_t string, const rbs_encoding_t *encoding, int start_pos, int end_pos); |
| 105 | + |
| 106 | +/** |
| 107 | + * Allocate new parserstate object. |
| 108 | + * |
| 109 | + * ``` |
| 110 | + * alloc_parser(buffer, string, encoding, 0, 1); |
| 111 | + * ``` |
| 112 | + * */ |
| 113 | +parserstate *alloc_parser(rbs_string_t string, const rbs_encoding_t *encoding, int start_pos, int end_pos); |
| 114 | +void free_parser(parserstate *parser); |
| 115 | + |
| 116 | +/** |
| 117 | + * Advance one token. |
| 118 | + * */ |
| 119 | +void parser_advance(parserstate *state); |
| 120 | + |
| 121 | +void print_parser(parserstate *state); |
| 122 | + |
| 123 | +/** |
| 124 | + * Returns a RBS::Comment object associated with an subject at `subject_line`. |
| 125 | + * |
| 126 | + * ```rbs |
| 127 | + * # Comment1 |
| 128 | + * class Foo # This is the subject line for Comment1 |
| 129 | + * |
| 130 | + * # Comment2 |
| 131 | + * %a{annotation} # This is the subject line for Comment2 |
| 132 | + * def foo: () -> void |
| 133 | + * end |
| 134 | + * ``` |
| 135 | + * */ |
| 136 | +rbs_ast_comment_t *get_comment(parserstate *state, int subject_line); |
5 | 137 |
|
6 | 138 | void set_error(parserstate *state, token tok, bool syntax_error, const char *fmt, ...) RBS_ATTRIBUTE_FORMAT(4, 5); |
7 | 139 |
|
8 | 140 | bool parse_type(parserstate *state, rbs_node_t **type); |
9 | 141 | bool parse_method_type(parserstate *state, rbs_methodtype_t **method_type); |
10 | 142 | bool parse_signature(parserstate *state, rbs_signature_t **signature); |
11 | 143 |
|
12 | | -void rbs__init_parser(); |
13 | | - |
14 | 144 | #endif |
0 commit comments