|
26 | 26 | /** |
27 | 27 | * A constant id is a unique identifier for a constant in the constant pool. |
28 | 28 | */ |
29 | | -typedef uintptr_t rbs_constant_id_t; |
| 29 | +typedef uint32_t rbs_constant_id_t; |
| 30 | + |
| 31 | +/** |
| 32 | + * A list of constant IDs. Usually used to represent a set of locals. |
| 33 | + */ |
| 34 | +typedef struct { |
| 35 | + /** The number of constant ids in the list. */ |
| 36 | + size_t size; |
| 37 | + |
| 38 | + /** The number of constant ids that have been allocated in the list. */ |
| 39 | + size_t capacity; |
| 40 | + |
| 41 | + /** The constant ids in the list. */ |
| 42 | + rbs_constant_id_t *ids; |
| 43 | +} rbs_constant_id_list_t; |
| 44 | + |
| 45 | +/** |
| 46 | + * Initialize a list of constant ids. |
| 47 | + * |
| 48 | + * @param list The list to initialize. |
| 49 | + */ |
| 50 | +void rbs_constant_id_list_init(rbs_constant_id_list_t *list); |
| 51 | + |
| 52 | +/** |
| 53 | + * Initialize a list of constant ids with a given capacity. |
| 54 | + * |
| 55 | + * @param list The list to initialize. |
| 56 | + * @param capacity The initial capacity of the list. |
| 57 | + */ |
| 58 | +void rbs_constant_id_list_init_capacity(rbs_constant_id_list_t *list, size_t capacity); |
| 59 | + |
| 60 | +/** |
| 61 | + * Append a constant id to a list of constant ids. Returns false if any |
| 62 | + * potential reallocations fail. |
| 63 | + * |
| 64 | + * @param list The list to append to. |
| 65 | + * @param id The id to append. |
| 66 | + * @return Whether the append succeeded. |
| 67 | + */ |
| 68 | +bool rbs_constant_id_list_append(rbs_constant_id_list_t *list, rbs_constant_id_t id); |
| 69 | + |
| 70 | +/** |
| 71 | + * Insert a constant id into a list of constant ids at the specified index. |
| 72 | + * |
| 73 | + * @param list The list to insert into. |
| 74 | + * @param index The index at which to insert. |
| 75 | + * @param id The id to insert. |
| 76 | + */ |
| 77 | +void rbs_constant_id_list_insert(rbs_constant_id_list_t *list, size_t index, rbs_constant_id_t id); |
| 78 | + |
| 79 | +/** |
| 80 | + * Checks if the current constant id list includes the given constant id. |
| 81 | + * |
| 82 | + * @param list The list to check. |
| 83 | + * @param id The id to check for. |
| 84 | + * @return Whether the list includes the given id. |
| 85 | + */ |
| 86 | +bool rbs_constant_id_list_includes(rbs_constant_id_list_t *list, rbs_constant_id_t id); |
| 87 | + |
| 88 | +/** |
| 89 | + * Free the memory associated with a list of constant ids. |
| 90 | + * |
| 91 | + * @param list The list to free. |
| 92 | + */ |
| 93 | +void rbs_constant_id_list_free(rbs_constant_id_list_t *list); |
| 94 | + |
| 95 | +/** |
| 96 | + * The type of bucket in the constant pool hash map. This determines how the |
| 97 | + * bucket should be freed. |
| 98 | + */ |
| 99 | +typedef unsigned int rbs_constant_pool_bucket_type_t; |
| 100 | + |
| 101 | +/** By default, each constant is a slice of the source. */ |
| 102 | +static const rbs_constant_pool_bucket_type_t RBS_CONSTANT_POOL_BUCKET_DEFAULT = 0; |
| 103 | + |
| 104 | +/** An owned constant is one for which memory has been allocated. */ |
| 105 | +static const rbs_constant_pool_bucket_type_t RBS_CONSTANT_POOL_BUCKET_OWNED = 1; |
| 106 | + |
| 107 | +/** A constant constant is known at compile time. */ |
| 108 | +static const rbs_constant_pool_bucket_type_t RBS_CONSTANT_POOL_BUCKET_CONSTANT = 2; |
| 109 | + |
| 110 | +/** A bucket in the hash map. */ |
| 111 | +typedef struct { |
| 112 | + /** The incremental ID used for indexing back into the pool. */ |
| 113 | + unsigned int id: 30; |
| 114 | + |
| 115 | + /** The type of the bucket, which determines how to free it. */ |
| 116 | + rbs_constant_pool_bucket_type_t type: 2; |
| 117 | + |
| 118 | + /** The hash of the bucket. */ |
| 119 | + uint32_t hash; |
| 120 | +} rbs_constant_pool_bucket_t; |
30 | 121 |
|
31 | 122 | /** A constant in the pool which effectively stores a string. */ |
32 | | -typedef uintptr_t rbs_constant_t; |
| 123 | +typedef struct { |
| 124 | + /** A pointer to the start of the string. */ |
| 125 | + const uint8_t *start; |
| 126 | + |
| 127 | + /** The length of the string. */ |
| 128 | + size_t length; |
| 129 | +} rbs_constant_t; |
33 | 130 |
|
34 | 131 | /** The overall constant pool, which stores constants found while parsing. */ |
35 | 132 | typedef struct { |
36 | | - void *dummy; // Workaround for structs not being allowed to be empty. |
| 133 | + /** The buckets in the hash map. */ |
| 134 | + rbs_constant_pool_bucket_t *buckets; |
| 135 | + |
| 136 | + /** The constants that are stored in the buckets. */ |
| 137 | + rbs_constant_t *constants; |
| 138 | + |
| 139 | + /** The number of buckets in the hash map. */ |
| 140 | + uint32_t size; |
| 141 | + |
| 142 | + /** The number of buckets that have been allocated in the hash map. */ |
| 143 | + uint32_t capacity; |
37 | 144 | } rbs_constant_pool_t; |
38 | 145 |
|
39 | | -// A temporary stand-in for the constant pool until start using a real implementation. |
40 | | -// For now, it just defers to Ruby's ID interning mechanism (`rb_intern3`). |
| 146 | +// A global constant pool for storing permenant keywords, such as the names of location children in `parser.c`. |
41 | 147 | extern rbs_constant_pool_t *RBS_GLOBAL_CONSTANT_POOL; |
42 | 148 |
|
43 | 149 | /** |
@@ -80,6 +186,18 @@ rbs_constant_id_t rbs_constant_pool_find(const rbs_constant_pool_t *pool, const |
80 | 186 | */ |
81 | 187 | rbs_constant_id_t rbs_constant_pool_insert_shared(rbs_constant_pool_t *pool, const uint8_t *start, size_t length); |
82 | 188 |
|
| 189 | +/** |
| 190 | + * Insert a constant into a constant pool from memory that is now owned by the |
| 191 | + * constant pool. Returns the id of the constant, or 0 if any potential calls to |
| 192 | + * resize fail. |
| 193 | + * |
| 194 | + * @param pool The pool to insert the constant into. |
| 195 | + * @param start A pointer to the start of the constant. |
| 196 | + * @param length The length of the constant. |
| 197 | + * @return The id of the constant. |
| 198 | + */ |
| 199 | +rbs_constant_id_t rbs_constant_pool_insert_owned(rbs_constant_pool_t *pool, uint8_t *start, size_t length); |
| 200 | + |
83 | 201 | /** |
84 | 202 | * Insert a constant into a constant pool from memory that is constant. Returns |
85 | 203 | * the id of the constant, or 0 if any potential calls to resize fail. |
|
0 commit comments