@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,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTruthy = isTruthy;
4
+ const runtime_types_1 = require("./runtime-types");
5
+ const value_utils_1 = require("./value-utils");
6
+ function isTruthy(value, scope) {
7
+ if (value === null || value === undefined)
8
+ return false;
9
+ if (value instanceof Number)
10
+ return value.valueOf() !== 0;
11
+ if (typeof value === 'boolean')
12
+ return value;
13
+ if (typeof value === 'number')
14
+ return value !== 0;
15
+ if (typeof value === 'bigint')
16
+ return value !== 0n;
17
+ if (typeof value === 'string')
18
+ return value.length > 0;
19
+ if (Array.isArray(value))
20
+ return value.length > 0;
21
+ if (value instanceof runtime_types_1.PyDict)
22
+ return value.size > 0;
23
+ if (value instanceof Set)
24
+ return value.size > 0;
25
+ if (value instanceof runtime_types_1.PyInstance) {
26
+ const boolAttr = this.findClassAttribute(value.klass, '__bool__');
27
+ if (boolAttr !== undefined) {
28
+ const bound = this.getAttribute(value, '__bool__', scope);
29
+ const result = typeof bound === 'function' ? bound() : bound;
30
+ if (typeof result !== 'boolean') {
31
+ throw new runtime_types_1.PyException('TypeError', '__bool__ should return bool');
32
+ }
33
+ return result;
34
+ }
35
+ const lenAttr = this.findClassAttribute(value.klass, '__len__');
36
+ if (lenAttr !== undefined) {
37
+ const bound = this.getAttribute(value, '__len__', scope);
38
+ const result = typeof bound === 'function' ? bound() : bound;
39
+ if (!(0, value_utils_1.isNumericLike)(result)) {
40
+ throw new runtime_types_1.PyException('TypeError', '__len__ should return int');
41
+ }
42
+ return (0, value_utils_1.toNumber)(result) !== 0;
43
+ }
44
+ }
45
+ return true;
46
+ }
47
+ //# sourceMappingURL=truthy.js.map
@@ -0,0 +1,28 @@
1
+ export declare const isPyNone: (value: any) => boolean;
2
+ export declare const isBigInt: (value: any) => value is bigint;
3
+ export declare const isIntObject: (value: any) => boolean;
4
+ export declare const isFloatObject: (value: any) => boolean;
5
+ export declare const isFloatLike: (value: any) => boolean;
6
+ export declare const isIntLike: (value: any) => boolean;
7
+ export declare const isNumericLike: (value: any) => boolean;
8
+ export declare const toNumber: (value: any) => number;
9
+ export declare const toBigIntValue: (value: any) => bigint;
10
+ export declare const shouldUseBigInt: (left: any, right: any) => boolean;
11
+ export declare const numericEquals: (left: any, right: any) => boolean;
12
+ export declare const numericCompare: (left: any, right: any) => {
13
+ kind: "float" | "int";
14
+ left: number | bigint;
15
+ right: number | bigint;
16
+ } | null;
17
+ export declare const bigIntFloorDiv: (left: bigint, right: bigint) => bigint;
18
+ export declare const pyTypeName: (value: any) => string;
19
+ export declare const pyRepr: (value: any) => string;
20
+ export declare const pyStr: (value: any) => string;
21
+ export declare const isComplex: (value: any) => any;
22
+ export declare const toComplex: (value: any) => any;
23
+ export declare const pythonModulo: (left: any, right: any) => number | bigint | Number;
24
+ export declare const parseStringToken: (tokenValue: string) => {
25
+ value: string;
26
+ isFString: boolean;
27
+ };
28
+ //# sourceMappingURL=value-utils.d.ts.map
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseStringToken = exports.pythonModulo = exports.toComplex = exports.isComplex = exports.pyStr = exports.pyRepr = exports.pyTypeName = exports.bigIntFloorDiv = exports.numericCompare = exports.numericEquals = exports.shouldUseBigInt = exports.toBigIntValue = exports.toNumber = exports.isNumericLike = exports.isIntLike = exports.isFloatLike = exports.isFloatObject = exports.isIntObject = exports.isBigInt = exports.isPyNone = void 0;
4
+ const runtime_types_1 = require("./runtime-types");
5
+ const isPyNone = (value) => value === null;
6
+ exports.isPyNone = isPyNone;
7
+ const isBigInt = (value) => typeof value === 'bigint';
8
+ exports.isBigInt = isBigInt;
9
+ const isIntObject = (value) => value instanceof Number && value.__int__ === true;
10
+ exports.isIntObject = isIntObject;
11
+ const isFloatObject = (value) => value instanceof Number && !(0, exports.isIntObject)(value);
12
+ exports.isFloatObject = isFloatObject;
13
+ const isFloatLike = (value) => (0, exports.isFloatObject)(value) || (typeof value === 'number' && !Number.isInteger(value));
14
+ exports.isFloatLike = isFloatLike;
15
+ const isIntLike = (value) => (0, exports.isBigInt)(value) ||
16
+ value === true ||
17
+ value === false ||
18
+ (typeof value === 'number' && Number.isInteger(value)) ||
19
+ (0, exports.isIntObject)(value);
20
+ exports.isIntLike = isIntLike;
21
+ const isNumericLike = (value) => (0, exports.isBigInt)(value) || typeof value === 'number' || value instanceof Number || typeof value === 'boolean';
22
+ exports.isNumericLike = isNumericLike;
23
+ const toNumber = (value) => {
24
+ if (value instanceof Number)
25
+ return value.valueOf();
26
+ if (typeof value === 'boolean')
27
+ return value ? 1 : 0;
28
+ if (typeof value === 'bigint')
29
+ return Number(value);
30
+ return value;
31
+ };
32
+ exports.toNumber = toNumber;
33
+ const toBigIntValue = (value) => {
34
+ if (typeof value === 'bigint')
35
+ return value;
36
+ if (value instanceof Number)
37
+ return BigInt(Math.trunc(value.valueOf()));
38
+ if (typeof value === 'number')
39
+ return BigInt(value);
40
+ return BigInt(value);
41
+ };
42
+ exports.toBigIntValue = toBigIntValue;
43
+ const shouldUseBigInt = (left, right) => ((0, exports.isBigInt)(left) || (0, exports.isBigInt)(right)) && !(0, exports.isFloatLike)(left) && !(0, exports.isFloatLike)(right);
44
+ exports.shouldUseBigInt = shouldUseBigInt;
45
+ const numericEquals = (left, right) => {
46
+ if ((0, exports.isNumericLike)(left) && (0, exports.isNumericLike)(right)) {
47
+ if ((0, exports.isFloatLike)(left) || (0, exports.isFloatLike)(right)) {
48
+ const leftNum = (0, exports.toNumber)(left);
49
+ const rightNum = (0, exports.toNumber)(right);
50
+ return !Number.isNaN(leftNum) && !Number.isNaN(rightNum) && leftNum === rightNum;
51
+ }
52
+ return (0, exports.toBigIntValue)(left) === (0, exports.toBigIntValue)(right);
53
+ }
54
+ return left === right;
55
+ };
56
+ exports.numericEquals = numericEquals;
57
+ const numericCompare = (left, right) => {
58
+ if (!(0, exports.isNumericLike)(left) || !(0, exports.isNumericLike)(right))
59
+ return null;
60
+ if ((0, exports.isFloatLike)(left) || (0, exports.isFloatLike)(right)) {
61
+ return { kind: 'float', left: (0, exports.toNumber)(left), right: (0, exports.toNumber)(right) };
62
+ }
63
+ return { kind: 'int', left: (0, exports.toBigIntValue)(left), right: (0, exports.toBigIntValue)(right) };
64
+ };
65
+ exports.numericCompare = numericCompare;
66
+ const bigIntFloorDiv = (left, right) => {
67
+ const quotient = left / right;
68
+ if (left % right === 0n)
69
+ return quotient;
70
+ if ((left < 0n) !== (right < 0n))
71
+ return quotient - 1n;
72
+ return quotient;
73
+ };
74
+ exports.bigIntFloorDiv = bigIntFloorDiv;
75
+ const pyTypeName = (value) => {
76
+ if (value === null)
77
+ return 'NoneType';
78
+ if ((0, exports.isBigInt)(value))
79
+ return 'int';
80
+ if ((0, exports.isIntObject)(value))
81
+ return 'int';
82
+ if (value instanceof Number)
83
+ return 'float';
84
+ if (typeof value === 'boolean')
85
+ return 'bool';
86
+ if (typeof value === 'number')
87
+ return Number.isInteger(value) ? 'int' : 'float';
88
+ if (typeof value === 'string')
89
+ return 'str';
90
+ if (Array.isArray(value))
91
+ return value.__tuple__ ? 'tuple' : 'list';
92
+ if (value instanceof Set)
93
+ return 'set';
94
+ if (value instanceof runtime_types_1.PyDict)
95
+ return 'dict';
96
+ if (value instanceof runtime_types_1.PyFunction)
97
+ return 'function';
98
+ if (value instanceof runtime_types_1.PyClass)
99
+ return 'type';
100
+ if (value instanceof runtime_types_1.PyInstance)
101
+ return value.klass.name;
102
+ return typeof value;
103
+ };
104
+ exports.pyTypeName = pyTypeName;
105
+ const pyRepr = (value) => {
106
+ if (value === null)
107
+ return 'None';
108
+ if (value instanceof Number) {
109
+ const num = value.valueOf();
110
+ if (Number.isNaN(num))
111
+ return 'nan';
112
+ if (num === Infinity)
113
+ return 'inf';
114
+ if (num === -Infinity)
115
+ return '-inf';
116
+ if ((0, exports.isIntObject)(value))
117
+ return String(num);
118
+ if (Object.is(num, -0))
119
+ return '-0.0';
120
+ return Number.isInteger(num) ? `${num}.0` : String(num);
121
+ }
122
+ if (typeof value === 'boolean')
123
+ return value ? 'True' : 'False';
124
+ if (typeof value === 'number')
125
+ return Number.isNaN(value) ? 'nan' : String(value);
126
+ if (typeof value === 'bigint')
127
+ return value.toString();
128
+ if (value && value.__complex__) {
129
+ const sign = value.im >= 0 ? '+' : '-';
130
+ const imag = Math.abs(value.im);
131
+ return `(${value.re}${sign}${imag}j)`;
132
+ }
133
+ if (typeof value === 'string')
134
+ return `'${value.replace(/'/g, "\\'")}'`;
135
+ if (Array.isArray(value)) {
136
+ const items = value.map((v) => (0, exports.pyRepr)(v)).join(', ');
137
+ if (value.__tuple__) {
138
+ if (value.length === 1)
139
+ return `(${items},)`;
140
+ return `(${items})`;
141
+ }
142
+ return `[${items}]`;
143
+ }
144
+ if (value instanceof Set) {
145
+ const items = Array.from(value.values()).map((v) => (0, exports.pyRepr)(v)).join(', ');
146
+ return `{${items}}`;
147
+ }
148
+ if (value instanceof runtime_types_1.PyDict) {
149
+ const items = Array.from(value.entries()).map(([k, v]) => `${(0, exports.pyRepr)(k)}: ${(0, exports.pyRepr)(v)}`).join(', ');
150
+ return `{${items}}`;
151
+ }
152
+ if (value instanceof runtime_types_1.PyFunction)
153
+ return `<function ${value.name}>`;
154
+ if (value instanceof runtime_types_1.PyClass)
155
+ return `<class '${value.name}'>`;
156
+ if (value instanceof runtime_types_1.PyInstance)
157
+ return `<${value.klass.name} object>`;
158
+ return String(value);
159
+ };
160
+ exports.pyRepr = pyRepr;
161
+ const pyStr = (value) => {
162
+ if (typeof value === 'string')
163
+ return value;
164
+ if (value && value.__complex__)
165
+ return (0, exports.pyRepr)(value);
166
+ if (value && value.__typeName__)
167
+ return `<class '${value.__typeName__}'>`;
168
+ if (value instanceof runtime_types_1.PyException)
169
+ return value.message;
170
+ return (0, exports.pyRepr)(value);
171
+ };
172
+ exports.pyStr = pyStr;
173
+ const isComplex = (value) => value && value.__complex__;
174
+ exports.isComplex = isComplex;
175
+ const toComplex = (value) => {
176
+ if ((0, exports.isComplex)(value))
177
+ return value;
178
+ if ((0, exports.isNumericLike)(value))
179
+ return { __complex__: true, re: (0, exports.toNumber)(value), im: 0 };
180
+ return { __complex__: true, re: 0, im: 0 };
181
+ };
182
+ exports.toComplex = toComplex;
183
+ const pythonModulo = (left, right) => {
184
+ if ((0, exports.shouldUseBigInt)(left, right)) {
185
+ const leftNum = (0, exports.toBigIntValue)(left);
186
+ const rightNum = (0, exports.toBigIntValue)(right);
187
+ if (rightNum === 0n)
188
+ throw new runtime_types_1.PyException('ZeroDivisionError', 'division by zero');
189
+ const remainder = leftNum % rightNum;
190
+ const adjust = remainder !== 0n && (leftNum < 0n) !== (rightNum < 0n);
191
+ const quotient = leftNum / rightNum - (adjust ? 1n : 0n);
192
+ return leftNum - quotient * rightNum;
193
+ }
194
+ const leftNum = (0, exports.toNumber)(left);
195
+ const rightNum = (0, exports.toNumber)(right);
196
+ if (rightNum === 0)
197
+ throw new runtime_types_1.PyException('ZeroDivisionError', 'division by zero');
198
+ const quotient = Math.floor(leftNum / rightNum);
199
+ const result = leftNum - quotient * rightNum;
200
+ if ((0, exports.isFloatObject)(left) || (0, exports.isFloatObject)(right)) {
201
+ return new Number(result);
202
+ }
203
+ return result;
204
+ };
205
+ exports.pythonModulo = pythonModulo;
206
+ const parseStringToken = (tokenValue) => {
207
+ let raw = tokenValue;
208
+ let isFString = false;
209
+ if (raw.startsWith('f') || raw.startsWith('F')) {
210
+ isFString = true;
211
+ raw = raw.slice(1);
212
+ }
213
+ const quote = raw[0];
214
+ if (raw.startsWith(quote.repeat(3))) {
215
+ const inner = raw.slice(3, -3);
216
+ return { value: inner, isFString };
217
+ }
218
+ const inner = raw.slice(1, -1);
219
+ return {
220
+ value: inner.replace(/\\n/g, '\n').replace(/\\t/g, '\t').replace(/\\"/g, '"').replace(/\\'/g, "'"),
221
+ isFString,
222
+ };
223
+ };
224
+ exports.parseStringToken = parseStringToken;
225
+ //# sourceMappingURL=value-utils.js.map
@@ -0,0 +1,56 @@
1
+ import { installBuiltins } from './builtins';
2
+ import { callFunction, containsYield, evaluateComprehension, expressionHasYield, generateComprehension } from './callable';
3
+ import { execute, executeBlock, executeBlockGenerator, executeStatementGenerator, iterableToArray, matchPattern, matchValueEquals, applyBindings } from './execution';
4
+ import { evaluateExpressionGenerator } from './expression-generator';
5
+ import { createAsyncioModule, importModule, loadModuleFromFile, resolveModulePath } from './imports';
6
+ import { applyFormatSpec, applyWidth, contains, evaluateExpression, evaluateExpressionString, executeExpressionInline, splitFormatSpec } from './expressions';
7
+ import { assignTarget, deleteTarget, executeStatement, toIterableArray } from './statements';
8
+ import { applyBinary, computeSliceBounds, computeSliceIndices, findClassAttribute, formatPercent, getAttribute, getSubscript, normalizeSliceStep, setAttribute } from './operations';
9
+ import { isTruthy } from './truthy';
10
+ export declare class VirtualMachine {
11
+ moduleCache: Map<string, any>;
12
+ moduleSearchPaths: string[];
13
+ constructor(moduleSearchPaths?: string[]);
14
+ execute: typeof execute;
15
+ installBuiltins: typeof installBuiltins;
16
+ importModule: typeof importModule;
17
+ createAsyncioModule: typeof createAsyncioModule;
18
+ loadModuleFromFile: typeof loadModuleFromFile;
19
+ resolveModulePath: typeof resolveModulePath;
20
+ executeBlock: typeof executeBlock;
21
+ iterableToArray: typeof iterableToArray;
22
+ matchValueEquals: typeof matchValueEquals;
23
+ matchPattern: typeof matchPattern;
24
+ applyBindings: typeof applyBindings;
25
+ executeBlockGenerator: typeof executeBlockGenerator;
26
+ executeStatementGenerator: typeof executeStatementGenerator;
27
+ evaluateExpressionGenerator: typeof evaluateExpressionGenerator;
28
+ executeStatement: typeof executeStatement;
29
+ assignTarget: typeof assignTarget;
30
+ toIterableArray: typeof toIterableArray;
31
+ deleteTarget: typeof deleteTarget;
32
+ evaluateExpression: typeof evaluateExpression;
33
+ evaluateExpressionString: typeof evaluateExpressionString;
34
+ executeExpressionInline: typeof executeExpressionInline;
35
+ applyFormatSpec: typeof applyFormatSpec;
36
+ splitFormatSpec: typeof splitFormatSpec;
37
+ applyWidth: typeof applyWidth;
38
+ contains: typeof contains;
39
+ isTruthy: typeof isTruthy;
40
+ applyBinary: typeof applyBinary;
41
+ formatPercent: typeof formatPercent;
42
+ getSubscript: typeof getSubscript;
43
+ computeSliceBounds: typeof computeSliceBounds;
44
+ computeSliceIndices: typeof computeSliceIndices;
45
+ normalizeSliceStep: typeof normalizeSliceStep;
46
+ getAttribute: typeof getAttribute;
47
+ setAttribute: typeof setAttribute;
48
+ findClassAttribute: typeof findClassAttribute;
49
+ callFunction: typeof callFunction;
50
+ containsYield: typeof containsYield;
51
+ evaluateComprehension: typeof evaluateComprehension;
52
+ generateComprehension: typeof generateComprehension;
53
+ expressionHasYield: typeof expressionHasYield;
54
+ }
55
+ export * from './runtime-types';
56
+ //# sourceMappingURL=vm.d.ts.map
package/dist/vm/vm.js ADDED
@@ -0,0 +1,75 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.VirtualMachine = void 0;
18
+ const builtins_1 = require("./builtins");
19
+ const callable_1 = require("./callable");
20
+ const execution_1 = require("./execution");
21
+ const expression_generator_1 = require("./expression-generator");
22
+ const imports_1 = require("./imports");
23
+ const expressions_1 = require("./expressions");
24
+ const statements_1 = require("./statements");
25
+ const operations_1 = require("./operations");
26
+ const truthy_1 = require("./truthy");
27
+ class VirtualMachine {
28
+ constructor(moduleSearchPaths = [process.cwd()]) {
29
+ this.moduleCache = new Map();
30
+ this.execute = execution_1.execute;
31
+ this.installBuiltins = builtins_1.installBuiltins;
32
+ this.importModule = imports_1.importModule;
33
+ this.createAsyncioModule = imports_1.createAsyncioModule;
34
+ this.loadModuleFromFile = imports_1.loadModuleFromFile;
35
+ this.resolveModulePath = imports_1.resolveModulePath;
36
+ this.executeBlock = execution_1.executeBlock;
37
+ this.iterableToArray = execution_1.iterableToArray;
38
+ this.matchValueEquals = execution_1.matchValueEquals;
39
+ this.matchPattern = execution_1.matchPattern;
40
+ this.applyBindings = execution_1.applyBindings;
41
+ this.executeBlockGenerator = execution_1.executeBlockGenerator;
42
+ this.executeStatementGenerator = execution_1.executeStatementGenerator;
43
+ this.evaluateExpressionGenerator = expression_generator_1.evaluateExpressionGenerator;
44
+ this.executeStatement = statements_1.executeStatement;
45
+ this.assignTarget = statements_1.assignTarget;
46
+ this.toIterableArray = statements_1.toIterableArray;
47
+ this.deleteTarget = statements_1.deleteTarget;
48
+ this.evaluateExpression = expressions_1.evaluateExpression;
49
+ this.evaluateExpressionString = expressions_1.evaluateExpressionString;
50
+ this.executeExpressionInline = expressions_1.executeExpressionInline;
51
+ this.applyFormatSpec = expressions_1.applyFormatSpec;
52
+ this.splitFormatSpec = expressions_1.splitFormatSpec;
53
+ this.applyWidth = expressions_1.applyWidth;
54
+ this.contains = expressions_1.contains;
55
+ this.isTruthy = truthy_1.isTruthy;
56
+ this.applyBinary = operations_1.applyBinary;
57
+ this.formatPercent = operations_1.formatPercent;
58
+ this.getSubscript = operations_1.getSubscript;
59
+ this.computeSliceBounds = operations_1.computeSliceBounds;
60
+ this.computeSliceIndices = operations_1.computeSliceIndices;
61
+ this.normalizeSliceStep = operations_1.normalizeSliceStep;
62
+ this.getAttribute = operations_1.getAttribute;
63
+ this.setAttribute = operations_1.setAttribute;
64
+ this.findClassAttribute = operations_1.findClassAttribute;
65
+ this.callFunction = callable_1.callFunction;
66
+ this.containsYield = callable_1.containsYield;
67
+ this.evaluateComprehension = callable_1.evaluateComprehension;
68
+ this.generateComprehension = callable_1.generateComprehension;
69
+ this.expressionHasYield = callable_1.expressionHasYield;
70
+ this.moduleSearchPaths = moduleSearchPaths;
71
+ }
72
+ }
73
+ exports.VirtualMachine = VirtualMachine;
74
+ __exportStar(require("./runtime-types"), exports);
75
+ //# sourceMappingURL=vm.js.map
@@ -0,0 +1,38 @@
1
+ # Assert 语句进行简单测试
2
+ def test_addition():
3
+ assert 2 + 2 == 4, "Addition failed"
4
+ assert 1 + 1 == 2
5
+ print("Addition tests passed")
6
+
7
+ def test_string():
8
+ assert "hello".upper() == "HELLO"
9
+ assert "hello" == "hello"
10
+ print("String tests passed")
11
+
12
+ def test_list():
13
+ lst = [1, 2, 3]
14
+ assert len(lst) == 3
15
+ assert 2 in lst
16
+ assert 4 not in lst
17
+ print("List tests passed")
18
+
19
+ def test_comparison():
20
+ assert 5 > 3
21
+ assert 2 < 5
22
+ assert 5 >= 5
23
+ print("Comparison tests passed")
24
+
25
+ # 运行测试
26
+ test_addition()
27
+ test_string()
28
+ test_list()
29
+ test_comparison()
30
+
31
+ print("\nAll tests passed!")
32
+
33
+ # 测试失败的示例
34
+ print("\nTesting failure case:")
35
+ try:
36
+ assert 1 == 2, "This assertion will fail"
37
+ except AssertionError as e:
38
+ print(f"Caught AssertionError: {e}")
@@ -0,0 +1,2 @@
1
+ # Exposes JS-number precision loss if integers are not BigInt-backed.
2
+ print(10**20 + 1 == 10**20)
@@ -0,0 +1,35 @@
1
+ # 布尔类型和逻辑运算
2
+ x = True
3
+ y = False
4
+
5
+ print("x and y:", x and y)
6
+ print("x or y:", x or y)
7
+ print("not x:", not x)
8
+
9
+ # 比较运算
10
+ a = 10
11
+ b = 20
12
+
13
+ print(f"{a} == {b}:", a == b)
14
+ print(f"{a} != {b}:", a != b)
15
+ print(f"{a} < {b}:", a < b)
16
+ print(f"{a} > {b}:", a > b)
17
+ print(f"{a} <= {b}:", a <= b)
18
+ print(f"{a} >= {b}:", a >= b)
19
+
20
+ # 链式比较
21
+ c = 15
22
+ print(f"{a} < {c} < {b}:", a < c < b)
23
+
24
+ # 成员运算符
25
+ numbers = [1, 2, 3, 4, 5]
26
+ print("3 in numbers:", 3 in numbers)
27
+ print("6 not in numbers:", 6 not in numbers)
28
+
29
+ # 布尔条件
30
+ if (x or (a < b and not y)):
31
+ print("Complex condition is true")
32
+
33
+ # 三元运算符
34
+ result = "positive" if a > 0 else "non-positive"
35
+ print(f"a is {result}")
@@ -0,0 +1,43 @@
1
+ # Break 和 Continue 语句
2
+ print("Break example:")
3
+ for i in range(10):
4
+ if i == 5:
5
+ break
6
+ print(i, end=" ")
7
+ print()
8
+
9
+ print("\nContinue example:")
10
+ for i in range(10):
11
+ if i % 2 == 0:
12
+ continue
13
+ print(i, end=" ")
14
+ print()
15
+
16
+ # 嵌套循环中的 break
17
+ print("\nNested loop with break:")
18
+ for i in range(3):
19
+ for j in range(3):
20
+ if j == 1:
21
+ break
22
+ print(f"({i}, {j})", end=" ")
23
+ print()
24
+
25
+ # While 循环中的 break 和 continue
26
+ print("\nWhile with break and continue:")
27
+ count = 0
28
+ while count < 10:
29
+ count += 1
30
+ if count == 3:
31
+ continue
32
+ if count == 8:
33
+ break
34
+ print(count, end=" ")
35
+ print()
36
+
37
+ # Pass 语句
38
+ print("\nPass statement:")
39
+ for i in range(3):
40
+ if i == 1:
41
+ pass # 占位符
42
+ else:
43
+ print(f"i = {i}")
@@ -0,0 +1,43 @@
1
+ # 类定义和对象
2
+ class Dog:
3
+ species = "Canis familiaris"
4
+
5
+ def __init__(self, name, age):
6
+ self.name = name
7
+ self.age = age
8
+
9
+ def bark(self):
10
+ return f"{self.name} says: Woof!"
11
+
12
+ def birthday(self):
13
+ self.age += 1
14
+ return f"{self.name} is now {self.age} years old"
15
+
16
+ # 创建对象
17
+ dog1 = Dog("Rex", 3)
18
+ dog2 = Dog("Buddy", 5)
19
+
20
+ print(dog1.bark())
21
+ print(dog2.bark())
22
+
23
+ # 访问属性
24
+ print(f"{dog1.name} is {dog1.age} years old")
25
+
26
+ # 调用方法
27
+ print(dog1.birthday())
28
+ print(f"Species: {dog1.species}")
29
+
30
+ # 继承
31
+ class Animal:
32
+ def __init__(self, name):
33
+ self.name = name
34
+
35
+ def speak(self):
36
+ return f"{self.name} makes a sound"
37
+
38
+ class Cat(Animal):
39
+ def speak(self):
40
+ return f"{self.name} says: Meow!"
41
+
42
+ cat = Cat("Whiskers")
43
+ print(cat.speak())
@@ -0,0 +1,6 @@
1
+ import asyncio
2
+
3
+ async def main():
4
+ return 3
5
+
6
+ print(asyncio.run(main()))
@@ -0,0 +1,3 @@
1
+ # Exploit: bool is a subclass of int; indexing should treat True as 1
2
+ arr = [10, 20]
3
+ print(arr[True])
@@ -0,0 +1,5 @@
1
+ d = {1: "int", True: "bool"}
2
+ print(len(d))
3
+ print(d[1])
4
+ print(d[True])
5
+ print(list(d.keys()))
@@ -0,0 +1,9 @@
1
+ class Trick:
2
+ def __bool__(self):
3
+ return False
4
+ def __len__(self):
5
+ return 1
6
+
7
+ t = Trick()
8
+ print(bool(t))
9
+ print("truthy" if t else "falsy")
@@ -0,0 +1,4 @@
1
+ x = -3
2
+ print(x // 2)
3
+ print(x % 2)
4
+ print((x // 2) * 2 + (x % 2))
@@ -0,0 +1,3 @@
1
+ a = int("257")
2
+ b = int("257")
3
+ print(a is b)
@@ -0,0 +1,3 @@
1
+ a = [3, 1]
2
+ print(a.sort())
3
+ print(a)
@@ -0,0 +1,13 @@
1
+ def classify(value):
2
+ match value:
3
+ case 0 | 1:
4
+ return "small"
5
+ case [a, b]:
6
+ return a + b
7
+ case _:
8
+ return "other"
9
+
10
+
11
+ print(classify([2, 3]))
12
+ print(classify(1))
13
+ print(classify("x"))
@@ -0,0 +1,3 @@
1
+ print('start')
2
+ print('a' * -1)
3
+ print('end')
@@ -0,0 +1,3 @@
1
+ # CPython preserves the sign of negative zero in float formatting.
2
+ print(-0.0)
3
+ print(float("-0.0"))
@@ -0,0 +1,4 @@
1
+ # Adversarial: Python round uses bankers rounding (ties to even)
2
+
3
+ print(round(2.5))
4
+ print(round(3.5))