3#include "prism/internal/char.h"
4#include "prism/internal/encoding.h"
5#include "prism/internal/parser.h"
13 PM_SLICE_TYPE_ERROR = -1,
22 PM_SLICE_TYPE_CONSTANT,
25 PM_SLICE_TYPE_METHOD_NAME
32pm_slice_type(
const uint8_t *source,
size_t length,
const char *encoding_name) {
34 const pm_encoding_t *encoding = pm_encoding_find((
const uint8_t *) encoding_name, (
const uint8_t *) (encoding_name + strlen(encoding_name)));
35 if (encoding == NULL)
return PM_SLICE_TYPE_ERROR;
38 if (length == 0)
return PM_SLICE_TYPE_NONE;
41 if ((width = encoding->alpha_char(source, (ptrdiff_t) length)) != 0) {
43 }
else if (*source ==
'_') {
46 }
else if ((*source >= 0x80) && ((width = encoding->char_width(source, (ptrdiff_t) length)) > 0)) {
50 return PM_SLICE_TYPE_NONE;
54 const uint8_t *end = source + length;
55 pm_slice_type_t result = encoding->isupper_char(source, end - source) ? PM_SLICE_TYPE_CONSTANT : PM_SLICE_TYPE_LOCAL;
61 while (source < end) {
62 if ((width = encoding->alnum_char(source, end - source)) != 0) {
65 }
else if (*source ==
'_') {
68 }
else if ((*source >= 0x80) && ((width = encoding->char_width(source, end - source)) > 0)) {
78 if (*source ==
'!' || *source ==
'?' || *source ==
'=') {
80 result = PM_SLICE_TYPE_METHOD_NAME;
84 return source == end ? result : PM_SLICE_TYPE_NONE;
91pm_string_query_local(
const uint8_t *source,
size_t length,
const char *encoding_name) {
92 switch (pm_slice_type(source, length, encoding_name)) {
93 case PM_SLICE_TYPE_ERROR:
95 case PM_SLICE_TYPE_NONE:
96 case PM_SLICE_TYPE_CONSTANT:
97 case PM_SLICE_TYPE_METHOD_NAME:
99 case PM_SLICE_TYPE_LOCAL:
103 assert(
false &&
"unreachable");
111pm_string_query_constant(
const uint8_t *source,
size_t length,
const char *encoding_name) {
112 switch (pm_slice_type(source, length, encoding_name)) {
113 case PM_SLICE_TYPE_ERROR:
115 case PM_SLICE_TYPE_NONE:
116 case PM_SLICE_TYPE_LOCAL:
117 case PM_SLICE_TYPE_METHOD_NAME:
119 case PM_SLICE_TYPE_CONSTANT:
123 assert(
false &&
"unreachable");
131pm_string_query_method_name(
const uint8_t *source,
size_t length,
const char *encoding_name) {
132#define B(p) ((p) ? PM_STRING_QUERY_TRUE : PM_STRING_QUERY_FALSE)
133#define C1(c) (*source == c)
134#define C2(s) (memcmp(source, s, 2) == 0)
135#define C3(s) (memcmp(source, s, 3) == 0)
137 switch (pm_slice_type(source, length, encoding_name)) {
138 case PM_SLICE_TYPE_ERROR:
140 case PM_SLICE_TYPE_NONE:
142 case PM_SLICE_TYPE_LOCAL:
144 return B((length != 2) || (source[0] !=
'_') || (source[1] ==
'0') || !pm_char_is_decimal_digit(source[1]));
145 case PM_SLICE_TYPE_CONSTANT:
147 case PM_SLICE_TYPE_METHOD_NAME:
154 return B(C1(
'&') || C1(
'`') || C1(
'!') || C1(
'^') || C1(
'>') || C1(
'<') || C1(
'-') || C1(
'%') || C1(
'|') || C1(
'+') || C1(
'/') || C1(
'*') || C1(
'~'));
156 return B(C2(
"!=") || C2(
"!~") || C2(
"[]") || C2(
"==") || C2(
"=~") || C2(
">=") || C2(
">>") || C2(
"<=") || C2(
"<<") || C2(
"**"));
158 return B(C3(
"===") || C3(
"<=>") || C3(
"[]="));
174pm_string_query_keyword(
const uint8_t *source,
size_t length,
const char *encoding_name) {
175 if (pm_encoding_find((
const uint8_t *) encoding_name, (
const uint8_t *) (encoding_name + strlen(encoding_name))) == NULL) {
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.