diff --git a/bin/message.py b/bin/message.py index b65a063..e72101b 100644 --- a/bin/message.py +++ b/bin/message.py @@ -1,6 +1,5 @@ import sys import os -import inspect from typing import Optional from path import BIN_PATH @@ -11,11 +10,16 @@ def debug_print(message, prefix: Optional[str] = None, err = False): prefix: prefix to show; script path if None """ - call_stack = inspect.stack() - script_path = call_stack[1].filename if len(call_stack) >= 2 else "??" + try: + frame = sys._getframe(1) + script_path = frame.f_code.co_filename + script_line = frame.f_lineno + except ValueError: + script_path = "??" + script_line = 0 + script_path = os.path.relpath(script_path, start=BIN_PATH) - script_line = call_stack[1].lineno prefix_message = f"{script_path}:{script_line}" if prefix is None else str(prefix) - print(f"\x1b[{31 if err else 32}m\x1b[1m[{prefix_message}]\x1b[m {str(message)}", file=sys.stderr) \ No newline at end of file + print(f"\x1b[{31 if err else 32}m\x1b[1m[{prefix_message}]\x1b[m {str(message)}", file=sys.stderr) diff --git a/bin/run.py b/bin/run.py index 70e5257..462ba25 100644 --- a/bin/run.py +++ b/bin/run.py @@ -1,7 +1,6 @@ import os import subprocess -from engine import rewrite from message import debug_print from path import BIN_PATH @@ -31,6 +30,8 @@ def compile(source_path): base_cpp = fp.read() with open(source_path, "w", encoding="utf8") as fp: fp.write(base_cpp) + from engine import rewrite + rewrite(source_path, [], []) debug_print(f"Compiling {source_path} ...") @@ -89,4 +90,4 @@ def execute(source_path, just=False, force=False): compile_if_modified(source_path) if not just: - exec(exec_path_of(source_path)) \ No newline at end of file + exec(exec_path_of(source_path)) diff --git a/bin/ysn b/bin/ysn index 93f7eda..7d42161 100755 --- a/bin/ysn +++ b/bin/ysn @@ -5,11 +5,44 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJ_DIR="$(dirname "$SCRIPT_DIR")" VENV_ACTIVATE="$PROJ_DIR/.env/bin/activate" +# Most paths still need Python, so fail early with a setup hint if the venv is missing. if [ ! -f "$VENV_ACTIVATE" ]; then printf 'Python environment is missing. Run ./setup.sh from %s first.\n' "$PROJ_DIR" >&2 exit 1 fi +# Fast path for the hot loop: `ysn a` can directly run `a.exe` when it is newer +# than `a.cpp`. Any option, dotted path, missing binary, or stale binary falls +# through to the Python implementation. +if [ "$#" -eq 1 ] && [[ "$1" != -* ]] && [[ "$1" != *.* ]]; then + SOURCE_PATH="$1.cpp" + EXEC_PATH="$1.exe" + + if [ -f "$SOURCE_PATH" ] && [ -x "$EXEC_PATH" ] && [ "$EXEC_PATH" -nt "$SOURCE_PATH" ]; then + if [[ "$EXEC_PATH" = /* ]]; then + RUN_PATH="$EXEC_PATH" + else + RUN_PATH="./$EXEC_PATH" + fi + + printf '\033[32m\033[1m[ysn]\033[m Fast path: Executing %s ...\n' "$EXEC_PATH" >&2 + start_us="${EPOCHREALTIME/./}" + set +e + "$RUN_PATH" + status="$?" + set -e + end_us="${EPOCHREALTIME/./}" + duration_ms="$(((end_us - start_us) / 1000))" + + if [ "$status" -eq 0 ]; then + printf '\033[32m\033[1m[ysn]\033[m Successfully exited in %s ms\n' "$duration_ms" >&2 + else + printf '\033[31m\033[1m[ysn]\033[m Execution failed in return code %s after %s ms\n' "$status" "$duration_ms" >&2 + fi + exit "$status" + fi +fi + # shellcheck disable=SC1090 source "$VENV_ACTIVATE" exec python "$SCRIPT_DIR/ysn.py" "$@" diff --git a/bin/ysn.py b/bin/ysn.py index 8b0db1a..d0323f5 100644 --- a/bin/ysn.py +++ b/bin/ysn.py @@ -3,7 +3,6 @@ import argparse import os -from engine import rewrite from run import execute def normalize_source_path(source_path: str) -> str: @@ -40,10 +39,12 @@ def normalize_module_name(module_name: str) -> str: if args.install is None and args.remove is None: execute(normalized_source_path, just=args.just, force=args.force) else: + from engine import rewrite + installed_modules = args.install if args.install is not None else [] removed_modules = args.remove if args.remove is not None else [] installed_modules = list(map(normalize_module_name, installed_modules)) removed_modules = list(map(normalize_module_name, removed_modules)) - rewrite(normalized_source_path, installed_modules, removed_modules) \ No newline at end of file + rewrite(normalized_source_path, installed_modules, removed_modules)