@atomic-ehr/fhirpath 0.0.1-canary.0c6931e.20250727185306

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.
Files changed (85) hide show
  1. package/README.md +473 -0
  2. package/dist/index.d.ts +462 -0
  3. package/dist/index.js +10307 -0
  4. package/dist/index.js.map +1 -0
  5. package/package.json +58 -0
  6. package/src/analyzer/analyzer.ts +499 -0
  7. package/src/analyzer/model-provider.ts +244 -0
  8. package/src/analyzer/schemas/index.ts +2 -0
  9. package/src/analyzer/schemas/types.ts +40 -0
  10. package/src/analyzer/types.ts +142 -0
  11. package/src/api/builder.ts +157 -0
  12. package/src/api/errors.ts +145 -0
  13. package/src/api/expression.ts +156 -0
  14. package/src/api/index.ts +122 -0
  15. package/src/api/inspect.ts +99 -0
  16. package/src/api/registry.ts +128 -0
  17. package/src/api/types.ts +210 -0
  18. package/src/compiler/compiler.ts +546 -0
  19. package/src/compiler/index.ts +2 -0
  20. package/src/compiler/prototype-context-adapter.ts +99 -0
  21. package/src/compiler/types.ts +24 -0
  22. package/src/index.ts +107 -0
  23. package/src/interpreter/README.md +78 -0
  24. package/src/interpreter/interpreter.ts +475 -0
  25. package/src/interpreter/types.ts +108 -0
  26. package/src/lexer/char-tables.ts +37 -0
  27. package/src/lexer/errors.ts +31 -0
  28. package/src/lexer/index.ts +5 -0
  29. package/src/lexer/lexer.ts +745 -0
  30. package/src/lexer/token.ts +104 -0
  31. package/src/lexer2/index.md +232 -0
  32. package/src/lexer2/index.perf.test.ts +68 -0
  33. package/src/lexer2/index.test.ts +549 -0
  34. package/src/lexer2/index.ts +1251 -0
  35. package/src/lexer2/notes.md +173 -0
  36. package/src/lexer2/optimization-summary.md +718 -0
  37. package/src/parser/ast-factory.ts +220 -0
  38. package/src/parser/ast.ts +144 -0
  39. package/src/parser/collection-parser.ts +89 -0
  40. package/src/parser/diagnostic-messages.ts +216 -0
  41. package/src/parser/diagnostics.ts +85 -0
  42. package/src/parser/error-reporter.ts +230 -0
  43. package/src/parser/index.ts +3 -0
  44. package/src/parser/literal-parser.ts +103 -0
  45. package/src/parser/parse-error.ts +16 -0
  46. package/src/parser/parser-error-factory.ts +141 -0
  47. package/src/parser/parser-state.ts +134 -0
  48. package/src/parser/parser.ts +1272 -0
  49. package/src/parser/pprint.ts +169 -0
  50. package/src/parser/precedence-manager.ts +64 -0
  51. package/src/parser/source-mapper.ts +248 -0
  52. package/src/parser/special-constructs.ts +142 -0
  53. package/src/parser/token-navigator.ts +110 -0
  54. package/src/parser/types.ts +60 -0
  55. package/src/parser2/index.md +177 -0
  56. package/src/parser2/index.perf.test.ts +184 -0
  57. package/src/parser2/index.test.ts +305 -0
  58. package/src/parser2/index.ts +578 -0
  59. package/src/parser2/optimization-summary.md +176 -0
  60. package/src/registry/default-analyzers.ts +257 -0
  61. package/src/registry/default-compilers.ts +31 -0
  62. package/src/registry/index.ts +96 -0
  63. package/src/registry/operations/arithmetic.ts +506 -0
  64. package/src/registry/operations/collection.ts +425 -0
  65. package/src/registry/operations/comparison.ts +432 -0
  66. package/src/registry/operations/existence.ts +703 -0
  67. package/src/registry/operations/filtering.ts +358 -0
  68. package/src/registry/operations/literals.ts +341 -0
  69. package/src/registry/operations/logical.ts +439 -0
  70. package/src/registry/operations/math.ts +128 -0
  71. package/src/registry/operations/membership.ts +132 -0
  72. package/src/registry/operations/navigation.ts +52 -0
  73. package/src/registry/operations/string.ts +507 -0
  74. package/src/registry/operations/subsetting.ts +174 -0
  75. package/src/registry/operations/type-checking.ts +162 -0
  76. package/src/registry/operations/type-conversion.ts +404 -0
  77. package/src/registry/operations/type-operators.ts +308 -0
  78. package/src/registry/operations/utility.ts +644 -0
  79. package/src/registry/registry.ts +146 -0
  80. package/src/registry/types.ts +161 -0
  81. package/src/registry/utils/evaluation-helpers.ts +93 -0
  82. package/src/registry/utils/index.ts +3 -0
  83. package/src/registry/utils/type-system.ts +173 -0
  84. package/src/runtime/context.ts +158 -0
  85. package/src/runtime/debug-context.ts +135 -0
