@lewin671/python-vm 0.1.0 → 0.1.2

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