@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,20 @@
1
+ import type { Parser } from './parser';
2
+ import { ASTNode } from '../types';
3
+ export declare function parseExpressionStatement(this: Parser): ASTNode;
4
+ export declare function parseExpressionList(this: Parser): ASTNode;
5
+ export declare function parseAssignmentOrExpression(this: Parser): ASTNode;
6
+ export declare function parseBlock(this: Parser): ASTNode[];
7
+ export declare function parseIfStatement(this: Parser): ASTNode;
8
+ export declare function parseWhileStatement(this: Parser): ASTNode;
9
+ export declare function parseForStatement(this: Parser): ASTNode;
10
+ export declare function parseFunctionParameters(this: Parser): ASTNode[];
11
+ export declare function parseFunctionDef(this: Parser, decorators?: ASTNode[]): ASTNode;
12
+ export declare function parseClassDef(this: Parser, decorators?: ASTNode[]): ASTNode;
13
+ export declare function parseDecorators(this: Parser): ASTNode[];
14
+ export declare function parseTryStatement(this: Parser): ASTNode;
15
+ export declare function parseWithStatement(this: Parser): ASTNode;
16
+ export declare function parseMatchStatement(this: Parser): ASTNode;
17
+ export declare function parseImportStatement(this: Parser): ASTNode;
18
+ export declare function parseStatement(this: Parser): ASTNode;
19
+ export declare function parseProgram(this: Parser): ASTNode;
20
+ //# sourceMappingURL=statements.d.ts.map
@@ -0,0 +1,388 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseExpressionStatement = parseExpressionStatement;
4
+ exports.parseExpressionList = parseExpressionList;
5
+ exports.parseAssignmentOrExpression = parseAssignmentOrExpression;
6
+ exports.parseBlock = parseBlock;
7
+ exports.parseIfStatement = parseIfStatement;
8
+ exports.parseWhileStatement = parseWhileStatement;
9
+ exports.parseForStatement = parseForStatement;
10
+ exports.parseFunctionParameters = parseFunctionParameters;
11
+ exports.parseFunctionDef = parseFunctionDef;
12
+ exports.parseClassDef = parseClassDef;
13
+ exports.parseDecorators = parseDecorators;
14
+ exports.parseTryStatement = parseTryStatement;
15
+ exports.parseWithStatement = parseWithStatement;
16
+ exports.parseMatchStatement = parseMatchStatement;
17
+ exports.parseImportStatement = parseImportStatement;
18
+ exports.parseStatement = parseStatement;
19
+ exports.parseProgram = parseProgram;
20
+ const types_1 = require("../types");
21
+ function parseExpressionStatement() {
22
+ return { type: types_1.ASTNodeType.EXPRESSION_STATEMENT, expression: this.parseExpression() };
23
+ }
24
+ function parseExpressionList() {
25
+ const first = this.parseExpression();
26
+ if (this.match(types_1.TokenType.COMMA)) {
27
+ const elements = [first];
28
+ while (this.match(types_1.TokenType.COMMA)) {
29
+ this.consume();
30
+ if (this.match(types_1.TokenType.NEWLINE) || this.match(types_1.TokenType.RPAREN) || this.match(types_1.TokenType.RBRACKET) || this.match(types_1.TokenType.RBRACE))
31
+ break;
32
+ elements.push(this.parseExpression());
33
+ }
34
+ return { type: types_1.ASTNodeType.TUPLE_LITERAL, elements };
35
+ }
36
+ return first;
37
+ }
38
+ function parseAssignmentOrExpression() {
39
+ const startPos = this.pos;
40
+ const target = this.parseTarget();
41
+ if (this.match(types_1.TokenType.ASSIGN)) {
42
+ this.consume();
43
+ const value = this.parseExpressionList();
44
+ return { type: types_1.ASTNodeType.ASSIGNMENT, targets: [target], value };
45
+ }
46
+ if (this.match(types_1.TokenType.OPERATOR) && ['+=', '-=', '*=', '/=', '%=', '//=', '**='].includes(this.peek()?.value || '')) {
47
+ const op = this.consume().value;
48
+ const value = this.parseExpressionList();
49
+ return { type: types_1.ASTNodeType.AUG_ASSIGNMENT, target, operator: op, value };
50
+ }
51
+ this.pos = startPos;
52
+ return this.parseExpressionStatement();
53
+ }
54
+ function parseBlock() {
55
+ this.expect(types_1.TokenType.NEWLINE);
56
+ this.expect(types_1.TokenType.INDENT);
57
+ const body = [];
58
+ while (!this.match(types_1.TokenType.DEDENT) && !this.match(types_1.TokenType.EOF)) {
59
+ const stmt = this.parseStatement();
60
+ body.push(stmt);
61
+ this.skipNewlines();
62
+ }
63
+ this.expect(types_1.TokenType.DEDENT);
64
+ return body;
65
+ }
66
+ function parseIfStatement() {
67
+ this.expect(types_1.TokenType.KEYWORD, 'if');
68
+ const test = this.parseExpression();
69
+ this.expect(types_1.TokenType.COLON);
70
+ const body = this.parseBlock();
71
+ const elifs = [];
72
+ while (this.match(types_1.TokenType.KEYWORD, 'elif')) {
73
+ this.consume();
74
+ const elifTest = this.parseExpression();
75
+ this.expect(types_1.TokenType.COLON);
76
+ const elifBody = this.parseBlock();
77
+ elifs.push({ test: elifTest, body: elifBody });
78
+ }
79
+ let orelse = [];
80
+ if (this.match(types_1.TokenType.KEYWORD, 'else')) {
81
+ this.consume();
82
+ this.expect(types_1.TokenType.COLON);
83
+ orelse = this.parseBlock();
84
+ }
85
+ return { type: types_1.ASTNodeType.IF_STATEMENT, test, body, elifs, orelse };
86
+ }
87
+ function parseWhileStatement() {
88
+ this.expect(types_1.TokenType.KEYWORD, 'while');
89
+ const test = this.parseExpression();
90
+ this.expect(types_1.TokenType.COLON);
91
+ const body = this.parseBlock();
92
+ return { type: types_1.ASTNodeType.WHILE_STATEMENT, test, body };
93
+ }
94
+ function parseForStatement() {
95
+ this.expect(types_1.TokenType.KEYWORD, 'for');
96
+ const target = this.parseTarget();
97
+ this.expect(types_1.TokenType.KEYWORD, 'in');
98
+ const iter = this.parseExpression();
99
+ this.expect(types_1.TokenType.COLON);
100
+ const body = this.parseBlock();
101
+ return { type: types_1.ASTNodeType.FOR_STATEMENT, target, iter, body };
102
+ }
103
+ function parseFunctionParameters() {
104
+ const params = [];
105
+ if (!this.match(types_1.TokenType.RPAREN)) {
106
+ while (true) {
107
+ if (this.match(types_1.TokenType.OPERATOR, '*')) {
108
+ this.consume();
109
+ const name = this.expect(types_1.TokenType.IDENTIFIER).value;
110
+ params.push({ type: 'VarArg', name });
111
+ }
112
+ else if (this.match(types_1.TokenType.OPERATOR, '**')) {
113
+ this.consume();
114
+ const name = this.expect(types_1.TokenType.IDENTIFIER).value;
115
+ params.push({ type: 'KwArg', name });
116
+ }
117
+ else if (this.match(types_1.TokenType.IDENTIFIER)) {
118
+ const name = this.consume().value;
119
+ let defaultValue = null;
120
+ if (this.match(types_1.TokenType.ASSIGN)) {
121
+ this.consume();
122
+ defaultValue = this.parseExpression();
123
+ }
124
+ params.push({ type: 'Param', name, defaultValue });
125
+ }
126
+ if (!this.match(types_1.TokenType.COMMA))
127
+ break;
128
+ this.consume();
129
+ if (this.match(types_1.TokenType.RPAREN))
130
+ break;
131
+ }
132
+ }
133
+ return params;
134
+ }
135
+ function parseFunctionDef(decorators = []) {
136
+ this.expect(types_1.TokenType.KEYWORD, 'def');
137
+ const name = this.expect(types_1.TokenType.IDENTIFIER).value;
138
+ this.expect(types_1.TokenType.LPAREN);
139
+ const params = this.parseFunctionParameters();
140
+ this.expect(types_1.TokenType.RPAREN);
141
+ this.expect(types_1.TokenType.COLON);
142
+ const body = this.parseBlock();
143
+ return { type: types_1.ASTNodeType.FUNCTION_DEF, name, params, body, decorators };
144
+ }
145
+ function parseClassDef(decorators = []) {
146
+ this.expect(types_1.TokenType.KEYWORD, 'class');
147
+ const name = this.expect(types_1.TokenType.IDENTIFIER).value;
148
+ let bases = [];
149
+ if (this.match(types_1.TokenType.LPAREN)) {
150
+ this.consume();
151
+ if (!this.match(types_1.TokenType.RPAREN)) {
152
+ bases.push(this.parseExpression());
153
+ while (this.match(types_1.TokenType.COMMA)) {
154
+ this.consume();
155
+ if (this.match(types_1.TokenType.RPAREN))
156
+ break;
157
+ bases.push(this.parseExpression());
158
+ }
159
+ }
160
+ this.expect(types_1.TokenType.RPAREN);
161
+ }
162
+ this.expect(types_1.TokenType.COLON);
163
+ const body = this.parseBlock();
164
+ return { type: types_1.ASTNodeType.CLASS_DEF, name, bases, body, decorators };
165
+ }
166
+ function parseDecorators() {
167
+ const decorators = [];
168
+ while (this.match(types_1.TokenType.AT)) {
169
+ this.consume();
170
+ const decorator = this.parseExpression();
171
+ decorators.push(decorator);
172
+ this.expect(types_1.TokenType.NEWLINE);
173
+ }
174
+ return decorators;
175
+ }
176
+ function parseTryStatement() {
177
+ this.expect(types_1.TokenType.KEYWORD, 'try');
178
+ this.expect(types_1.TokenType.COLON);
179
+ const body = this.parseBlock();
180
+ const handlers = [];
181
+ while (this.match(types_1.TokenType.KEYWORD, 'except')) {
182
+ this.consume();
183
+ let exceptionType = null;
184
+ let name = null;
185
+ if (!this.match(types_1.TokenType.COLON)) {
186
+ exceptionType = this.parseExpression();
187
+ if (this.match(types_1.TokenType.KEYWORD, 'as')) {
188
+ this.consume();
189
+ name = this.expect(types_1.TokenType.IDENTIFIER).value;
190
+ }
191
+ }
192
+ this.expect(types_1.TokenType.COLON);
193
+ const handlerBody = this.parseBlock();
194
+ handlers.push({ exceptionType, name, body: handlerBody });
195
+ }
196
+ let orelse = [];
197
+ if (this.match(types_1.TokenType.KEYWORD, 'else')) {
198
+ this.consume();
199
+ this.expect(types_1.TokenType.COLON);
200
+ orelse = this.parseBlock();
201
+ }
202
+ let finalbody = [];
203
+ if (this.match(types_1.TokenType.KEYWORD, 'finally')) {
204
+ this.consume();
205
+ this.expect(types_1.TokenType.COLON);
206
+ finalbody = this.parseBlock();
207
+ }
208
+ return { type: types_1.ASTNodeType.TRY_STATEMENT, body, handlers, orelse, finalbody };
209
+ }
210
+ function parseWithStatement() {
211
+ this.expect(types_1.TokenType.KEYWORD, 'with');
212
+ const items = [];
213
+ while (true) {
214
+ const context = this.parseExpression();
215
+ let target = null;
216
+ if (this.match(types_1.TokenType.KEYWORD, 'as')) {
217
+ this.consume();
218
+ target = this.parseTarget();
219
+ }
220
+ items.push({ context, target });
221
+ if (!this.match(types_1.TokenType.COMMA))
222
+ break;
223
+ this.consume();
224
+ }
225
+ this.expect(types_1.TokenType.COLON);
226
+ const body = this.parseBlock();
227
+ return { type: types_1.ASTNodeType.WITH_STATEMENT, items, body };
228
+ }
229
+ function parseMatchStatement() {
230
+ this.expect(types_1.TokenType.KEYWORD, 'match');
231
+ const subject = this.parseExpression();
232
+ this.expect(types_1.TokenType.COLON);
233
+ this.expect(types_1.TokenType.NEWLINE);
234
+ this.expect(types_1.TokenType.INDENT);
235
+ const cases = [];
236
+ while (!this.match(types_1.TokenType.DEDENT) && !this.match(types_1.TokenType.EOF)) {
237
+ this.expect(types_1.TokenType.KEYWORD, 'case');
238
+ const pattern = this.parsePattern();
239
+ let guard = null;
240
+ if (this.match(types_1.TokenType.KEYWORD, 'if')) {
241
+ this.consume();
242
+ guard = this.parseExpression();
243
+ }
244
+ this.expect(types_1.TokenType.COLON);
245
+ const body = this.parseBlock();
246
+ cases.push({ pattern, guard, body });
247
+ }
248
+ this.expect(types_1.TokenType.DEDENT);
249
+ return { type: types_1.ASTNodeType.MATCH_STATEMENT, subject, cases };
250
+ }
251
+ function parseImportStatement() {
252
+ this.expect(types_1.TokenType.KEYWORD, 'import');
253
+ const names = [];
254
+ const parseName = () => {
255
+ let name = this.expect(types_1.TokenType.IDENTIFIER).value;
256
+ while (this.match(types_1.TokenType.DOT)) {
257
+ this.consume();
258
+ name += `.${this.expect(types_1.TokenType.IDENTIFIER).value}`;
259
+ }
260
+ let alias = null;
261
+ if (this.match(types_1.TokenType.KEYWORD, 'as')) {
262
+ this.consume();
263
+ alias = this.expect(types_1.TokenType.IDENTIFIER).value;
264
+ }
265
+ names.push({ name, alias });
266
+ };
267
+ parseName();
268
+ while (this.match(types_1.TokenType.COMMA)) {
269
+ this.consume();
270
+ parseName();
271
+ }
272
+ return { type: types_1.ASTNodeType.IMPORT_STATEMENT, names };
273
+ }
274
+ function parseStatement() {
275
+ this.skipNewlines();
276
+ if (this.match(types_1.TokenType.AT)) {
277
+ const decorators = this.parseDecorators();
278
+ if (this.match(types_1.TokenType.KEYWORD, 'async')) {
279
+ this.consume();
280
+ if (!this.match(types_1.TokenType.KEYWORD, 'def'))
281
+ throw new Error('async must be followed by def');
282
+ const node = this.parseFunctionDef(decorators);
283
+ node.isAsync = true;
284
+ return node;
285
+ }
286
+ if (this.match(types_1.TokenType.KEYWORD, 'def'))
287
+ return this.parseFunctionDef(decorators);
288
+ if (this.match(types_1.TokenType.KEYWORD, 'class'))
289
+ return this.parseClassDef(decorators);
290
+ throw new Error('Decorator must be followed by def or class');
291
+ }
292
+ if (this.match(types_1.TokenType.KEYWORD, 'async')) {
293
+ this.consume();
294
+ if (!this.match(types_1.TokenType.KEYWORD, 'def'))
295
+ throw new Error('async must be followed by def');
296
+ const node = this.parseFunctionDef();
297
+ node.isAsync = true;
298
+ return node;
299
+ }
300
+ if (this.match(types_1.TokenType.KEYWORD, 'import'))
301
+ return this.parseImportStatement();
302
+ if (this.match(types_1.TokenType.KEYWORD, 'def'))
303
+ return this.parseFunctionDef();
304
+ if (this.match(types_1.TokenType.KEYWORD, 'class'))
305
+ return this.parseClassDef();
306
+ if (this.match(types_1.TokenType.KEYWORD, 'if'))
307
+ return this.parseIfStatement();
308
+ if (this.match(types_1.TokenType.KEYWORD, 'for'))
309
+ return this.parseForStatement();
310
+ if (this.match(types_1.TokenType.KEYWORD, 'while'))
311
+ return this.parseWhileStatement();
312
+ if (this.match(types_1.TokenType.KEYWORD, 'try'))
313
+ return this.parseTryStatement();
314
+ if (this.match(types_1.TokenType.KEYWORD, 'with'))
315
+ return this.parseWithStatement();
316
+ if (this.match(types_1.TokenType.KEYWORD, 'match'))
317
+ return this.parseMatchStatement();
318
+ if (this.match(types_1.TokenType.KEYWORD, 'return')) {
319
+ this.consume();
320
+ const value = this.match(types_1.TokenType.NEWLINE) ? null : this.parseExpressionList();
321
+ return { type: types_1.ASTNodeType.RETURN_STATEMENT, value };
322
+ }
323
+ if (this.match(types_1.TokenType.KEYWORD, 'break')) {
324
+ this.consume();
325
+ return { type: types_1.ASTNodeType.BREAK_STATEMENT };
326
+ }
327
+ if (this.match(types_1.TokenType.KEYWORD, 'continue')) {
328
+ this.consume();
329
+ return { type: types_1.ASTNodeType.CONTINUE_STATEMENT };
330
+ }
331
+ if (this.match(types_1.TokenType.KEYWORD, 'pass')) {
332
+ this.consume();
333
+ return { type: types_1.ASTNodeType.PASS_STATEMENT };
334
+ }
335
+ if (this.match(types_1.TokenType.KEYWORD, 'assert')) {
336
+ this.consume();
337
+ const test = this.parseExpression();
338
+ let message = null;
339
+ if (this.match(types_1.TokenType.COMMA)) {
340
+ this.consume();
341
+ message = this.parseExpression();
342
+ }
343
+ return { type: types_1.ASTNodeType.ASSERT_STATEMENT, test, message };
344
+ }
345
+ if (this.match(types_1.TokenType.KEYWORD, 'raise')) {
346
+ this.consume();
347
+ const exc = this.match(types_1.TokenType.NEWLINE) ? null : this.parseExpression();
348
+ return { type: types_1.ASTNodeType.RAISE_STATEMENT, exception: exc };
349
+ }
350
+ if (this.match(types_1.TokenType.KEYWORD, 'global')) {
351
+ this.consume();
352
+ const names = [];
353
+ names.push(this.expect(types_1.TokenType.IDENTIFIER).value);
354
+ while (this.match(types_1.TokenType.COMMA)) {
355
+ this.consume();
356
+ names.push(this.expect(types_1.TokenType.IDENTIFIER).value);
357
+ }
358
+ return { type: types_1.ASTNodeType.GLOBAL_STATEMENT, names };
359
+ }
360
+ if (this.match(types_1.TokenType.KEYWORD, 'nonlocal')) {
361
+ this.consume();
362
+ const names = [];
363
+ names.push(this.expect(types_1.TokenType.IDENTIFIER).value);
364
+ while (this.match(types_1.TokenType.COMMA)) {
365
+ this.consume();
366
+ names.push(this.expect(types_1.TokenType.IDENTIFIER).value);
367
+ }
368
+ return { type: types_1.ASTNodeType.NONLOCAL_STATEMENT, names };
369
+ }
370
+ if (this.match(types_1.TokenType.KEYWORD, 'del')) {
371
+ this.consume();
372
+ const target = this.parseExpression();
373
+ return { type: types_1.ASTNodeType.DELETE_STATEMENT, target };
374
+ }
375
+ return this.parseAssignmentOrExpression();
376
+ }
377
+ function parseProgram() {
378
+ const body = [];
379
+ this.skipNewlines();
380
+ while (this.pos < this.tokens.length && !this.match(types_1.TokenType.EOF)) {
381
+ const stmt = this.parseStatement();
382
+ body.push(stmt);
383
+ this.skipNewlines();
384
+ }
385
+ this.expect(types_1.TokenType.EOF);
386
+ return { type: types_1.ASTNodeType.PROGRAM, body };
387
+ }
388
+ //# sourceMappingURL=statements.js.map
@@ -0,0 +1,6 @@
1
+ import type { Parser } from './parser';
2
+ import { ASTNode } from '../types';
3
+ export declare function parsePostfixTarget(this: Parser): ASTNode;
4
+ export declare function parseTargetElement(this: Parser): ASTNode;
5
+ export declare function parseTarget(this: Parser): ASTNode;
6
+ //# sourceMappingURL=targets.d.ts.map
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parsePostfixTarget = parsePostfixTarget;
4
+ exports.parseTargetElement = parseTargetElement;
5
+ exports.parseTarget = parseTarget;
6
+ const types_1 = require("../types");
7
+ function parsePostfixTarget() {
8
+ let expr = this.parseAtom();
9
+ while (this.match(types_1.TokenType.LBRACKET) ||
10
+ (this.match(types_1.TokenType.DOT) && this.peek(1)?.type === types_1.TokenType.IDENTIFIER)) {
11
+ if (this.match(types_1.TokenType.LBRACKET)) {
12
+ this.consume();
13
+ const index = this.parseSlice();
14
+ this.expect(types_1.TokenType.RBRACKET);
15
+ expr = { type: types_1.ASTNodeType.SUBSCRIPT, object: expr, index };
16
+ }
17
+ else if (this.match(types_1.TokenType.DOT)) {
18
+ this.consume();
19
+ const name = this.expect(types_1.TokenType.IDENTIFIER).value;
20
+ expr = { type: types_1.ASTNodeType.ATTRIBUTE, object: expr, name };
21
+ }
22
+ }
23
+ return expr;
24
+ }
25
+ function parseTargetElement() {
26
+ if (this.match(types_1.TokenType.OPERATOR, '*')) {
27
+ this.consume();
28
+ const target = this.parseTargetElement();
29
+ return { type: types_1.ASTNodeType.STARRED, target };
30
+ }
31
+ if (this.match(types_1.TokenType.IDENTIFIER))
32
+ return this.parsePostfixTarget();
33
+ if (this.match(types_1.TokenType.LPAREN)) {
34
+ this.consume();
35
+ const target = this.parseTarget();
36
+ this.expect(types_1.TokenType.RPAREN);
37
+ return target;
38
+ }
39
+ if (this.match(types_1.TokenType.LBRACKET)) {
40
+ this.consume();
41
+ const elements = [];
42
+ if (!this.match(types_1.TokenType.RBRACKET)) {
43
+ elements.push(this.parseTarget());
44
+ while (this.match(types_1.TokenType.COMMA)) {
45
+ this.consume();
46
+ if (this.match(types_1.TokenType.RBRACKET))
47
+ break;
48
+ elements.push(this.parseTarget());
49
+ }
50
+ }
51
+ this.expect(types_1.TokenType.RBRACKET);
52
+ return { type: types_1.ASTNodeType.LIST_LITERAL, elements };
53
+ }
54
+ return this.parsePostfixTarget();
55
+ }
56
+ function parseTarget() {
57
+ if (this.match(types_1.TokenType.OPERATOR, '*')) {
58
+ this.consume();
59
+ const target = this.parseTargetElement();
60
+ return { type: types_1.ASTNodeType.STARRED, target };
61
+ }
62
+ const first = this.parseTargetElement();
63
+ if (this.match(types_1.TokenType.COMMA)) {
64
+ const elements = [first];
65
+ while (this.match(types_1.TokenType.COMMA)) {
66
+ this.consume();
67
+ if (this.match(types_1.TokenType.NEWLINE) || this.match(types_1.TokenType.EOF))
68
+ break;
69
+ elements.push(this.parseTargetElement());
70
+ }
71
+ return { type: types_1.ASTNodeType.TUPLE_LITERAL, elements };
72
+ }
73
+ return first;
74
+ }
75
+ //# sourceMappingURL=targets.js.map
@@ -0,0 +1,63 @@
1
+ /**
2
+ * AST 节点类型定义
3
+ */
4
+ export interface ASTNode {
5
+ type: string;
6
+ [key: string]: any;
7
+ }
8
+ export declare enum ASTNodeType {
9
+ PROGRAM = "Program",
10
+ ASSIGNMENT = "Assignment",
11
+ AUG_ASSIGNMENT = "AugAssignment",
12
+ EXPRESSION_STATEMENT = "ExpressionStatement",
13
+ IF_STATEMENT = "IfStatement",
14
+ WHILE_STATEMENT = "WhileStatement",
15
+ FOR_STATEMENT = "ForStatement",
16
+ FUNCTION_DEF = "FunctionDef",
17
+ RETURN_STATEMENT = "ReturnStatement",
18
+ BREAK_STATEMENT = "BreakStatement",
19
+ CONTINUE_STATEMENT = "ContinueStatement",
20
+ PASS_STATEMENT = "PassStatement",
21
+ IMPORT_STATEMENT = "ImportStatement",
22
+ CLASS_DEF = "ClassDef",
23
+ TRY_STATEMENT = "TryStatement",
24
+ WITH_STATEMENT = "WithStatement",
25
+ ASSERT_STATEMENT = "AssertStatement",
26
+ RAISE_STATEMENT = "RaiseStatement",
27
+ GLOBAL_STATEMENT = "GlobalStatement",
28
+ NONLOCAL_STATEMENT = "NonlocalStatement",
29
+ DELETE_STATEMENT = "DeleteStatement",
30
+ MATCH_STATEMENT = "MatchStatement",
31
+ MATCH_CASE = "MatchCase",
32
+ MATCH_PATTERN_VALUE = "MatchPatternValue",
33
+ MATCH_PATTERN_CAPTURE = "MatchPatternCapture",
34
+ MATCH_PATTERN_WILDCARD = "MatchPatternWildcard",
35
+ MATCH_PATTERN_OR = "MatchPatternOr",
36
+ MATCH_PATTERN_SEQUENCE = "MatchPatternSequence",
37
+ BINARY_OPERATION = "BinaryOperation",
38
+ UNARY_OPERATION = "UnaryOperation",
39
+ NUMBER_LITERAL = "NumberLiteral",
40
+ STRING_LITERAL = "StringLiteral",
41
+ BOOLEAN_LITERAL = "BooleanLiteral",
42
+ NONE_LITERAL = "NoneLiteral",
43
+ LIST_LITERAL = "ListLiteral",
44
+ TUPLE_LITERAL = "TupleLiteral",
45
+ DICT_LITERAL = "DictLiteral",
46
+ SET_LITERAL = "SetLiteral",
47
+ IDENTIFIER = "Identifier",
48
+ ATTRIBUTE = "Attribute",
49
+ SUBSCRIPT = "Subscript",
50
+ SLICE = "Slice",
51
+ CALL = "Call",
52
+ COMPARE = "Compare",
53
+ BOOL_OPERATION = "BoolOperation",
54
+ IF_EXPRESSION = "IfExpression",
55
+ LAMBDA = "Lambda",
56
+ LIST_COMP = "ListComp",
57
+ DICT_COMP = "DictComp",
58
+ SET_COMP = "SetComp",
59
+ GENERATOR_EXPR = "GeneratorExpr",
60
+ YIELD = "Yield",
61
+ STARRED = "Starred"
62
+ }
63
+ //# sourceMappingURL=ast.d.ts.map
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ASTNodeType = void 0;
4
+ var ASTNodeType;
5
+ (function (ASTNodeType) {
6
+ ASTNodeType["PROGRAM"] = "Program";
7
+ ASTNodeType["ASSIGNMENT"] = "Assignment";
8
+ ASTNodeType["AUG_ASSIGNMENT"] = "AugAssignment";
9
+ ASTNodeType["EXPRESSION_STATEMENT"] = "ExpressionStatement";
10
+ ASTNodeType["IF_STATEMENT"] = "IfStatement";
11
+ ASTNodeType["WHILE_STATEMENT"] = "WhileStatement";
12
+ ASTNodeType["FOR_STATEMENT"] = "ForStatement";
13
+ ASTNodeType["FUNCTION_DEF"] = "FunctionDef";
14
+ ASTNodeType["RETURN_STATEMENT"] = "ReturnStatement";
15
+ ASTNodeType["BREAK_STATEMENT"] = "BreakStatement";
16
+ ASTNodeType["CONTINUE_STATEMENT"] = "ContinueStatement";
17
+ ASTNodeType["PASS_STATEMENT"] = "PassStatement";
18
+ ASTNodeType["IMPORT_STATEMENT"] = "ImportStatement";
19
+ ASTNodeType["CLASS_DEF"] = "ClassDef";
20
+ ASTNodeType["TRY_STATEMENT"] = "TryStatement";
21
+ ASTNodeType["WITH_STATEMENT"] = "WithStatement";
22
+ ASTNodeType["ASSERT_STATEMENT"] = "AssertStatement";
23
+ ASTNodeType["RAISE_STATEMENT"] = "RaiseStatement";
24
+ ASTNodeType["GLOBAL_STATEMENT"] = "GlobalStatement";
25
+ ASTNodeType["NONLOCAL_STATEMENT"] = "NonlocalStatement";
26
+ ASTNodeType["DELETE_STATEMENT"] = "DeleteStatement";
27
+ ASTNodeType["MATCH_STATEMENT"] = "MatchStatement";
28
+ ASTNodeType["MATCH_CASE"] = "MatchCase";
29
+ ASTNodeType["MATCH_PATTERN_VALUE"] = "MatchPatternValue";
30
+ ASTNodeType["MATCH_PATTERN_CAPTURE"] = "MatchPatternCapture";
31
+ ASTNodeType["MATCH_PATTERN_WILDCARD"] = "MatchPatternWildcard";
32
+ ASTNodeType["MATCH_PATTERN_OR"] = "MatchPatternOr";
33
+ ASTNodeType["MATCH_PATTERN_SEQUENCE"] = "MatchPatternSequence";
34
+ ASTNodeType["BINARY_OPERATION"] = "BinaryOperation";
35
+ ASTNodeType["UNARY_OPERATION"] = "UnaryOperation";
36
+ ASTNodeType["NUMBER_LITERAL"] = "NumberLiteral";
37
+ ASTNodeType["STRING_LITERAL"] = "StringLiteral";
38
+ ASTNodeType["BOOLEAN_LITERAL"] = "BooleanLiteral";
39
+ ASTNodeType["NONE_LITERAL"] = "NoneLiteral";
40
+ ASTNodeType["LIST_LITERAL"] = "ListLiteral";
41
+ ASTNodeType["TUPLE_LITERAL"] = "TupleLiteral";
42
+ ASTNodeType["DICT_LITERAL"] = "DictLiteral";
43
+ ASTNodeType["SET_LITERAL"] = "SetLiteral";
44
+ ASTNodeType["IDENTIFIER"] = "Identifier";
45
+ ASTNodeType["ATTRIBUTE"] = "Attribute";
46
+ ASTNodeType["SUBSCRIPT"] = "Subscript";
47
+ ASTNodeType["SLICE"] = "Slice";
48
+ ASTNodeType["CALL"] = "Call";
49
+ ASTNodeType["COMPARE"] = "Compare";
50
+ ASTNodeType["BOOL_OPERATION"] = "BoolOperation";
51
+ ASTNodeType["IF_EXPRESSION"] = "IfExpression";
52
+ ASTNodeType["LAMBDA"] = "Lambda";
53
+ ASTNodeType["LIST_COMP"] = "ListComp";
54
+ ASTNodeType["DICT_COMP"] = "DictComp";
55
+ ASTNodeType["SET_COMP"] = "SetComp";
56
+ ASTNodeType["GENERATOR_EXPR"] = "GeneratorExpr";
57
+ ASTNodeType["YIELD"] = "Yield";
58
+ ASTNodeType["STARRED"] = "Starred";
59
+ })(ASTNodeType || (exports.ASTNodeType = ASTNodeType = {}));
60
+ //# sourceMappingURL=ast.js.map
@@ -0,0 +1,38 @@
1
+ /**
2
+ * 字节码类型定义
3
+ */
4
+ export interface ByteCode {
5
+ instructions: Instruction[];
6
+ constants: any[];
7
+ names: string[];
8
+ ast?: any;
9
+ }
10
+ export interface Instruction {
11
+ opcode: OpCode;
12
+ arg?: number;
13
+ }
14
+ export declare enum OpCode {
15
+ LOAD_CONST = 0,
16
+ LOAD_NAME = 1,
17
+ STORE_NAME = 2,
18
+ BINARY_ADD = 3,
19
+ BINARY_SUBTRACT = 4,
20
+ BINARY_MULTIPLY = 5,
21
+ BINARY_DIVIDE = 6,
22
+ BINARY_MODULO = 7,
23
+ BINARY_POWER = 8,
24
+ COMPARE_EQ = 9,
25
+ COMPARE_NE = 10,
26
+ COMPARE_LT = 11,
27
+ COMPARE_GT = 12,
28
+ COMPARE_LE = 13,
29
+ COMPARE_GE = 14,
30
+ LOGICAL_AND = 15,
31
+ LOGICAL_OR = 16,
32
+ LOGICAL_NOT = 17,
33
+ CALL_FUNCTION = 18,
34
+ RETURN_VALUE = 19,
35
+ PRINT_ITEM = 20,
36
+ PRINT_NEWLINE = 21
37
+ }
38
+ //# sourceMappingURL=bytecode.d.ts.map