3#include "prism/internal/char.h"
4#include "prism/internal/encoding.h"
12 PM_SLICE_TYPE_ERROR = -1,
21 PM_SLICE_TYPE_CONSTANT,
24 PM_SLICE_TYPE_METHOD_NAME
31pm_slice_type(
const uint8_t *source,
size_t length,
const char *encoding_name) {
33 const pm_encoding_t *encoding = pm_encoding_find((
const uint8_t *) encoding_name, (
const uint8_t *) (encoding_name + strlen(encoding_name)));
34 if (encoding == NULL)
return PM_SLICE_TYPE_ERROR;
37 if (length == 0)
return PM_SLICE_TYPE_NONE;
40 if ((width = encoding->alpha_char(source, (ptrdiff_t) length)) != 0) {
42 }
else if (*source ==
'_') {
45 }
else if ((*source >= 0x80) && ((width = encoding->char_width(source, (ptrdiff_t) length)) > 0)) {
49 return PM_SLICE_TYPE_NONE;
53 const uint8_t *end = source + length;
54 pm_slice_type_t result = encoding->isupper_char(source, end - source) ? PM_SLICE_TYPE_CONSTANT : PM_SLICE_TYPE_LOCAL;
60 while (source < end) {
61 if ((width = encoding->alnum_char(source, end - source)) != 0) {
64 }
else if (*source ==
'_') {
67 }
else if ((*source >= 0x80) && ((width = encoding->char_width(source, end - source)) > 0)) {
77 if (*source ==
'!' || *source ==
'?' || *source ==
'=') {
79 result = PM_SLICE_TYPE_METHOD_NAME;
83 return source == end ? result : PM_SLICE_TYPE_NONE;
90pm_string_query_local(
const uint8_t *source,
size_t length,
const char *encoding_name) {
91 switch (pm_slice_type(source, length, encoding_name)) {
92 case PM_SLICE_TYPE_ERROR:
94 case PM_SLICE_TYPE_NONE:
95 case PM_SLICE_TYPE_CONSTANT:
96 case PM_SLICE_TYPE_METHOD_NAME:
98 case PM_SLICE_TYPE_LOCAL:
102 assert(
false &&
"unreachable");
110pm_string_query_constant(
const uint8_t *source,
size_t length,
const char *encoding_name) {
111 switch (pm_slice_type(source, length, encoding_name)) {
112 case PM_SLICE_TYPE_ERROR:
114 case PM_SLICE_TYPE_NONE:
115 case PM_SLICE_TYPE_LOCAL:
116 case PM_SLICE_TYPE_METHOD_NAME:
118 case PM_SLICE_TYPE_CONSTANT:
122 assert(
false &&
"unreachable");
130pm_string_query_method_name(
const uint8_t *source,
size_t length,
const char *encoding_name) {
131#define B(p) ((p) ? PM_STRING_QUERY_TRUE : PM_STRING_QUERY_FALSE)
132#define C1(c) (*source == c)
133#define C2(s) (memcmp(source, s, 2) == 0)
134#define C3(s) (memcmp(source, s, 3) == 0)
136 switch (pm_slice_type(source, length, encoding_name)) {
137 case PM_SLICE_TYPE_ERROR:
139 case PM_SLICE_TYPE_NONE:
141 case PM_SLICE_TYPE_LOCAL:
143 return B((length != 2) || (source[0] !=
'_') || (source[1] ==
'0') || !pm_char_is_decimal_digit(source[1]));
144 case PM_SLICE_TYPE_CONSTANT:
146 case PM_SLICE_TYPE_METHOD_NAME:
153 return B(C1(
'&') || C1(
'`') || C1(
'!') || C1(
'^') || C1(
'>') || C1(
'<') || C1(
'-') || C1(
'%') || C1(
'|') || C1(
'+') || C1(
'/') || C1(
'*') || C1(
'~'));
155 return B(C2(
"!=") || C2(
"!~") || C2(
"[]") || C2(
"==") || C2(
"=~") || C2(
">=") || C2(
">>") || C2(
"<=") || C2(
"<<") || C2(
"**"));
157 return B(C3(
"===") || C3(
"<=>") || C3(
"[]="));
Functions for querying properties of strings, such as whether they are valid local variable names,...
pm_string_query_t
Represents the results of a slice query.
@ PM_STRING_QUERY_TRUE
Returned if the result of the slice query is true.
@ PM_STRING_QUERY_ERROR
Returned if the encoding given to a slice query was invalid.
@ PM_STRING_QUERY_FALSE
Returned if the result of the slice query is false.