soml-lang 0.0.1 → 0.0.3

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.
@@ -0,0 +1,264 @@
1
+ /**
2
+ A position in the source: a 1-based line, and a 0-based column in UTF-16 code units, as in ESTree.
3
+ */
4
+ export type Position = {
5
+ /**
6
+ The 1-based line.
7
+ */
8
+ readonly line: number;
9
+ /**
10
+ The 0-based column, in UTF-16 code units.
11
+ */
12
+ readonly column: number;
13
+ };
14
+ /**
15
+ Where a node, token, or comment is in the source.
16
+ */
17
+ export type SourceLocation = {
18
+ /**
19
+ The position of the first character.
20
+ */
21
+ readonly start: Position;
22
+ /**
23
+ The position after the last character.
24
+ */
25
+ readonly end: Position;
26
+ };
27
+ type Located<Type extends string> = {
28
+ readonly type: Type;
29
+ /**
30
+ The start and end, as UTF-16 offsets into the text.
31
+ */
32
+ readonly range: readonly [start: number, end: number];
33
+ /**
34
+ The start and end, as lines and columns.
35
+ */
36
+ readonly loc: SourceLocation;
37
+ };
38
+ /**
39
+ A token. `value` is its source text.
40
+
41
+ A `Punctuator` is one of `{`, `}`, `[`, `]`, `:`, `,`, and `.`. A `Keyword` is `true`, `false`, or `null`. `infinity` and `-infinity` are `Float` tokens, and a quoted key segment is a `String` token.
42
+ */
43
+ export type Token = Located<'Punctuator' | 'BareKey' | 'String' | 'Integer' | 'Float' | 'Keyword' | 'Instant' | 'Duration'> & {
44
+ readonly value: string;
45
+ };
46
+ /**
47
+ A comment. `value` is its text without its delimiters.
48
+ */
49
+ export type Comment = Located<'Line' | 'Block'> & {
50
+ readonly value: string;
51
+ };
52
+ /**
53
+ The root of a tree.
54
+ */
55
+ export type DocumentNode = Located<'Document'> & {
56
+ /**
57
+ The document's collection, an object or an array.
58
+ */
59
+ readonly body: ObjectNode | ArrayNode;
60
+ /**
61
+ Every token, in source order, without comments.
62
+ */
63
+ readonly tokens: readonly Token[];
64
+ /**
65
+ Every comment, in source order.
66
+ */
67
+ readonly comments: readonly Comment[];
68
+ };
69
+ /**
70
+ An object, written with braces or as a top-level object without them.
71
+ */
72
+ export type ObjectNode = Located<'Object'> & {
73
+ /**
74
+ The members, in source order.
75
+ */
76
+ readonly members: readonly MemberNode[];
77
+ /**
78
+ `false` only for a top-level object written without braces.
79
+ */
80
+ readonly braced: boolean;
81
+ };
82
+ /**
83
+ A `key: value` member of an object.
84
+ */
85
+ export type MemberNode = Located<'Member'> & {
86
+ /**
87
+ The key, which can be dotted.
88
+ */
89
+ readonly key: KeyNode;
90
+ /**
91
+ The value after the `:`.
92
+ */
93
+ readonly value: ValueNode;
94
+ };
95
+ /**
96
+ An array, with its items in `elements`.
97
+ */
98
+ export type ArrayNode = Located<'Array'> & {
99
+ /**
100
+ The items, in source order.
101
+ */
102
+ readonly elements: readonly ValueNode[];
103
+ };
104
+ /**
105
+ A key, with more than one segment when it is dotted.
106
+ */
107
+ export type KeyNode = Located<'Key'> & {
108
+ /**
109
+ The segments between the dots, in source order.
110
+ */
111
+ readonly segments: readonly KeySegmentNode[];
112
+ };
113
+ /**
114
+ One segment of a key, which is the whole key unless it is dotted.
115
+ */
116
+ export type KeySegmentNode = Located<'KeySegment'> & {
117
+ /**
118
+ The decoded key.
119
+ */
120
+ readonly value: string;
121
+ /**
122
+ How the segment is written: bare, as `'...'`, or as `"..."`.
123
+ */
124
+ readonly style: 'bare' | 'literal' | 'escaped';
125
+ };
126
+ /**
127
+ A string, written as `'...'`, `"..."`, or a block string.
128
+ */
129
+ export type StringNode = Located<'String'> & {
130
+ /**
131
+ The decoded string.
132
+ */
133
+ readonly value: string;
134
+ /**
135
+ Whether the string is written with `'` (literal) or `"` (escaped).
136
+ */
137
+ readonly style: 'literal' | 'escaped';
138
+ /**
139
+ Whether it is a block string.
140
+ */
141
+ readonly block: boolean;
142
+ };
143
+ /**
144
+ An int, in any radix.
145
+ */
146
+ export type IntegerNode = Located<'Integer'> & {
147
+ /**
148
+ The value, which is always a `bigint`.
149
+ */
150
+ readonly value: bigint;
151
+ /**
152
+ The radix it is written in: `2` for `0b`, `8` for `0o`, `16` for `0x`, and otherwise `10`.
153
+ */
154
+ readonly radix: 2 | 8 | 10 | 16;
155
+ };
156
+ /**
157
+ A float, including `infinity` and `-infinity`.
158
+ */
159
+ export type FloatNode = Located<'Float'> & {
160
+ /**
161
+ The value, including `Infinity` and `-Infinity`.
162
+ */
163
+ readonly value: number;
164
+ };
165
+ /**
166
+ `true` or `false`.
167
+ */
168
+ export type BooleanNode = Located<'Boolean'> & {
169
+ /**
170
+ The value.
171
+ */
172
+ readonly value: boolean;
173
+ };
174
+ /**
175
+ The `null` keyword, which has no fields of its own.
176
+ */
177
+ export type NullNode = Located<'Null'>;
178
+ /**
179
+ An instant, such as `2026-09-19T14:00:00Z`.
180
+ */
181
+ export type InstantNode = Located<'Instant'> & {
182
+ /**
183
+ Made when it is first read, so that only reading it needs `Temporal`. Spreading or serializing the node reads it too.
184
+ */
185
+ readonly value: Temporal.Instant;
186
+ };
187
+ /**
188
+ One part of a duration, such as `30m` in `1h30m`.
189
+ */
190
+ export type DurationPart = {
191
+ /**
192
+ The number as it is written, with any `_` and fraction, such as `1_000` or `1.5`.
193
+ */
194
+ readonly number: string;
195
+ /**
196
+ The unit.
197
+ */
198
+ readonly unit: 'h' | 'm' | 's' | 'ms' | 'us' | 'ns';
199
+ };
200
+ /**
201
+ A duration, such as `1h30m`.
202
+ */
203
+ export type DurationNode = Located<'Duration'> & {
204
+ /**
205
+ Made when it is first read, so that only reading it needs `Temporal`. Spreading or serializing the node reads it too.
206
+ */
207
+ readonly value: Temporal.Duration;
208
+ /**
209
+ Whether it is written with a `-`, which negates the whole duration.
210
+ */
211
+ readonly negative: boolean;
212
+ /**
213
+ The parts as they are written, in order. So `-1h30m` is `negative` with the parts `1` `h` and `30` `m`.
214
+ */
215
+ readonly parts: readonly DurationPart[];
216
+ };
217
+ /**
218
+ A node that is a value.
219
+ */
220
+ export type ValueNode = ObjectNode | ArrayNode | StringNode | IntegerNode | FloatNode | BooleanNode | NullNode | InstantNode | DurationNode;
221
+ /**
222
+ Any node in a tree.
223
+ */
224
+ export type Node = DocumentNode | MemberNode | KeyNode | KeySegmentNode | ValueNode;
225
+ /**
226
+ The properties of each node type that hold its child nodes, in source order, for tools that walk the tree, such as an ESLint language plugin.
227
+
228
+ @example
229
+ ```
230
+ import {visitorKeys} from 'soml-lang';
231
+
232
+ visitorKeys.Member;
233
+ //=> ['key', 'value']
234
+
235
+ visitorKeys.Integer;
236
+ //=> []
237
+ ```
238
+ */
239
+ export declare const visitorKeys: Readonly<Record<Node['type'], readonly string[]>>;
240
+ /**
241
+ Parse a document into a syntax tree, for tools such as linters and formatters. Returns a `Document` node, which also holds every token and comment.
242
+
243
+ Every node, token, and comment has a `range`, which is `[start, end]` as UTF-16 offsets into `text`, and a `loc`, which is `{start: {line, column}, end: {line, column}}`, with a 1-based line and a 0-based column in UTF-16 code units, as in ESTree. A `ParseError` counts its column differently, for people to read, so use its `offset` to find the position in the tree. A scalar node or a key segment shares its `range` and `loc` with its token, and other nodes, except `Document`, share the positions in `loc` with their first and last token, so treat them as read-only.
244
+
245
+ @param text - The document.
246
+ @returns The root node, which also holds every token and comment.
247
+ @throws {ParseError} When the document is not valid, the same as `parse()`.
248
+ @throws {TypeError} When `text` is not a string.
249
+
250
+ @example
251
+ ```
252
+ import {parseTree} from 'soml-lang';
253
+
254
+ const tree = parseTree('port: 8080 # The default');
255
+
256
+ tree.body.members[0].value;
257
+ //=> {type: 'Integer', value: 8080n, radix: 10, range: [6, 10], loc: {…}}
258
+
259
+ tree.comments[0];
260
+ //=> {type: 'Line', value: ' The default', range: [11, 24], loc: {…}}
261
+ ```
262
+ */
263
+ export declare function parseTree(text: string): DocumentNode;
264
+ export {};