prism 0.15.1 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -1
- data/Makefile +12 -0
- data/README.md +3 -1
- data/config.yml +66 -50
- data/docs/configuration.md +2 -0
- data/docs/fuzzing.md +1 -1
- data/docs/javascript.md +90 -0
- data/docs/releasing.md +27 -0
- data/docs/ruby_api.md +2 -0
- data/docs/serialization.md +28 -29
- data/ext/prism/api_node.c +856 -826
- data/ext/prism/api_pack.c +20 -9
- data/ext/prism/extension.c +494 -119
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +3157 -747
- data/include/prism/defines.h +40 -8
- data/include/prism/diagnostic.h +36 -3
- data/include/prism/enc/pm_encoding.h +119 -28
- data/include/prism/node.h +38 -30
- data/include/prism/options.h +204 -0
- data/include/prism/pack.h +44 -33
- data/include/prism/parser.h +445 -199
- data/include/prism/prettyprint.h +26 -0
- data/include/prism/regexp.h +16 -2
- data/include/prism/util/pm_buffer.h +102 -18
- data/include/prism/util/pm_char.h +162 -48
- data/include/prism/util/pm_constant_pool.h +128 -34
- data/include/prism/util/pm_list.h +68 -38
- data/include/prism/util/pm_memchr.h +18 -3
- data/include/prism/util/pm_newline_list.h +71 -28
- data/include/prism/util/pm_state_stack.h +25 -7
- data/include/prism/util/pm_string.h +115 -27
- data/include/prism/util/pm_string_list.h +25 -6
- data/include/prism/util/pm_strncasecmp.h +32 -0
- data/include/prism/util/pm_strpbrk.h +31 -17
- data/include/prism/version.h +28 -3
- data/include/prism.h +229 -36
- data/lib/prism/compiler.rb +5 -5
- data/lib/prism/debug.rb +43 -13
- data/lib/prism/desugar_compiler.rb +1 -1
- data/lib/prism/dispatcher.rb +27 -26
- data/lib/prism/dsl.rb +16 -16
- data/lib/prism/ffi.rb +138 -61
- data/lib/prism/lex_compat.rb +26 -16
- data/lib/prism/mutation_compiler.rb +11 -11
- data/lib/prism/node.rb +426 -227
- data/lib/prism/node_ext.rb +23 -16
- data/lib/prism/node_inspector.rb +1 -1
- data/lib/prism/pack.rb +79 -40
- data/lib/prism/parse_result/comments.rb +7 -2
- data/lib/prism/parse_result/newlines.rb +4 -0
- data/lib/prism/parse_result.rb +157 -21
- data/lib/prism/pattern.rb +14 -3
- data/lib/prism/ripper_compat.rb +28 -10
- data/lib/prism/serialize.rb +935 -307
- data/lib/prism/visitor.rb +9 -5
- data/lib/prism.rb +20 -2
- data/prism.gemspec +11 -2
- data/rbi/prism.rbi +7305 -0
- data/rbi/prism_static.rbi +196 -0
- data/sig/prism.rbs +4468 -0
- data/sig/prism_static.rbs +123 -0
- data/src/diagnostic.c +56 -53
- data/src/enc/pm_big5.c +1 -0
- data/src/enc/pm_euc_jp.c +1 -0
- data/src/enc/pm_gbk.c +1 -0
- data/src/enc/pm_shift_jis.c +1 -0
- data/src/enc/pm_tables.c +316 -80
- data/src/enc/pm_unicode.c +54 -9
- data/src/enc/pm_windows_31j.c +1 -0
- data/src/node.c +357 -345
- data/src/options.c +170 -0
- data/src/prettyprint.c +7697 -1643
- data/src/prism.c +1964 -1125
- data/src/regexp.c +153 -95
- data/src/serialize.c +432 -397
- data/src/token_type.c +3 -1
- data/src/util/pm_buffer.c +88 -23
- data/src/util/pm_char.c +103 -57
- data/src/util/pm_constant_pool.c +52 -22
- data/src/util/pm_list.c +12 -4
- data/src/util/pm_memchr.c +5 -3
- data/src/util/pm_newline_list.c +25 -63
- data/src/util/pm_state_stack.c +9 -3
- data/src/util/pm_string.c +95 -85
- data/src/util/pm_string_list.c +14 -15
- data/src/util/pm_strncasecmp.c +10 -3
- data/src/util/pm_strpbrk.c +25 -19
- metadata +12 -3
- data/docs/prism.png +0 -0
data/src/token_type.c
CHANGED
@@ -9,7 +9,9 @@
|
|
9
9
|
|
10
10
|
#include "prism/ast.h"
|
11
11
|
|
12
|
-
|
12
|
+
/**
|
13
|
+
* Returns a string representation of the given token type.
|
14
|
+
*/
|
13
15
|
PRISM_EXPORTED_FUNCTION const char *
|
14
16
|
pm_token_type_to_str(pm_token_type_t token_type)
|
15
17
|
{
|
data/src/util/pm_buffer.c
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
#include "prism/util/pm_buffer.h"
|
2
2
|
|
3
|
-
|
3
|
+
/**
|
4
|
+
* Return the size of the pm_buffer_t struct.
|
5
|
+
*/
|
4
6
|
size_t
|
5
7
|
pm_buffer_sizeof(void) {
|
6
8
|
return sizeof(pm_buffer_t);
|
7
9
|
}
|
8
10
|
|
9
|
-
|
11
|
+
/**
|
12
|
+
* Initialize a pm_buffer_t with the given capacity.
|
13
|
+
*/
|
10
14
|
bool
|
11
15
|
pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity) {
|
12
16
|
buffer->length = 0;
|
@@ -16,33 +20,45 @@ pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity) {
|
|
16
20
|
return buffer->value != NULL;
|
17
21
|
}
|
18
22
|
|
19
|
-
|
23
|
+
/**
|
24
|
+
* Initialize a pm_buffer_t with its default values.
|
25
|
+
*/
|
20
26
|
bool
|
21
27
|
pm_buffer_init(pm_buffer_t *buffer) {
|
22
28
|
return pm_buffer_init_capacity(buffer, 1024);
|
23
29
|
}
|
24
30
|
|
25
|
-
|
31
|
+
/**
|
32
|
+
* Return the value of the buffer.
|
33
|
+
*/
|
26
34
|
char *
|
27
35
|
pm_buffer_value(pm_buffer_t *buffer) {
|
28
36
|
return buffer->value;
|
29
37
|
}
|
30
38
|
|
31
|
-
|
39
|
+
/**
|
40
|
+
* Return the length of the buffer.
|
41
|
+
*/
|
32
42
|
size_t
|
33
43
|
pm_buffer_length(pm_buffer_t *buffer) {
|
34
44
|
return buffer->length;
|
35
45
|
}
|
36
46
|
|
37
|
-
|
47
|
+
/**
|
48
|
+
* Append the given amount of space to the buffer.
|
49
|
+
*/
|
38
50
|
static inline void
|
39
51
|
pm_buffer_append_length(pm_buffer_t *buffer, size_t length) {
|
40
52
|
size_t next_length = buffer->length + length;
|
41
53
|
|
42
54
|
if (next_length > buffer->capacity) {
|
43
|
-
|
55
|
+
if (buffer->capacity == 0) {
|
56
|
+
buffer->capacity = 1;
|
57
|
+
}
|
58
|
+
|
59
|
+
while (next_length > buffer->capacity) {
|
44
60
|
buffer->capacity *= 2;
|
45
|
-
}
|
61
|
+
}
|
46
62
|
|
47
63
|
buffer->value = realloc(buffer->value, buffer->capacity);
|
48
64
|
}
|
@@ -50,55 +66,104 @@ pm_buffer_append_length(pm_buffer_t *buffer, size_t length) {
|
|
50
66
|
buffer->length = next_length;
|
51
67
|
}
|
52
68
|
|
53
|
-
|
69
|
+
/**
|
70
|
+
* Append a generic pointer to memory to the buffer.
|
71
|
+
*/
|
54
72
|
static inline void
|
55
73
|
pm_buffer_append(pm_buffer_t *buffer, const void *source, size_t length) {
|
74
|
+
size_t cursor = buffer->length;
|
56
75
|
pm_buffer_append_length(buffer, length);
|
57
|
-
memcpy(buffer->value +
|
76
|
+
memcpy(buffer->value + cursor, source, length);
|
58
77
|
}
|
59
78
|
|
60
|
-
|
79
|
+
/**
|
80
|
+
* Append the given amount of space as zeroes to the buffer.
|
81
|
+
*/
|
61
82
|
void
|
62
83
|
pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length) {
|
84
|
+
size_t cursor = buffer->length;
|
63
85
|
pm_buffer_append_length(buffer, length);
|
64
|
-
memset(buffer->value +
|
86
|
+
memset(buffer->value + cursor, 0, length);
|
65
87
|
}
|
66
88
|
|
67
|
-
|
89
|
+
/**
|
90
|
+
* Append a formatted string to the buffer.
|
91
|
+
*/
|
68
92
|
void
|
69
|
-
|
93
|
+
pm_buffer_append_format(pm_buffer_t *buffer, const char *format, ...) {
|
94
|
+
va_list arguments;
|
95
|
+
va_start(arguments, format);
|
96
|
+
int result = vsnprintf(NULL, 0, format, arguments);
|
97
|
+
va_end(arguments);
|
98
|
+
|
99
|
+
if (result < 0) return;
|
100
|
+
size_t length = (size_t) (result + 1);
|
101
|
+
|
102
|
+
size_t cursor = buffer->length;
|
103
|
+
pm_buffer_append_length(buffer, length);
|
104
|
+
|
105
|
+
va_start(arguments, format);
|
106
|
+
vsnprintf(buffer->value + cursor, length, format, arguments);
|
107
|
+
va_end(arguments);
|
108
|
+
|
109
|
+
buffer->length--;
|
110
|
+
}
|
111
|
+
|
112
|
+
/**
|
113
|
+
* Append a string to the buffer.
|
114
|
+
*/
|
115
|
+
void
|
116
|
+
pm_buffer_append_string(pm_buffer_t *buffer, const char *value, size_t length) {
|
70
117
|
pm_buffer_append(buffer, value, length);
|
71
118
|
}
|
72
119
|
|
73
|
-
|
120
|
+
/**
|
121
|
+
* Append a list of bytes to the buffer.
|
122
|
+
*/
|
74
123
|
void
|
75
124
|
pm_buffer_append_bytes(pm_buffer_t *buffer, const uint8_t *value, size_t length) {
|
76
125
|
pm_buffer_append(buffer, (const char *) value, length);
|
77
126
|
}
|
78
127
|
|
79
|
-
|
128
|
+
/**
|
129
|
+
* Append a single byte to the buffer.
|
130
|
+
*/
|
80
131
|
void
|
81
|
-
|
132
|
+
pm_buffer_append_byte(pm_buffer_t *buffer, uint8_t value) {
|
82
133
|
const void *source = &value;
|
83
134
|
pm_buffer_append(buffer, source, sizeof(uint8_t));
|
84
135
|
}
|
85
136
|
|
86
|
-
|
137
|
+
/**
|
138
|
+
* Append a 32-bit unsigned integer to the buffer as a variable-length integer.
|
139
|
+
*/
|
87
140
|
void
|
88
|
-
|
141
|
+
pm_buffer_append_varint(pm_buffer_t *buffer, uint32_t value) {
|
89
142
|
if (value < 128) {
|
90
|
-
|
143
|
+
pm_buffer_append_byte(buffer, (uint8_t) value);
|
91
144
|
} else {
|
92
145
|
uint32_t n = value;
|
93
146
|
while (n >= 128) {
|
94
|
-
|
147
|
+
pm_buffer_append_byte(buffer, (uint8_t) (n | 128));
|
95
148
|
n >>= 7;
|
96
149
|
}
|
97
|
-
|
150
|
+
pm_buffer_append_byte(buffer, (uint8_t) n);
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
/**
|
155
|
+
* Concatenate one buffer onto another.
|
156
|
+
*/
|
157
|
+
void
|
158
|
+
pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source) {
|
159
|
+
if (source->length > 0) {
|
160
|
+
pm_buffer_append(destination, source->value, source->length);
|
98
161
|
}
|
99
162
|
}
|
100
163
|
|
101
|
-
|
164
|
+
/**
|
165
|
+
* Free the memory associated with the buffer.
|
166
|
+
*/
|
102
167
|
void
|
103
168
|
pm_buffer_free(pm_buffer_t *buffer) {
|
104
169
|
free(buffer->value);
|
data/src/util/pm_char.c
CHANGED
@@ -53,6 +53,10 @@ static const uint8_t pm_number_table[256] = {
|
|
53
53
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Fx
|
54
54
|
};
|
55
55
|
|
56
|
+
/**
|
57
|
+
* Returns the number of characters at the start of the string that match the
|
58
|
+
* given kind. Disallows searching past the given maximum number of characters.
|
59
|
+
*/
|
56
60
|
static inline size_t
|
57
61
|
pm_strspn_char_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
|
58
62
|
if (length <= 0) return 0;
|
@@ -64,16 +68,20 @@ pm_strspn_char_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
|
|
64
68
|
return size;
|
65
69
|
}
|
66
70
|
|
67
|
-
|
68
|
-
|
71
|
+
/**
|
72
|
+
* Returns the number of characters at the start of the string that are
|
73
|
+
* whitespace. Disallows searching past the given maximum number of characters.
|
74
|
+
*/
|
69
75
|
size_t
|
70
76
|
pm_strspn_whitespace(const uint8_t *string, ptrdiff_t length) {
|
71
77
|
return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_WHITESPACE);
|
72
78
|
}
|
73
79
|
|
74
|
-
|
75
|
-
|
76
|
-
|
80
|
+
/**
|
81
|
+
* Returns the number of characters at the start of the string that are
|
82
|
+
* whitespace while also tracking the location of each newline. Disallows
|
83
|
+
* searching past the given maximum number of characters.
|
84
|
+
*/
|
77
85
|
size_t
|
78
86
|
pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newline_list_t *newline_list) {
|
79
87
|
if (length <= 0) return 0;
|
@@ -92,40 +100,53 @@ pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newlin
|
|
92
100
|
return size;
|
93
101
|
}
|
94
102
|
|
95
|
-
|
96
|
-
|
103
|
+
/**
|
104
|
+
* Returns the number of characters at the start of the string that are inline
|
105
|
+
* whitespace. Disallows searching past the given maximum number of characters.
|
106
|
+
*/
|
97
107
|
size_t
|
98
108
|
pm_strspn_inline_whitespace(const uint8_t *string, ptrdiff_t length) {
|
99
109
|
return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_INLINE_WHITESPACE);
|
100
110
|
}
|
101
111
|
|
102
|
-
|
103
|
-
|
112
|
+
/**
|
113
|
+
* Returns the number of characters at the start of the string that are regexp
|
114
|
+
* options. Disallows searching past the given maximum number of characters.
|
115
|
+
*/
|
104
116
|
size_t
|
105
117
|
pm_strspn_regexp_option(const uint8_t *string, ptrdiff_t length) {
|
106
118
|
return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_REGEXP_OPTION);
|
107
119
|
}
|
108
120
|
|
121
|
+
/**
|
122
|
+
* Returns true if the given character matches the given kind.
|
123
|
+
*/
|
109
124
|
static inline bool
|
110
125
|
pm_char_is_char_kind(const uint8_t b, uint8_t kind) {
|
111
126
|
return (pm_byte_table[b] & kind) != 0;
|
112
127
|
}
|
113
128
|
|
114
|
-
|
129
|
+
/**
|
130
|
+
* Returns true if the given character is a whitespace character.
|
131
|
+
*/
|
115
132
|
bool
|
116
133
|
pm_char_is_whitespace(const uint8_t b) {
|
117
134
|
return pm_char_is_char_kind(b, PRISM_CHAR_BIT_WHITESPACE);
|
118
135
|
}
|
119
136
|
|
120
|
-
|
137
|
+
/**
|
138
|
+
* Returns true if the given character is an inline whitespace character.
|
139
|
+
*/
|
121
140
|
bool
|
122
141
|
pm_char_is_inline_whitespace(const uint8_t b) {
|
123
142
|
return pm_char_is_char_kind(b, PRISM_CHAR_BIT_INLINE_WHITESPACE);
|
124
143
|
}
|
125
144
|
|
126
|
-
|
127
|
-
|
128
|
-
|
145
|
+
/**
|
146
|
+
* Scan through the string and return the number of characters at the start of
|
147
|
+
* the string that match the given kind. Disallows searching past the given
|
148
|
+
* maximum number of characters.
|
149
|
+
*/
|
129
150
|
static inline size_t
|
130
151
|
pm_strspn_number_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
|
131
152
|
if (length <= 0) return 0;
|
@@ -137,12 +158,14 @@ pm_strspn_number_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
|
|
137
158
|
return size;
|
138
159
|
}
|
139
160
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
161
|
+
/**
|
162
|
+
* Scan through the string and return the number of characters at the start of
|
163
|
+
* the string that match the given kind. Disallows searching past the given
|
164
|
+
* maximum number of characters.
|
165
|
+
*
|
166
|
+
* Additionally, report the location of the last invalid underscore character
|
167
|
+
* found in the string through the out invalid parameter.
|
168
|
+
*/
|
146
169
|
static inline size_t
|
147
170
|
pm_strspn_number_kind_underscores(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid, uint8_t kind) {
|
148
171
|
if (length <= 0) return 0;
|
@@ -166,93 +189,116 @@ pm_strspn_number_kind_underscores(const uint8_t *string, ptrdiff_t length, const
|
|
166
189
|
return size;
|
167
190
|
}
|
168
191
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
192
|
+
/**
|
193
|
+
* Returns the number of characters at the start of the string that are binary
|
194
|
+
* digits or underscores. Disallows searching past the given maximum number of
|
195
|
+
* characters.
|
196
|
+
*
|
197
|
+
* If multiple underscores are found in a row or if an underscore is
|
198
|
+
* found at the end of the number, then the invalid pointer is set to the index
|
199
|
+
* of the first invalid underscore.
|
200
|
+
*/
|
176
201
|
size_t
|
177
202
|
pm_strspn_binary_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
|
178
203
|
return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_BINARY_NUMBER);
|
179
204
|
}
|
180
205
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
206
|
+
/**
|
207
|
+
* Returns the number of characters at the start of the string that are octal
|
208
|
+
* digits or underscores. Disallows searching past the given maximum number of
|
209
|
+
* characters.
|
210
|
+
*
|
211
|
+
* If multiple underscores are found in a row or if an underscore is
|
212
|
+
* found at the end of the number, then the invalid pointer is set to the index
|
213
|
+
* of the first invalid underscore.
|
214
|
+
*/
|
188
215
|
size_t
|
189
216
|
pm_strspn_octal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
|
190
217
|
return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_OCTAL_NUMBER);
|
191
218
|
}
|
192
219
|
|
193
|
-
|
194
|
-
|
220
|
+
/**
|
221
|
+
* Returns the number of characters at the start of the string that are decimal
|
222
|
+
* digits. Disallows searching past the given maximum number of characters.
|
223
|
+
*/
|
195
224
|
size_t
|
196
225
|
pm_strspn_decimal_digit(const uint8_t *string, ptrdiff_t length) {
|
197
226
|
return pm_strspn_number_kind(string, length, PRISM_NUMBER_BIT_DECIMAL_DIGIT);
|
198
227
|
}
|
199
228
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
229
|
+
/**
|
230
|
+
* Returns the number of characters at the start of the string that are decimal
|
231
|
+
* digits or underscores. Disallows searching past the given maximum number of
|
232
|
+
* characters.
|
233
|
+
*
|
234
|
+
* If multiple underscores are found in a row or if an underscore is
|
235
|
+
* found at the end of the number, then the invalid pointer is set to the index
|
236
|
+
* of the first invalid underscore
|
237
|
+
*/
|
207
238
|
size_t
|
208
239
|
pm_strspn_decimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
|
209
240
|
return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_DECIMAL_NUMBER);
|
210
241
|
}
|
211
242
|
|
212
|
-
|
213
|
-
|
214
|
-
|
243
|
+
/**
|
244
|
+
* Returns the number of characters at the start of the string that are
|
245
|
+
* hexadecimal digits. Disallows searching past the given maximum number of
|
246
|
+
* characters.
|
247
|
+
*/
|
215
248
|
size_t
|
216
249
|
pm_strspn_hexadecimal_digit(const uint8_t *string, ptrdiff_t length) {
|
217
250
|
return pm_strspn_number_kind(string, length, PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT);
|
218
251
|
}
|
219
252
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
253
|
+
/**
|
254
|
+
* Returns the number of characters at the start of the string that are
|
255
|
+
* hexadecimal digits or underscores. Disallows searching past the given maximum
|
256
|
+
* number of characters.
|
257
|
+
*
|
258
|
+
* If multiple underscores are found in a row or if an underscore is
|
259
|
+
* found at the end of the number, then the invalid pointer is set to the index
|
260
|
+
* of the first invalid underscore.
|
261
|
+
*/
|
227
262
|
size_t
|
228
263
|
pm_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
|
229
264
|
return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER);
|
230
265
|
}
|
231
266
|
|
267
|
+
/**
|
268
|
+
* Returns true if the given character matches the given kind.
|
269
|
+
*/
|
232
270
|
static inline bool
|
233
271
|
pm_char_is_number_kind(const uint8_t b, uint8_t kind) {
|
234
272
|
return (pm_number_table[b] & kind) != 0;
|
235
273
|
}
|
236
274
|
|
237
|
-
|
275
|
+
/**
|
276
|
+
* Returns true if the given character is a binary digit.
|
277
|
+
*/
|
238
278
|
bool
|
239
279
|
pm_char_is_binary_digit(const uint8_t b) {
|
240
280
|
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_BINARY_DIGIT);
|
241
281
|
}
|
242
282
|
|
243
|
-
|
283
|
+
/**
|
284
|
+
* Returns true if the given character is an octal digit.
|
285
|
+
*/
|
244
286
|
bool
|
245
287
|
pm_char_is_octal_digit(const uint8_t b) {
|
246
288
|
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_OCTAL_DIGIT);
|
247
289
|
}
|
248
290
|
|
249
|
-
|
291
|
+
/**
|
292
|
+
* Returns true if the given character is a decimal digit.
|
293
|
+
*/
|
250
294
|
bool
|
251
295
|
pm_char_is_decimal_digit(const uint8_t b) {
|
252
296
|
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_DECIMAL_DIGIT);
|
253
297
|
}
|
254
298
|
|
255
|
-
|
299
|
+
/**
|
300
|
+
* Returns true if the given character is a hexadecimal digit.
|
301
|
+
*/
|
256
302
|
bool
|
257
303
|
pm_char_is_hexadecimal_digit(const uint8_t b) {
|
258
304
|
return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT);
|
data/src/util/pm_constant_pool.c
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
#include "prism/util/pm_constant_pool.h"
|
2
2
|
|
3
|
-
|
3
|
+
/**
|
4
|
+
* Initialize a list of constant ids.
|
5
|
+
*/
|
4
6
|
void
|
5
7
|
pm_constant_id_list_init(pm_constant_id_list_t *list) {
|
6
8
|
list->ids = NULL;
|
@@ -8,8 +10,10 @@ pm_constant_id_list_init(pm_constant_id_list_t *list) {
|
|
8
10
|
list->capacity = 0;
|
9
11
|
}
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
+
/**
|
14
|
+
* Append a constant id to a list of constant ids. Returns false if any
|
15
|
+
* potential reallocations fail.
|
16
|
+
*/
|
13
17
|
bool
|
14
18
|
pm_constant_id_list_append(pm_constant_id_list_t *list, pm_constant_id_t id) {
|
15
19
|
if (list->size >= list->capacity) {
|
@@ -22,7 +26,9 @@ pm_constant_id_list_append(pm_constant_id_list_t *list, pm_constant_id_t id) {
|
|
22
26
|
return true;
|
23
27
|
}
|
24
28
|
|
25
|
-
|
29
|
+
/**
|
30
|
+
* Checks if the current constant id list includes the given constant id.
|
31
|
+
*/
|
26
32
|
bool
|
27
33
|
pm_constant_id_list_includes(pm_constant_id_list_t *list, pm_constant_id_t id) {
|
28
34
|
for (size_t index = 0; index < list->size; index++) {
|
@@ -31,13 +37,17 @@ pm_constant_id_list_includes(pm_constant_id_list_t *list, pm_constant_id_t id) {
|
|
31
37
|
return false;
|
32
38
|
}
|
33
39
|
|
34
|
-
|
40
|
+
/**
|
41
|
+
* Get the memory size of a list of constant ids.
|
42
|
+
*/
|
35
43
|
size_t
|
36
44
|
pm_constant_id_list_memsize(pm_constant_id_list_t *list) {
|
37
45
|
return sizeof(pm_constant_id_list_t) + (list->capacity * sizeof(pm_constant_id_t));
|
38
46
|
}
|
39
47
|
|
40
|
-
|
48
|
+
/**
|
49
|
+
* Free the memory associated with a list of constant ids.
|
50
|
+
*/
|
41
51
|
void
|
42
52
|
pm_constant_id_list_free(pm_constant_id_list_t *list) {
|
43
53
|
if (list->ids != NULL) {
|
@@ -45,8 +55,10 @@ pm_constant_id_list_free(pm_constant_id_list_t *list) {
|
|
45
55
|
}
|
46
56
|
}
|
47
57
|
|
48
|
-
|
49
|
-
|
58
|
+
/**
|
59
|
+
* A relatively simple hash function (djb2) that is used to hash strings. We are
|
60
|
+
* optimizing here for simplicity and speed.
|
61
|
+
*/
|
50
62
|
static inline uint32_t
|
51
63
|
pm_constant_pool_hash(const uint8_t *start, size_t length) {
|
52
64
|
// This is a prime number used as the initial value for the hash function.
|
@@ -59,7 +71,9 @@ pm_constant_pool_hash(const uint8_t *start, size_t length) {
|
|
59
71
|
return value;
|
60
72
|
}
|
61
73
|
|
62
|
-
|
74
|
+
/**
|
75
|
+
* https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
76
|
+
*/
|
63
77
|
static uint32_t
|
64
78
|
next_power_of_two(uint32_t v) {
|
65
79
|
// Avoid underflow in subtraction on next line.
|
@@ -84,7 +98,9 @@ is_power_of_two(uint32_t size) {
|
|
84
98
|
}
|
85
99
|
#endif
|
86
100
|
|
87
|
-
|
101
|
+
/**
|
102
|
+
* Resize a constant pool to a given capacity.
|
103
|
+
*/
|
88
104
|
static inline bool
|
89
105
|
pm_constant_pool_resize(pm_constant_pool_t *pool) {
|
90
106
|
assert(is_power_of_two(pool->capacity));
|
@@ -136,7 +152,9 @@ pm_constant_pool_resize(pm_constant_pool_t *pool) {
|
|
136
152
|
return true;
|
137
153
|
}
|
138
154
|
|
139
|
-
|
155
|
+
/**
|
156
|
+
* Initialize a new constant pool with a given capacity.
|
157
|
+
*/
|
140
158
|
bool
|
141
159
|
pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity) {
|
142
160
|
const uint32_t maximum = (~((uint32_t) 0));
|
@@ -154,14 +172,18 @@ pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity) {
|
|
154
172
|
return true;
|
155
173
|
}
|
156
174
|
|
157
|
-
|
175
|
+
/**
|
176
|
+
* Return a pointer to the constant indicated by the given constant id.
|
177
|
+
*/
|
158
178
|
pm_constant_t *
|
159
|
-
pm_constant_pool_id_to_constant(pm_constant_pool_t *pool, pm_constant_id_t constant_id) {
|
179
|
+
pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool, pm_constant_id_t constant_id) {
|
160
180
|
assert(constant_id > 0 && constant_id <= pool->size);
|
161
181
|
return &pool->constants[constant_id - 1];
|
162
182
|
}
|
163
183
|
|
164
|
-
|
184
|
+
/**
|
185
|
+
* Insert a constant into a constant pool and return its index in the pool.
|
186
|
+
*/
|
165
187
|
static inline pm_constant_id_t
|
166
188
|
pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t length, pm_constant_pool_bucket_type_t type) {
|
167
189
|
if (pool->size >= (pool->capacity / 4 * 3)) {
|
@@ -225,29 +247,37 @@ pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t l
|
|
225
247
|
return id;
|
226
248
|
}
|
227
249
|
|
228
|
-
|
229
|
-
|
250
|
+
/**
|
251
|
+
* Insert a constant into a constant pool. Returns the id of the constant, or 0
|
252
|
+
* if any potential calls to resize fail.
|
253
|
+
*/
|
230
254
|
pm_constant_id_t
|
231
255
|
pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
|
232
256
|
return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_DEFAULT);
|
233
257
|
}
|
234
258
|
|
235
|
-
|
236
|
-
|
237
|
-
|
259
|
+
/**
|
260
|
+
* Insert a constant into a constant pool from memory that is now owned by the
|
261
|
+
* constant pool. Returns the id of the constant, or 0 if any potential calls to
|
262
|
+
* resize fail.
|
263
|
+
*/
|
238
264
|
pm_constant_id_t
|
239
265
|
pm_constant_pool_insert_owned(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
|
240
266
|
return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_OWNED);
|
241
267
|
}
|
242
268
|
|
243
|
-
|
244
|
-
|
269
|
+
/**
|
270
|
+
* Insert a constant into a constant pool from memory that is constant. Returns
|
271
|
+
* the id of the constant, or 0 if any potential calls to resize fail.
|
272
|
+
*/
|
245
273
|
pm_constant_id_t
|
246
274
|
pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
|
247
275
|
return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_CONSTANT);
|
248
276
|
}
|
249
277
|
|
250
|
-
|
278
|
+
/**
|
279
|
+
* Free the memory associated with a constant pool.
|
280
|
+
*/
|
251
281
|
void
|
252
282
|
pm_constant_pool_free(pm_constant_pool_t *pool) {
|
253
283
|
// For each constant in the current constant pool, free the contents if the
|