@hyperscale0/hsx 1.0.0-alpha.1
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.
- package/AUTHORS +8 -0
- package/CHANGELOG.md +59 -0
- package/LICENSE +661 -0
- package/LICENSING.md +52 -0
- package/README.md +170 -0
- package/SECURITY.md +47 -0
- package/TRADEMARKS.md +35 -0
- package/bin/hsx.ts +15 -0
- package/dist/bin/hsx.d.ts +7 -0
- package/dist/bin/hsx.d.ts.map +1 -0
- package/dist/bin/hsx.js +14 -0
- package/dist/bin/hsx.js.map +1 -0
- package/dist/src/ast.d.ts +172 -0
- package/dist/src/ast.d.ts.map +1 -0
- package/dist/src/ast.js +22 -0
- package/dist/src/ast.js.map +1 -0
- package/dist/src/check.d.ts +11 -0
- package/dist/src/check.d.ts.map +1 -0
- package/dist/src/check.js +1214 -0
- package/dist/src/check.js.map +1 -0
- package/dist/src/cli.d.ts +20 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +137 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/compile.d.ts +39 -0
- package/dist/src/compile.d.ts.map +1 -0
- package/dist/src/compile.js +59 -0
- package/dist/src/compile.js.map +1 -0
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lex.d.ts +23 -0
- package/dist/src/lex.d.ts.map +1 -0
- package/dist/src/lex.js +125 -0
- package/dist/src/lex.js.map +1 -0
- package/dist/src/lower.d.ts +93 -0
- package/dist/src/lower.d.ts.map +1 -0
- package/dist/src/lower.js +2081 -0
- package/dist/src/lower.js.map +1 -0
- package/dist/src/model.d.ts +307 -0
- package/dist/src/model.d.ts.map +1 -0
- package/dist/src/model.js +15 -0
- package/dist/src/model.js.map +1 -0
- package/dist/src/parse.d.ts +19 -0
- package/dist/src/parse.d.ts.map +1 -0
- package/dist/src/parse.js +484 -0
- package/dist/src/parse.js.map +1 -0
- package/dist/src/version.d.ts +16 -0
- package/dist/src/version.d.ts.map +1 -0
- package/dist/src/version.js +16 -0
- package/dist/src/version.js.map +1 -0
- package/package.json +79 -0
- package/spec/hsx-ir.schema.json +522 -0
- package/src/ast.ts +231 -0
- package/src/check.ts +1699 -0
- package/src/cli.ts +173 -0
- package/src/compile.ts +98 -0
- package/src/index.ts +16 -0
- package/src/lex.ts +161 -0
- package/src/lower.ts +2619 -0
- package/src/model.ts +340 -0
- package/src/parse.ts +580 -0
- package/src/version.ts +17 -0
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The HSX parser. Recursive descent over the lexer's token stream, total:
|
|
3
|
+
* it always returns a best-effort `Program` plus diagnostics, recovering at
|
|
4
|
+
* the next top-level keyword after an error so one mistake never hides the
|
|
5
|
+
* rest of the file. Diagnostics speak the author's language and point at
|
|
6
|
+
* source spans.
|
|
7
|
+
*/
|
|
8
|
+
import { lex } from "./lex.js";
|
|
9
|
+
export function parseProgram(source) {
|
|
10
|
+
const lexed = lex(source);
|
|
11
|
+
const parser = new Parser(lexed.tokens, [...lexed.diagnostics]);
|
|
12
|
+
const program = parser.parseProgram(source.length);
|
|
13
|
+
return { diagnostics: parser.diagnostics, program };
|
|
14
|
+
}
|
|
15
|
+
class Parser {
|
|
16
|
+
diagnostics;
|
|
17
|
+
tokens;
|
|
18
|
+
index = 0;
|
|
19
|
+
constructor(tokens, diagnostics) {
|
|
20
|
+
this.tokens = tokens;
|
|
21
|
+
this.diagnostics = diagnostics;
|
|
22
|
+
}
|
|
23
|
+
parseProgram(sourceLength) {
|
|
24
|
+
const decls = [];
|
|
25
|
+
while (!this.at("eof")) {
|
|
26
|
+
const decl = this.parseDecl();
|
|
27
|
+
if (decl) {
|
|
28
|
+
decls.push(decl);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
this.recoverToDecl();
|
|
32
|
+
}
|
|
33
|
+
return { decls, span: { end: sourceLength, start: 0 } };
|
|
34
|
+
}
|
|
35
|
+
// --- Declarations --------------------------------------------------------
|
|
36
|
+
parseDecl() {
|
|
37
|
+
const token = this.peek();
|
|
38
|
+
if (token.kind !== "keyword" || token.text === "from") {
|
|
39
|
+
this.error(token.span, token.kind === "eof"
|
|
40
|
+
? "the program ends unexpectedly"
|
|
41
|
+
: `expected a declaration (program, import, party, asset, settlement, or port), found "${token.text}"`);
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
switch (token.text) {
|
|
45
|
+
case "program":
|
|
46
|
+
return this.parseProgramDecl();
|
|
47
|
+
case "import":
|
|
48
|
+
return this.parseImportDecl();
|
|
49
|
+
case "party":
|
|
50
|
+
return this.parsePartyDecl();
|
|
51
|
+
case "asset":
|
|
52
|
+
return this.parseAssetDecl();
|
|
53
|
+
case "settlement":
|
|
54
|
+
return this.parseSettlementDecl();
|
|
55
|
+
case "port":
|
|
56
|
+
return this.parsePortDecl();
|
|
57
|
+
default:
|
|
58
|
+
this.error(token.span, `"${token.text}" cannot start a declaration`);
|
|
59
|
+
this.advance();
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
parseProgramDecl() {
|
|
64
|
+
const start = this.advance();
|
|
65
|
+
const name = this.expectIdent("the program needs a snake_case name");
|
|
66
|
+
if (!name)
|
|
67
|
+
return undefined;
|
|
68
|
+
let title;
|
|
69
|
+
if (this.at("string")) {
|
|
70
|
+
const token = this.advance();
|
|
71
|
+
title = { kind: "string", span: token.span, value: token.value };
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
kind: "program",
|
|
75
|
+
name,
|
|
76
|
+
span: this.spanFrom(start.span),
|
|
77
|
+
...(title ? { title } : {}),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
parseImportDecl() {
|
|
81
|
+
const start = this.advance();
|
|
82
|
+
if (!this.expectPunct("{", 'import lists its names in braces: import { held_payment } from "settlement"')) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
const names = [];
|
|
86
|
+
while (!this.atPunct("}") && !this.at("eof")) {
|
|
87
|
+
const name = this.expectIdent("expected an imported name");
|
|
88
|
+
if (!name)
|
|
89
|
+
return undefined;
|
|
90
|
+
names.push(name);
|
|
91
|
+
if (this.atPunct(","))
|
|
92
|
+
this.advance();
|
|
93
|
+
}
|
|
94
|
+
if (!this.expectPunct("}", "the import name list never closes")) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
if (!this.at("keyword") || this.peek().text !== "from") {
|
|
98
|
+
this.error(this.peek().span, 'import needs from: import { held_payment } from "settlement"');
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
this.advance();
|
|
102
|
+
if (!this.at("string")) {
|
|
103
|
+
this.error(this.peek().span, 'the import source must be a quoted module name like "settlement"');
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
const sourceToken = this.advance();
|
|
107
|
+
if (names.length === 0) {
|
|
108
|
+
this.error(start.span, "import brings in at least one name");
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
from: {
|
|
112
|
+
kind: "string",
|
|
113
|
+
span: sourceToken.span,
|
|
114
|
+
value: sourceToken.value,
|
|
115
|
+
},
|
|
116
|
+
kind: "import",
|
|
117
|
+
names,
|
|
118
|
+
span: this.spanFrom(start.span),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
parsePartyDecl() {
|
|
122
|
+
const start = this.advance();
|
|
123
|
+
const name = this.expectIdent("the party needs a name, like: party buyer: person");
|
|
124
|
+
if (!name)
|
|
125
|
+
return undefined;
|
|
126
|
+
if (!this.expectPunct(":", `party ${name.name} needs a kind, like: party ${name.name}: person`)) {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
const partyKind = this.expectIdent(`expected a kind for party ${name.name}`);
|
|
130
|
+
if (!partyKind)
|
|
131
|
+
return undefined;
|
|
132
|
+
const attrs = this.atPunct("{") ? this.parseBlock() : undefined;
|
|
133
|
+
return {
|
|
134
|
+
...(attrs ? { attrs } : {}),
|
|
135
|
+
kind: "party",
|
|
136
|
+
name,
|
|
137
|
+
partyKind,
|
|
138
|
+
span: this.spanFrom(start.span),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
parseAssetDecl() {
|
|
142
|
+
const start = this.advance();
|
|
143
|
+
const name = this.expectIdent("the asset needs a name, like: asset vehicle: good");
|
|
144
|
+
if (!name)
|
|
145
|
+
return undefined;
|
|
146
|
+
if (!this.expectPunct(":", `asset ${name.name} needs a kind, like: asset ${name.name}: good`)) {
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
const assetKind = this.expectIdent(`expected a kind for asset ${name.name}`);
|
|
150
|
+
if (!assetKind)
|
|
151
|
+
return undefined;
|
|
152
|
+
const attrs = this.atPunct("{") ? this.parseBlock() : undefined;
|
|
153
|
+
return {
|
|
154
|
+
assetKind,
|
|
155
|
+
...(attrs ? { attrs } : {}),
|
|
156
|
+
kind: "asset",
|
|
157
|
+
name,
|
|
158
|
+
span: this.spanFrom(start.span),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
parseSettlementDecl() {
|
|
162
|
+
const start = this.advance();
|
|
163
|
+
const name = this.expectIdent("the settlement needs a name, like: settlement sale = held_payment { ... }");
|
|
164
|
+
if (!name)
|
|
165
|
+
return undefined;
|
|
166
|
+
if (!this.expectPunct("=", `settlement ${name.name} instantiates an archetype: settlement ${name.name} = held_payment { ... }`)) {
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
const archetype = this.expectIdent(`expected an archetype name for settlement ${name.name}`);
|
|
170
|
+
if (!archetype)
|
|
171
|
+
return undefined;
|
|
172
|
+
if (!this.atPunct("{")) {
|
|
173
|
+
this.error(this.peek().span, `settlement ${name.name} needs a body in braces`);
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
const body = this.parseBlock();
|
|
177
|
+
if (!body)
|
|
178
|
+
return undefined;
|
|
179
|
+
return {
|
|
180
|
+
archetype,
|
|
181
|
+
body,
|
|
182
|
+
kind: "settlement",
|
|
183
|
+
name,
|
|
184
|
+
span: this.spanFrom(start.span),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
parsePortDecl() {
|
|
188
|
+
const start = this.advance();
|
|
189
|
+
const name = this.expectIdent("the port needs a name, like: port confirm_handover { ... }");
|
|
190
|
+
if (!name)
|
|
191
|
+
return undefined;
|
|
192
|
+
if (!this.atPunct("{")) {
|
|
193
|
+
this.error(this.peek().span, `port ${name.name} needs a body in braces`);
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
const body = this.parseBlock();
|
|
197
|
+
if (!body)
|
|
198
|
+
return undefined;
|
|
199
|
+
return { body, kind: "port", name, span: this.spanFrom(start.span) };
|
|
200
|
+
}
|
|
201
|
+
// --- Entries and expressions ---------------------------------------------
|
|
202
|
+
parseBlock() {
|
|
203
|
+
const open = this.advance();
|
|
204
|
+
const entries = [];
|
|
205
|
+
while (!this.atPunct("}") && !this.at("eof")) {
|
|
206
|
+
const before = this.index;
|
|
207
|
+
const entry = this.parseEntry();
|
|
208
|
+
if (!entry) {
|
|
209
|
+
this.recoverInBlock();
|
|
210
|
+
// recoverInBlock bails without consuming when it lands on a depth-0
|
|
211
|
+
// keyword (e.g. `from` used as an entry key), and a failed
|
|
212
|
+
// parseEntry may not have consumed either. Without forced progress
|
|
213
|
+
// this loop never terminates.
|
|
214
|
+
if (this.index === before)
|
|
215
|
+
this.advance();
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
entries.push(entry);
|
|
219
|
+
if (this.atPunct(","))
|
|
220
|
+
this.advance();
|
|
221
|
+
}
|
|
222
|
+
if (!this.expectPunct("}", "this block never closes; add the matching }")) {
|
|
223
|
+
return { entries, kind: "block", span: this.spanFrom(open.span) };
|
|
224
|
+
}
|
|
225
|
+
return { entries, kind: "block", span: this.spanFrom(open.span) };
|
|
226
|
+
}
|
|
227
|
+
parseEntry() {
|
|
228
|
+
const key = this.expectIdent("expected an entry name here");
|
|
229
|
+
if (!key)
|
|
230
|
+
return undefined;
|
|
231
|
+
const qualifiers = [];
|
|
232
|
+
if (this.atPunct("(")) {
|
|
233
|
+
this.advance();
|
|
234
|
+
while (!this.atPunct(")") && !this.at("eof")) {
|
|
235
|
+
const qualifier = this.expectIdent(`expected a qualifier inside ${key.name}( ... )`);
|
|
236
|
+
if (!qualifier)
|
|
237
|
+
return undefined;
|
|
238
|
+
qualifiers.push(qualifier);
|
|
239
|
+
if (this.atPunct(","))
|
|
240
|
+
this.advance();
|
|
241
|
+
}
|
|
242
|
+
if (!this.expectPunct(")", `${key.name}( ... ) never closes`)) {
|
|
243
|
+
return undefined;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
let value;
|
|
247
|
+
if (this.atPunct("{")) {
|
|
248
|
+
value = this.parseBlock();
|
|
249
|
+
}
|
|
250
|
+
else if (this.atPunct(":")) {
|
|
251
|
+
this.advance();
|
|
252
|
+
value = this.parseExpr();
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
this.error(this.peek().span, `entry ${key.name} needs a value: either "${key.name}: <value>" or "${key.name} { ... }"`);
|
|
256
|
+
return undefined;
|
|
257
|
+
}
|
|
258
|
+
if (!value)
|
|
259
|
+
return undefined;
|
|
260
|
+
return {
|
|
261
|
+
key,
|
|
262
|
+
qualifiers,
|
|
263
|
+
span: { end: value.span.end, start: key.span.start },
|
|
264
|
+
value,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
parseExpr() {
|
|
268
|
+
const token = this.peek();
|
|
269
|
+
if (token.kind === "string") {
|
|
270
|
+
this.advance();
|
|
271
|
+
return { kind: "string", span: token.span, value: token.value };
|
|
272
|
+
}
|
|
273
|
+
if (token.kind === "number") {
|
|
274
|
+
this.advance();
|
|
275
|
+
return { kind: "number", raw: token.value, span: token.span };
|
|
276
|
+
}
|
|
277
|
+
if (token.kind === "percent") {
|
|
278
|
+
this.advance();
|
|
279
|
+
const bps = percentToBps(token.value);
|
|
280
|
+
if (bps === undefined) {
|
|
281
|
+
this.error(token.span, `${token.text} is finer than the money system can settle; percents go down to a hundredth (basis point), like 99.75%`);
|
|
282
|
+
return { bps: 0, kind: "percent", raw: token.value, span: token.span };
|
|
283
|
+
}
|
|
284
|
+
return { bps, kind: "percent", raw: token.value, span: token.span };
|
|
285
|
+
}
|
|
286
|
+
if (this.atPunct("[")) {
|
|
287
|
+
const open = this.advance();
|
|
288
|
+
const items = [];
|
|
289
|
+
while (!this.atPunct("]") && !this.at("eof")) {
|
|
290
|
+
const item = this.parseExpr();
|
|
291
|
+
if (!item)
|
|
292
|
+
return undefined;
|
|
293
|
+
items.push(item);
|
|
294
|
+
if (this.atPunct(","))
|
|
295
|
+
this.advance();
|
|
296
|
+
}
|
|
297
|
+
if (!this.expectPunct("]", "this list never closes; add the matching ]")) {
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
return { items, kind: "list", span: this.spanFrom(open.span) };
|
|
301
|
+
}
|
|
302
|
+
if (this.atPunct("{")) {
|
|
303
|
+
return this.parseBlock();
|
|
304
|
+
}
|
|
305
|
+
if (token.kind === "keyword" && token.text === "port") {
|
|
306
|
+
const start = this.advance();
|
|
307
|
+
const name = this.expectIdent("expected a port name after the port keyword");
|
|
308
|
+
if (!name)
|
|
309
|
+
return undefined;
|
|
310
|
+
let within;
|
|
311
|
+
if (this.at("ident") && this.peek().text === "within") {
|
|
312
|
+
this.advance();
|
|
313
|
+
within = this.expectIdent("expected a fixed duration after within, like P14D");
|
|
314
|
+
if (!within)
|
|
315
|
+
return undefined;
|
|
316
|
+
}
|
|
317
|
+
let deadline;
|
|
318
|
+
if (this.atPunct("|")) {
|
|
319
|
+
this.advance();
|
|
320
|
+
if (!this.at("ident") || this.peek().text !== "at") {
|
|
321
|
+
this.error(this.peek().span, "after | comes the date the platform decides on, like: | at(releaseDueAt)");
|
|
322
|
+
return undefined;
|
|
323
|
+
}
|
|
324
|
+
this.advance();
|
|
325
|
+
if (!this.expectPunct("(", "at names its date field in parentheses: at(releaseDueAt)")) {
|
|
326
|
+
return undefined;
|
|
327
|
+
}
|
|
328
|
+
deadline = this.expectIdent("expected a stored date field inside at( ... ), like at(releaseDueAt)");
|
|
329
|
+
if (!deadline)
|
|
330
|
+
return undefined;
|
|
331
|
+
if (!this.expectPunct(")", "at( ... ) never closes"))
|
|
332
|
+
return undefined;
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
...(deadline ? { deadline } : {}),
|
|
336
|
+
kind: "port_ref",
|
|
337
|
+
name,
|
|
338
|
+
span: this.spanFrom(start.span),
|
|
339
|
+
...(within ? { within } : {}),
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
if (token.kind === "ident") {
|
|
343
|
+
const ident = this.parseIdent();
|
|
344
|
+
if (this.atPunct(".")) {
|
|
345
|
+
this.advance();
|
|
346
|
+
const member = this.expectIdent(`expected the exit after ${ident.name}., like ${ident.name}.release`);
|
|
347
|
+
if (!member)
|
|
348
|
+
return undefined;
|
|
349
|
+
return {
|
|
350
|
+
kind: "settlement_ref",
|
|
351
|
+
member,
|
|
352
|
+
owner: ident,
|
|
353
|
+
span: { end: member.span.end, start: ident.span.start },
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
if (this.atPunct("(")) {
|
|
357
|
+
this.advance();
|
|
358
|
+
const args = [];
|
|
359
|
+
while (!this.atPunct(")") && !this.at("eof")) {
|
|
360
|
+
const arg = this.parseExpr();
|
|
361
|
+
if (!arg)
|
|
362
|
+
return undefined;
|
|
363
|
+
args.push(arg);
|
|
364
|
+
if (this.atPunct(","))
|
|
365
|
+
this.advance();
|
|
366
|
+
}
|
|
367
|
+
if (!this.expectPunct(")", `${ident.name}( ... ) never closes`)) {
|
|
368
|
+
return undefined;
|
|
369
|
+
}
|
|
370
|
+
return {
|
|
371
|
+
args,
|
|
372
|
+
callee: ident,
|
|
373
|
+
kind: "call",
|
|
374
|
+
span: this.spanFrom(ident.span),
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
if (this.atPunct(":")) {
|
|
378
|
+
this.advance();
|
|
379
|
+
const type = this.parseExpr();
|
|
380
|
+
if (!type)
|
|
381
|
+
return undefined;
|
|
382
|
+
return {
|
|
383
|
+
kind: "binding",
|
|
384
|
+
name: ident,
|
|
385
|
+
span: { end: type.span.end, start: ident.span.start },
|
|
386
|
+
type,
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
return ident;
|
|
390
|
+
}
|
|
391
|
+
this.error(token.span, token.kind === "eof"
|
|
392
|
+
? "the program ends where a value was expected"
|
|
393
|
+
: `"${token.text}" is not a value HSX understands here`);
|
|
394
|
+
return undefined;
|
|
395
|
+
}
|
|
396
|
+
// --- Recovery ------------------------------------------------------------
|
|
397
|
+
recoverToDecl() {
|
|
398
|
+
while (!this.at("eof")) {
|
|
399
|
+
const token = this.peek();
|
|
400
|
+
if (token.kind === "keyword" && token.text !== "from")
|
|
401
|
+
return;
|
|
402
|
+
this.advance();
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
/** Skip to the next plausible entry start or the end of the block. */
|
|
406
|
+
recoverInBlock() {
|
|
407
|
+
let depth = 0;
|
|
408
|
+
while (!this.at("eof")) {
|
|
409
|
+
const token = this.peek();
|
|
410
|
+
if (token.kind === "punct") {
|
|
411
|
+
if (token.text === "{" || token.text === "[" || token.text === "(")
|
|
412
|
+
depth += 1;
|
|
413
|
+
if (token.text === "}" || token.text === "]" || token.text === ")") {
|
|
414
|
+
if (depth === 0)
|
|
415
|
+
return;
|
|
416
|
+
depth -= 1;
|
|
417
|
+
}
|
|
418
|
+
if (token.text === "," && depth === 0) {
|
|
419
|
+
this.advance();
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (token.kind === "keyword" && depth === 0)
|
|
424
|
+
return;
|
|
425
|
+
this.advance();
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
// --- Token helpers -------------------------------------------------------
|
|
429
|
+
peek() {
|
|
430
|
+
return this.tokens[this.index];
|
|
431
|
+
}
|
|
432
|
+
previous() {
|
|
433
|
+
return this.tokens[Math.max(0, this.index - 1)];
|
|
434
|
+
}
|
|
435
|
+
advance() {
|
|
436
|
+
const token = this.peek();
|
|
437
|
+
if (token.kind !== "eof")
|
|
438
|
+
this.index += 1;
|
|
439
|
+
return token;
|
|
440
|
+
}
|
|
441
|
+
at(kind) {
|
|
442
|
+
return this.peek().kind === kind;
|
|
443
|
+
}
|
|
444
|
+
atPunct(glyph) {
|
|
445
|
+
const token = this.peek();
|
|
446
|
+
return token.kind === "punct" && token.text === glyph;
|
|
447
|
+
}
|
|
448
|
+
parseIdent() {
|
|
449
|
+
const token = this.advance();
|
|
450
|
+
return { kind: "ident", name: token.text, span: token.span };
|
|
451
|
+
}
|
|
452
|
+
expectIdent(message) {
|
|
453
|
+
if (this.at("ident"))
|
|
454
|
+
return this.parseIdent();
|
|
455
|
+
this.error(this.peek().span, message);
|
|
456
|
+
return undefined;
|
|
457
|
+
}
|
|
458
|
+
expectPunct(glyph, message) {
|
|
459
|
+
if (this.atPunct(glyph)) {
|
|
460
|
+
this.advance();
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
this.error(this.peek().span, message);
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
spanFrom(start) {
|
|
467
|
+
return { end: this.previous().span.end, start: start.start };
|
|
468
|
+
}
|
|
469
|
+
error(span, message) {
|
|
470
|
+
this.diagnostics.push({ message, span });
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Convert a percent literal's raw digits to exact basis points, or refuse
|
|
475
|
+
* when the literal is finer than a basis point. "99.5" -> 9950; "0.05" -> 5.
|
|
476
|
+
*/
|
|
477
|
+
export function percentToBps(raw) {
|
|
478
|
+
const [whole = "0", fraction = ""] = raw.split(".");
|
|
479
|
+
if (fraction.length > 2)
|
|
480
|
+
return undefined;
|
|
481
|
+
const scaled = fraction.padEnd(2, "0");
|
|
482
|
+
return Number(whole) * 100 + Number(scaled === "" ? "0" : scaled);
|
|
483
|
+
}
|
|
484
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two versions HSX carries, and the difference between them.
|
|
3
|
+
*
|
|
4
|
+
* `HSX_VERSION` is the npm package's semver: it moves when this compiler's
|
|
5
|
+
* code changes, including changes that only affect diagnostics or docs.
|
|
6
|
+
*
|
|
7
|
+
* `HSX_IR_VERSION` is the format number stamped into every compiled document
|
|
8
|
+
* as its `hsx` field. It moves only when the emitted IR shape changes in a
|
|
9
|
+
* way a consumer must notice, so a runtime can refuse a document it does not
|
|
10
|
+
* understand by reading one integer. A package release almost never bumps it.
|
|
11
|
+
*/
|
|
12
|
+
/** Stamped into every compiled HSX-JSON document as `hsx`. */
|
|
13
|
+
export declare const HSX_IR_VERSION = 1;
|
|
14
|
+
/** Kept equal to the package.json version by `test/spec.spec.ts`. */
|
|
15
|
+
export declare const HSX_VERSION = "1.0.0-alpha.1";
|
|
16
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,8DAA8D;AAC9D,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,qEAAqE;AACrE,eAAO,MAAM,WAAW,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two versions HSX carries, and the difference between them.
|
|
3
|
+
*
|
|
4
|
+
* `HSX_VERSION` is the npm package's semver: it moves when this compiler's
|
|
5
|
+
* code changes, including changes that only affect diagnostics or docs.
|
|
6
|
+
*
|
|
7
|
+
* `HSX_IR_VERSION` is the format number stamped into every compiled document
|
|
8
|
+
* as its `hsx` field. It moves only when the emitted IR shape changes in a
|
|
9
|
+
* way a consumer must notice, so a runtime can refuse a document it does not
|
|
10
|
+
* understand by reading one integer. A package release almost never bumps it.
|
|
11
|
+
*/
|
|
12
|
+
/** Stamped into every compiled HSX-JSON document as `hsx`. */
|
|
13
|
+
export const HSX_IR_VERSION = 1;
|
|
14
|
+
/** Kept equal to the package.json version by `test/spec.spec.ts`. */
|
|
15
|
+
export const HSX_VERSION = "1.0.0-alpha.1";
|
|
16
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,8DAA8D;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC,qEAAqE;AACrE,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hyperscale0/hsx",
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
|
+
"description": "The HSX language: a compiler from a textual description of a financial product's money movement to the HSX-JSON IR.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"hsx",
|
|
7
|
+
"compiler",
|
|
8
|
+
"dsl",
|
|
9
|
+
"fintech",
|
|
10
|
+
"escrow",
|
|
11
|
+
"settlement",
|
|
12
|
+
"payments",
|
|
13
|
+
"money-movement",
|
|
14
|
+
"language"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://github.com/hyperscale0/hyperscale-hsx#readme",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/hyperscale0/hyperscale-hsx/issues"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/hyperscale0/hyperscale-hsx.git"
|
|
23
|
+
},
|
|
24
|
+
"license": "AGPL-3.0-only",
|
|
25
|
+
"author": "Hyperscale LLC",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"sideEffects": false,
|
|
28
|
+
"main": "./dist/src/index.js",
|
|
29
|
+
"module": "./dist/src/index.js",
|
|
30
|
+
"types": "./dist/src/index.d.ts",
|
|
31
|
+
"bin": {
|
|
32
|
+
"hsx": "./dist/bin/hsx.js"
|
|
33
|
+
},
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/src/index.d.ts",
|
|
37
|
+
"default": "./dist/src/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./spec/hsx-ir.schema.json": "./spec/hsx-ir.schema.json",
|
|
40
|
+
"./package.json": "./package.json"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"AUTHORS",
|
|
44
|
+
"CHANGELOG.md",
|
|
45
|
+
"LICENSE",
|
|
46
|
+
"LICENSING.md",
|
|
47
|
+
"README.md",
|
|
48
|
+
"SECURITY.md",
|
|
49
|
+
"TRADEMARKS.md",
|
|
50
|
+
"bin",
|
|
51
|
+
"dist",
|
|
52
|
+
"spec",
|
|
53
|
+
"src"
|
|
54
|
+
],
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": ">=22.0.0"
|
|
57
|
+
},
|
|
58
|
+
"publishConfig": {
|
|
59
|
+
"access": "public",
|
|
60
|
+
"tag": "alpha"
|
|
61
|
+
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "tsc -p tsconfig.build.json",
|
|
64
|
+
"check": "bun test && tsc -p tsconfig.json",
|
|
65
|
+
"postpack": "bun scripts/pack-exports.ts restore",
|
|
66
|
+
"prepack": "bun run build && bun scripts/pack-exports.ts apply",
|
|
67
|
+
"test": "bun test",
|
|
68
|
+
"typecheck": "tsc -p tsconfig.json"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@types/bun": "1.4.0",
|
|
72
|
+
"typescript": "6.0.3"
|
|
73
|
+
},
|
|
74
|
+
"contributors": [
|
|
75
|
+
"Meshael AlBakaawi",
|
|
76
|
+
"Amir Ayub",
|
|
77
|
+
"Sara AlBakaawi"
|
|
78
|
+
]
|
|
79
|
+
}
|