@@ -0,0 +1,305 @@
1
+ import { describe, it, expect } from 'bun:test';
2
+ import { parse, NodeType } from './index';
3
+
4
+ describe('Parser2', () => {
5
+ describe('literals', () => {
6
+ it('parses numbers', () => {
7
+ const ast = parse('42');
8
+ expect(ast.type).toBe(NodeType.Literal);
9
+ expect((ast as any).value).toBe(42);
10
+ expect((ast as any).valueType).toBe('number');
11
+ });
12
+
13
+ it('parses decimal numbers', () => {
14
+ const ast = parse('3.14');
15
+ expect(ast.type).toBe(NodeType.Literal);
16
+ expect((ast as any).value).toBe(3.14);
17
+ expect((ast as any).valueType).toBe('number');
18
+ });
19
+
20
+ it('parses strings', () => {
21
+ const ast = parse("'hello world'");
22
+ expect(ast.type).toBe(NodeType.Literal);
23
+ expect((ast as any).value).toBe('hello world');
24
+ expect((ast as any).valueType).toBe('string');
25
+ });
26
+
27
+ it('parses booleans', () => {
28
+ let ast = parse('true');
29
+ expect(ast.type).toBe(NodeType.Literal);
30
+ expect((ast as any).value).toBe(true);
31
+ expect((ast as any).valueType).toBe('boolean');
32
+
33
+ ast = parse('false');
34
+ expect(ast.type).toBe(NodeType.Literal);
35
+ expect((ast as any).value).toBe(false);
36
+ expect((ast as any).valueType).toBe('boolean');
37
+ });
38
+
39
+ it('parses null', () => {
40
+ const ast = parse('null');
41
+ expect(ast.type).toBe(NodeType.Literal);
42
+ expect((ast as any).value).toBe(null);
43
+ expect((ast as any).valueType).toBe('null');
44
+ });
45
+
46
+ it('parses datetime', () => {
47
+ const ast = parse('@2023-01-01T12:00:00');
48
+ expect(ast.type).toBe(NodeType.Literal);
49
+ expect((ast as any).value).toBe('2023-01-01T12:00:00');
50
+ expect((ast as any).valueType).toBe('datetime');
51
+ });
52
+
53
+ it('parses time', () => {
54
+ const ast = parse('@T12:00:00');
55
+ expect(ast.type).toBe(NodeType.Literal);
56
+ expect((ast as any).value).toBe('T12:00:00');
57
+ expect((ast as any).valueType).toBe('time');
58
+ });
59
+ });
60
+
61
+ describe('identifiers', () => {
62
+ it('parses simple identifiers', () => {
63
+ const ast = parse('name');
64
+ expect(ast.type).toBe(NodeType.Identifier);
65
+ expect((ast as any).name).toBe('name');
66
+ });
67
+
68
+ it('parses type identifiers', () => {
69
+ const ast = parse('Patient');
70
+ expect(ast.type).toBe(NodeType.TypeOrIdentifier);
71
+ expect((ast as any).name).toBe('Patient');
72
+ });
73
+
74
+ it('parses delimited identifiers', () => {
75
+ const ast = parse('`special-name`');
76
+ expect(ast.type).toBe(NodeType.Identifier);
77
+ expect((ast as any).name).toBe('special-name');
78
+ });
79
+ });
80
+
81
+ describe('variables', () => {
82
+ it('parses $this', () => {
83
+ const ast = parse('$this');
84
+ expect(ast.type).toBe(NodeType.Variable);
85
+ expect((ast as any).name).toBe('$this');
86
+ });
87
+
88
+ it('parses $index', () => {
89
+ const ast = parse('$index');
90
+ expect(ast.type).toBe(NodeType.Variable);
91
+ expect((ast as any).name).toBe('$index');
92
+ });
93
+
94
+ it('parses environment variables', () => {
95
+ const ast = parse('%env');
96
+ expect(ast.type).toBe(NodeType.Variable);
97
+ expect((ast as any).name).toBe('%env');
98
+ });
99
+ });
100
+
101
+ describe('binary operators', () => {
102
+ it('parses arithmetic operators', () => {
103
+ let ast = parse('1 + 2');
104
+ expect(ast.type).toBe(NodeType.Binary);
105
+ expect((ast as any).left.value).toBe(1);
106
+ expect((ast as any).right.value).toBe(2);
107
+
108
+ ast = parse('5 - 3');
109
+ expect(ast.type).toBe(NodeType.Binary);
110
+ expect((ast as any).left.value).toBe(5);
111
+ expect((ast as any).right.value).toBe(3);
112
+
113
+ ast = parse('2 * 3');
114
+ expect(ast.type).toBe(NodeType.Binary);
115
+ expect((ast as any).left.value).toBe(2);
116
+ expect((ast as any).right.value).toBe(3);
117
+
118
+ ast = parse('10 / 2');
119
+ expect(ast.type).toBe(NodeType.Binary);
120
+ expect((ast as any).left.value).toBe(10);
121
+ expect((ast as any).right.value).toBe(2);
122
+ });
123
+
124
+ it('respects operator precedence', () => {
125
+ const ast = parse('1 + 2 * 3');
126
+ expect(ast.type).toBe(NodeType.Binary);
127
+ expect((ast as any).left.value).toBe(1);
128
+ expect((ast as any).right.type).toBe(NodeType.Binary);
129
+ expect((ast as any).right.left.value).toBe(2);
130
+ expect((ast as any).right.right.value).toBe(3);
131
+ });
132
+
133
+ it('handles parentheses', () => {
134
+ const ast = parse('(1 + 2) * 3');
135
+ expect(ast.type).toBe(NodeType.Binary);
136
+ expect((ast as any).left.type).toBe(NodeType.Binary);
137
+ expect((ast as any).left.left.value).toBe(1);
138
+ expect((ast as any).left.right.value).toBe(2);
139
+ expect((ast as any).right.value).toBe(3);
140
+ });
141
+
142
+ it('parses comparison operators', () => {
143
+ const ast = parse('age > 18');
144
+ expect(ast.type).toBe(NodeType.Binary);
145
+ expect((ast as any).left.name).toBe('age');
146
+ expect((ast as any).right.value).toBe(18);
147
+ });
148
+
149
+ it('parses logical operators', () => {
150
+ const ast = parse('true and false');
151
+ expect(ast.type).toBe(NodeType.Binary);
152
+ expect((ast as any).left.value).toBe(true);
153
+ expect((ast as any).right.value).toBe(false);
154
+ });
155
+ });
156
+
157
+ describe('unary operators', () => {
158
+ it('parses unary plus', () => {
159
+ const ast = parse('+5');
160
+ expect(ast.type).toBe(NodeType.Unary);
161
+ expect((ast as any).operand.value).toBe(5);
162
+ });
163
+
164
+ it('parses unary minus', () => {
165
+ const ast = parse('-5');
166
+ expect(ast.type).toBe(NodeType.Unary);
167
+ expect((ast as any).operand.value).toBe(5);
168
+ });
169
+ });
170
+
171
+ describe('member access', () => {
172
+ it('parses dot notation', () => {
173
+ const ast = parse('Patient.name');
174
+ expect(ast.type).toBe(NodeType.Binary);
175
+ expect((ast as any).left.name).toBe('Patient');
176
+ expect((ast as any).right.name).toBe('name');
177
+ });
178
+
179
+ it('parses chained access', () => {
180
+ const ast = parse('Patient.name.given');
181
+ expect(ast.type).toBe(NodeType.Binary);
182
+ expect((ast as any).left.type).toBe(NodeType.Binary);
183
+ expect((ast as any).left.left.name).toBe('Patient');
184
+ expect((ast as any).left.right.name).toBe('name');
185
+ expect((ast as any).right.name).toBe('given');
186
+ });
187
+ });
188
+
189
+ describe('function calls', () => {
190
+ it('parses function calls without arguments', () => {
191
+ const ast = parse('empty()');
192
+ expect(ast.type).toBe(NodeType.Function);
193
+ expect((ast as any).name.name).toBe('empty');
194
+ expect((ast as any).arguments).toHaveLength(0);
195
+ });
196
+
197
+ it('parses function calls with arguments', () => {
198
+ const ast = parse('where(active = true)');
199
+ expect(ast.type).toBe(NodeType.Function);
200
+ expect((ast as any).name.name).toBe('where');
201
+ expect((ast as any).arguments).toHaveLength(1);
202
+ expect((ast as any).arguments[0].type).toBe(NodeType.Binary);
203
+ });
204
+
205
+ it('parses function calls with multiple arguments', () => {
206
+ const ast = parse('substring(0, 5)');
207
+ expect(ast.type).toBe(NodeType.Function);
208
+ expect((ast as any).name.name).toBe('substring');
209
+ expect((ast as any).arguments).toHaveLength(2);
210
+ expect((ast as any).arguments[0].value).toBe(0);
211
+ expect((ast as any).arguments[1].value).toBe(5);
212
+ });
213
+ });
214
+
215
+ describe('indexing', () => {
216
+ it('parses indexing', () => {
217
+ const ast = parse('list[0]');
218
+ expect(ast.type).toBe(NodeType.Index);
219
+ expect((ast as any).expression.name).toBe('list');
220
+ expect((ast as any).index.value).toBe(0);
221
+ });
222
+
223
+ it('parses chained indexing', () => {
224
+ const ast = parse('matrix[0][1]');
225
+ expect(ast.type).toBe(NodeType.Index);
226
+ expect((ast as any).expression.type).toBe(NodeType.Index);
227
+ expect((ast as any).index.value).toBe(1);
228
+ });
229
+ });
230
+
231
+ describe('collections', () => {
232
+ it('parses empty collection', () => {
233
+ const ast = parse('{}');
234
+ expect(ast.type).toBe(NodeType.Collection);
235
+ expect((ast as any).elements).toHaveLength(0);
236
+ });
237
+
238
+ it('parses collection with elements', () => {
239
+ const ast = parse('{1, 2, 3}');
240
+ expect(ast.type).toBe(NodeType.Collection);
241
+ expect((ast as any).elements).toHaveLength(3);
242
+ expect((ast as any).elements[0].value).toBe(1);
243
+ expect((ast as any).elements[1].value).toBe(2);
244
+ expect((ast as any).elements[2].value).toBe(3);
245
+ });
246
+ });
247
+
248
+ describe('union operator', () => {
249
+ it('parses union operator', () => {
250
+ const ast = parse('a | b');
251
+ expect(ast.type).toBe(NodeType.Union);
252
+ expect((ast as any).operands).toHaveLength(2);
253
+ expect((ast as any).operands[0].name).toBe('a');
254
+ expect((ast as any).operands[1].name).toBe('b');
255
+ });
256
+
257
+ it('parses multiple unions', () => {
258
+ const ast = parse('a | b | c');
259
+ expect(ast.type).toBe(NodeType.Union);
260
+ expect((ast as any).operands).toHaveLength(3);
261
+ expect((ast as any).operands[0].name).toBe('a');
262
+ expect((ast as any).operands[1].name).toBe('b');
263
+ expect((ast as any).operands[2].name).toBe('c');
264
+ });
265
+ });
266
+
267
+ describe('type operations', () => {
268
+ it('parses is operator', () => {
269
+ const ast = parse('value is String');
270
+ expect(ast.type).toBe(NodeType.MembershipTest);
271
+ expect((ast as any).expression.name).toBe('value');
272
+ expect((ast as any).targetType).toBe('String');
273
+ });
274
+
275
+ it('parses as operator', () => {
276
+ const ast = parse('value as String');
277
+ expect(ast.type).toBe(NodeType.TypeCast);
278
+ expect((ast as any).expression.name).toBe('value');
279
+ expect((ast as any).targetType).toBe('String');
280
+ });
281
+ });
282
+
283
+ describe('complex expressions', () => {
284
+ it('parses method chaining with function calls', () => {
285
+ const ast = parse('Patient.name.where(use = \'official\').given');
286
+ expect(ast.type).toBe(NodeType.Binary);
287
+ expect((ast as any).right.name).toBe('given');
288
+
289
+ const whereCall = (ast as any).left;
290
+ expect(whereCall.type).toBe(NodeType.Binary);
291
+ expect(whereCall.right.type).toBe(NodeType.Function);
292
+ expect((whereCall.right as any).name.name).toBe('where');
293
+ });
294
+
295
+ it('parses complex arithmetic', () => {
296
+ const ast = parse('(age + 5) * 2 - 10');
297
+ expect(ast.type).toBe(NodeType.Binary);
298
+ // Further assertions on the structure...
299
+ });
300
+ it('parses complex arithmetic', () => {
301
+ const ast = parse('Patient.name.given.where(use = "official").given');
302
+ console.log(JSON.stringify(ast, null, 2));
303
+ });
304
+ });
305
+ });