codecin 6.2.2__tar.gz → 6.3.1__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-6.2.2 → codecin-6.3.1}/CHANGELOG.md +42 -0
- {codecin-6.2.2/codecin.egg-info → codecin-6.3.1}/PKG-INFO +3 -5
- {codecin-6.2.2 → codecin-6.3.1}/README.md +2 -4
- {codecin-6.2.2 → codecin-6.3.1}/codecin/__init__.py +1 -1
- {codecin-6.2.2 → codecin-6.3.1}/codecin/cli.py +25 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/cpu.py +21 -1
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/aot/aot.go +5 -1
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/keyboard.go +10 -1
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/keyboard_other.go +13 -9
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/keyboard_stub.go +3 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/keyboard_test.go +7 -7
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/keyboard_windows.go +30 -18
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/native.go +7 -1
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/version_gen.go +1 -1
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/vm.go +29 -24
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/main.go +14 -8
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native.py +6 -3
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native_codegen.py +1 -0
- {codecin-6.2.2 → codecin-6.3.1/codecin.egg-info}/PKG-INFO +3 -5
- {codecin-6.2.2 → codecin-6.3.1}/codecin.egg-info/SOURCES.txt +1 -0
- codecin-6.3.1/examples/terminal_cache_demo.cin +135 -0
- {codecin-6.2.2 → codecin-6.3.1}/LICENSE +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/MANIFEST.in +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/aot.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/assembler.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/cin.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/config.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/console.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/crom.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/cvm.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/disasm.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/environment.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/errors.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/isa.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/array.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/bigint.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/bits.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/bitset.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/codec.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/combin.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/conv.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/cppstd.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/cstd.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/csv.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/dp.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/ffi.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/fmt.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/frac.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/gostd.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/graph.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/gui.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/hash.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/heap.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/io.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/json.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/key.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/math.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/matrix.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/net.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/path.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/queue.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/rand.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/set.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/sort.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/stat.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/str.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/termux.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/test.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/text.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/time.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/token.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/tree.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/unionfind.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/validate.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/lib/vec.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/logger.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/memory.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/mkn.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/aot/stub_main.go.txt +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/build.ps1 +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/build.sh +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/compiler/codegen.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/compiler/compile_test.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/compiler/parser.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/compiler/syscalls.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/compiler/tokenizer.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/compiler/types.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/args.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/audio.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/audio_other.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/audio_test.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/audio_windows.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/canvas.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/console_other.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/console_windows.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/crom.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/encode.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/engine_test.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/ffi_nocgo.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/ffi_registry.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/ffi_unix.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/ffi_windows.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/gui.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/gui_stub.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/gui_test.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/gui_windows.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/gui_x11.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/host_test.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/hostcrypto.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/hostdesktop.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/hostnet.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/isa_gen.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/keyboard_termios_darwin.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/keyboard_termios_linux.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/keyboard_windows_test.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/lineedit.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/lineedit_test.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/lineint_unix.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/lineint_windows.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/mem_other.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/mem_windows.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/netsock.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/ops_ext.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/stdin.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/stdin_other.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/stdin_windows.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/system.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/termux.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/vkb_darwin.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/vkb_linux.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/engine/vkb_stub.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/go.mod +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/native/ir/ir.go +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/object.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/optimizer.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/packaging/__init__.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/packaging/archive.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/packaging/model.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/packaging/store.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/packaging/toml.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/packaging/vcs.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/pic.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/pic_api.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/pic_login.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/pic_registry.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/registers.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/stats.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/stdlib.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/toolkit.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin/version.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin.egg-info/dependency_links.txt +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin.egg-info/entry_points.txt +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin.egg-info/requires.txt +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/codecin.egg-info/top_level.txt +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/examples/args_demo.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/examples/asm_constants.asm +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/examples/bitwise_builtins.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/examples/control_flow.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/examples/enum_range_for.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/examples/gui_demo.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/examples/literals_types.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/examples/local_audio.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/examples/modules_demo.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/examples/stdlib_demo.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/examples/system_interaction.cin +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/misc/vim/ftdetect/codecin.vim +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/misc/vim/syntax/cin.vim +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/misc/vim/syntax/codecinasm.vim +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/misc/vscode-cin/.vscodeignore +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/misc/vscode-cin/README.md +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/misc/vscode-cin/build.bat +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/misc/vscode-cin/language-configuration.json +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/misc/vscode-cin/package.json +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/misc/vscode-cin/snippets/cin.json +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/misc/vscode-cin/syntaxes/cin.tmLanguage.json +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/pyproject.toml +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/script/bump_version.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/script/check_paths.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/script/gen_isa_docs.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/script/gen_native_isa.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/setup.cfg +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/setup.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_aggregate_and_const.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_all_libs_together.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_aot.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_assembler_ext.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_bin_compat.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_cin_host.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_cin_host_ext.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_cin_new_features.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_cin_syntax.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_cin_syntax_ext.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_cin_system.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_cli.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_compiler_errors.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_environment.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_examples.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_features_ab.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_features_import.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_features_importloc.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_ffi_net.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_gui.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_index_subscript_type.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_isa_single_source.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_issue_regress.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_keyboard.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_bigint.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_bitset.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_codec.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_combin.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_compat.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_csv.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_dp.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_fmt.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_frac.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_graph.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_heap.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_path.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_set.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_text.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_token.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_tree.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_lib_unionfind.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_libs.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_libs_ext.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_literals_and_bom.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_native_codegen.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_native_hardening.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_native_lib_lookup.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_nested_subscript_codegen.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_no_go_cli.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_object_link.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_p0_fixes.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_packaging.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_paths_consistency.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_sparse_memory.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_struct_value_semantics.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_switch_semantics.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_v620_cvm.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_v620_import.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_v620_mkn.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_v620_packaging.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_v620_pic.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_v620_pic_git.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_v620_pic_registry.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_version.py +0 -0
- {codecin-6.2.2 → codecin-6.3.1}/tests/test_workflows.py +0 -0
|
@@ -5,6 +5,48 @@
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
## [6.3.1] - 2026-10-25
|
|
9
|
+
|
|
10
|
+
一次以「终端缓存与实时输出」为主题的小版本:新增终端缓存技术,启动/编译期间
|
|
11
|
+
提前键入的内容不再丢失,程序输出在执行过程中即可实时呈现,终端交互与动态特效
|
|
12
|
+
更加生动流畅;同时保留完整输出缓存,管道 / 重定向 / 测试捕获行为保持不变。
|
|
13
|
+
|
|
14
|
+
### 新增 (Added)
|
|
15
|
+
|
|
16
|
+
#### 终端缓存技术
|
|
17
|
+
|
|
18
|
+
- **输入缓存 (type-ahead)**:键盘监听 / 交互式行输入首次激活时,不再清空
|
|
19
|
+
终端里尚未被读取的残留输入,而是读入统一的键码队列 —— 用户在程序启动、
|
|
20
|
+
编译期间提前键入的字符不会丢失,`get_key` / `key_wait` / `input` /
|
|
21
|
+
`input_str` 可直接消费。
|
|
22
|
+
- Windows 端同时跳过鼠标、窗口、焦点与 key-up 事件继续读取,避免队列
|
|
23
|
+
被非按键事件卡住。
|
|
24
|
+
- 需要主动丢弃旧输入时调用 `key_flush()`:清空键码队列、解码中间态与
|
|
25
|
+
终端残留输入(Windows `FlushConsoleInputBuffer`,Unix 非阻塞排空)。
|
|
26
|
+
- **输出缓存**:实时输出模式下,程序输出在逐条写往终端的同时仍完整保留在
|
|
27
|
+
执行结果中(`Result.Output`),新增 `streamed` 标记告知宿主"已实时显示、
|
|
28
|
+
不要重复打印";API 调用方与测试仍可读取完整输出。
|
|
29
|
+
- **运行前状态实时显示**:真实终端下依次输出 `Loading <文件> ...` →
|
|
30
|
+
`Loaded N instructions in X ms` → `Running ...`,编译/装载阶段不再黑屏
|
|
31
|
+
等待;`--log-level ERROR` 与管道输出保持干净。
|
|
32
|
+
- **演示程序**:新增 `examples/terminal_cache_demo.cin`,覆盖打字机/旋转指示器/
|
|
33
|
+
进度条实时动画、动画期间提前输入的文字与原始键码读取,以及 `key_flush()`
|
|
34
|
+
显式清理;直接运行 `codecin examples/terminal_cache_demo.cin` 即可体验。
|
|
35
|
+
|
|
36
|
+
### 变更 (Changed)
|
|
37
|
+
|
|
38
|
+
- **执行与输出时效性优化**:Python CLI 与 AOT 产物(VM 后端及生成的原生
|
|
39
|
+
后端)在真实终端下改为边执行边写标准输出,`print` / 终端绘制类特效不再
|
|
40
|
+
等整个程序结束后一次性出现;管道 / 重定向 / 测试捕获仍保持"缓冲 + 结束
|
|
41
|
+
回传",输出字节与旧版本完全一致。
|
|
42
|
+
- **原生 ABI 扩展**:`codecin_run_v2` 的 `flags` 新增 bit1 = 实时输出请求;
|
|
43
|
+
结果缓冲 36 字节头中 `offset 2` 由保留字节改为 `streamed` 标志(`offset 3`
|
|
44
|
+
仍为保留字节),布局与长度不变。
|
|
45
|
+
- 版本号提升至 **6.3.1**(`codecin/__init__.py` 单一真源,
|
|
46
|
+
`codecin/native/engine/version_gen.go` 同步)。
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
8
50
|
## [6.2.2] - 2026-10-24
|
|
9
51
|
|
|
10
52
|
一次以「注册服务与输入设备」为主题的小版本:`registry` 服务端由 Go 迁移到
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codecin
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.3.1
|
|
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
|
|
@@ -76,12 +76,10 @@ cvm env
|
|
|
76
76
|
安装后的包无需修改源码即可导入:
|
|
77
77
|
|
|
78
78
|
```cin
|
|
79
|
-
import "hello"
|
|
80
|
-
import "hello/util.cin"
|
|
79
|
+
import "hello"
|
|
80
|
+
import "hello/util.cin"
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
完整设计、格式与验收标准见 [V6.2.0-PLAN.md](V6.2.0-PLAN.md)。
|
|
84
|
-
|
|
85
83
|
## 文档
|
|
86
84
|
|
|
87
85
|
**官方文档站**位于独立仓库
|
|
@@ -58,12 +58,10 @@ cvm env
|
|
|
58
58
|
安装后的包无需修改源码即可导入:
|
|
59
59
|
|
|
60
60
|
```cin
|
|
61
|
-
import "hello"
|
|
62
|
-
import "hello/util.cin"
|
|
61
|
+
import "hello"
|
|
62
|
+
import "hello/util.cin"
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
完整设计、格式与验收标准见 [V6.2.0-PLAN.md](V6.2.0-PLAN.md)。
|
|
66
|
-
|
|
67
65
|
## 文档
|
|
68
66
|
|
|
69
67
|
**官方文档站**位于独立仓库
|
|
@@ -8,6 +8,7 @@ import argparse
|
|
|
8
8
|
import contextlib
|
|
9
9
|
import os
|
|
10
10
|
import sys
|
|
11
|
+
import time
|
|
11
12
|
from typing import List, Optional
|
|
12
13
|
|
|
13
14
|
from . import __version__
|
|
@@ -36,6 +37,14 @@ HELP_INTRO = f"""{Colors.colorize(f'Code CIN v{__version__}', Colors.CYAN, True)
|
|
|
36
37
|
"""
|
|
37
38
|
|
|
38
39
|
|
|
40
|
+
def _stdout_is_tty() -> bool:
|
|
41
|
+
"""stdout 是否为真实终端 (仅此时打印运行前进度状态)。"""
|
|
42
|
+
try:
|
|
43
|
+
return bool(sys.stdout is not None and sys.stdout.isatty())
|
|
44
|
+
except (OSError, ValueError, AttributeError):
|
|
45
|
+
return False
|
|
46
|
+
|
|
47
|
+
|
|
39
48
|
def build_parser() -> argparse.ArgumentParser:
|
|
40
49
|
"""参数表单一来源 (与 Config 字段一一对应)。"""
|
|
41
50
|
p = argparse.ArgumentParser(
|
|
@@ -446,6 +455,13 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
446
455
|
if ns.build_exe is not None:
|
|
447
456
|
return _run_aot_build(ns, console, program_file, config)
|
|
448
457
|
|
|
458
|
+
# 运行前进度/状态只在真实终端且未静音 (log-level ERROR) 时显示,
|
|
459
|
+
# 管道/重定向与"保持示例输出干净"的场景不受影响。
|
|
460
|
+
tty = _stdout_is_tty() and config.log_level.upper() not in ('ERROR', 'CRITICAL')
|
|
461
|
+
if tty:
|
|
462
|
+
console.print(Colors.colorize(
|
|
463
|
+
f"Loading {os.path.basename(program_file)} ...", Colors.CYAN))
|
|
464
|
+
load_started = time.perf_counter()
|
|
449
465
|
try:
|
|
450
466
|
from .cpu import CPU
|
|
451
467
|
cpu = CPU(config, program_file, crom_file=crom_file)
|
|
@@ -460,6 +476,12 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
460
476
|
console.print_exception()
|
|
461
477
|
return 1
|
|
462
478
|
|
|
479
|
+
if tty:
|
|
480
|
+
console.print(Colors.colorize(
|
|
481
|
+
f"Loaded {len(cpu.instructions)} instructions in "
|
|
482
|
+
f"{(time.perf_counter() - load_started) * 1000:.1f} ms",
|
|
483
|
+
Colors.GREEN))
|
|
484
|
+
|
|
463
485
|
try:
|
|
464
486
|
# 管道/重定向输入预读到 input_buffer: 让 input() 在原生与解释器路径下
|
|
465
487
|
# 都能读到 `"42" | codecin t.cin` 这样的标准输入 (交互 TTY 不预读)。
|
|
@@ -477,6 +499,9 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
477
499
|
if config.compile_only:
|
|
478
500
|
return 0
|
|
479
501
|
|
|
502
|
+
if tty:
|
|
503
|
+
console.print(Colors.colorize("Running ...", Colors.CYAN))
|
|
504
|
+
sys.stdout.flush() # 状态行先落盘, 程序实时输出紧随其后
|
|
480
505
|
cpu.run()
|
|
481
506
|
except KeyboardInterrupt:
|
|
482
507
|
pass
|
|
@@ -33,6 +33,14 @@ NATIVE_HINT = (
|
|
|
33
33
|
"或 codecin/native/build.sh (Linux/Termux/macOS), 然后重试。")
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
def _stdout_is_tty() -> bool:
|
|
37
|
+
"""stdout 是否为真实终端 (决定是否请求实时输出)。"""
|
|
38
|
+
try:
|
|
39
|
+
return bool(sys.stdout is not None and sys.stdout.isatty())
|
|
40
|
+
except (OSError, ValueError, AttributeError):
|
|
41
|
+
return False
|
|
42
|
+
|
|
43
|
+
|
|
36
44
|
class CPU:
|
|
37
45
|
def __init__(self, config, filename: Optional[str] = None,
|
|
38
46
|
crom_file: Optional[str] = None,
|
|
@@ -184,6 +192,13 @@ class CPU:
|
|
|
184
192
|
bytecode = encode_program(self.instructions, self.entry_pc, all_labels)
|
|
185
193
|
segments = self.memory.snapshot_segments()
|
|
186
194
|
import time as _time
|
|
195
|
+
# 真实终端 + 非捕获模式: 请求原生引擎边执行边输出 (输出缓存仍会回传)。
|
|
196
|
+
stream = (not self._capture_output) and _stdout_is_tty()
|
|
197
|
+
if stream:
|
|
198
|
+
try:
|
|
199
|
+
sys.stdout.flush() # 先落盘 Python 侧日志, 保证输出顺序
|
|
200
|
+
except (OSError, ValueError):
|
|
201
|
+
pass
|
|
187
202
|
t0 = _time.perf_counter()
|
|
188
203
|
result = engine.run_v2(
|
|
189
204
|
bytecode=bytecode,
|
|
@@ -197,6 +212,7 @@ class CPU:
|
|
|
197
212
|
args=list(self.config.program_args),
|
|
198
213
|
seed=self.config.seed,
|
|
199
214
|
sandbox=self.config.sandbox_mode,
|
|
215
|
+
stream_output=stream,
|
|
200
216
|
)
|
|
201
217
|
elapsed = _time.perf_counter() - t0
|
|
202
218
|
if result is None:
|
|
@@ -211,7 +227,11 @@ class CPU:
|
|
|
211
227
|
|
|
212
228
|
self._apply_native_state(result)
|
|
213
229
|
if result.get('output'):
|
|
214
|
-
|
|
230
|
+
if result.get('streamed'):
|
|
231
|
+
# 终端已实时显示; 这里只把完整输出放进缓存供调用方读取
|
|
232
|
+
self.output_buffer.append(result['output'])
|
|
233
|
+
else:
|
|
234
|
+
self._emit_text(result['output'])
|
|
215
235
|
if result.get('error'):
|
|
216
236
|
raise ExecutionError(result['error'])
|
|
217
237
|
return False
|
|
@@ -54,13 +54,17 @@ func Main(bytecode, segFile []byte) int {
|
|
|
54
54
|
MemSize: int64(memSize),
|
|
55
55
|
Input: in,
|
|
56
56
|
MaxSteps: maxSteps,
|
|
57
|
+
// AOT 产物在真实终端下边跑边输出; 管道/重定向保持结束一次性打印。
|
|
58
|
+
StreamOutput: true,
|
|
57
59
|
})
|
|
58
60
|
if res == nil {
|
|
59
61
|
fmt.Fprintln(os.Stderr, "runtime error: no result")
|
|
60
62
|
return 1
|
|
61
63
|
}
|
|
62
64
|
engine.ConsoleInit()
|
|
63
|
-
|
|
65
|
+
if !res.Streamed { // 实时模式下输出已写到终端, Output 只是缓存
|
|
66
|
+
fmt.Print(res.Output)
|
|
67
|
+
}
|
|
64
68
|
if res.Status == engine.StatusError ||
|
|
65
69
|
res.Status == engine.StatusUnsupported {
|
|
66
70
|
msg := res.ErrMsg
|
|
@@ -80,12 +80,17 @@ var keyOutSink = func(s string) {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
// keyEnsure 惰性启用键盘监听; 可重复调用 (恢复后再次调用会重新启用)。
|
|
83
|
-
// 返回是否"本次调用刚激活" (真实终端首次启用), 供 VM
|
|
83
|
+
// 返回是否"本次调用刚激活" (真实终端首次启用), 供 VM 切换实时输出。
|
|
84
|
+
// 激活时把终端里已经键入、尚未被程序读取的字符读入队列 (type-ahead 缓存),
|
|
85
|
+
// 不丢弃 —— 用户在程序启动/编译期间敲下的输入不会丢失。
|
|
84
86
|
func keyEnsure() bool {
|
|
85
87
|
keyMu.Lock()
|
|
86
88
|
defer keyMu.Unlock()
|
|
87
89
|
if !keyReady && !keyForcedOff {
|
|
88
90
|
keyReady = keyEnablePlatform()
|
|
91
|
+
if keyReady {
|
|
92
|
+
keyDrainLocked()
|
|
93
|
+
}
|
|
89
94
|
return keyReady
|
|
90
95
|
}
|
|
91
96
|
return false
|
|
@@ -155,6 +160,7 @@ func (vm *vmState) keyGet() uint64 {
|
|
|
155
160
|
}
|
|
156
161
|
|
|
157
162
|
// keyFlush SYS 118: key_flush() 清空键码队列与解码中间态 -> 0
|
|
163
|
+
// 同时丢弃终端里尚未读取的输入缓存, 避免下一次轮询又把旧键读回来。
|
|
158
164
|
func (vm *vmState) keyFlush() uint64 {
|
|
159
165
|
if keyEnsure() {
|
|
160
166
|
vm.enterDirectOut()
|
|
@@ -168,6 +174,9 @@ func (vm *vmState) keyFlush() uint64 {
|
|
|
168
174
|
keyU8N = 0
|
|
169
175
|
keyU8Acc = 0
|
|
170
176
|
keyResetPlatform()
|
|
177
|
+
if keyReady {
|
|
178
|
+
keyFlushPlatform()
|
|
179
|
+
}
|
|
171
180
|
return 0
|
|
172
181
|
}
|
|
173
182
|
|
|
@@ -31,15 +31,7 @@ func keyEnablePlatform() bool {
|
|
|
31
31
|
if ttyIoctl(ttySetAttr, &raw) != nil {
|
|
32
32
|
return false
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
// 已是非阻塞 (VMIN=0/VTIME=0): read 无输入时立即返回 0, 不会卡住。
|
|
36
|
-
var b [64]byte
|
|
37
|
-
for {
|
|
38
|
-
n, err := syscall.Read(0, b[:])
|
|
39
|
-
if n <= 0 || err != nil {
|
|
40
|
-
break
|
|
41
|
-
}
|
|
42
|
-
}
|
|
34
|
+
|
|
43
35
|
return true
|
|
44
36
|
}
|
|
45
37
|
|
|
@@ -53,6 +45,18 @@ func keyRestorePlatform() {
|
|
|
53
45
|
// keyResetPlatform 重置平台侧解码中间态 (key_flush 调用; Unix 无)。
|
|
54
46
|
func keyResetPlatform() {}
|
|
55
47
|
|
|
48
|
+
// keyFlushPlatform 丢弃内核输入队列里尚未读取的字节 (key_flush)。
|
|
49
|
+
// 仅在 raw 模式 (VMIN=0/VTIME=0) 下调用, read 无输入时立即返回 0。
|
|
50
|
+
func keyFlushPlatform() {
|
|
51
|
+
var b [64]byte
|
|
52
|
+
for {
|
|
53
|
+
n, err := syscall.Read(0, b[:])
|
|
54
|
+
if n <= 0 || err != nil {
|
|
55
|
+
break
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
56
60
|
// keyNext 非阻塞读 stdin 并经转义序列状态机解码。
|
|
57
61
|
func keyNext() (uint64, bool) {
|
|
58
62
|
for {
|
|
@@ -178,8 +178,8 @@ func TestKeyHitAndDrainGuard(t *testing.T) {
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
// TestEnterDirectOutStreamsBuffer
|
|
182
|
-
// 之后 outWrite
|
|
181
|
+
// TestEnterDirectOutStreamsBuffer 实时输出模式: 激活时先把已缓冲输出落盘,
|
|
182
|
+
// 之后 outWrite 逐条直写, 同时缓冲保留完整缓存 (Result.Output 仍可读取)。
|
|
183
183
|
func TestEnterDirectOutStreamsBuffer(t *testing.T) {
|
|
184
184
|
resetKeyState()
|
|
185
185
|
defer resetKeyState()
|
|
@@ -191,21 +191,21 @@ func TestEnterDirectOutStreamsBuffer(t *testing.T) {
|
|
|
191
191
|
vm := newHostVM(4096)
|
|
192
192
|
vm.outWrite("A")
|
|
193
193
|
if vm.out.String() != "A" {
|
|
194
|
-
t.Fatalf("
|
|
194
|
+
t.Fatalf("实时输出激活前输出应留在缓冲, 实际 %q", vm.out.String())
|
|
195
195
|
}
|
|
196
196
|
vm.enterDirectOut()
|
|
197
197
|
if len(got) != 1 || got[0] != "A" {
|
|
198
198
|
t.Fatalf("激活时应把已缓冲输出落盘, 实际 %v", got)
|
|
199
199
|
}
|
|
200
|
-
if vm.out.
|
|
201
|
-
t.
|
|
200
|
+
if vm.out.String() != "A" || !vm.outDirect {
|
|
201
|
+
t.Fatalf("激活后应保留输出缓存且置实时标志, 实际 %q", vm.out.String())
|
|
202
202
|
}
|
|
203
203
|
vm.outWrite("B")
|
|
204
204
|
if len(got) != 2 || got[1] != "B" {
|
|
205
205
|
t.Fatalf("激活后输出应逐条直写, 实际 %v", got)
|
|
206
206
|
}
|
|
207
|
-
if vm.out.
|
|
208
|
-
t.Fatalf("
|
|
207
|
+
if vm.out.String() != "AB" {
|
|
208
|
+
t.Fatalf("实时模式下仍应缓存完整输出, 实际 %q", vm.out.String())
|
|
209
209
|
}
|
|
210
210
|
if vm.outCount != 2 {
|
|
211
211
|
t.Fatalf("outCount 应累计 2, 实际 %d", vm.outCount)
|
|
@@ -52,8 +52,8 @@ var (
|
|
|
52
52
|
keySurrogate rune // UTF-16 高代理缓存 (与下一事件低代理组合)
|
|
53
53
|
)
|
|
54
54
|
|
|
55
|
-
// keyEnablePlatform 校验 stdin
|
|
56
|
-
//
|
|
55
|
+
// keyEnablePlatform 校验 stdin 为真实控制台后启用。启动前已键入的字符
|
|
56
|
+
// 不再丢弃: keyEnsure 会立即把它们读入键码队列 (终端输入缓存)。
|
|
57
57
|
func keyEnablePlatform() bool {
|
|
58
58
|
h := consoleHandle()
|
|
59
59
|
if h == 0 {
|
|
@@ -71,7 +71,6 @@ func keyEnablePlatform() bool {
|
|
|
71
71
|
raw |= cmExtendedFlags
|
|
72
72
|
raw &^= cmQuickEdit
|
|
73
73
|
_, _, _ = procSetConsoleMode.Call(h, uintptr(raw))
|
|
74
|
-
_, _, _ = procFlushInputBuf.Call(h)
|
|
75
74
|
return true
|
|
76
75
|
}
|
|
77
76
|
|
|
@@ -87,6 +86,13 @@ func keyRestorePlatform() {
|
|
|
87
86
|
// keyResetPlatform 重置平台侧解码中间态 (key_flush 调用)。
|
|
88
87
|
func keyResetPlatform() { keySurrogate = 0 }
|
|
89
88
|
|
|
89
|
+
// keyFlushPlatform 丢弃控制台输入缓冲里尚未读取的残留事件 (key_flush)。
|
|
90
|
+
func keyFlushPlatform() {
|
|
91
|
+
if h := consoleHandle(); h != 0 {
|
|
92
|
+
_, _, _ = procFlushInputBuf.Call(h)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
90
96
|
func consoleHandle() uintptr {
|
|
91
97
|
h, _, _ := procGetStdHandle.Call(stdInputHandle)
|
|
92
98
|
return h
|
|
@@ -105,27 +111,33 @@ var vkKeycode = map[uint16]uint64{
|
|
|
105
111
|
// keyNext 非阻塞取下一个已解码键码 (PeekConsoleInputW 先行探测, 不会阻塞)。
|
|
106
112
|
// INPUT_RECORD/KEY_EVENT_RECORD 按固定偏移手工解码
|
|
107
113
|
// (sizeof(INPUT_RECORD)=20; keyDown@4 repeat@8 vk@10 char@14 state@16)。
|
|
114
|
+
// 鼠标/窗口/焦点事件与 key-up 事件直接丢弃并继续读, 直到取到按键或队列为空。
|
|
108
115
|
func keyNext() (uint64, bool) {
|
|
109
116
|
h := consoleHandle()
|
|
110
117
|
if h == 0 {
|
|
111
118
|
return 0, false
|
|
112
119
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
uintptr(unsafe.Pointer(&
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
uintptr(unsafe.Pointer(&
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
120
|
+
for {
|
|
121
|
+
var buf [20]byte
|
|
122
|
+
var n uint32
|
|
123
|
+
r, _, _ := procPeekInput.Call(h, uintptr(unsafe.Pointer(&buf[0])), 1,
|
|
124
|
+
uintptr(unsafe.Pointer(&n)))
|
|
125
|
+
if r == 0 || n == 0 {
|
|
126
|
+
return 0, false
|
|
127
|
+
}
|
|
128
|
+
r, _, _ = procReadInput.Call(h, uintptr(unsafe.Pointer(&buf[0])), 1,
|
|
129
|
+
uintptr(unsafe.Pointer(&n)))
|
|
130
|
+
if r == 0 || n == 0 {
|
|
131
|
+
return 0, false
|
|
132
|
+
}
|
|
133
|
+
if le16(buf[0:2]) != evtKeyEvent {
|
|
134
|
+
continue // 鼠标/窗口/焦点等事件: 已读出并丢弃
|
|
135
|
+
}
|
|
136
|
+
if code, ok := decodeKeyEvent(buf[4:20]); ok {
|
|
137
|
+
return code, true
|
|
138
|
+
}
|
|
139
|
+
// key-up / 修饰键 / 代理对中间态: 继续读下一个事件
|
|
127
140
|
}
|
|
128
|
-
return decodeKeyEvent(buf[4:20])
|
|
129
141
|
}
|
|
130
142
|
|
|
131
143
|
func le16(b []byte) uint16 { return uint16(b[0]) | uint16(b[1])<<8 }
|
|
@@ -85,6 +85,12 @@ func NewNativeRuntime(memSize, sp, heapBase int64, segments []MemSeg,
|
|
|
85
85
|
// SetInput 设置 stdin 重定向数据 (IN 指令使用)。
|
|
86
86
|
func (r *NativeRuntime) SetInput(data []byte) { r.vm.inData = data }
|
|
87
87
|
|
|
88
|
+
// SetStreamOutput 请求实时输出 (AOT 产物): 真实终端下逐条直写 stdout,
|
|
89
|
+
// 同时保留完整缓存 (Finish 不会再打印缓存, 避免重复)。
|
|
90
|
+
func (r *NativeRuntime) SetStreamOutput(on bool) {
|
|
91
|
+
r.vm.outDirect = on && stdoutIsTerminal()
|
|
92
|
+
}
|
|
93
|
+
|
|
88
94
|
// SetSandbox 打开沙箱宿主调用限制。
|
|
89
95
|
func (r *NativeRuntime) SetSandbox(on bool) { r.vm.sandbox = on }
|
|
90
96
|
|
|
@@ -620,7 +626,7 @@ func (r *NativeRuntime) Finish(ok bool) int {
|
|
|
620
626
|
r.errMsg = "output limit exceeded (16 MiB)"
|
|
621
627
|
}
|
|
622
628
|
}
|
|
623
|
-
if r.vm.out.Len() > 0 {
|
|
629
|
+
if r.vm.out.Len() > 0 && !r.vm.outDirect {
|
|
624
630
|
fmt.Print(r.vm.out.String())
|
|
625
631
|
}
|
|
626
632
|
if ok {
|
|
@@ -57,7 +57,7 @@ type vmState struct {
|
|
|
57
57
|
out strings.Builder
|
|
58
58
|
outOver bool // 输出超过 maxOutputBytes (截断并置错误)
|
|
59
59
|
outCount int // 两种模式的累计输出字节 (16 MiB 限额依据)
|
|
60
|
-
outDirect bool //
|
|
60
|
+
outDirect bool // 实时输出模式: 逐条直写 stdout, 同时保留缓冲 (Result.Output 缓存)
|
|
61
61
|
sysIdx int
|
|
62
62
|
rng *rand.Rand
|
|
63
63
|
inData []byte
|
|
@@ -144,10 +144,9 @@ func (vm *vmState) outWrite(s string) {
|
|
|
144
144
|
}
|
|
145
145
|
vm.outCount += len(s)
|
|
146
146
|
if vm.outDirect {
|
|
147
|
-
keyOutSink(s)
|
|
148
|
-
return
|
|
147
|
+
keyOutSink(s) // 实时可见
|
|
149
148
|
}
|
|
150
|
-
vm.out.WriteString(s)
|
|
149
|
+
vm.out.WriteString(s) // 同时缓存: 调用方仍可通过 Result.Output 读取完整输出
|
|
151
150
|
}
|
|
152
151
|
|
|
153
152
|
// outByte 追加单字节输出 (同上限)。
|
|
@@ -161,16 +160,15 @@ func (vm *vmState) outByte(b byte) {
|
|
|
161
160
|
}
|
|
162
161
|
vm.outCount++
|
|
163
162
|
if vm.outDirect {
|
|
164
|
-
keyOutSink(string(b))
|
|
165
|
-
return
|
|
163
|
+
keyOutSink(string(b)) // 实时可见
|
|
166
164
|
}
|
|
167
|
-
vm.out.WriteByte(b)
|
|
165
|
+
vm.out.WriteByte(b) // 同时缓存
|
|
168
166
|
}
|
|
169
167
|
|
|
170
|
-
// enterDirectOut
|
|
171
|
-
//
|
|
172
|
-
//
|
|
173
|
-
//
|
|
168
|
+
// enterDirectOut 切换到实时输出模式: 先把已缓冲输出落到终端 (激活前的提示
|
|
169
|
+
// 先显示), 之后输出逐条直写 stdout, 不再等程序结束。缓冲保留, 因此
|
|
170
|
+
// Result.Output 仍包含完整输出 (输出缓存), 调用方依据 Streamed 跳过重复打印。
|
|
171
|
+
// 非终端 (管道/测试捕获) 不会主动切换; 键盘监听激活时也可能走到这里。
|
|
174
172
|
func (vm *vmState) enterDirectOut() {
|
|
175
173
|
if vm.outDirect {
|
|
176
174
|
return
|
|
@@ -178,7 +176,6 @@ func (vm *vmState) enterDirectOut() {
|
|
|
178
176
|
vm.outDirect = true
|
|
179
177
|
if vm.out.Len() > 0 {
|
|
180
178
|
keyOutSink(vm.out.String())
|
|
181
|
-
vm.out.Reset()
|
|
182
179
|
}
|
|
183
180
|
}
|
|
184
181
|
|
|
@@ -199,6 +196,7 @@ type Result struct {
|
|
|
199
196
|
Vec [32][4]float64
|
|
200
197
|
Flags struct{ N, Z, C, V bool }
|
|
201
198
|
Output string
|
|
199
|
+
Streamed bool // 输出已实时写到终端 (Output 仅为缓存, 调用方不要再打印)
|
|
202
200
|
ErrMsg string
|
|
203
201
|
Segments []MemSeg // 脏页合并段 (稀疏内存回传)
|
|
204
202
|
MemSize int64
|
|
@@ -216,6 +214,9 @@ type RunOptions struct {
|
|
|
216
214
|
MaxSteps int64
|
|
217
215
|
Sandbox bool // 沙箱: 屏蔽宿主能力系统调用
|
|
218
216
|
Seed int64 // 随机种子; 0 = 时间随机
|
|
217
|
+
// StreamOutput 请求实时输出: 真实终端下边执行边写 stdout,
|
|
218
|
+
// 同时保留完整输出缓存 (Result.Output)。非终端忽略此请求。
|
|
219
|
+
StreamOutput bool
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
func decodeBytecode(bc []byte) ([]instruction, int, bool) {
|
|
@@ -318,6 +319,8 @@ func RunV2(opts *RunOptions) *Result {
|
|
|
318
319
|
if opts.Seed != 0 {
|
|
319
320
|
vm.rng.Seed(opts.Seed)
|
|
320
321
|
}
|
|
322
|
+
// 真实终端才启用实时输出; 管道/重定向/测试捕获保持"结束一次性回传"。
|
|
323
|
+
vm.outDirect = opts.StreamOutput && stdoutIsTerminal()
|
|
321
324
|
vm.dirtyBits = make([]uint64,
|
|
322
325
|
(uint64(memSize)+(1<<(dirtyPageShift+6))-1)>>(dirtyPageShift+6))
|
|
323
326
|
// 初始段视为已写内容: 数据段通常会被改写, 直接并入脏位图, 免去逐字节 touch。
|
|
@@ -341,16 +344,17 @@ func RunV2(opts *RunOptions) *Result {
|
|
|
341
344
|
}
|
|
342
345
|
}
|
|
343
346
|
r := &Result{
|
|
344
|
-
Status:
|
|
345
|
-
Pc:
|
|
346
|
-
Sp:
|
|
347
|
-
HeapPtr:
|
|
348
|
-
Steps:
|
|
349
|
-
Regs:
|
|
350
|
-
Vec:
|
|
351
|
-
Output:
|
|
352
|
-
|
|
353
|
-
|
|
347
|
+
Status: status,
|
|
348
|
+
Pc: vm.pc,
|
|
349
|
+
Sp: vm.sp,
|
|
350
|
+
HeapPtr: vm.heapPtr,
|
|
351
|
+
Steps: vm.steps,
|
|
352
|
+
Regs: vm.regs,
|
|
353
|
+
Vec: vm.vec,
|
|
354
|
+
Output: vm.out.String(),
|
|
355
|
+
Streamed: vm.outDirect,
|
|
356
|
+
ErrMsg: errMsg,
|
|
357
|
+
MemSize: memSize,
|
|
354
358
|
}
|
|
355
359
|
r.Flags.N, r.Flags.Z, r.Flags.C, r.Flags.V = vm.flags.N, vm.flags.Z, vm.flags.C, vm.flags.V
|
|
356
360
|
r.Segments = vm.dirtySegments()
|
|
@@ -1055,14 +1059,15 @@ func (vm *vmState) prepareQueryInput() {
|
|
|
1055
1059
|
// flushOut 在阻塞读标准输入前, 把已缓冲输出冲刷到真实终端。
|
|
1056
1060
|
// 仅在 stdout 为终端时生效 (交互提示可见); 管道/重定向/测试捕获保持
|
|
1057
1061
|
// 纯缓冲语义 —— 输出仍随 Result.Output 一次性回传, 字节序列不变。
|
|
1058
|
-
//
|
|
1062
|
+
// 冲刷后保持实时模式且不清空缓存: 后续输出继续直写, Result.Output 仍是
|
|
1063
|
+
// 完整缓存 (Result.Streamed=true, Python 侧据此不重复打印)。
|
|
1059
1064
|
func (vm *vmState) flushOut() {
|
|
1060
1065
|
if vm.outDirect || vm.out.Len() == 0 || !stdoutIsTerminal() {
|
|
1061
1066
|
return
|
|
1062
1067
|
}
|
|
1063
1068
|
consoleInit()
|
|
1064
1069
|
keyOutSink(vm.out.String())
|
|
1065
|
-
vm.
|
|
1070
|
+
vm.outDirect = true
|
|
1066
1071
|
}
|
|
1067
1072
|
|
|
1068
1073
|
// ---------------- SYS ----------------
|
|
@@ -25,7 +25,7 @@ import (
|
|
|
25
25
|
// err_len u16 | err ...
|
|
26
26
|
|
|
27
27
|
// v2 结果缓冲布局 (与 codecin/native.py _parse_result_v2 严格一致):
|
|
28
|
-
// status u8 | NZCV 标志 u8 (bit0=N bit1=Z bit2=C bit3=V) |
|
|
28
|
+
// status u8 | NZCV 标志 u8 (bit0=N bit1=Z bit2=C bit3=V) | streamed u8 | pad u8
|
|
29
29
|
// pc u64 sp u64 heap_ptr u64 steps u64
|
|
30
30
|
// regs 33×u64
|
|
31
31
|
// vec 32×4×f64
|
|
@@ -158,6 +158,7 @@ func marshalResultV2(res *engine.Result) unsafe.Pointer {
|
|
|
158
158
|
|
|
159
159
|
var status byte
|
|
160
160
|
var flg byte
|
|
161
|
+
var streamed byte
|
|
161
162
|
pc, sp, heap, steps := uint64(0), uint64(0), uint64(0), uint64(0)
|
|
162
163
|
var regs [33]uint64
|
|
163
164
|
var vec [32][4]float64
|
|
@@ -184,6 +185,9 @@ func marshalResultV2(res *engine.Result) unsafe.Pointer {
|
|
|
184
185
|
if res.Flags.V {
|
|
185
186
|
flg |= 8
|
|
186
187
|
}
|
|
188
|
+
if res.Streamed {
|
|
189
|
+
streamed = 1
|
|
190
|
+
}
|
|
187
191
|
}
|
|
188
192
|
|
|
189
193
|
segsBytes := 0
|
|
@@ -195,6 +199,7 @@ func marshalResultV2(res *engine.Result) unsafe.Pointer {
|
|
|
195
199
|
|
|
196
200
|
buf[0] = status
|
|
197
201
|
buf[1] = flg
|
|
202
|
+
buf[2] = streamed
|
|
198
203
|
pos := 4
|
|
199
204
|
binary.LittleEndian.PutUint64(buf[pos:], pc)
|
|
200
205
|
binary.LittleEndian.PutUint64(buf[pos+8:], sp)
|
|
@@ -276,13 +281,14 @@ func codecin_run_v2(reqPtr unsafe.Pointer, reqLen C.int,
|
|
|
276
281
|
}
|
|
277
282
|
|
|
278
283
|
opts := &engine.RunOptions{
|
|
279
|
-
Entry:
|
|
280
|
-
SP:
|
|
281
|
-
HeapBase:
|
|
282
|
-
MemSize:
|
|
283
|
-
MaxSteps:
|
|
284
|
-
Seed:
|
|
285
|
-
Sandbox:
|
|
284
|
+
Entry: int64(entry),
|
|
285
|
+
SP: int64(sp),
|
|
286
|
+
HeapBase: int64(heapBase),
|
|
287
|
+
MemSize: int64(memSize),
|
|
288
|
+
MaxSteps: int64(maxSteps),
|
|
289
|
+
Seed: int64(seed),
|
|
290
|
+
Sandbox: flags&1 != 0,
|
|
291
|
+
StreamOutput: flags&2 != 0,
|
|
286
292
|
}
|
|
287
293
|
pos := 0
|
|
288
294
|
bcLen := readU32(&pos)
|