@lewin671/python-vm 0.1.0

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 (144) hide show
  1. package/.claude/settings.local.json +3 -0
  2. package/.prettierrc +7 -0
  3. package/Agents.md +66 -0
  4. package/README.md +93 -0
  5. package/README_zh-CN.md +93 -0
  6. package/SETUP.md +171 -0
  7. package/dist/compiler.d.ts +20 -0
  8. package/dist/compiler.js +91 -0
  9. package/dist/compiler_module/compiler.d.ts +8 -0
  10. package/dist/compiler_module/compiler.js +22 -0
  11. package/dist/compiler_module/index.d.ts +2 -0
  12. package/dist/compiler_module/index.js +6 -0
  13. package/dist/index.d.ts +4 -0
  14. package/dist/index.js +67 -0
  15. package/dist/lexer/index.d.ts +2 -0
  16. package/dist/lexer/index.js +6 -0
  17. package/dist/lexer/lexer.d.ts +16 -0
  18. package/dist/lexer/lexer.js +403 -0
  19. package/dist/parser/expressions.d.ts +30 -0
  20. package/dist/parser/expressions.js +483 -0
  21. package/dist/parser/index.d.ts +2 -0
  22. package/dist/parser/index.js +6 -0
  23. package/dist/parser/parser.d.ts +63 -0
  24. package/dist/parser/parser.js +129 -0
  25. package/dist/parser/statements.d.ts +20 -0
  26. package/dist/parser/statements.js +388 -0
  27. package/dist/parser/targets.d.ts +6 -0
  28. package/dist/parser/targets.js +75 -0
  29. package/dist/types/ast.d.ts +63 -0
  30. package/dist/types/ast.js +60 -0
  31. package/dist/types/bytecode.d.ts +38 -0
  32. package/dist/types/bytecode.js +35 -0
  33. package/dist/types/index.d.ts +4 -0
  34. package/dist/types/index.js +20 -0
  35. package/dist/types/token.d.ts +34 -0
  36. package/dist/types/token.js +39 -0
  37. package/dist/vm/builtins.d.ts +4 -0
  38. package/dist/vm/builtins.js +269 -0
  39. package/dist/vm/callable.d.ts +8 -0
  40. package/dist/vm/callable.js +161 -0
  41. package/dist/vm/execution.d.ts +15 -0
  42. package/dist/vm/execution.js +283 -0
  43. package/dist/vm/expression-generator.d.ts +3 -0
  44. package/dist/vm/expression-generator.js +70 -0
  45. package/dist/vm/expressions.d.ts +13 -0
  46. package/dist/vm/expressions.js +390 -0
  47. package/dist/vm/imports.d.ts +7 -0
  48. package/dist/vm/imports.js +99 -0
  49. package/dist/vm/index.d.ts +3 -0
  50. package/dist/vm/index.js +21 -0
  51. package/dist/vm/operations.d.ts +16 -0
  52. package/dist/vm/operations.js +439 -0
  53. package/dist/vm/runtime-types.d.ts +84 -0
  54. package/dist/vm/runtime-types.js +290 -0
  55. package/dist/vm/statements.d.ts +7 -0
  56. package/dist/vm/statements.js +381 -0
  57. package/dist/vm/truthy.d.ts +4 -0
  58. package/dist/vm/truthy.js +47 -0
  59. package/dist/vm/value-utils.d.ts +28 -0
  60. package/dist/vm/value-utils.js +225 -0
  61. package/dist/vm/vm.d.ts +56 -0
  62. package/dist/vm/vm.js +75 -0
  63. package/examples/assert_testing.py +38 -0
  64. package/examples/big_int_precision.py +2 -0
  65. package/examples/boolean_logic.py +35 -0
  66. package/examples/break_continue.py +43 -0
  67. package/examples/classes_objects.py +43 -0
  68. package/examples/compiler_killer_async.py +6 -0
  69. package/examples/compiler_killer_bigint.py +3 -0
  70. package/examples/compiler_killer_bool_int_dict_key.py +5 -0
  71. package/examples/compiler_killer_bool_len.py +9 -0
  72. package/examples/compiler_killer_floor_division.py +4 -0
  73. package/examples/compiler_killer_is_identity.py +3 -0
  74. package/examples/compiler_killer_list_sort_return.py +3 -0
  75. package/examples/compiler_killer_match.py +13 -0
  76. package/examples/compiler_killer_negative_repeat.py +3 -0
  77. package/examples/compiler_killer_negative_zero_repr.py +3 -0
  78. package/examples/compiler_killer_rounding.py +4 -0
  79. package/examples/compiler_killer_slice_assign.py +3 -0
  80. package/examples/comprehensions.py +28 -0
  81. package/examples/conditions.py +13 -0
  82. package/examples/context_manager.py +35 -0
  83. package/examples/decorators.py +50 -0
  84. package/examples/exceptions.py +40 -0
  85. package/examples/fibonacci.py +10 -0
  86. package/examples/functions.py +38 -0
  87. package/examples/generator.py +51 -0
  88. package/examples/global_nonlocal.py +48 -0
  89. package/examples/hello.py +3 -0
  90. package/examples/itertools_example.py +33 -0
  91. package/examples/lists_dicts.py +29 -0
  92. package/examples/loops.py +19 -0
  93. package/examples/math_ops.py +15 -0
  94. package/examples/nan_set.py +6 -0
  95. package/examples/numbers_operators.py +51 -0
  96. package/examples/sets.py +36 -0
  97. package/examples/slicing.py +29 -0
  98. package/examples/starred_unpacking.py +3 -0
  99. package/examples/string_formatting.py +36 -0
  100. package/examples/strings.py +22 -0
  101. package/examples/tuples.py +45 -0
  102. package/examples/type_conversion.py +41 -0
  103. package/jest.config.js +15 -0
  104. package/notes/iterations/compiler-runtime/compiler-runtime_2025-09-16.md +25 -0
  105. package/notes/iterations/compiler-runtime/compiler-runtime_2026-01-16.md +24 -0
  106. package/notes/iterations/compiler-runtime/compiler-runtime_test_2026-01-16.md +21 -0
  107. package/notes/iterations/floor-division/floor-division_2026-01-16.md +29 -0
  108. package/package.json +36 -0
  109. package/prompts/commit.txt +9 -0
  110. package/prompts/task.txt +21 -0
  111. package/prompts/test.txt +23 -0
  112. package/scripts/codex-loop.js +215 -0
  113. package/scripts/verify.sh +12 -0
  114. package/src/compiler.ts +58 -0
  115. package/src/compiler_module/compiler.ts +19 -0
  116. package/src/compiler_module/index.ts +1 -0
  117. package/src/index.ts +39 -0
  118. package/src/lexer/index.ts +1 -0
  119. package/src/lexer/lexer.ts +402 -0
  120. package/src/parser/expressions.ts +462 -0
  121. package/src/parser/index.ts +1 -0
  122. package/src/parser/parser.ts +102 -0
  123. package/src/parser/statements.ts +366 -0
  124. package/src/parser/targets.ts +71 -0
  125. package/src/types/ast.ts +64 -0
  126. package/src/types/bytecode.ts +50 -0
  127. package/src/types/index.ts +3 -0
  128. package/src/types/token.ts +44 -0
  129. package/src/vm/builtins.ts +237 -0
  130. package/src/vm/callable.ts +154 -0
  131. package/src/vm/execution.ts +251 -0
  132. package/src/vm/expression-generator.ts +65 -0
  133. package/src/vm/expressions.ts +373 -0
  134. package/src/vm/imports.ts +61 -0
  135. package/src/vm/index.ts +2 -0
  136. package/src/vm/operations.ts +414 -0
  137. package/src/vm/runtime-types.ts +292 -0
  138. package/src/vm/statements.ts +358 -0
  139. package/src/vm/truthy.ts +36 -0
  140. package/src/vm/value-utils.ts +173 -0
  141. package/src/vm/vm.ts +80 -0
  142. package/tests/compiler.test.ts +111 -0
  143. package/tsconfig.json +20 -0
  144. package/vitest.config.ts +16 -0
