Ruby 4.1.0dev (2026-03-27 revision 6c1071f35630ec165dac1fbecd39e105b8bcf6ec)
options.h
1#ifndef PRISM_INTERNAL_OPTIONS_H
2#define PRISM_INTERNAL_OPTIONS_H
3
4#include "prism/options.h"
5
6/* A scope of locals surrounding the code that is being parsed. */
8 /* The number of locals in the scope. */
9 size_t locals_count;
10
11 /* The names of the locals in the scope. */
12 pm_string_t *locals;
13
14 /* Flags for the set of forwarding parameters in this scope. */
15 uint8_t forwarding;
16};
17
18/*
19 * The version of Ruby syntax that we should be parsing with. This is used to
20 * allow consumers to specify which behavior they want in case they need to
21 * parse in the same way as a specific version of CRuby would have.
22 */
23typedef enum {
24 /*
25 * If an explicit version is not provided, the current version of prism will
26 * be used.
27 */
28 PM_OPTIONS_VERSION_UNSET = 0,
29
30 /* The vendored version of prism in CRuby 3.3.x. */
31 PM_OPTIONS_VERSION_CRUBY_3_3 = 1,
32
33 /* The vendored version of prism in CRuby 3.4.x. */
34 PM_OPTIONS_VERSION_CRUBY_3_4 = 2,
35
36 /* The vendored version of prism in CRuby 4.0.x. */
37 PM_OPTIONS_VERSION_CRUBY_3_5 = 3,
38
39 /* The vendored version of prism in CRuby 4.0.x. */
40 PM_OPTIONS_VERSION_CRUBY_4_0 = 3,
41
42 /* The vendored version of prism in CRuby 4.1.x. */
43 PM_OPTIONS_VERSION_CRUBY_4_1 = 4,
44
45 /* The current version of prism. */
46 PM_OPTIONS_VERSION_LATEST = PM_OPTIONS_VERSION_CRUBY_4_1
47} pm_options_version_t;
48
49/* The options that can be passed to the parser. */
51 /*
52 * The callback to call when additional switches are found in a shebang
53 * comment.
54 */
55 pm_options_shebang_callback_t shebang_callback;
56
57 /*
58 * Any additional data that should be passed along to the shebang callback
59 * if one was set.
60 */
61 void *shebang_callback_data;
62
63 /* The name of the file that is currently being parsed. */
64 pm_string_t filepath;
65
66 /*
67 * The line within the file that the parse starts on. This value is
68 * 1-indexed.
69 */
70 int32_t line;
71
72 /*
73 * The name of the encoding that the source file is in. Note that this must
74 * correspond to a name that can be found with Encoding.find in Ruby.
75 */
76 pm_string_t encoding;
77
78 /* The number of scopes surrounding the code that is being parsed. */
79 size_t scopes_count;
80
81 /*
82 * The scopes surrounding the code that is being parsed. For most parses
83 * this will be NULL, but for evals it will be the locals that are in scope
84 * surrounding the eval. Scopes are ordered from the outermost scope to the
85 * innermost one.
86 */
87 pm_options_scope_t *scopes;
88
89 /*
90 * The version of prism that we should be parsing with. This is used to
91 * allow consumers to specify which behavior they want in case they need to
92 * parse exactly as a specific version of CRuby.
93 */
94 pm_options_version_t version;
95
96 /* A bitset of the various options that were set on the command line. */
97 uint8_t command_line;
98
99 /*
100 * Whether or not the frozen string literal option has been set.
101 * May be:
102 * - PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED
103 * - PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED
104 * - PM_OPTIONS_FROZEN_STRING_LITERAL_UNSET
105 */
106 int8_t frozen_string_literal;
107
108 /*
109 * Whether or not the encoding magic comments should be respected. This is a
110 * niche use-case where you want to parse a file with a specific encoding
111 * but ignore any encoding magic comments at the top of the file.
112 */
113 bool encoding_locked;
114
115 /*
116 * When the file being parsed is the main script, the shebang will be
117 * considered for command-line flags (or for implicit -x). The caller needs
118 * to pass this information to the parser so that it can behave correctly.
119 */
120 bool main_script;
121
122 /*
123 * When the file being parsed is considered a "partial" script, jumps will
124 * not be marked as errors if they are not contained within loops/blocks.
125 * This is used in the case that you're parsing a script that you know will
126 * be embedded inside another script later, but you do not have that context
127 * yet. For example, when parsing an ERB template that will be evaluated
128 * inside another script.
129 */
130 bool partial_script;
131
132 /*
133 * Whether or not the parser should freeze the nodes that it creates. This
134 * makes it possible to have a deeply frozen AST that is safe to share
135 * between concurrency primitives.
136 */
137 bool freeze;
138};
139
140/* Free the internal memory associated with the options. */
141void pm_options_cleanup(pm_options_t *options);
142
143/*
144 * Deserialize an options struct from the given binary string. This is used to
145 * pass options to the parser from an FFI call so that consumers of the library
146 * from an FFI perspective don't have to worry about the structure of our
147 * options structs. Since the source of these calls will be from Ruby
148 * implementation internals we assume it is from a trusted source.
149 *
150 * `data` is assumed to be a valid pointer pointing to well-formed data. The
151 * layout of this data should be the same every time, and is described below:
152 *
153 * | # bytes | field |
154 * | ------- | -------------------------- |
155 * | `4` | the length of the filepath |
156 * | ... | the filepath bytes |
157 * | `4` | the line number |
158 * | `4` | the length the encoding |
159 * | ... | the encoding bytes |
160 * | `1` | frozen string literal |
161 * | `1` | -p command line option |
162 * | `1` | -n command line option |
163 * | `1` | -l command line option |
164 * | `1` | -a command line option |
165 * | `1` | the version |
166 * | `1` | encoding locked |
167 * | `1` | main script |
168 * | `1` | partial script |
169 * | `1` | freeze |
170 * | `4` | the number of scopes |
171 * | ... | the scopes |
172 *
173 * The version field is an enum, so it should be one of the following values:
174 *
175 * | value | version |
176 * | ----- | ------------------------- |
177 * | `0` | use the latest version of prism |
178 * | `1` | use the version of prism that is vendored in CRuby 3.3.0 |
179 * | `2` | use the version of prism that is vendored in CRuby 3.4.0 |
180 * | `3` | use the version of prism that is vendored in CRuby 4.0.0 |
181 * | `4` | use the version of prism that is vendored in CRuby 4.1.0 |
182 *
183 * Each scope is laid out as follows:
184 *
185 * | # bytes | field |
186 * | ------- | -------------------------- |
187 * | `4` | the number of locals |
188 * | `1` | the forwarding flags |
189 * | ... | the locals |
190 *
191 * Each local is laid out as follows:
192 *
193 * | # bytes | field |
194 * | ------- | -------------------------- |
195 * | `4` | the length of the local |
196 * | ... | the local bytes |
197 *
198 * Some additional things to note about this layout:
199 *
200 * * The filepath can have a length of 0, in which case we'll consider it an
201 * empty string.
202 * * The line number should be 0-indexed.
203 * * The encoding can have a length of 0, in which case we'll use the default
204 * encoding (UTF-8). If it's not 0, it should correspond to a name of an
205 * encoding that can be passed to `Encoding.find` in Ruby.
206 * * The frozen string literal, encoding locked, main script, and partial script
207 * fields are booleans, so their values should be either 0 or 1.
208 * * The number of scopes can be 0.
209 */
210void pm_options_read(pm_options_t *options, const char *data);
211
212#endif
The options that can be passed to parsing.
void(* pm_options_shebang_callback_t)(pm_options_t *options, const uint8_t *source, size_t length, void *shebang_callback_data)
The callback called when additional switches are found in a shebang comment that need to be processed...
Definition options.h:71
A generic string type that can have various ownership semantics.
Definition stringy.h:18