@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,25 +0,0 @@
1
- # compiler-runtime: Negative repeat handling
2
-
3
- - Date: 2025-09-16
4
- - Stage: test
5
- - Status: resolved
6
-
7
- ## Problem / Symptom
8
-
9
- RangeError: Invalid count value: -1 during binary * on strings/lists.
10
-
11
- ## Impact / Risk
12
-
13
- Example execution fails when Python code repeats strings or lists with a negative count.
14
-
15
- ## Current Understanding
16
-
17
- JavaScript String.repeat/Array(length) throw for negative counts, but Python returns empty sequences.
18
-
19
- ## Next Steps
20
-
21
- Keep repeat behavior aligned with Python for other edge cases (e.g., non-integer counts).
22
-
23
- ## Evidence (optional)
24
-
25
- - Tests: `scripts/verify.sh`
@@ -1,24 +0,0 @@
1
- # compiler-runtime: Starred assignment unpacking
2
-
3
- - Date: 2026-01-16
4
- - Stage: test
5
- - Status: resolved
6
-
7
- ## Problem / Symptom
8
-
9
- Tests failed parsing assignment targets with starred unpacking (e.g., `a, *middle, b = values`) and raised "Unexpected token in expression: *".
10
-
11
- ## Impact / Risk
12
-
13
- Example files using starred unpacking could not be parsed or executed, blocking `scripts/verify.sh`.
14
-
15
- ## Current Understanding
16
-
17
- Parser did not allow `*` in assignment targets and VM assignment logic only handled fixed-length tuple/list destructuring. Added a STARRED AST node for targets, parsed it in assignment targets, and implemented unpacking logic in the VM with iterable normalization.
18
-
19
- ## Next Steps
20
-
21
- None. Re-run verify if adding more starred assignment cases.
22
-
23
- ## Evidence (optional)
24
- - Tests: `scripts/verify.sh`
@@ -1,21 +0,0 @@
1
- # compiler-runtime: starred unpacking parse failure
2
-
3
- - Date: 2026-01-16
4
- - Stage: test
5
- - Status: open
6
-
7
- ## Problem / Symptom
8
- Parser throws "Unexpected token in expression: *" when encountering starred assignment unpacking.
9
-
10
- ## Impact / Risk
11
- Example files using starred unpacking cause the compiler test suite to fail.
12
-
13
- ## Current Understanding
14
- CPython accepts `a, *middle, b = [1,2,3,4,5]`, but the TypeScript parser rejects `*` in assignment targets.
15
-
16
- ## Next Steps
17
- Add starred assignment target support or document it as unsupported and exclude such examples.
18
-
19
- ## Evidence (optional)
20
- - Tests: `./scripts/verify.sh`
21
- - Logs: tests/compiler.test.ts reports "Unexpected token in expression: *"
@@ -1,29 +0,0 @@
1
- # floor-division: Python modulo semantics for negatives
2
-
3
- - Date: 2026-01-16
4
- - Stage: test
5
- - Status: resolved
6
-
7
- ## Problem / Symptom
8
-
9
- Floor-division example failed recomposition: `x = -3` produced `x % 2 == -1` and `(x // 2) * 2 + (x % 2) == -5`.
10
-
11
- ## Impact / Risk
12
-
13
- Modulo on negative operands followed JavaScript remainder semantics, breaking Python identity `a == (a // b) * b + (a % b)`.
14
-
15
- ## Current Understanding
16
-
17
- Python defines `%` using floor division: `a - floor(a / b) * b`. VM `%` used `left % right` and needed to align with Python semantics, including float operand handling.
18
-
19
- ## Next Steps
20
-
21
- None.
22
-
23
- ## Related Iterations (optional)
24
- - Linked issues from other stages:
25
-
26
- ## Evidence (optional)
27
- - Logs:
28
- - Tests: `scripts/verify.sh`
29
- - Diffs/Commits:
@@ -1,9 +0,0 @@
1
- Write a concise git commit message for the changes.
2
- Commit only the current changes in the working tree. After committing, ensure `git status` is clean.
3
- Format:
4
- <type>: <summary>
5
-
6
- Rules:
7
- - Use imperative mood.
8
- - Keep summary under 72 characters.
9
- - Pick a sensible type (feat, fix, chore, refactor, test, docs).
package/prompts/task.txt DELETED
@@ -1,21 +0,0 @@
1
- You are working in this repository to implement a Python compiler in TypeScript.
2
- Your goal is to make `scripts/verify.sh` pass by implementing the compiler using proper compiler principles (parsing, analysis, transformation, codegen as appropriate), not shortcuts.
3
-
4
- Hard constraints:
5
- - Do NOT modify any existing files under `tests/`, `examples/`, or `scripts/`.
6
- - Do not rely on third-party compiler/transpiler libraries; implement compiler stages yourself.
7
- - Do not use shell commands, environment tricks, or config tweaks to bypass the compiler implementation tasks.
8
- - Do not stub, mock, or hardcode outputs to make tests pass without real compiler behavior.
9
- - Do not skip or short-circuit required logic (e.g., early returns that avoid work).
10
- - Do not disable, skip, or relax tests/verification (no test filters, no timeouts-as-passing).
11
- - Do not change tooling or build setup to mask failures (no rewriting scripts or test runners).
12
- - Keep changes focused and minimal; avoid unrelated refactors.
13
- - Prefer TypeScript changes in `src/` as needed.
14
- - If you add new files, keep them small and well-scoped.
15
- - Refactor the file proactively if it's too long to maintain.
16
-
17
- Process:
18
- - Inspect failures and determine the minimal fix.
19
- - If tests fail, use the error output to guide changes.
20
- - Provide a concise explanation of what you changed and why.
21
- - At the end of the task, use the persistent-notes skill to record durable project notes in `notes/iterations`.
package/prompts/test.txt DELETED
@@ -1,23 +0,0 @@
1
- **Role:** You are a **Python Adversarial Architect**. Your sole objective is to generate "Compiler-Killer" Python scripts that expose semantic discrepancies between CPython and a TypeScript-based implementation.
2
-
3
- **The Mission:**
4
- Create a Python file in `examples/` that causes `./scripts/verify.sh` to **FAIL** while maintaining perfect validity in standard Python 3.
5
-
6
- **Core Constraints:**
7
-
8
- * **Validity:** The code MUST be valid Python 3.10+ and run without errors in CPython.
9
- * **Differential Success:** The code MUST produce a different result, crash, or hang when executed via the TypeScript compiler.
10
- * **Black-Box Integrity:** Do NOT read `src/` or `tests/`. Your only inputs are the output/errors from `./scripts/verify.sh`.
11
- * **Brevity:** Keep it under 20 lines. Focus on a single, atomic edge case.
12
- * **Restricted Access:** Only modify files in the `examples/` directory.
13
-
14
- **Output Structure:**
15
-
16
- 1. **Exploit Hypothesis:** A one-sentence description of the Python semantic you are targeting.
17
- 2. **Adversarial Code:** The code block to be saved in `examples/`.
18
- 3. **Expected CPython Output:** The "correct" result.
19
- 4. **Predicted Compiler Failure:** Why you expect the TypeScript implementation to break.
20
-
21
- **Post-Task Action:**
22
-
23
- * At the end of the task, use the **persistent-notes** skill to record durable project notes in `notes/iterations`. These notes should summarize the case tested, the outcome, and what was learned for the next iteration.
@@ -1,215 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
-
4
- const fs = require("fs");
5
- const path = require("path");
6
- const os = require("os");
7
- const { spawnSync } = require("child_process");
8
-
9
- function parseArgs(argv) {
10
- const args = {
11
- maxIter: 5,
12
- testPromptPath: "prompts/test.txt",
13
- promptPath: "prompts/task.txt",
14
- commitPromptPath: "prompts/commit.txt",
15
- testCmd: "codex --dangerously-bypass-approvals-and-sandbox exec",
16
- taskCmd: "codex --dangerously-bypass-approvals-and-sandbox exec",
17
- commitCmd: "codex --dangerously-bypass-approvals-and-sandbox exec",
18
- };
19
-
20
- for (let i = 0; i < argv.length; i += 1) {
21
- const arg = argv[i];
22
- if (arg === "--max-iter") {
23
- args.maxIter = Number(argv[i + 1]);
24
- i += 1;
25
- } else if (arg === "--test-prompt") {
26
- args.testPromptPath = argv[i + 1];
27
- i += 1;
28
- } else if (arg === "--prompt") {
29
- args.promptPath = argv[i + 1];
30
- i += 1;
31
- } else if (arg === "--test-cmd") {
32
- args.testCmd = argv[i + 1];
33
- i += 1;
34
- } else if (arg === "--task-cmd") {
35
- args.taskCmd = argv[i + 1];
36
- i += 1;
37
- } else if (arg === "--commit-prompt") {
38
- args.commitPromptPath = argv[i + 1];
39
- i += 1;
40
- } else if (arg === "--commit-cmd") {
41
- args.commitCmd = argv[i + 1];
42
- i += 1;
43
- } else if (arg === "--help" || arg === "-h") {
44
- return { help: true };
45
- }
46
- }
47
-
48
- return args;
49
- }
50
-
51
- function usage() {
52
- return [
53
- "Usage: scripts/codex-loop.js [options]",
54
- "",
55
- "Options:",
56
- " --max-iter <n> Max iterations (default 5)",
57
- " --test-prompt <path> Test prompt file path (default prompts/test.txt)",
58
- " --test-cmd <cmd> Test command (default \"codex --dangerously-bypass-approvals-and-sandbox exec\")",
59
- " --prompt <path> Task prompt file path (default prompts/task.txt)",
60
- " --task-cmd <cmd> Task command (default \"codex --dangerously-bypass-approvals-and-sandbox exec\")",
61
- " --commit-prompt <path> Commit prompt file (default prompts/commit.txt)",
62
- " --commit-cmd <cmd> Commit command (default \"codex --dangerously-bypass-approvals-and-sandbox exec\")",
63
- "",
64
- "Workflow: Test Agent -> Task Agent -> Commit Agent",
65
- ].join("\n");
66
- }
67
-
68
- function runShell(cmd, opts = {}) {
69
- const result = spawnSync(cmd, {
70
- shell: true,
71
- stdio: ["pipe", "inherit", "inherit"],
72
- env: opts.env || process.env,
73
- input: opts.input || undefined,
74
- });
75
- return result.status ?? 1;
76
- }
77
-
78
- function readPrompt(promptPath) {
79
- if (!fs.existsSync(promptPath)) {
80
- throw new Error(`Prompt file not found: ${promptPath}`);
81
- }
82
- return fs.readFileSync(promptPath, "utf8");
83
- }
84
-
85
- function buildPrompt(base, testOutput) {
86
- if (!testOutput) return base;
87
- return `${base}\n\n[Test failures]\n${testOutput}`;
88
- }
89
-
90
- function runTest(testCmd, testPromptPath, log, errorLog) {
91
- log("=== PHASE: Test (Generate test cases & find issues) ===");
92
- const testPrompt = readPrompt(testPromptPath);
93
- const testStatus = runShell(testCmd, { input: testPrompt });
94
-
95
- if (testStatus !== 0) {
96
- errorLog(`✗ Test agent failed (exit ${testStatus}).`);
97
- return false;
98
- }
99
-
100
- log("✓ Test agent completed - issues identified.");
101
- return true;
102
- }
103
-
104
- function runTask(taskCmd, taskPromptPath, testOutput, log, errorLog) {
105
- log("=== PHASE: Task ===");
106
- const basePrompt = readPrompt(taskPromptPath);
107
- const combinedPrompt = buildPrompt(basePrompt, testOutput);
108
- const taskStatus = runShell(taskCmd, { input: combinedPrompt });
109
-
110
- if (taskStatus !== 0) {
111
- errorLog(`✗ Task command failed (exit ${taskStatus}).`);
112
- return false;
113
- }
114
-
115
- log("✓ Task completed successfully.");
116
- return true;
117
- }
118
-
119
- function runCommit(commitCmd, commitPromptPath, gitDir, cwd, log, errorLog) {
120
- log("=== PHASE: Commit ===");
121
- const commitPrompt = readPrompt(path.resolve(commitPromptPath));
122
- const commitStatus = runShell(commitCmd, { input: commitPrompt });
123
-
124
- if (commitStatus !== 0) {
125
- errorLog(`✗ Commit command failed (exit ${commitStatus}).`);
126
- return false;
127
- }
128
-
129
- log("✓ Commit completed successfully.");
130
- return true;
131
- }
132
-
133
- function main() {
134
- const args = parseArgs(process.argv.slice(2));
135
- if (args.help) {
136
- console.log(usage());
137
- process.exit(0);
138
- }
139
- if (!Number.isFinite(args.maxIter) || args.maxIter < 1) {
140
- console.error("Invalid --max-iter value.");
141
- process.exit(1);
142
- }
143
-
144
- let lastTestOutput = "";
145
- const promptPath = path.resolve(args.promptPath);
146
- const cwd = process.cwd();
147
- const gitDir = path.resolve(cwd, ".git");
148
-
149
- // Initialize logging
150
- const now = new Date();
151
- const dateStr = now.toISOString().replace(/[:.]/g, "-").slice(0, -5);
152
- const logFile = path.join(os.tmpdir(), `codex-loop-${dateStr}.log`);
153
-
154
- console.log(`Logging to ${logFile}`);
155
- const log = (message) => {
156
- console.log(message);
157
- fs.appendFileSync(logFile, `${message}\n`, "utf8");
158
- };
159
-
160
- const errorLog = (message) => {
161
- console.error(message);
162
- fs.appendFileSync(logFile, `[ERROR] ${message}\n`, "utf8");
163
- };
164
-
165
- for (let i = 1; i <= args.maxIter; i += 1) {
166
- log(`\n========== Iteration ${i}/${args.maxIter} ==========`);
167
-
168
- // STEP 1: Test (AI Agent generates test cases and identifies issues)
169
- const testSuccess = runTest(
170
- args.testCmd,
171
- path.resolve(args.testPromptPath),
172
- log,
173
- errorLog
174
- );
175
- if (!testSuccess) {
176
- errorLog("Test agent execution failed. Exiting.");
177
- process.exit(1);
178
- }
179
-
180
- // STEP 2: Task (AI Agent fixes issues)
181
- const taskSuccess = runTask(
182
- args.taskCmd,
183
- promptPath,
184
- "",
185
- log,
186
- errorLog
187
- );
188
- if (!taskSuccess) {
189
- errorLog("Task execution failed. Exiting.");
190
- process.exit(1);
191
- }
192
-
193
- // STEP 3: Commit
194
- const commitSuccess = runCommit(
195
- args.commitCmd,
196
- path.resolve(args.commitPromptPath),
197
- gitDir,
198
- cwd,
199
- log,
200
- errorLog
201
- );
202
- if (!commitSuccess) {
203
- errorLog("Commit execution failed. Exiting.");
204
- process.exit(1);
205
- }
206
-
207
- log(`Iteration ${i} completed. Restarting test phase...\n`);
208
- }
209
-
210
- errorLog("Reached max iterations without completion.");
211
- errorLog(`Log file: ${logFile}`);
212
- process.exit(1);
213
- }
214
-
215
- main();
package/scripts/verify.sh DELETED
@@ -1,12 +0,0 @@
1
- #!/bin/bash
2
-
3
- # Script to verify the project by running tests
4
- # This script runs the test suite and can optionally generate coverage reports
5
-
6
- set -e # Exit on first error
7
-
8
- echo "🔍 Running tests..."
9
- npm test
10
-
11
- echo ""
12
- echo "✅ All tests passed!"
package/src/compiler.ts DELETED
@@ -1,58 +0,0 @@
1
- /**
2
- * Python Compiler - 主入口
3
- * 用于编译和执行 Python 代码
4
- */
5
-
6
- import { Lexer } from './lexer';
7
- import { Parser } from './parser';
8
- import { Compiler } from './compiler_module';
9
- import { VirtualMachine } from './vm';
10
- import * as path from 'path';
11
-
12
- export class PythonCompiler {
13
- /**
14
- * 编译并运行 Python 代码
15
- * @param code Python 源代码
16
- * @returns 执行结果
17
- */
18
- run(code: string): any {
19
- // 1. 词法分析
20
- const lexer = new Lexer(code);
21
- const tokens = lexer.tokenize();
22
-
23
- // 2. 语法分析
24
- const parser = new Parser(tokens);
25
- const ast = parser.parse();
26
-
27
- // 3. 编译到字节码
28
- const compiler = new Compiler();
29
- const bytecode = compiler.compile(ast);
30
-
31
- // 4. 执行字节码
32
- const vm = new VirtualMachine([process.cwd()]);
33
- const result = vm.execute(bytecode);
34
-
35
- return result;
36
- }
37
-
38
- /**
39
- * 运行 Python 文件
40
- * @param filePath 文件路径
41
- * @returns 执行结果
42
- */
43
- runFile(filePath: string): any {
44
- const fs = require('fs');
45
- const code = fs.readFileSync(filePath, 'utf-8');
46
- const lexer = new Lexer(code);
47
- const tokens = lexer.tokenize();
48
- const parser = new Parser(tokens);
49
- const ast = parser.parse();
50
- const compiler = new Compiler();
51
- const bytecode = compiler.compile(ast);
52
- const vm = new VirtualMachine([path.dirname(filePath), process.cwd()]);
53
- return vm.execute(bytecode);
54
- }
55
- }
56
-
57
- // 重新导出类型,供外部使用
58
- export * from './types';
@@ -1,19 +0,0 @@
1
- import { ASTNode, ASTNodeType, ByteCode, OpCode } from '../types';
2
-
3
- /**
4
- * 编译器 - 将 AST 编译为字节码
5
- */
6
- export class Compiler {
7
- compile(ast: ASTNode): ByteCode {
8
- if (ast.type !== ASTNodeType.PROGRAM) {
9
- throw new Error(`Expected Program node, got ${ast.type}`);
10
- }
11
-
12
- return {
13
- instructions: [],
14
- constants: [],
15
- names: [],
16
- ast
17
- };
18
- }
19
- }
@@ -1 +0,0 @@
1
- export { Compiler } from './compiler';
package/src/index.ts DELETED
@@ -1,39 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { PythonCompiler } from './compiler';
4
- import * as fs from 'fs';
5
-
6
- // 导出公共 API
7
- export { PythonCompiler };
8
-
9
- function main() {
10
- const args = process.argv.slice(2);
11
-
12
- if (args.length === 0) {
13
- console.error('Usage: python-compiler-ts <file.py>');
14
- process.exit(1);
15
- }
16
-
17
- const filePath = args[0];
18
-
19
- if (!fs.existsSync(filePath)) {
20
- console.error(`Error: File '${filePath}' not found`);
21
- process.exit(1);
22
- }
23
-
24
- const compiler = new PythonCompiler();
25
-
26
- try {
27
- const result = compiler.runFile(filePath);
28
- if (result !== undefined) {
29
- console.log(result);
30
- }
31
- } catch (error) {
32
- console.error('Error:', error instanceof Error ? error.message : error);
33
- process.exit(1);
34
- }
35
- }
36
-
37
- if (require.main === module) {
38
- main();
39
- }
@@ -1 +0,0 @@
1
- export { Lexer } from './lexer';