@@ -0,0 +1,483 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseStringLiteral = parseStringLiteral;
4
+ exports.parseLiteral = parseLiteral;
5
+ exports.parseIdentifier = parseIdentifier;
6
+ exports.parseArguments = parseArguments;
7
+ exports.parseSlice = parseSlice;
8
+ exports.parsePatternAtom = parsePatternAtom;
9
+ exports.parsePattern = parsePattern;
10
+ exports.parseLambdaParameters = parseLambdaParameters;
11
+ exports.parseLambda = parseLambda;
12
+ exports.parseAtom = parseAtom;
13
+ exports.parsePostfix = parsePostfix;
14
+ exports.parseUnary = parseUnary;
15
+ exports.parsePower = parsePower;
16
+ exports.parseFactor = parseFactor;
17
+ exports.parseTerm = parseTerm;
18
+ exports.parseShift = parseShift;
19
+ exports.parseBitAnd = parseBitAnd;
20
+ exports.parseBitXor = parseBitXor;
21
+ exports.parseBitOr = parseBitOr;
22
+ exports.parseComparison = parseComparison;
23
+ exports.parseNot = parseNot;
24
+ exports.parseAnd = parseAnd;
25
+ exports.parseOr = parseOr;
26
+ exports.parseIfExpression = parseIfExpression;
27
+ exports.parseExpression = parseExpression;
28
+ exports.parseExpressionNoIf = parseExpressionNoIf;
29
+ exports.parseComprehension = parseComprehension;
30
+ const types_1 = require("../types");
31
+ function parseStringLiteral() {
32
+ let value = '';
33
+ while (this.match(types_1.TokenType.STRING))
34
+ value += this.consume().value;
35
+ return { type: types_1.ASTNodeType.STRING_LITERAL, value };
36
+ }
37
+ function parseLiteral() {
38
+ const token = this.peek();
39
+ if (!token)
40
+ throw new Error('Expected literal');
41
+ if (token.type === types_1.TokenType.NUMBER) {
42
+ this.consume();
43
+ return { type: types_1.ASTNodeType.NUMBER_LITERAL, value: token.value };
44
+ }
45
+ if (token.type === types_1.TokenType.STRING)
46
+ return this.parseStringLiteral();
47
+ if (token.type === types_1.TokenType.BOOLEAN) {
48
+ this.consume();
49
+ return { type: types_1.ASTNodeType.BOOLEAN_LITERAL, value: token.value === 'True' };
50
+ }
51
+ if (token.type === types_1.TokenType.NONE) {
52
+ this.consume();
53
+ return { type: types_1.ASTNodeType.NONE_LITERAL, value: null };
54
+ }
55
+ throw new Error(`Unexpected token type for literal: ${types_1.TokenType[token.type]}`);
56
+ }
57
+ function parseIdentifier() {
58
+ const token = this.expect(types_1.TokenType.IDENTIFIER);
59
+ return { type: types_1.ASTNodeType.IDENTIFIER, name: token.value };
60
+ }
61
+ function parseArguments() {
62
+ const args = [];
63
+ if (!this.match(types_1.TokenType.RPAREN)) {
64
+ while (true) {
65
+ if (this.match(types_1.TokenType.OPERATOR, '*') || this.match(types_1.TokenType.OPERATOR, '**')) {
66
+ const op = this.consume().value;
67
+ const value = this.parseExpression();
68
+ args.push({ type: op === '*' ? 'StarArg' : 'KwArg', value });
69
+ }
70
+ else if (this.match(types_1.TokenType.IDENTIFIER) && this.peek(1)?.type === types_1.TokenType.ASSIGN) {
71
+ const name = this.consume().value;
72
+ this.consume();
73
+ const value = this.parseExpression();
74
+ args.push({ type: 'KeywordArg', name, value });
75
+ }
76
+ else {
77
+ args.push(this.parseExpression());
78
+ }
79
+ if (!this.match(types_1.TokenType.COMMA))
80
+ break;
81
+ this.consume();
82
+ if (this.match(types_1.TokenType.RPAREN))
83
+ break;
84
+ }
85
+ }
86
+ return args;
87
+ }
88
+ function parseSlice() {
89
+ let start = null;
90
+ let end = null;
91
+ let step = null;
92
+ if (!this.match(types_1.TokenType.COLON))
93
+ start = this.parseExpression();
94
+ if (this.match(types_1.TokenType.COLON)) {
95
+ this.consume();
96
+ if (!this.match(types_1.TokenType.COLON) && !this.match(types_1.TokenType.RBRACKET))
97
+ end = this.parseExpression();
98
+ if (this.match(types_1.TokenType.COLON)) {
99
+ this.consume();
100
+ if (!this.match(types_1.TokenType.RBRACKET))
101
+ step = this.parseExpression();
102
+ }
103
+ return { type: types_1.ASTNodeType.SLICE, start, end, step };
104
+ }
105
+ return start;
106
+ }
107
+ function parsePatternAtom() {
108
+ if (this.match(types_1.TokenType.NUMBER) || this.match(types_1.TokenType.STRING) || this.match(types_1.TokenType.BOOLEAN) || this.match(types_1.TokenType.NONE)) {
109
+ return { type: types_1.ASTNodeType.MATCH_PATTERN_VALUE, value: this.parseLiteral() };
110
+ }
111
+ if (this.match(types_1.TokenType.IDENTIFIER)) {
112
+ const name = this.consume().value;
113
+ if (name === '_')
114
+ return { type: types_1.ASTNodeType.MATCH_PATTERN_WILDCARD };
115
+ return { type: types_1.ASTNodeType.MATCH_PATTERN_CAPTURE, name };
116
+ }
117
+ if (this.match(types_1.TokenType.LBRACKET)) {
118
+ this.consume();
119
+ const elements = [];
120
+ if (!this.match(types_1.TokenType.RBRACKET)) {
121
+ elements.push(this.parsePattern());
122
+ while (this.match(types_1.TokenType.COMMA)) {
123
+ this.consume();
124
+ if (this.match(types_1.TokenType.RBRACKET))
125
+ break;
126
+ elements.push(this.parsePattern());
127
+ }
128
+ }
129
+ this.expect(types_1.TokenType.RBRACKET);
130
+ return { type: types_1.ASTNodeType.MATCH_PATTERN_SEQUENCE, elements };
131
+ }
132
+ throw new Error(`Unexpected token in pattern: ${this.peek()?.value}`);
133
+ }
134
+ function parsePattern() {
135
+ let pattern = this.parsePatternAtom();
136
+ if (this.match(types_1.TokenType.OPERATOR, '|')) {
137
+ const patterns = [pattern];
138
+ while (this.match(types_1.TokenType.OPERATOR, '|')) {
139
+ this.consume();
140
+ patterns.push(this.parsePatternAtom());
141
+ }
142
+ pattern = { type: types_1.ASTNodeType.MATCH_PATTERN_OR, patterns };
143
+ }
144
+ return pattern;
145
+ }
146
+ function parseLambdaParameters() {
147
+ const params = [];
148
+ if (this.match(types_1.TokenType.COLON))
149
+ return params;
150
+ while (true) {
151
+ if (this.match(types_1.TokenType.OPERATOR, '*')) {
152
+ this.consume();
153
+ params.push(`*${this.expect(types_1.TokenType.IDENTIFIER).value}`);
154
+ }
155
+ else if (this.match(types_1.TokenType.OPERATOR, '**')) {
156
+ this.consume();
157
+ params.push(`**${this.expect(types_1.TokenType.IDENTIFIER).value}`);
158
+ }
159
+ else {
160
+ const name = this.expect(types_1.TokenType.IDENTIFIER).value;
161
+ if (this.match(types_1.TokenType.ASSIGN)) {
162
+ this.consume();
163
+ this.parseExpression();
164
+ }
165
+ params.push(name);
166
+ }
167
+ if (!this.match(types_1.TokenType.COMMA))
168
+ break;
169
+ this.consume();
170
+ }
171
+ return params;
172
+ }
173
+ function parseLambda() {
174
+ this.consume(); // lambda
175
+ const params = this.parseLambdaParameters();
176
+ this.expect(types_1.TokenType.COLON);
177
+ const body = this.parseExpression();
178
+ return { type: types_1.ASTNodeType.LAMBDA, params, body };
179
+ }
180
+ function parseAtom() {
181
+ if (this.match(types_1.TokenType.LPAREN)) {
182
+ this.consume();
183
+ if (this.match(types_1.TokenType.RPAREN)) {
184
+ this.consume();
185
+ return { type: types_1.ASTNodeType.TUPLE_LITERAL, elements: [] };
186
+ }
187
+ const expr = this.parseExpression();
188
+ if (this.match(types_1.TokenType.KEYWORD, 'for')) {
189
+ const comprehension = this.parseComprehension(expr);
190
+ this.expect(types_1.TokenType.RPAREN);
191
+ return { type: types_1.ASTNodeType.GENERATOR_EXPR, expression: expr, comprehension };
192
+ }
193
+ if (this.match(types_1.TokenType.COMMA)) {
194
+ const elements = [expr];
195
+ while (this.match(types_1.TokenType.COMMA)) {
196
+ this.consume();
197
+ if (this.match(types_1.TokenType.RPAREN))
198
+ break;
199
+ elements.push(this.parseExpression());
200
+ }
201
+ this.expect(types_1.TokenType.RPAREN);
202
+ return { type: types_1.ASTNodeType.TUPLE_LITERAL, elements };
203
+ }
204
+ this.expect(types_1.TokenType.RPAREN);
205
+ return expr;
206
+ }
207
+ if (this.match(types_1.TokenType.KEYWORD, 'yield')) {
208
+ this.consume();
209
+ const value = this.match(types_1.TokenType.NEWLINE) || this.match(types_1.TokenType.COMMA) || this.match(types_1.TokenType.RPAREN) ? null : this.parseExpression();
210
+ return { type: types_1.ASTNodeType.YIELD, value };
211
+ }
212
+ if (this.match(types_1.TokenType.KEYWORD, 'lambda')) {
213
+ return this.parseLambda();
214
+ }
215
+ if (this.match(types_1.TokenType.LBRACKET)) {
216
+ this.consume();
217
+ if (this.match(types_1.TokenType.RBRACKET)) {
218
+ this.consume();
219
+ return { type: types_1.ASTNodeType.LIST_LITERAL, elements: [] };
220
+ }
221
+ const first = this.parseExpression();
222
+ if (this.match(types_1.TokenType.KEYWORD, 'for')) {
223
+ const comprehension = this.parseComprehension(first);
224
+ this.expect(types_1.TokenType.RBRACKET);
225
+ return { type: types_1.ASTNodeType.LIST_COMP, expression: first, comprehension };
226
+ }
227
+ const elements = [first];
228
+ while (this.match(types_1.TokenType.COMMA)) {
229
+ this.consume();
230
+ if (this.match(types_1.TokenType.RBRACKET))
231
+ break;
232
+ elements.push(this.parseExpression());
233
+ }
234
+ this.expect(types_1.TokenType.RBRACKET);
235
+ return { type: types_1.ASTNodeType.LIST_LITERAL, elements };
236
+ }
237
+ if (this.match(types_1.TokenType.LBRACE)) {
238
+ this.consume();
239
+ if (this.match(types_1.TokenType.RBRACE)) {
240
+ this.consume();
241
+ return { type: types_1.ASTNodeType.DICT_LITERAL, entries: [] };
242
+ }
243
+ const key = this.parseExpression();
244
+ if (this.match(types_1.TokenType.COLON)) {
245
+ this.consume();
246
+ const value = this.parseExpression();
247
+ if (this.match(types_1.TokenType.KEYWORD, 'for')) {
248
+ const comprehension = this.parseComprehension({ type: 'KeyValue', key, value });
249
+ this.expect(types_1.TokenType.RBRACE);
250
+ return { type: types_1.ASTNodeType.DICT_COMP, key, value, comprehension };
251
+ }
252
+ const entries = [{ key, value }];
253
+ while (this.match(types_1.TokenType.COMMA)) {
254
+ this.consume();
255
+ if (this.match(types_1.TokenType.RBRACE))
256
+ break;
257
+ const k = this.parseExpression();
258
+ this.expect(types_1.TokenType.COLON);
259
+ const v = this.parseExpression();
260
+ entries.push({ key: k, value: v });
261
+ }
262
+ this.expect(types_1.TokenType.RBRACE);
263
+ return { type: types_1.ASTNodeType.DICT_LITERAL, entries };
264
+ }
265
+ if (this.match(types_1.TokenType.KEYWORD, 'for')) {
266
+ const comprehension = this.parseComprehension(key);
267
+ this.expect(types_1.TokenType.RBRACE);
268
+ return { type: types_1.ASTNodeType.SET_COMP, expression: key, comprehension };
269
+ }
270
+ const elements = [key];
271
+ while (this.match(types_1.TokenType.COMMA)) {
272
+ this.consume();
273
+ if (this.match(types_1.TokenType.RBRACE))
274
+ break;
275
+ elements.push(this.parseExpression());
276
+ }
277
+ this.expect(types_1.TokenType.RBRACE);
278
+ return { type: types_1.ASTNodeType.SET_LITERAL, elements };
279
+ }
280
+ if (this.match(types_1.TokenType.IDENTIFIER)) {
281
+ const name = this.consume().value;
282
+ return { type: types_1.ASTNodeType.IDENTIFIER, name };
283
+ }
284
+ return this.parseLiteral();
285
+ }
286
+ function parsePostfix() {
287
+ let expr = this.parseAtom();
288
+ while (this.match(types_1.TokenType.LPAREN) ||
289
+ this.match(types_1.TokenType.LBRACKET) ||
290
+ (this.match(types_1.TokenType.DOT) && this.peek(1)?.type === types_1.TokenType.IDENTIFIER)) {
291
+ if (this.match(types_1.TokenType.LPAREN)) {
292
+ this.consume();
293
+ const args = this.parseArguments();
294
+ this.expect(types_1.TokenType.RPAREN);
295
+ expr = { type: types_1.ASTNodeType.CALL, callee: expr, args };
296
+ }
297
+ else if (this.match(types_1.TokenType.LBRACKET)) {
298
+ this.consume();
299
+ const index = this.parseSlice();
300
+ this.expect(types_1.TokenType.RBRACKET);
301
+ expr = { type: types_1.ASTNodeType.SUBSCRIPT, object: expr, index };
302
+ }
303
+ else if (this.match(types_1.TokenType.DOT)) {
304
+ this.consume();
305
+ const name = this.expect(types_1.TokenType.IDENTIFIER).value;
306
+ expr = { type: types_1.ASTNodeType.ATTRIBUTE, object: expr, name };
307
+ }
308
+ }
309
+ return expr;
310
+ }
311
+ function parseUnary() {
312
+ if (this.match(types_1.TokenType.OPERATOR, '+') || this.match(types_1.TokenType.OPERATOR, '-') || this.match(types_1.TokenType.OPERATOR, '~')) {
313
+ const operator = this.consume().value;
314
+ const operand = this.parseUnary();
315
+ return { type: types_1.ASTNodeType.UNARY_OPERATION, operator, operand };
316
+ }
317
+ if (this.match(types_1.TokenType.KEYWORD) && this.peek()?.value === 'not') {
318
+ this.consume();
319
+ const operand = this.parseUnary();
320
+ return { type: types_1.ASTNodeType.UNARY_OPERATION, operator: 'not', operand };
321
+ }
322
+ return this.parsePostfix();
323
+ }
324
+ function parsePower() {
325
+ let left = this.parseUnary();
326
+ if (this.match(types_1.TokenType.OPERATOR, '**')) {
327
+ this.consume();
328
+ const right = this.parsePower();
329
+ left = { type: types_1.ASTNodeType.BINARY_OPERATION, operator: '**', left, right };
330
+ }
331
+ return left;
332
+ }
333
+ function parseFactor() {
334
+ let left = this.parsePower();
335
+ while (this.match(types_1.TokenType.OPERATOR, '*') || this.match(types_1.TokenType.OPERATOR, '/') || this.match(types_1.TokenType.OPERATOR, '//') || this.match(types_1.TokenType.OPERATOR, '%')) {
336
+ const operator = this.consume().value;
337
+ const right = this.parsePower();
338
+ left = { type: types_1.ASTNodeType.BINARY_OPERATION, operator, left, right };
339
+ }
340
+ return left;
341
+ }
342
+ function parseTerm() {
343
+ let left = this.parseFactor();
344
+ while (this.match(types_1.TokenType.OPERATOR, '+') || this.match(types_1.TokenType.OPERATOR, '-')) {
345
+ const operator = this.consume().value;
346
+ const right = this.parseFactor();
347
+ left = { type: types_1.ASTNodeType.BINARY_OPERATION, operator, left, right };
348
+ }
349
+ return left;
350
+ }
351
+ function parseShift() {
352
+ let left = this.parseTerm();
353
+ while (this.match(types_1.TokenType.OPERATOR, '<<') || this.match(types_1.TokenType.OPERATOR, '>>')) {
354
+ const operator = this.consume().value;
355
+ const right = this.parseTerm();
356
+ left = { type: types_1.ASTNodeType.BINARY_OPERATION, operator, left, right };
357
+ }
358
+ return left;
359
+ }
360
+ function parseBitAnd() {
361
+ let left = this.parseShift();
362
+ while (this.match(types_1.TokenType.OPERATOR, '&')) {
363
+ this.consume();
364
+ const right = this.parseShift();
365
+ left = { type: types_1.ASTNodeType.BINARY_OPERATION, operator: '&', left, right };
366
+ }
367
+ return left;
368
+ }
369
+ function parseBitXor() {
370
+ let left = this.parseBitAnd();
371
+ while (this.match(types_1.TokenType.OPERATOR, '^')) {
372
+ this.consume();
373
+ const right = this.parseBitAnd();
374
+ left = { type: types_1.ASTNodeType.BINARY_OPERATION, operator: '^', left, right };
375
+ }
376
+ return left;
377
+ }
378
+ function parseBitOr() {
379
+ let left = this.parseBitXor();
380
+ while (this.match(types_1.TokenType.OPERATOR, '|')) {
381
+ this.consume();
382
+ const right = this.parseBitXor();
383
+ left = { type: types_1.ASTNodeType.BINARY_OPERATION, operator: '|', left, right };
384
+ }
385
+ return left;
386
+ }
387
+ function parseComparison() {
388
+ let left = this.parseBitOr();
389
+ const operators = [];
390
+ const comparators = [];
391
+ while (true) {
392
+ if (this.match(types_1.TokenType.KEYWORD, 'not') && this.peek(1)?.type === types_1.TokenType.KEYWORD && this.peek(1)?.value === 'in') {
393
+ this.consume();
394
+ this.consume();
395
+ operators.push('not in');
396
+ comparators.push(this.parseBitOr());
397
+ continue;
398
+ }
399
+ if (this.match(types_1.TokenType.KEYWORD, 'is') && this.peek(1)?.type === types_1.TokenType.KEYWORD && this.peek(1)?.value === 'not') {
400
+ this.consume();
401
+ this.consume();
402
+ operators.push('is not');
403
+ comparators.push(this.parseBitOr());
404
+ continue;
405
+ }
406
+ if (this.match(types_1.TokenType.OPERATOR, '==') ||
407
+ this.match(types_1.TokenType.OPERATOR, '!=') ||
408
+ this.match(types_1.TokenType.OPERATOR, '<') ||
409
+ this.match(types_1.TokenType.OPERATOR, '>') ||
410
+ this.match(types_1.TokenType.OPERATOR, '<=') ||
411
+ this.match(types_1.TokenType.OPERATOR, '>=') ||
412
+ this.match(types_1.TokenType.KEYWORD, 'in') ||
413
+ this.match(types_1.TokenType.KEYWORD, 'is')) {
414
+ operators.push(this.consume().value);
415
+ comparators.push(this.parseBitOr());
416
+ continue;
417
+ }
418
+ break;
419
+ }
420
+ if (operators.length === 0)
421
+ return left;
422
+ return { type: types_1.ASTNodeType.COMPARE, left, ops: operators, comparators };
423
+ }
424
+ function parseNot() {
425
+ if (this.match(types_1.TokenType.KEYWORD, 'not')) {
426
+ this.consume();
427
+ const operand = this.parseNot();
428
+ return { type: types_1.ASTNodeType.UNARY_OPERATION, operator: 'not', operand };
429
+ }
430
+ return this.parseComparison();
431
+ }
432
+ function parseAnd() {
433
+ let left = this.parseNot();
434
+ while (this.match(types_1.TokenType.KEYWORD, 'and')) {
435
+ this.consume();
436
+ const right = this.parseNot();
437
+ left = { type: types_1.ASTNodeType.BOOL_OPERATION, operator: 'and', values: [left, right] };
438
+ }
439
+ return left;
440
+ }
441
+ function parseOr() {
442
+ let left = this.parseAnd();
443
+ while (this.match(types_1.TokenType.KEYWORD, 'or')) {
444
+ this.consume();
445
+ const right = this.parseAnd();
446
+ left = { type: types_1.ASTNodeType.BOOL_OPERATION, operator: 'or', values: [left, right] };
447
+ }
448
+ return left;
449
+ }
450
+ function parseIfExpression() {
451
+ const expr = this.parseOr();
452
+ if (this.match(types_1.TokenType.KEYWORD, 'if')) {
453
+ this.consume();
454
+ const test = this.parseOr();
455
+ this.expect(types_1.TokenType.KEYWORD, 'else');
456
+ const alternate = this.parseIfExpression();
457
+ return { type: types_1.ASTNodeType.IF_EXPRESSION, test, consequent: expr, alternate };
458
+ }
459
+ return expr;
460
+ }
461
+ function parseExpression() {
462
+ return this.parseIfExpression();
463
+ }
464
+ function parseExpressionNoIf() {
465
+ return this.parseOr();
466
+ }
467
+ function parseComprehension(expression) {
468
+ const clauses = [];
469
+ while (this.match(types_1.TokenType.KEYWORD, 'for')) {
470
+ this.consume();
471
+ const target = this.parseTarget();
472
+ this.expect(types_1.TokenType.KEYWORD, 'in');
473
+ const iter = this.parseExpressionNoIf();
474
+ const ifs = [];
475
+ while (this.match(types_1.TokenType.KEYWORD, 'if')) {
476
+ this.consume();
477
+ ifs.push(this.parseExpression());
478
+ }
479
+ clauses.push({ target, iter, ifs });
480
+ }
481
+ return { clauses, expression };
482
+ }
483
+ //# sourceMappingURL=expressions.js.map
@@ -0,0 +1,2 @@
1
+ export { Parser } from './parser';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Parser = void 0;
4
+ var parser_1 = require("./parser");
5
+ Object.defineProperty(exports, "Parser", { enumerable: true, get: function () { return parser_1.Parser; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,63 @@
1
+ import { Token, TokenType, ASTNode } from '../types';
2
+ import * as Expr from './expressions';
3
+ import * as Target from './targets';
4
+ import * as Stmt from './statements';
5
+ export declare class Parser {
6
+ tokens: Token[];
7
+ pos: number;
8
+ constructor(tokens: Token[]);
9
+ peek(offset?: number): Token | null;
10
+ consume(): Token;
11
+ match(type: TokenType, value?: string): boolean;
12
+ expect(type: TokenType, value?: string): Token;
13
+ skipNewlines(): void;
14
+ parseStringLiteral: typeof Expr.parseStringLiteral;
15
+ parseLiteral: typeof Expr.parseLiteral;
16
+ parseIdentifier: typeof Expr.parseIdentifier;
17
+ parseArguments: typeof Expr.parseArguments;
18
+ parseSlice: typeof Expr.parseSlice;
19
+ parsePatternAtom: typeof Expr.parsePatternAtom;
20
+ parsePattern: typeof Expr.parsePattern;
21
+ parseLambdaParameters: typeof Expr.parseLambdaParameters;
22
+ parseLambda: typeof Expr.parseLambda;
23
+ parseAtom: typeof Expr.parseAtom;
24
+ parsePostfix: typeof Expr.parsePostfix;
25
+ parsePostfixTarget: typeof Target.parsePostfixTarget;
26
+ parseTargetElement: typeof Target.parseTargetElement;
27
+ parseTarget: typeof Target.parseTarget;
28
+ parseUnary: typeof Expr.parseUnary;
29
+ parsePower: typeof Expr.parsePower;
30
+ parseFactor: typeof Expr.parseFactor;
31
+ parseTerm: typeof Expr.parseTerm;
32
+ parseShift: typeof Expr.parseShift;
33
+ parseBitAnd: typeof Expr.parseBitAnd;
34
+ parseBitXor: typeof Expr.parseBitXor;
35
+ parseBitOr: typeof Expr.parseBitOr;
36
+ parseComparison: typeof Expr.parseComparison;
37
+ parseNot: typeof Expr.parseNot;
38
+ parseAnd: typeof Expr.parseAnd;
39
+ parseOr: typeof Expr.parseOr;
40
+ parseIfExpression: typeof Expr.parseIfExpression;
41
+ parseExpression: typeof Expr.parseExpression;
42
+ parseExpressionNoIf: typeof Expr.parseExpressionNoIf;
43
+ parseComprehension: typeof Expr.parseComprehension;
44
+ parseExpressionStatement: typeof Stmt.parseExpressionStatement;
45
+ parseExpressionList: typeof Stmt.parseExpressionList;
46
+ parseAssignmentOrExpression: typeof Stmt.parseAssignmentOrExpression;
47
+ parseBlock: typeof Stmt.parseBlock;
48
+ parseIfStatement: typeof Stmt.parseIfStatement;
49
+ parseWhileStatement: typeof Stmt.parseWhileStatement;
50
+ parseForStatement: typeof Stmt.parseForStatement;
51
+ parseFunctionParameters: typeof Stmt.parseFunctionParameters;
52
+ parseFunctionDef: typeof Stmt.parseFunctionDef;
53
+ parseClassDef: typeof Stmt.parseClassDef;
54
+ parseDecorators: typeof Stmt.parseDecorators;
55
+ parseTryStatement: typeof Stmt.parseTryStatement;
56
+ parseWithStatement: typeof Stmt.parseWithStatement;
57
+ parseMatchStatement: typeof Stmt.parseMatchStatement;
58
+ parseImportStatement: typeof Stmt.parseImportStatement;
59
+ parseStatement: typeof Stmt.parseStatement;
60
+ parseProgram: typeof Stmt.parseProgram;
61
+ parse(): ASTNode;
62
+ }
63
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Parser = void 0;
37
+ const types_1 = require("../types");
38
+ const Expr = __importStar(require("./expressions"));
39
+ const Target = __importStar(require("./targets"));
40
+ const Stmt = __importStar(require("./statements"));
41
+ class Parser {
42
+ constructor(tokens) {
43
+ this.pos = 0;
44
+ // Expression parsing
45
+ this.parseStringLiteral = Expr.parseStringLiteral;
46
+ this.parseLiteral = Expr.parseLiteral;
47
+ this.parseIdentifier = Expr.parseIdentifier;
48
+ this.parseArguments = Expr.parseArguments;
49
+ this.parseSlice = Expr.parseSlice;
50
+ this.parsePatternAtom = Expr.parsePatternAtom;
51
+ this.parsePattern = Expr.parsePattern;
52
+ this.parseLambdaParameters = Expr.parseLambdaParameters;
53
+ this.parseLambda = Expr.parseLambda;
54
+ this.parseAtom = Expr.parseAtom;
55
+ this.parsePostfix = Expr.parsePostfix;
56
+ this.parsePostfixTarget = Target.parsePostfixTarget;
57
+ this.parseTargetElement = Target.parseTargetElement;
58
+ this.parseTarget = Target.parseTarget;
59
+ this.parseUnary = Expr.parseUnary;
60
+ this.parsePower = Expr.parsePower;
61
+ this.parseFactor = Expr.parseFactor;
62
+ this.parseTerm = Expr.parseTerm;
63
+ this.parseShift = Expr.parseShift;
64
+ this.parseBitAnd = Expr.parseBitAnd;
65
+ this.parseBitXor = Expr.parseBitXor;
66
+ this.parseBitOr = Expr.parseBitOr;
67
+ this.parseComparison = Expr.parseComparison;
68
+ this.parseNot = Expr.parseNot;
69
+ this.parseAnd = Expr.parseAnd;
70
+ this.parseOr = Expr.parseOr;
71
+ this.parseIfExpression = Expr.parseIfExpression;
72
+ this.parseExpression = Expr.parseExpression;
73
+ this.parseExpressionNoIf = Expr.parseExpressionNoIf;
74
+ this.parseComprehension = Expr.parseComprehension;
75
+ // Statement parsing
76
+ this.parseExpressionStatement = Stmt.parseExpressionStatement;
77
+ this.parseExpressionList = Stmt.parseExpressionList;
78
+ this.parseAssignmentOrExpression = Stmt.parseAssignmentOrExpression;
79
+ this.parseBlock = Stmt.parseBlock;
80
+ this.parseIfStatement = Stmt.parseIfStatement;
81
+ this.parseWhileStatement = Stmt.parseWhileStatement;
82
+ this.parseForStatement = Stmt.parseForStatement;
83
+ this.parseFunctionParameters = Stmt.parseFunctionParameters;
84
+ this.parseFunctionDef = Stmt.parseFunctionDef;
85
+ this.parseClassDef = Stmt.parseClassDef;
86
+ this.parseDecorators = Stmt.parseDecorators;
87
+ this.parseTryStatement = Stmt.parseTryStatement;
88
+ this.parseWithStatement = Stmt.parseWithStatement;
89
+ this.parseMatchStatement = Stmt.parseMatchStatement;
90
+ this.parseImportStatement = Stmt.parseImportStatement;
91
+ this.parseStatement = Stmt.parseStatement;
92
+ this.parseProgram = Stmt.parseProgram;
93
+ this.tokens = tokens;
94
+ }
95
+ peek(offset = 0) {
96
+ return this.pos + offset < this.tokens.length ? this.tokens[this.pos + offset] : null;
97
+ }
98
+ consume() {
99
+ if (this.pos >= this.tokens.length)
100
+ throw new Error('Unexpected end of input');
101
+ return this.tokens[this.pos++];
102
+ }
103
+ match(type, value) {
104
+ const token = this.peek();
105
+ return !!token && token.type === type && (value === undefined || token.value === value);
106
+ }
107
+ expect(type, value) {
108
+ const token = this.peek();
109
+ if (!token)
110
+ throw new Error(`Expected ${types_1.TokenType[type]}${value ? ` \"${value}\"` : ''}, but got end of input`);
111
+ if (token.type !== type) {
112
+ throw new Error(`Expected ${types_1.TokenType[type]}${value ? ` \"${value}\"` : ''}, but got ${types_1.TokenType[token.type]} \"${token.value}\" at line ${token.line}`);
113
+ }
114
+ if (value !== undefined && token.value !== value) {
115
+ throw new Error(`Expected \"${value}\", but got \"${token.value}\" at line ${token.line}`);
116
+ }
117
+ return this.consume();
118
+ }
119
+ skipNewlines() {
120
+ while (this.match(types_1.TokenType.NEWLINE)) {
121
+ this.consume();
122
+ }
123
+ }
124
+ parse() {
125
+ return this.parseProgram();
126
+ }
127
+ }
128
+ exports.Parser = Parser;
129
+ //# sourceMappingURL=parser.js.map