codecin 5.7.4__tar.gz → 5.8.2__tar.gz
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.
- {codecin-5.7.4 → codecin-5.8.2}/CHANGELOG.md +257 -2
- {codecin-5.7.4/codecin.egg-info → codecin-5.8.2}/PKG-INFO +10 -10
- {codecin-5.7.4 → codecin-5.8.2}/README.md +9 -9
- {codecin-5.7.4 → codecin-5.8.2}/codecin/__init__.py +1 -1
- {codecin-5.7.4 → codecin-5.8.2}/codecin/aot.py +3 -2
- {codecin-5.7.4 → codecin-5.8.2}/codecin/cin.py +53 -7
- {codecin-5.7.4 → codecin-5.8.2}/codecin/cli.py +75 -3
- {codecin-5.7.4 → codecin-5.8.2}/codecin/config.py +4 -2
- {codecin-5.7.4 → codecin-5.8.2}/codecin/cpu.py +54 -7
- {codecin-5.7.4 → codecin-5.8.2}/codecin/disasm.py +2 -2
- codecin-5.8.2/codecin/environment.py +176 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/isa.py +28 -0
- codecin-5.8.2/codecin/lib/cppstd.cin +418 -0
- codecin-5.8.2/codecin/lib/cstd.cin +424 -0
- codecin-5.8.2/codecin/lib/gostd.cin +415 -0
- codecin-5.8.2/codecin/lib/gui.cin +206 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/key.cin +26 -2
- {codecin-5.7.4 → codecin-5.8.2}/codecin/memory.py +6 -1
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/aot/aot.go +4 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/compiler/codegen.go +57 -2
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/compiler/syscalls.go +21 -0
- codecin-5.8.2/codecin/native/engine/args.go +37 -0
- codecin-5.8.2/codecin/native/engine/audio.go +402 -0
- codecin-5.8.2/codecin/native/engine/audio_other.go +105 -0
- codecin-5.8.2/codecin/native/engine/audio_test.go +279 -0
- codecin-5.8.2/codecin/native/engine/audio_windows.go +190 -0
- codecin-5.8.2/codecin/native/engine/console_other.go +9 -0
- codecin-5.8.2/codecin/native/engine/console_windows.go +43 -0
- codecin-5.8.2/codecin/native/engine/gui.go +178 -0
- codecin-5.8.2/codecin/native/engine/gui_stub.go +11 -0
- codecin-5.8.2/codecin/native/engine/gui_test.go +148 -0
- codecin-5.8.2/codecin/native/engine/gui_windows.go +426 -0
- codecin-5.8.2/codecin/native/engine/gui_x11.go +721 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/isa_gen.go +21 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/keyboard.go +165 -11
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/keyboard_other.go +3 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/keyboard_stub.go +3 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/keyboard_test.go +53 -26
- codecin-5.8.2/codecin/native/engine/keyboard_windows.go +196 -0
- codecin-5.8.2/codecin/native/engine/keyboard_windows_test.go +97 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/mem_other.go +0 -2
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/mem_windows.go +0 -2
- codecin-5.8.2/codecin/native/engine/stdin.go +66 -0
- codecin-5.8.2/codecin/native/engine/stdin_other.go +9 -0
- codecin-5.8.2/codecin/native/engine/stdin_windows.go +60 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/system.go +0 -3
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/version_gen.go +1 -1
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/vm.go +155 -47
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/main.go +21 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native.py +17 -1
- codecin-5.8.2/codecin/stdlib.py +123 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/version.py +1 -1
- {codecin-5.7.4 → codecin-5.8.2/codecin.egg-info}/PKG-INFO +10 -10
- {codecin-5.7.4 → codecin-5.8.2}/codecin.egg-info/SOURCES.txt +25 -0
- codecin-5.8.2/examples/args_demo.cin +22 -0
- {codecin-5.7.4 → codecin-5.8.2}/examples/asm_constants.asm +1 -1
- {codecin-5.7.4 → codecin-5.8.2}/examples/bitwise_builtins.cin +1 -1
- {codecin-5.7.4 → codecin-5.8.2}/examples/control_flow.cin +1 -1
- {codecin-5.7.4 → codecin-5.8.2}/examples/enum_range_for.cin +1 -1
- codecin-5.8.2/examples/gui_demo.cin +49 -0
- {codecin-5.7.4 → codecin-5.8.2}/examples/literals_types.cin +1 -1
- codecin-5.8.2/examples/local_audio.cin +58 -0
- {codecin-5.7.4 → codecin-5.8.2}/examples/modules_demo.cin +1 -1
- {codecin-5.7.4 → codecin-5.8.2}/examples/stdlib_demo.cin +1 -1
- {codecin-5.7.4 → codecin-5.8.2}/examples/system_interaction.cin +1 -1
- {codecin-5.7.4 → codecin-5.8.2}/setup.py +11 -1
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_all_libs_together.py +3 -0
- codecin-5.8.2/tests/test_cin_host.py +143 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_cli.py +14 -0
- codecin-5.8.2/tests/test_environment.py +57 -0
- codecin-5.8.2/tests/test_gui.py +177 -0
- codecin-5.8.2/tests/test_issue_regress.py +263 -0
- codecin-5.8.2/tests/test_lib_compat.py +532 -0
- codecin-5.7.4/codecin/lib/gui.cin +0 -94
- codecin-5.7.4/codecin/native/engine/audio.go +0 -152
- codecin-5.7.4/codecin/native/engine/audio_other.go +0 -46
- codecin-5.7.4/codecin/native/engine/audio_windows.go +0 -43
- codecin-5.7.4/codecin/native/engine/keyboard_windows.go +0 -70
- codecin-5.7.4/tests/test_cin_host.py +0 -59
- {codecin-5.7.4 → codecin-5.8.2}/LICENSE +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/MANIFEST.in +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/assembler.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/cache.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/console.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/crom.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/debugger.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/errors.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/jit.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/array.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/bigint.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/bits.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/bitset.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/codec.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/combin.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/conv.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/csv.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/dp.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/fmt.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/frac.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/graph.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/hash.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/heap.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/io.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/json.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/math.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/matrix.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/path.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/queue.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/rand.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/set.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/sort.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/stat.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/str.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/termux.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/test.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/text.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/time.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/token.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/tree.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/unionfind.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/validate.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/lib/vec.cin +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/logger.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/aot/stub_main.go.txt +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/build.ps1 +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/build.sh +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/compiler/compile_test.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/compiler/parser.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/compiler/tokenizer.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/compiler/types.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/canvas.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/crom.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/encode.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/engine_test.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/host_test.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/hostcrypto.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/hostdesktop.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/hostnet.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/keyboard_termios_darwin.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/keyboard_termios_linux.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/engine/termux.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/go.mod +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/native/ir/ir.go +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/registers.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin/stats.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin.egg-info/dependency_links.txt +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin.egg-info/entry_points.txt +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin.egg-info/requires.txt +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/codecin.egg-info/top_level.txt +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/misc/vim/ftdetect/codecin.vim +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/misc/vim/syntax/cin.vim +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/misc/vim/syntax/codecinasm.vim +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/misc/vscode-cin/.vscodeignore +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/misc/vscode-cin/README.md +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/misc/vscode-cin/build.bat +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/misc/vscode-cin/language-configuration.json +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/misc/vscode-cin/package.json +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/misc/vscode-cin/snippets/cin.json +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/misc/vscode-cin/syntaxes/cin.tmLanguage.json +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/pyproject.toml +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/script/bump_version.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/script/check_paths.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/script/gen_isa_docs.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/script/gen_native_isa.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/setup.cfg +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_aggregate_and_const.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_aot.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_assembler_ext.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_cache.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_cin_host_ext.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_cin_new_features.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_cin_syntax.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_cin_syntax_ext.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_cin_system.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_compiler_errors.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_cpu_interpreted.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_debugger.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_examples.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_features_ab.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_features_crom_mmu.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_features_import.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_features_importloc.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_features_mmu.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_features_remote.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_index_subscript_type.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_isa_dispatch.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_isa_single_source.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_keyboard.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_bigint.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_bitset.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_codec.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_combin.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_csv.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_dp.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_fmt.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_frac.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_graph.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_heap.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_path.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_set.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_text.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_token.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_tree.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_lib_unionfind.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_libs.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_libs_ext.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_literals_and_bom.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_memory_protection.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_native_hardening.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_native_lib_lookup.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_nested_subscript_codegen.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_no_go_cli.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_p0_fixes.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_packaging.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_paths_consistency.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_struct_value_semantics.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_switch_semantics.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_three_paths.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_version.py +0 -0
- {codecin-5.7.4 → codecin-5.8.2}/tests/test_workflows.py +0 -0
|
@@ -5,6 +5,261 @@
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
## [5.8.2] - 2026-10-04
|
|
9
|
+
|
|
10
|
+
一次以「真实压测程序暴露的错误信息与栈安全」为主线的修复发布。核心结论:
|
|
11
|
+
5.5.3 的浮点下标修复在三条执行路径均有效(`a[(n * p) / 100]` 一类变量参与
|
|
12
|
+
的浮点表达式同样覆盖);用户在 Termux 上报告的 `address ffffffffffffc6f8
|
|
13
|
+
out of bounds` 实为**局部大数组把栈推成负地址**——`int lat[10000]` 需要
|
|
14
|
+
80 KB 局部空间,超过默认 64 KB 内存后 SP 绕回,越界检查检查的是绕回后的
|
|
15
|
+
地址。为此新增带防护的帧分配系统调用(SYS 137),并全面改进运行时/编译期
|
|
16
|
+
错误信息、补齐 CLI 直传参数与高精度计时。
|
|
17
|
+
|
|
18
|
+
### 修复 (Fixed)
|
|
19
|
+
|
|
20
|
+
#### 局部大数组撑爆栈(静默生成负地址)
|
|
21
|
+
- **函数序言的帧分配改为带防护的系统调用**。此前 prologue 用裸 `ADDI sp, sp,
|
|
22
|
+
-frame_bytes` 递减栈指针,局部数组总大小超过可用内存时 SP 绕回为巨大无符号
|
|
23
|
+
值(如 0xFFFFFFFFFFFFC6F8),后续所有访问都指向"负地址",报错只看到一句
|
|
24
|
+
out of bounds,看不出真因。现在两侧编译器(`cin.py` / `codegen.go`)改为
|
|
25
|
+
`SYS ALLOCFRAME`:VM 侧用**有符号比较**在分配前检查栈余量(含 4 KB 警戒
|
|
26
|
+
线),不足时直接报
|
|
27
|
+
`Stack overflow: frame needs N bytes, stack headroom only M bytes (...)
|
|
28
|
+
Try --mem-size (default 65536) or smaller local arrays`,
|
|
29
|
+
不再让绕回地址流入访存路径。Python 解释器、JIT、Go 原生三条路径语义一致。
|
|
30
|
+
- **负地址越界提示兜底**:地址 >= 2^63 的越界报错(Python `memory.py` 与
|
|
31
|
+
Go `checkAddr`)追加
|
|
32
|
+
`(negative address: stack overflow or bad pointer?)`,把"看起来像随机大数"
|
|
33
|
+
的地址翻译成可排查的方向。
|
|
34
|
+
|
|
35
|
+
#### 错误信息补全(问题 2/4/5)
|
|
36
|
+
- **Heap exhausted 附用量与建议**:三处堆耗尽点(malloc / 字符串拼接 / 字符串
|
|
37
|
+
操作)在 Python 与 Go 两侧逐字一致地报
|
|
38
|
+
`Heap exhausted: need N bytes, free M bytes (heap 0x...0x...).
|
|
39
|
+
Try --mem-size (default 65536) or reduce allocations`。
|
|
40
|
+
- **非常量数组长度的编译期报错附 hint**:
|
|
41
|
+
`array lengths must be compile-time constants; declare it as
|
|
42
|
+
\`const int NAME = ...\`; variable-length arrays are not supported —
|
|
43
|
+
use a fixed-size array plus a count variable`。
|
|
44
|
+
- **`float(x)` / `int(x)` 报错附替代写法**:提示使用 `to_float(x)` / `to_int(x)`
|
|
45
|
+
或依赖混合表达式的隐式提升。
|
|
46
|
+
|
|
47
|
+
#### 兼容层与文档
|
|
48
|
+
- `gostd.cin` 头注释明确列出当前覆盖的包(strings / strconv / math / slices /
|
|
49
|
+
os.Args)与**未覆盖项**(time、os 文件读写、net/http、sync),并指向对应
|
|
50
|
+
内建(`time_ms/time_us/time_ns`、`file_*` 函数族),避免"Go 标准库兼容层"
|
|
51
|
+
的命名让人误以为常用包会逐步全覆盖。
|
|
52
|
+
|
|
53
|
+
### 新增 (Added)
|
|
54
|
+
|
|
55
|
+
#### CLI 程序名后直传参数
|
|
56
|
+
- `codecin 压测.cin https://example.com 24` 现在可用:程序文件之后的裸参数
|
|
57
|
+
原样传给 CIN 程序(`arg_count()` / `arg(i)`),已知 CLI 选项放在程序之前或
|
|
58
|
+
之后均可识别;形如选项的直传参数给出 stderr 提示并用 `--` 显式分隔。
|
|
59
|
+
`--` 分隔符行为不变且优先级最高,`--help` 新增 Program arguments 说明段。
|
|
60
|
+
|
|
61
|
+
#### 高精度计时 `time_us()` / `time_ns()`(SYS 138/139)
|
|
62
|
+
- 微秒 / 纳秒级单调计时,补齐 `time_ms()` 只能测毫秒的短板(压测与微基准
|
|
63
|
+
基础设施)。两侧编译器同步登记,解释器 / JIT / 原生三条路径均可用;
|
|
64
|
+
与 ALLOCFRAME 同属核心 VM 机制,不触发沙箱门禁与原生路径限定。
|
|
65
|
+
|
|
66
|
+
#### 显式类型转换 `to_int()` / `to_float()`
|
|
67
|
+
- 数值类型(int/float/bool)间的显式转换,语义与隐式转换一致(float→int 向零
|
|
68
|
+
截断)。非数值参数在编译期报错并说明。
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## [5.8.0] - 2026-10-04
|
|
73
|
+
|
|
74
|
+
一次「图形、媒体与跨平台兼容」发布:新增 **GUI 窗口**(Windows Win32 /
|
|
75
|
+
Linux X11)、**本地音频扩展**(真实音量 / 播放进度 / 合成蜂鸣)、**键盘输入
|
|
76
|
+
多平台优化**(Unicode 码点、F11/F12、修饰键组合),并补齐 **命令行参数与
|
|
77
|
+
行输入**(SYS 129..131)、**终端输出缓存的跨平台冲刷**(Windows VT/UTF-8
|
|
78
|
+
初始化)与 **C/C++/Go 三语言标准库兼容层**(36 → 39 个)。随后在同一版本内
|
|
79
|
+
继续增强:**音频控制全家桶**(查询 / 暂停恢复 / 音量读取,SYS 132..136)、
|
|
80
|
+
**三兼容层 API 扩容**(40+ 新函数)、**工具链缺失检测与平台化安装提示**
|
|
81
|
+
(environment)与 **`--libs` 内置库清单**(标注执行路径要求)。核心实现全部
|
|
82
|
+
在 Go 原生引擎(纯标准库,零第三方依赖),三条执行路径语义与 5.7.x 保持一致。
|
|
83
|
+
|
|
84
|
+
### 新增 (Added)
|
|
85
|
+
|
|
86
|
+
#### GUI 窗口(SYS 119..125、128,全部 Go 原生实现)
|
|
87
|
+
|
|
88
|
+
- **`gui_new(w, h, title)` / `gui_update()` / `gui_close()` / `gui_closed()` /
|
|
89
|
+
`gui_active()` / `mouse_x()` / `mouse_y()` / `mouse_button()`**:
|
|
90
|
+
- `gui_new` 成功返回 0 并把画布内建(`set_color` / `fill_rect` / `fill_circle` /
|
|
91
|
+
`draw_line` / `draw_text`)直接绑定为**窗口后备缓冲直画**,`gui_update`
|
|
92
|
+
处理事件并呈现一帧(主循环每帧调用);`gui_close` 销毁窗口(画布保留,
|
|
93
|
+
仍可 `save_png`);点 X / Alt+F4 / WM 删除协议由 `gui_closed` 报告。
|
|
94
|
+
- 平台后端:Windows 用 Win32(专用窗口线程 + 消息泵,`StretchDIBits`
|
|
95
|
+
呈现,`AdjustWindowRect` 精确客户区);Linux 用**纯 Go X11 客户端**
|
|
96
|
+
(Unix socket / TCP 连接、MIT-MAGIC-COOKIE-1 认证、`PutImage` 分块呈现、
|
|
97
|
+
WM_DELETE_WINDOW 协议);其他平台与无显示服务环境一律优雅失败
|
|
98
|
+
(`gui_new` 返回 -1,不报错不崩溃)。
|
|
99
|
+
- 鼠标:客户区坐标 + 键位掩码(bit0 左 / bit1 右 / bit2 中);键盘事件注入
|
|
100
|
+
与终端共用的同一键码队列(`get_key` 可直接读)。
|
|
101
|
+
- 并发安全:快照复制防撕裂(呈现线程读 / VM 线程写)。
|
|
102
|
+
- **`codecin/lib/gui.cin` 重构**:窗口封装 `g_new` / `g_update` / `g_close` /
|
|
103
|
+
`g_closed` / `g_active` / `g_clear` / `g_mouse_*`(含键位判定),并**保留**
|
|
104
|
+
5.7.x 的离屏绘图助手(`g_rgb` / `g_bar_chart` / `g_line_chart` / `g_grid` /
|
|
105
|
+
`g_rect_outline` / `g_save` / `g_show`)。
|
|
106
|
+
|
|
107
|
+
#### 本地音频扩展(SYS 126、127)
|
|
108
|
+
|
|
109
|
+
- **`audio_pos()`**:当前播放已进行毫秒;无播放 / 已播完 / 时长未知返回 -1。
|
|
110
|
+
- **`beep(freq, ms)`**:合成 16-bit 单声道 22050Hz 正弦蜂鸣(10% / 5ms 淡入
|
|
111
|
+
淡出防爆音);频率 20..20000 Hz、单次上限 10 秒,参数校验在三平台一致地
|
|
112
|
+
于触碰设备之前完成。
|
|
113
|
+
- Windows 后端从 PlaySoundW 升级为 **waveOut 流式**:`audio_volume` 经
|
|
114
|
+
`waveOutSetVolume` 实时生效、`audio_stop` 即时中止(`waveOutReset`);
|
|
115
|
+
Unix 后端向 `paplay` / `ffplay` / `afplay` 透传音量参数。
|
|
116
|
+
|
|
117
|
+
#### 音频控制增强(SYS 132..136)
|
|
118
|
+
|
|
119
|
+
- **`audio_duration()`**:当前播放总时长毫秒;无播放 / 自然播完 / 时长未知返回 -1
|
|
120
|
+
(播放与暂停期间返回同一总时长)。
|
|
121
|
+
- **`audio_playing()`**:1 = 正在发声(已开始、未暂停、未播完),否则 0。
|
|
122
|
+
- **`audio_pause()`**:暂停当前播放(Windows `waveOutPause`;Unix 向播放器
|
|
123
|
+
进程投递 SIGSTOP),成功 0;无播放 / 已暂停 / 平台失败为 -1。
|
|
124
|
+
- **`audio_resume()`**:恢复暂停的播放,时间基线整体后移暂停时长——
|
|
125
|
+
`audio_pos` 无缝续走、自然结束时刻保持正确;成功 0 / 无暂停可恢复 -1。
|
|
126
|
+
- **`audio_level()`**:读取当前音量 0..100(`audio_volume` 的读端)。
|
|
127
|
+
- **`audio_pos` 暂停冻结**:暂停期间进度停在暂停时刻,不随真实时间前进;
|
|
128
|
+
`audio_stop` / 重新播放即解除暂停态。
|
|
129
|
+
- 五个内建在两侧编译器同步登记,ISA 真源(`isa.py`)→ Go 生成物一致。
|
|
130
|
+
|
|
131
|
+
#### 键盘输入多平台优化(键码表扩展)
|
|
132
|
+
|
|
133
|
+
- 新增键码:**F11 / F12**(1031 / 1032)、**Ctrl+方向**(1101..1104)、
|
|
134
|
+
**Shift+方向**(1105..1108)、**Shift+Tab**(1109)。
|
|
135
|
+
- **XTerm 修饰参数解析**:`CSI 1;5C`(Ctrl+Right)等修饰变体三端一致。
|
|
136
|
+
- **Unicode 码点解码**(Linux / macOS / Termux):终端 UTF-8 多字节序列解码为
|
|
137
|
+
码点(>255,如 "中" → 0x4E2D),非法序列回退按字节处理;Windows 端
|
|
138
|
+
UTF-16 代理对组合为同一码点。
|
|
139
|
+
- **Windows 输入重写**:msvcrt `_getch` → `ReadConsoleInputW` 事件流
|
|
140
|
+
(UTF-16 字符 + VK 虚拟键,键抬起过滤、重复计数、扩展键),启用时关闭
|
|
141
|
+
QuickEdit 防误选卡死。
|
|
142
|
+
- `codecin/lib/key.cin`:`K_F11` / `K_F12` / `K_CTRL_*` / `K_SHIFT_*` /
|
|
143
|
+
`K_SHIFT_TAB` 常量与 `k_is_function` / `k_is_modified_arrow` 判定;
|
|
144
|
+
`k_is_special` 范围同步扩展。
|
|
145
|
+
|
|
146
|
+
#### 命令行参数与行输入(SYS 129..131,跨平台一致语义)
|
|
147
|
+
|
|
148
|
+
- **`arg_count()` / `arg(i)`**:读取传给 CIN 程序的命令行参数(不含程序文件名;
|
|
149
|
+
越界 / 负下标返回空串)。传参约定三端统一:
|
|
150
|
+
- CLI:`codecin prog.cin -- a b c`(`--` 之后的参数全部交给 CIN 程序);
|
|
151
|
+
- AOT 产物:直接取进程 `os.Args[1:]`;
|
|
152
|
+
- c-shared 库:新导出 `codecin_set_args`,Python 桥接层每次运行前注入
|
|
153
|
+
(空列表即清空,同进程多次运行不残留)。
|
|
154
|
+
- **`input_str()`**:读入一行 UTF-8 文本(不含行尾;EOF 为空串)。优先消费
|
|
155
|
+
预读输入缓冲(与解释器 `input()` 的管道语义一致),耗尽后阻塞读标准输入;
|
|
156
|
+
Windows 控制台用 `ReadConsoleW`(UTF-16 → UTF-8,中文输入不乱码),其余平台
|
|
157
|
+
用 `bufio` 按行读;行尾 `\n` / `\r\n` 三平台统一剥离,与键盘 raw 模式
|
|
158
|
+
(监听激活时临时恢复行模式)互不干扰。
|
|
159
|
+
- 新内建在两侧编译器同步登记(`arg_count` / `arg` / `input_str`)。
|
|
160
|
+
|
|
161
|
+
#### 终端输出缓存与 Windows 控制台兼容
|
|
162
|
+
|
|
163
|
+
- **阻塞读前冲刷输出缓冲**:原生引擎把输出缓冲到程序结束一次性回传;
|
|
164
|
+
当 `input_str()` / 数字输入将要阻塞读真实终端时先冲刷已缓冲输出,
|
|
165
|
+
`"你的名字: "` 这类交互提示立即可见。冲刷**仅在 stdout 为终端时生效**——
|
|
166
|
+
管道 / 重定向 / 测试捕获下输出字节序列与旧版本完全一致。
|
|
167
|
+
- **Windows 控制台一次性初始化**(进程级、幂等、失败安全):
|
|
168
|
+
`ENABLE_VIRTUAL_TERMINAL_PROCESSING`(ANSI/VT 转义序列在传统 conhost 上
|
|
169
|
+
与 Linux/macOS 行为一致)+ `SetConsoleOutputCP(65001)`(输出代码页切
|
|
170
|
+
UTF-8,中文 Windows 默认 GBK 下中文/Emoji 不再乱码)。
|
|
171
|
+
- AOT 产物在打印输出前执行同一初始化;非 Windows 平台为空操作
|
|
172
|
+
(终端原生支持 VT 与 UTF-8)。
|
|
173
|
+
|
|
174
|
+
#### C / C++ / Go 标准库兼容层(36 → 39 个,全部纯 CIN)
|
|
175
|
+
|
|
176
|
+
- **`codecin/lib/cstd.cin`(`libc_*`)**:`<ctype.h>`(isdigit / toupper …,
|
|
177
|
+
字符码可用字符字面量 `'A'` 直接传入)、`<string.h>`(strlen / strcmp /
|
|
178
|
+
strstr / strchr / strrev / memcpy …)、`<stdlib.h>`(abs / atoi / qsort_asc)、
|
|
179
|
+
`<math.h>`(fabs / sqrt / pow / floor / ceil / fmod 商向零截断)与
|
|
180
|
+
`<stdio.h>`(puts / print)。
|
|
181
|
+
- **`codecin/lib/cppstd.cin`(`stl_*`)**:`std::string`(find / rfind /
|
|
182
|
+
substr / append / to_string,npos 以 -1 表示)、`vector<int>` / `stack<int>` /
|
|
183
|
+
`queue<int>`(**数组 + 长度游标**表达,push/pop 返回新长度)、
|
|
184
|
+
`<utility>`(max / min / abs / swap / sort 固定升序)。
|
|
185
|
+
- **`codecin/lib/gostd.cin`(`go_*`)**:`strings`(Contains / Index /
|
|
186
|
+
HasPrefix / Repeat / Count / ReplaceAll / EqualFold …)、`strconv`(Itoa /
|
|
187
|
+
Atoi / FormatFloat)、`math`、`slices`(Index / Contains / Max / Reverse …)
|
|
188
|
+
与 `os.Args`(经 `go_os_args_len` / `go_os_args_get`,依赖原生路径)。
|
|
189
|
+
- 类型映射约定:C `char*` → `string`、C `char` → 字符码 `int`、C 数组参数 →
|
|
190
|
+
CIN 数组引用 + 显式长度;与 C/C++ 指针返回值不可表达的 API(如返回
|
|
191
|
+
`char*` 的 strchr)以**下标**语义对齐,头注释均注明差异。
|
|
192
|
+
|
|
193
|
+
#### 兼容层 API 扩容(三库 40+ 新函数,纯 CIN、三路径一致)
|
|
194
|
+
|
|
195
|
+
- **cstd**:`<ctype.h>` 补 iscntrl / isgraph / isblank / ispunct / toascii;
|
|
196
|
+
`<string.h>` 补 memmove / strspn / strcspn / strpbrk / strlwr / strupr;
|
|
197
|
+
`<stdlib.h>` 补 labs / rand / srand;`<math.h>` 补 sin / cos / tan /
|
|
198
|
+
round(C 语义半值远离零)/ trunc;`<stdio.h>` 补 putchar(配套内部
|
|
199
|
+
字符码 → 字符串转换)。
|
|
200
|
+
- **cppstd**:`std::string` 补 starts_with / ends_with(C++20)/
|
|
201
|
+
find_first_of / find_last_of / at / front / back / insert / erase /
|
|
202
|
+
replace;`vector<int>` 补 find / count / insert / erase;`<algorithm>`
|
|
203
|
+
补 sort 降序版与 clamp。
|
|
204
|
+
- **gostd**:`strings` 补 LastIndex / IndexAny / TrimLeft / TrimRight /
|
|
205
|
+
TrimPrefix / TrimSuffix;`strconv` 补 FormatInt(base 2..36)/
|
|
206
|
+
ParseInt(任意进制解析);`math` 补 Round / Trunc;`slices` 补
|
|
207
|
+
LastIndex / Equal / Clone / Sort。
|
|
208
|
+
|
|
209
|
+
#### 工具链缺失检测与平台化安装提示(environment)
|
|
210
|
+
|
|
211
|
+
- **`codecin/environment.py`**:`find_tool` / `tool_available`(只读
|
|
212
|
+
`shutil.which` 探测,绝不自动安装)、`install_hint`(按当前平台给出可复制
|
|
213
|
+
执行的安装命令:Windows winget/MSYS2、macOS brew/xcode-select、Linux
|
|
214
|
+
apt/dnf/pacman、Termux pkg)、`missing_tool_message`(缺工具 + 用途 +
|
|
215
|
+
怎么装合一)、`native_runtime_hint`(原生库缺失时的三条出路指引)。
|
|
216
|
+
- 接入点(所有缺失入口提示一致):
|
|
217
|
+
- AOT 构建缺 Go:报错附 `install_hint('go')`(原先只有干巴巴的
|
|
218
|
+
"go 命令未找到");
|
|
219
|
+
- 解释路径(含 `--no-native`)调用宿主能力内建:报错附原生库安装指引;
|
|
220
|
+
- pip 安装(`setup.py`)缺 Go:打印安装命令并说明重装后获得原生加速。
|
|
221
|
+
|
|
222
|
+
#### `--libs`:内置标准库清单与执行路径标注
|
|
223
|
+
|
|
224
|
+
- 新 CLI 选项 **`--libs`**:列出 `codecin/lib/` 全部官方库并按**执行路径
|
|
225
|
+
要求**标注三类——纯 CIN(三路径一致)/ 兼容层(C/C++/Go 三语言标准库
|
|
226
|
+
兼容层)/ 需原生运行时(调用宿主能力内建,`--no-native` 与沙箱下不可用)。
|
|
227
|
+
- 分类由**源码扫描**得出(是否引用 `HOST_BUILTINS` 内建名),与库头注释
|
|
228
|
+
保持单一事实来源;`gostd.cin` 的 `go_os_args_*` 原生依赖自动标注。
|
|
229
|
+
|
|
230
|
+
#### 其他
|
|
231
|
+
|
|
232
|
+
- 新内建在两侧编译器同步登记:Python `HOST_BUILTINS` 与 Go
|
|
233
|
+
`compiler.hostBuiltins`(并补上 5.6.0 遗漏的 `key_hit` / `get_key` /
|
|
234
|
+
`key_flush`)。
|
|
235
|
+
- 新示例:`examples/gui_demo.cin`(无显示服务自动降级为提示后退出)、
|
|
236
|
+
`examples/local_audio.cin`、`examples/args_demo.cin`(`--` 传参与
|
|
237
|
+
`input_str`)。
|
|
238
|
+
- 新测试:`tests/test_lib_compat.py`(三兼容层函数语义、参数注入管道、
|
|
239
|
+
预读缓冲行输入、无原生库可编译,解释 / 原生双路径参数化)。
|
|
240
|
+
- 本轮新增:Go 侧 `engine/audio_test.go`(audio_duration / playing /
|
|
241
|
+
pause / resume 状态机、暂停冻结、自然播完回落)、`tests/test_environment.py`
|
|
242
|
+
(安装提示契约)、`tests/test_cli.py::test_list_libs_reports_categories`
|
|
243
|
+
(--libs 分类标注);`examples/local_audio.cin` 增补音量读取与暂停 /
|
|
244
|
+
恢复演示。
|
|
245
|
+
|
|
246
|
+
### 变更 (Changed)
|
|
247
|
+
|
|
248
|
+
- **`lib/gui.cin` 签名变更**(窗口化重构):`g_new(w, h)` → `g_new(w, h, title)`
|
|
249
|
+
(旧的无窗口画布用法请直接使用 `canvas(w, h)`);`g_clear(w, h, rgb)` →
|
|
250
|
+
`g_clear(rgb)`(沿用最近一次窗口尺寸,从未开窗时返回 -1)。
|
|
251
|
+
图表助手内部已同步适配,`g_bar_chart` / `g_line_chart` / `g_save` /
|
|
252
|
+
`g_show` 调用方式不变。
|
|
253
|
+
|
|
254
|
+
### 修复 (Fixed)
|
|
255
|
+
|
|
256
|
+
- 音频自然播完后 `audio_pos` 不再恒返回总时长(正确恢复 -1)。
|
|
257
|
+
- GUI:Windows 窗口线程改为常驻,`gui_close` 之后可以再次 `gui_new`;
|
|
258
|
+
窗口销毁(无论来自 `gui_close` 还是用户点 X)后清理失效句柄。
|
|
259
|
+
- `guiSnapshot` 增加窗口打开校验(关闭后不再产出快照)。
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
8
263
|
## [5.7.4] - 2026-09-28
|
|
9
264
|
|
|
10
265
|
一次「静默错误清零 + 标准库扩容」的发布:修掉一族会**静默破坏内存/静默给错结果**的
|
|
@@ -316,7 +571,7 @@ struct 缺陷与两处**同一程序两条路径结论不同**的分歧,并把
|
|
|
316
571
|
|
|
317
572
|
### 修复 (Fixed)
|
|
318
573
|
|
|
319
|
-
- `
|
|
574
|
+
- `codecin --help` 的首行版本号长期停留在 `Code CIN v5.3`,现直接取
|
|
320
575
|
`codecin.__version__`(此前是全仓唯一残留的版本串)。
|
|
321
576
|
- `--build-exe` 在程序文件不存在时抛裸 `FileNotFoundError` traceback,现在与普通路径
|
|
322
577
|
一样给出 `Build Error` 面板。
|
|
@@ -367,7 +622,7 @@ struct 缺陷与两处**同一程序两条路径结论不同**的分歧,并把
|
|
|
367
622
|
### 新增 (Added)
|
|
368
623
|
|
|
369
624
|
- **AOT 静态编译: 编译成独立可执行文件 (Windows / Linux / macOS)**:
|
|
370
|
-
`
|
|
625
|
+
`codecin program.cin --build-exe app` 或 `codecin build program.cin -o app`,
|
|
371
626
|
支持 `--target OS/ARCH` 交叉编译(windows/amd64|arm64、linux/amd64|arm64、darwin/amd64|arm64)。
|
|
372
627
|
产物内嵌 UCBC 字节码与初始内存镜像,由内置 Go VM 执行,**不依赖 Python、Go 工具链、
|
|
373
628
|
libc 或任何动态库**(`CGO_ENABLED=0`,Linux 产物无 `PT_INTERP`);入口 shell 模板由
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codecin
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.8.2
|
|
4
4
|
Summary: Code CIN - 高级语言与运行时 (CIN/PL/ASM 工具链 + Go 原生 VM + ARM64/RISC-V/FP/Vector 指令集)
|
|
5
5
|
Author: ByUsi Studio, 北啊呢
|
|
6
6
|
License-Expression: MIT
|
|
@@ -443,9 +443,9 @@ codecin --version
|
|
|
443
443
|
|
|
444
444
|
3. 运行:
|
|
445
445
|
```
|
|
446
|
-
|
|
446
|
+
codecin basic.cin # 唯一 CLI 入口 (自动用 Go 原生库)
|
|
447
447
|
codecin basic.cin # 安装后等价的 console script
|
|
448
|
-
|
|
448
|
+
codecin --help
|
|
449
449
|
```
|
|
450
450
|
|
|
451
451
|
> **Python 只是 CLI 外壳**: 语言实现 (`codecin/native/` 下的 Go 编译器与字节码 VM) 全部在 Go 侧,
|
|
@@ -485,11 +485,11 @@ ruff check codecin cpu.py script tests
|
|
|
485
485
|
|
|
486
486
|
```bash
|
|
487
487
|
# 本机平台
|
|
488
|
-
|
|
488
|
+
codecin program.cin --build-exe program # Windows 自动补 .exe
|
|
489
489
|
|
|
490
490
|
# 交叉编译 (只需要安装 Go 工具链)
|
|
491
|
-
|
|
492
|
-
|
|
491
|
+
codecin program.cin --build-exe app-linux --build-target linux/amd64
|
|
492
|
+
codecin program.cin --build-exe app-mac --build-target darwin/arm64
|
|
493
493
|
```
|
|
494
494
|
|
|
495
495
|
| 目标 | 说明 |
|
|
@@ -506,10 +506,10 @@ python cpu.py program.cin --build-exe app-mac --build-target darwin/arm64
|
|
|
506
506
|
### 命令行选项
|
|
507
507
|
|
|
508
508
|
**基础执行**
|
|
509
|
-
- `
|
|
510
|
-
- `
|
|
511
|
-
- `
|
|
512
|
-
- `
|
|
509
|
+
- `codecin program.cin` - 运行CIN程序
|
|
510
|
+
- `codecin program.pl` - 运行PL程序
|
|
511
|
+
- `codecin program.asm` - 运行ASM程序
|
|
512
|
+
- `codecin program.bin` - 运行字节码
|
|
513
513
|
|
|
514
514
|
**执行路径**
|
|
515
515
|
- `--no-native` - 禁用 Go 原生库, 强制纯 Python
|
|
@@ -425,9 +425,9 @@ codecin --version
|
|
|
425
425
|
|
|
426
426
|
3. 运行:
|
|
427
427
|
```
|
|
428
|
-
|
|
428
|
+
codecin basic.cin # 唯一 CLI 入口 (自动用 Go 原生库)
|
|
429
429
|
codecin basic.cin # 安装后等价的 console script
|
|
430
|
-
|
|
430
|
+
codecin --help
|
|
431
431
|
```
|
|
432
432
|
|
|
433
433
|
> **Python 只是 CLI 外壳**: 语言实现 (`codecin/native/` 下的 Go 编译器与字节码 VM) 全部在 Go 侧,
|
|
@@ -467,11 +467,11 @@ ruff check codecin cpu.py script tests
|
|
|
467
467
|
|
|
468
468
|
```bash
|
|
469
469
|
# 本机平台
|
|
470
|
-
|
|
470
|
+
codecin program.cin --build-exe program # Windows 自动补 .exe
|
|
471
471
|
|
|
472
472
|
# 交叉编译 (只需要安装 Go 工具链)
|
|
473
|
-
|
|
474
|
-
|
|
473
|
+
codecin program.cin --build-exe app-linux --build-target linux/amd64
|
|
474
|
+
codecin program.cin --build-exe app-mac --build-target darwin/arm64
|
|
475
475
|
```
|
|
476
476
|
|
|
477
477
|
| 目标 | 说明 |
|
|
@@ -488,10 +488,10 @@ python cpu.py program.cin --build-exe app-mac --build-target darwin/arm64
|
|
|
488
488
|
### 命令行选项
|
|
489
489
|
|
|
490
490
|
**基础执行**
|
|
491
|
-
- `
|
|
492
|
-
- `
|
|
493
|
-
- `
|
|
494
|
-
- `
|
|
491
|
+
- `codecin program.cin` - 运行CIN程序
|
|
492
|
+
- `codecin program.pl` - 运行PL程序
|
|
493
|
+
- `codecin program.asm` - 运行ASM程序
|
|
494
|
+
- `codecin program.bin` - 运行字节码
|
|
495
495
|
|
|
496
496
|
**执行路径**
|
|
497
497
|
- `--no-native` - 禁用 Go 原生库, 强制纯 Python
|
|
@@ -362,8 +362,9 @@ def build(bytecode: bytes,
|
|
|
362
362
|
try:
|
|
363
363
|
proc, detail = _run_go_build(cmd, mod, env, logger)
|
|
364
364
|
except FileNotFoundError as e:
|
|
365
|
-
|
|
366
|
-
|
|
365
|
+
from .environment import missing_tool_message
|
|
366
|
+
raise AotError(missing_tool_message(
|
|
367
|
+
'go', 'AOT 构建独立可执行文件')) from e
|
|
367
368
|
except subprocess.TimeoutExpired as e:
|
|
368
369
|
raise AotError('go build 超时') from e
|
|
369
370
|
if proc.returncode != 0:
|
|
@@ -210,6 +210,8 @@ HOST_BUILTINS = {
|
|
|
210
210
|
'chdir': (Syscall.CHDIR, 1, 'int'),
|
|
211
211
|
# 时间与系统信息
|
|
212
212
|
'time_ms': (Syscall.TIMEMS, 0, 'int'),
|
|
213
|
+
'time_us': (Syscall.TIMEUS, 0, 'int'),
|
|
214
|
+
'time_ns': (Syscall.TIMENS, 0, 'int'),
|
|
213
215
|
'sleep_ms': (Syscall.SLEEPMS, 1, 'int'),
|
|
214
216
|
'cpu_count': (Syscall.CPUCOUNT, 0, 'int'),
|
|
215
217
|
'arch_name': (Syscall.ARCHNAME, 0, 'string'),
|
|
@@ -242,11 +244,30 @@ HOST_BUILTINS = {
|
|
|
242
244
|
'key_hit': (Syscall.KEYHIT, 0, 'int'),
|
|
243
245
|
'get_key': (Syscall.KEYGET, 0, 'int'),
|
|
244
246
|
'key_flush': (Syscall.KEYFLUSH, 0, 'int'),
|
|
247
|
+
# GUI 窗口 (Windows Win32 / Linux X11, 其他平台优雅失败)
|
|
248
|
+
'gui_new': (Syscall.GUINEW, 3, 'int'),
|
|
249
|
+
'gui_update': (Syscall.GUIUPDATE, 0, 'int'),
|
|
250
|
+
'gui_close': (Syscall.GUICLOSE, 0, 'int'),
|
|
251
|
+
'gui_closed': (Syscall.GUICLOSED, 0, 'int'),
|
|
252
|
+
'gui_active': (Syscall.GUIACTIVE, 0, 'int'),
|
|
253
|
+
'mouse_x': (Syscall.MOUSEX, 0, 'int'),
|
|
254
|
+
'mouse_y': (Syscall.MOUSEY, 0, 'int'),
|
|
255
|
+
'mouse_button': (Syscall.MOUSEBTN, 0, 'int'),
|
|
256
|
+
# 音频扩展 (播放进度与蜂鸣合成)
|
|
257
|
+
'audio_pos': (Syscall.AUDIOPOS, 0, 'int'),
|
|
258
|
+
'beep': (Syscall.AUDIOBEEP, 2, 'int'),
|
|
259
|
+
# 音频控制增强 (查询 / 暂停恢复 / 音量读取)
|
|
260
|
+
'audio_duration': (Syscall.AUDIODUR, 0, 'int'),
|
|
261
|
+
'audio_playing': (Syscall.AUDIOPLAYING, 0, 'int'),
|
|
262
|
+
'audio_pause': (Syscall.AUDIOPAUSE, 0, 'int'),
|
|
263
|
+
'audio_resume': (Syscall.AUDIORESUME, 0, 'int'),
|
|
264
|
+
'audio_level': (Syscall.AUDIOLEVEL, 0, 'int'),
|
|
265
|
+
# 命令行参数与行输入 (跨平台一致)
|
|
266
|
+
'arg_count': (Syscall.ARGC, 0, 'int'),
|
|
267
|
+
'arg': (Syscall.ARGV, 1, 'string'),
|
|
268
|
+
'input_str': (Syscall.READLINE, 0, 'string'),
|
|
245
269
|
}
|
|
246
270
|
|
|
247
|
-
# 内建函数最少参数个数 (按各分支实际索引的最大下标 + 1 得出)。
|
|
248
|
-
# 缺失参数旧代码会直接 IndexError 崩溃 (如 sqrt()、substr("a",1)),
|
|
249
|
-
# 现在统一报 CompilerError。必须与 Go 侧 compiler.builtinMinArgs 保持一致。
|
|
250
271
|
BUILTIN_MIN_ARGS = {
|
|
251
272
|
'println': 0, 'print': 0,
|
|
252
273
|
'sqrt': 1, 'sin': 1, 'cos': 1, 'tan': 1,
|
|
@@ -934,7 +955,11 @@ class Parser:
|
|
|
934
955
|
return ('int', self.enums[node[1]])
|
|
935
956
|
raise CompilerError(
|
|
936
957
|
f"Constant expression uses non-constant name '{node[1]}' "
|
|
937
|
-
f"at {self._loc()}"
|
|
958
|
+
f"at {self._loc()} "
|
|
959
|
+
"(hint: array lengths must be compile-time constants; "
|
|
960
|
+
f"declare it as `const int {node[1]} = ...`; "
|
|
961
|
+
"variable-length arrays are not supported — use a fixed-size "
|
|
962
|
+
"array plus a count variable)")
|
|
938
963
|
if kind == 'neg':
|
|
939
964
|
ctype, value = self._const_value_ast(node[1])
|
|
940
965
|
if ctype == 'string':
|
|
@@ -1977,12 +2002,15 @@ class CodeGen:
|
|
|
1977
2002
|
self.locals[pname] = (ptype, poff, False)
|
|
1978
2003
|
|
|
1979
2004
|
self.label(f.name)
|
|
1980
|
-
# prologue: 保存调用方 FP, 建立帧指针,
|
|
2005
|
+
# prologue: 保存调用方 FP, 建立帧指针, 分配局部空间。
|
|
2006
|
+
# 帧分配走 SYS ALLOCFRAME (带栈溢出防护): 此前直接 ADDI SP 减帧长,
|
|
2007
|
+
# 局部大数组会把 SP 推到负地址 —— 轻则报晦涩的越界地址
|
|
2008
|
+
# (如 address ffff...c6f8), 重则静默覆盖全局/堆内存。
|
|
1981
2009
|
self.emit('PUSH', self.reg(29))
|
|
1982
2010
|
self.emit('MOV', self.reg(29), self.reg(32)) # FP = SP
|
|
1983
2011
|
if self.frame_bytes:
|
|
1984
|
-
self.emit('
|
|
1985
|
-
self.emit('
|
|
2012
|
+
self.emit('MOV', self.reg(0), self.imm(self.frame_bytes))
|
|
2013
|
+
self.emit('SYS', self.imm(Syscall.ALLOCFRAME))
|
|
1986
2014
|
|
|
1987
2015
|
# struct 局部变量: 堆分配对象 (槽里存对象指针, 与全局 struct 同一模型)
|
|
1988
2016
|
for _name, (t, loff, _is_block) in list(self.locals.items()):
|
|
@@ -3524,6 +3552,18 @@ class CodeGen:
|
|
|
3524
3552
|
'rtrim': Syscall.RTRIM}[name]
|
|
3525
3553
|
self.emit('SYS', self.imm(sys_id))
|
|
3526
3554
|
return 'string'
|
|
3555
|
+
if name in ('to_int', 'to_float'):
|
|
3556
|
+
# 显式类型转换: to_int(x) 向零截断 (与 int x = 1.9 一致),
|
|
3557
|
+
# to_float(x) 整数提升为浮点。参数类型静态已知, 非数值报编译错。
|
|
3558
|
+
t = self.gen_value(args[0])
|
|
3559
|
+
target = 'int' if name == 'to_int' else 'float'
|
|
3560
|
+
if t not in ('int', 'float', 'bool'):
|
|
3561
|
+
raise CompilerError(
|
|
3562
|
+
f"{name}() expects a numeric argument, got {t} "
|
|
3563
|
+
f"at {self._loc()}"
|
|
3564
|
+
+ (f" (hint: use atoi() to parse a string)" if t == 'string' else ""))
|
|
3565
|
+
self._convert(t, target)
|
|
3566
|
+
return target
|
|
3527
3567
|
if name == 'atoi':
|
|
3528
3568
|
self.gen_value(args[0])
|
|
3529
3569
|
self.emit('SYS', self.imm(Syscall.ATOI))
|
|
@@ -3543,6 +3583,12 @@ class CodeGen:
|
|
|
3543
3583
|
return 'int'
|
|
3544
3584
|
|
|
3545
3585
|
# 用户函数 (已在 _gen_call 开头优先分派; 走到这里说明名字未知)
|
|
3586
|
+
if name in ('int', 'float'):
|
|
3587
|
+
# 常见迁移习惯: C/Python 风格的显式转换函数。给出可操作的替代写法。
|
|
3588
|
+
raise CompilerError(
|
|
3589
|
+
f"Unknown function: {name} (hint: use "
|
|
3590
|
+
f"to_{name}(x) for explicit conversion, or rely on implicit "
|
|
3591
|
+
"promotion in mixed int/float expressions)")
|
|
3546
3592
|
raise CompilerError(f"Unknown function: {name}")
|
|
3547
3593
|
|
|
3548
3594
|
@staticmethod
|
|
@@ -17,7 +17,11 @@ from .console import Colors, Console, Panel
|
|
|
17
17
|
HELP_INTRO = f"""{Colors.colorize(f'Code CIN v{__version__}', Colors.CYAN, True)}
|
|
18
18
|
|
|
19
19
|
{Colors.colorize('Usage:', Colors.YELLOW)}
|
|
20
|
-
|
|
20
|
+
codecin [options] <program.[cin|pl|asm|bin]> [args...]
|
|
21
|
+
|
|
22
|
+
{Colors.colorize('Program arguments:', Colors.YELLOW)}
|
|
23
|
+
program 之后的裸参数原样传给 CIN 程序 (arg_count()/arg(i) 读取);
|
|
24
|
+
CLI 选项放在 program 之前或之后均可识别, 形如选项的参数请用 `--` 显式分隔。
|
|
21
25
|
|
|
22
26
|
{Colors.colorize('Supported formats:', Colors.YELLOW)}
|
|
23
27
|
.cin CIN 高级语言 (函数/struct/数组/浮点/字符串)
|
|
@@ -48,6 +52,9 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
48
52
|
'包路径) 后退出; 与 --json 合用输出机器可读 JSON')
|
|
49
53
|
p.add_argument('--json', action='store_true', dest='json_output',
|
|
50
54
|
help='配合 --build-info 输出 JSON (需与 --build-info 同时使用)')
|
|
55
|
+
p.add_argument('--libs', action='store_true', dest='list_libs',
|
|
56
|
+
help='列出内置标准库并标注执行路径要求 '
|
|
57
|
+
'(纯 CIN / C·C++·Go 兼容层 / 需原生运行时) 后退出')
|
|
51
58
|
|
|
52
59
|
# 执行路径
|
|
53
60
|
p.add_argument('--no-native', action='store_true',
|
|
@@ -216,9 +223,55 @@ def _run_aot_build(ns: argparse.Namespace, console, program_file: str,
|
|
|
216
223
|
return 0
|
|
217
224
|
|
|
218
225
|
|
|
226
|
+
def _extract_program_args(args: List[str], parser: argparse.ArgumentParser):
|
|
227
|
+
"""把程序文件之后的裸参数透传给 CIN 程序 (arg_count()/arg(i))。
|
|
228
|
+
|
|
229
|
+
规则 (向后兼容): 第一个非选项 token 是程序文件; 此后遇到已知 CLI 选项
|
|
230
|
+
(及其取值) 仍归 CLI 解析, 其余裸 token 归程序参数。`--` 分隔的参数已在
|
|
231
|
+
main 里摘出, 优先级更高。返回 (cli_args, program_args)。
|
|
232
|
+
"""
|
|
233
|
+
takes_value = {}
|
|
234
|
+
for act in parser._actions: # noqa: SLF001 - argparse 无公开枚举接口
|
|
235
|
+
for s in getattr(act, 'option_strings', []):
|
|
236
|
+
takes_value[s] = getattr(act, 'nargs', None) != 0
|
|
237
|
+
cli_args: List[str] = []
|
|
238
|
+
prog_args: List[str] = []
|
|
239
|
+
seen_prog = False
|
|
240
|
+
i, n = 0, len(args)
|
|
241
|
+
while i < n:
|
|
242
|
+
tok = args[i]
|
|
243
|
+
# --opt=value 形式按其选项名识别
|
|
244
|
+
optname = tok.split('=', 1)[0] if tok.startswith('--') else tok
|
|
245
|
+
if optname in takes_value:
|
|
246
|
+
cli_args.append(tok)
|
|
247
|
+
if takes_value[optname] and '=' not in tok:
|
|
248
|
+
i += 1
|
|
249
|
+
if i < n:
|
|
250
|
+
cli_args.append(args[i])
|
|
251
|
+
i += 1
|
|
252
|
+
continue
|
|
253
|
+
if not seen_prog:
|
|
254
|
+
cli_args.append(tok)
|
|
255
|
+
seen_prog = True
|
|
256
|
+
i += 1
|
|
257
|
+
continue
|
|
258
|
+
prog_args.append(tok)
|
|
259
|
+
i += 1
|
|
260
|
+
return cli_args, prog_args
|
|
261
|
+
|
|
262
|
+
|
|
219
263
|
def main(argv: Optional[List[str]] = None) -> int:
|
|
220
264
|
args = list(sys.argv[1:] if argv is None else argv)
|
|
221
265
|
|
|
266
|
+
# `--` 之后的参数原样传给 CIN 程序 (arg_count()/arg(i) 读取), 不参与
|
|
267
|
+
# CLI 自身解析; 与 Go `os.Args[1:]`、C `argv[1..]` 的习惯一致。
|
|
268
|
+
if '--' in args:
|
|
269
|
+
sep = args.index('--')
|
|
270
|
+
program_args = args[sep + 1:]
|
|
271
|
+
args = args[:sep]
|
|
272
|
+
else:
|
|
273
|
+
program_args = []
|
|
274
|
+
|
|
222
275
|
# 中文 Windows 默认 stdout/stderr 是 GBK, 输出非 GBK 字符 (emoji 等) 会直接
|
|
223
276
|
# UnicodeEncodeError; 且重定向产物字节与 Go 路径 (恒 UTF-8) 不一致。
|
|
224
277
|
# 统一切成 UTF-8, 无法编码的字符以 ? 替换而不是崩溃。
|
|
@@ -234,8 +287,20 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
234
287
|
|
|
235
288
|
console = Console()
|
|
236
289
|
parser = build_parser()
|
|
290
|
+
|
|
291
|
+
# 程序文件之后的裸参数透传给 CIN 程序 (问题反馈 #3): 已知 CLI 选项
|
|
292
|
+
# (含取值) 仍归 argparse, 其余 token 归 arg_count()/arg(i)。
|
|
293
|
+
cli_args, direct_args = _extract_program_args(args, parser)
|
|
294
|
+
if direct_args:
|
|
295
|
+
for tok in direct_args:
|
|
296
|
+
if tok.startswith('-') and tok not in ('-',) \
|
|
297
|
+
and not tok.lstrip('-').split('=')[0].isdigit():
|
|
298
|
+
sys.stderr.write(
|
|
299
|
+
f"note: {tok!r} 不是 CLI 选项, 已作为程序参数传递 "
|
|
300
|
+
f"(arg_count/arg); 如需强制传参请用 `-- {tok}`\n")
|
|
301
|
+
|
|
237
302
|
try:
|
|
238
|
-
ns = parser.parse_args(
|
|
303
|
+
ns = parser.parse_args(cli_args)
|
|
239
304
|
except SystemExit as e:
|
|
240
305
|
# argparse 错误 (未知选项/非法数值): 已打印 usage, 返回其退出码
|
|
241
306
|
return int(e.code) if e.code is not None else 2
|
|
@@ -253,6 +318,11 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
253
318
|
sys.stdout.write(format_build_info() + "\n")
|
|
254
319
|
return 0
|
|
255
320
|
|
|
321
|
+
if ns.list_libs:
|
|
322
|
+
from .stdlib import format_library_report
|
|
323
|
+
sys.stdout.write(format_library_report() + "\n")
|
|
324
|
+
return 0
|
|
325
|
+
|
|
256
326
|
if ns.program is None:
|
|
257
327
|
console.print(Panel("No program file specified.\n"
|
|
258
328
|
"Use --help for usage information.",
|
|
@@ -261,6 +331,8 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
261
331
|
|
|
262
332
|
config = Config()
|
|
263
333
|
_apply_namespace(config, ns)
|
|
334
|
+
# 直传参数与 `--` 后参数合并 (直传在前, 位置顺序与命令行一致)
|
|
335
|
+
config.program_args = direct_args + program_args
|
|
264
336
|
config.validate()
|
|
265
337
|
|
|
266
338
|
program_file = ns.program
|
|
@@ -300,7 +372,7 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
300
372
|
|
|
301
373
|
try:
|
|
302
374
|
# 管道/重定向输入预读到 input_buffer: 让 input() 在原生与解释器路径下
|
|
303
|
-
# 都能读到 `"42" |
|
|
375
|
+
# 都能读到 `"42" | codecin t.cin` 这样的标准输入 (交互 TTY 不预读)。
|
|
304
376
|
try:
|
|
305
377
|
if sys.stdin is not None and not sys.stdin.isatty():
|
|
306
378
|
cpu.input_buffer = sys.stdin.read() or ""
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""运行配置与命令行参数解析。"""
|
|
2
2
|
|
|
3
|
-
from dataclasses import dataclass
|
|
4
|
-
from typing import Optional
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import List, Optional
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
@dataclass
|
|
@@ -41,6 +41,8 @@ class Config:
|
|
|
41
41
|
mmu: bool = False
|
|
42
42
|
# A4: 远程调试服务端口 (None = 不启动)
|
|
43
43
|
debug_server_port: Optional[int] = None
|
|
44
|
+
# 传给 CIN 程序的命令行参数 (cli 里 `--` 之后的参数; 供 arg_count()/arg(i))
|
|
45
|
+
program_args: List[str] = field(default_factory=list)
|
|
44
46
|
|
|
45
47
|
# 命令行解析请使用 codecin/cli.py build_parser() (argparse, 单一来源)。
|
|
46
48
|
# Config 仅承载运行配置, 由 cli._apply_namespace 填充。
|