ASTpytcl 0.1.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.
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.4
2
+ Name: ASTpytcl
3
+ Version: 0.1.1
4
+ Summary: A zero-dependency, CPython-AST-powered Tcl environment with Python FFI and macro bridges
5
+ Author: erider0x90
6
+ Project-URL: Homepage, https://tclpy.github.io/TCLpy/
7
+ Project-URL: Repository, https://github.com/TCLpy/TCLpy
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ Provides-Extra: dev
14
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
15
+ Requires-Dist: pyinstaller>=5.0.0; extra == "dev"
16
+
17
+ <p align="center">
18
+ <img src="assets/LogoTCLpy.jpg" alt="TCLpy Astrolabe Snake Logo" width="220" style="border-radius: 12px;">
19
+ </p>
20
+
21
+ # TCLpy 🚀
22
+
23
+
24
+ **A Lightweight, Zero-Dependency Tcl-to-Python Compiler & FFI Bridge**
25
+
26
+ `tclpy` is a high-performance, open-source Tcl-to-Python bridge and execution engine. Instead of running a string-based interpreter, `tclpy` compiles Tcl source code directly into native CPython AST nodes (`ast.Assign`, `ast.If`, `ast.For`, `ast.Call`), delivering seamless Python interoperability while preserving Tcl's core "everything is a string" command semantics. `tclpy` was inspired by hylang. We want to bring the fun back to coding in TCL.
27
+
28
+ ---
29
+
30
+ ## Key Features
31
+
32
+ - **AST-Based Compilation**: Compiles Tcl control flow, variable bindings, and command calls directly into CPython Abstract Syntax Tree nodes for native execution speed.
33
+ - **Direct Python Interop**: Import any Python module or standard library package via `py::import` and invoke functions using Tcl's double-colon notation (`math::sqrt`, `os::listdir`).
34
+ - **Unified Scope Model**: Shares state transparently between Tcl `proc` definitions, variable namespaces, and Python objects.
35
+ - **Tcl-First Presentation**: Internal storage leverages high-performance Python objects, while external output marshaling formats collections into traditional space-separated Tcl strings.
36
+ - **Zero-Overhead Hybrid Execution**: Keeps Tcl managing high-level application state, event loops, and logic, while executing Python object-heavy operations smoothly.
37
+ - **Minimalist Design Philosophy**: Avoids unnecessary AST bloat by providing `py_exec` for inline Python edge cases rather than polluting the core grammar.
38
+
39
+ ---
40
+
41
+ ## Recent Features & Capabilities
42
+
43
+ - **TCP Socket Support**: Full support for client connections (`socket host port`) and background server listeners (`socket -server callback port`) using multithreading and environment-bound callback execution.
44
+ - **Channel & Flush Operations**: Interoperable channel management (`_open_channels`) supporting `open`, `gets`, `puts`, `close`, and `flush` across both files and network streams.
45
+ - **Extended String Command Suite**: Comprehensive implementation of Tcl `string` subcommands including `length`, `index`, `range`, `compare`, `equal`, `first`, `last`, `match`, `map`, `toupper`, `tolower`, `trim`, `replace`, and `is`.
46
+
47
+ ---
48
+
49
+ ## Core Command Set
50
+
51
+ | Category | Commands |
52
+ | :--- | :--- |
53
+ | **Variables & Data** | `set`, `unset`, `incr` |
54
+ | **Control Flow** | `if` / `elseif` / `else`, `while`, `foreach`, `break`, `continue` |
55
+ | **Procedures & Logic** | `proc`, `return`, `expr` |
56
+ | **Collections** | `llength`, `lindex`, `lappend` |
57
+ | **I/O & Output** | `puts`, `read`, `gets`, `open`, `close`, `socket`, `flush` |
58
+ | **Python Bridge** | `py::import` (access Python libraries), `py_exec` (run inline Python code) |
59
+
60
+ ---
61
+
62
+ ### String Operations Quick Reference
63
+
64
+ | Operation | Syntax Example | Description | Result |
65
+ | :--- | :--- | :--- | :--- |
66
+ | **length** | `string length "Hello"` | Returns the number of characters. | `5` |
67
+ | **index** | `string index "Tcl" 1` | Retrieves the character at a 0-based index. | `c` |
68
+ | **range** | `string range "Python" 0 2` | Extracts a substring from start to end index. | `Pyt` |
69
+ | **compare** | `string compare "abc" "def"` | Lexicographically compares two strings (-1, 0, 1). | `-1` |
70
+ | **equal** | `string equal -nocase "A" "a"` | Returns 1 if identical, 0 otherwise. | `1` |
71
+ | **first** | `string first "bc" "abcde"` | Finds first index of a substring. | `1` |
72
+ | **last** | `string last "a" "banana"` | Finds last index of a substring. | `5` |
73
+ | **match** | `string match "test*" "testing"` | Performs glob-style wildcard pattern matching. | `1` |
74
+ | **map** | `string map {a 1 b 2} "abab"` | Replaces substrings based on key-value pairs. | `1212` |
75
+ | **replace** | `string replace "I like Java" 7 10 "Tcl"` | Replaces a range of characters. | `"I like Tcl"` |
76
+ | **tolower** | `string tolower "HELLO"` | Converts string to lowercase. | `"hello"` |
77
+ | **toupper** | `string toupper "hello"` | Converts string to uppercase. | `"HELLO"` |
78
+ | **trim** | `string trim " abc "` | Strips leading/trailing whitespaces. | `"abc"` |
79
+ | **is** | `string is integer -strict "123"` | Validates character classes. | `1` |
80
+
81
+ ---
82
+
83
+ ## Quickstart & Installation
84
+
85
+ ```bash
86
+ git clone [https://github.com/TCLpy/TCLpy.git](https://github.com/TCLpy/TCLpy.git)
87
+ cd tclpy
88
+ pip install -e .
@@ -0,0 +1,72 @@
1
+ <p align="center">
2
+ <img src="assets/LogoTCLpy.jpg" alt="TCLpy Astrolabe Snake Logo" width="220" style="border-radius: 12px;">
3
+ </p>
4
+
5
+ # TCLpy 🚀
6
+
7
+
8
+ **A Lightweight, Zero-Dependency Tcl-to-Python Compiler & FFI Bridge**
9
+
10
+ `tclpy` is a high-performance, open-source Tcl-to-Python bridge and execution engine. Instead of running a string-based interpreter, `tclpy` compiles Tcl source code directly into native CPython AST nodes (`ast.Assign`, `ast.If`, `ast.For`, `ast.Call`), delivering seamless Python interoperability while preserving Tcl's core "everything is a string" command semantics. `tclpy` was inspired by hylang. We want to bring the fun back to coding in TCL.
11
+
12
+ ---
13
+
14
+ ## Key Features
15
+
16
+ - **AST-Based Compilation**: Compiles Tcl control flow, variable bindings, and command calls directly into CPython Abstract Syntax Tree nodes for native execution speed.
17
+ - **Direct Python Interop**: Import any Python module or standard library package via `py::import` and invoke functions using Tcl's double-colon notation (`math::sqrt`, `os::listdir`).
18
+ - **Unified Scope Model**: Shares state transparently between Tcl `proc` definitions, variable namespaces, and Python objects.
19
+ - **Tcl-First Presentation**: Internal storage leverages high-performance Python objects, while external output marshaling formats collections into traditional space-separated Tcl strings.
20
+ - **Zero-Overhead Hybrid Execution**: Keeps Tcl managing high-level application state, event loops, and logic, while executing Python object-heavy operations smoothly.
21
+ - **Minimalist Design Philosophy**: Avoids unnecessary AST bloat by providing `py_exec` for inline Python edge cases rather than polluting the core grammar.
22
+
23
+ ---
24
+
25
+ ## Recent Features & Capabilities
26
+
27
+ - **TCP Socket Support**: Full support for client connections (`socket host port`) and background server listeners (`socket -server callback port`) using multithreading and environment-bound callback execution.
28
+ - **Channel & Flush Operations**: Interoperable channel management (`_open_channels`) supporting `open`, `gets`, `puts`, `close`, and `flush` across both files and network streams.
29
+ - **Extended String Command Suite**: Comprehensive implementation of Tcl `string` subcommands including `length`, `index`, `range`, `compare`, `equal`, `first`, `last`, `match`, `map`, `toupper`, `tolower`, `trim`, `replace`, and `is`.
30
+
31
+ ---
32
+
33
+ ## Core Command Set
34
+
35
+ | Category | Commands |
36
+ | :--- | :--- |
37
+ | **Variables & Data** | `set`, `unset`, `incr` |
38
+ | **Control Flow** | `if` / `elseif` / `else`, `while`, `foreach`, `break`, `continue` |
39
+ | **Procedures & Logic** | `proc`, `return`, `expr` |
40
+ | **Collections** | `llength`, `lindex`, `lappend` |
41
+ | **I/O & Output** | `puts`, `read`, `gets`, `open`, `close`, `socket`, `flush` |
42
+ | **Python Bridge** | `py::import` (access Python libraries), `py_exec` (run inline Python code) |
43
+
44
+ ---
45
+
46
+ ### String Operations Quick Reference
47
+
48
+ | Operation | Syntax Example | Description | Result |
49
+ | :--- | :--- | :--- | :--- |
50
+ | **length** | `string length "Hello"` | Returns the number of characters. | `5` |
51
+ | **index** | `string index "Tcl" 1` | Retrieves the character at a 0-based index. | `c` |
52
+ | **range** | `string range "Python" 0 2` | Extracts a substring from start to end index. | `Pyt` |
53
+ | **compare** | `string compare "abc" "def"` | Lexicographically compares two strings (-1, 0, 1). | `-1` |
54
+ | **equal** | `string equal -nocase "A" "a"` | Returns 1 if identical, 0 otherwise. | `1` |
55
+ | **first** | `string first "bc" "abcde"` | Finds first index of a substring. | `1` |
56
+ | **last** | `string last "a" "banana"` | Finds last index of a substring. | `5` |
57
+ | **match** | `string match "test*" "testing"` | Performs glob-style wildcard pattern matching. | `1` |
58
+ | **map** | `string map {a 1 b 2} "abab"` | Replaces substrings based on key-value pairs. | `1212` |
59
+ | **replace** | `string replace "I like Java" 7 10 "Tcl"` | Replaces a range of characters. | `"I like Tcl"` |
60
+ | **tolower** | `string tolower "HELLO"` | Converts string to lowercase. | `"hello"` |
61
+ | **toupper** | `string toupper "hello"` | Converts string to uppercase. | `"HELLO"` |
62
+ | **trim** | `string trim " abc "` | Strips leading/trailing whitespaces. | `"abc"` |
63
+ | **is** | `string is integer -strict "123"` | Validates character classes. | `1` |
64
+
65
+ ---
66
+
67
+ ## Quickstart & Installation
68
+
69
+ ```bash
70
+ git clone [https://github.com/TCLpy/TCLpy.git](https://github.com/TCLpy/TCLpy.git)
71
+ cd tclpy
72
+ pip install -e .
@@ -0,0 +1,38 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "ASTpytcl"
7
+ version = "0.1.1"
8
+ description = "A zero-dependency, CPython-AST-powered Tcl environment with Python FFI and macro bridges"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ authors = [
12
+ { name = "erider0x90" }
13
+ ]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ dependencies = [
20
+ # Core engine is zero-dependency Python stdlib + CPython AST
21
+ ]
22
+
23
+ [project.optional-dependencies]
24
+ dev = [
25
+ "pytest>=7.0.0",
26
+ "pyinstaller>=5.0.0",
27
+ ]
28
+
29
+ [project.scripts]
30
+ tclpy = "tclpy.cli:main"
31
+
32
+ [tool.setuptools.packages.find]
33
+ where = ["src"]
34
+
35
+ [project.urls]
36
+ Homepage = "https://tclpy.github.io/TCLpy/"
37
+ Repository = "https://github.com/TCLpy/TCLpy"
38
+ # Bug Tracker = "https://github.com/TCLpy/TCLpy/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.4
2
+ Name: ASTpytcl
3
+ Version: 0.1.1
4
+ Summary: A zero-dependency, CPython-AST-powered Tcl environment with Python FFI and macro bridges
5
+ Author: erider0x90
6
+ Project-URL: Homepage, https://tclpy.github.io/TCLpy/
7
+ Project-URL: Repository, https://github.com/TCLpy/TCLpy
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ Provides-Extra: dev
14
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
15
+ Requires-Dist: pyinstaller>=5.0.0; extra == "dev"
16
+
17
+ <p align="center">
18
+ <img src="assets/LogoTCLpy.jpg" alt="TCLpy Astrolabe Snake Logo" width="220" style="border-radius: 12px;">
19
+ </p>
20
+
21
+ # TCLpy 🚀
22
+
23
+
24
+ **A Lightweight, Zero-Dependency Tcl-to-Python Compiler & FFI Bridge**
25
+
26
+ `tclpy` is a high-performance, open-source Tcl-to-Python bridge and execution engine. Instead of running a string-based interpreter, `tclpy` compiles Tcl source code directly into native CPython AST nodes (`ast.Assign`, `ast.If`, `ast.For`, `ast.Call`), delivering seamless Python interoperability while preserving Tcl's core "everything is a string" command semantics. `tclpy` was inspired by hylang. We want to bring the fun back to coding in TCL.
27
+
28
+ ---
29
+
30
+ ## Key Features
31
+
32
+ - **AST-Based Compilation**: Compiles Tcl control flow, variable bindings, and command calls directly into CPython Abstract Syntax Tree nodes for native execution speed.
33
+ - **Direct Python Interop**: Import any Python module or standard library package via `py::import` and invoke functions using Tcl's double-colon notation (`math::sqrt`, `os::listdir`).
34
+ - **Unified Scope Model**: Shares state transparently between Tcl `proc` definitions, variable namespaces, and Python objects.
35
+ - **Tcl-First Presentation**: Internal storage leverages high-performance Python objects, while external output marshaling formats collections into traditional space-separated Tcl strings.
36
+ - **Zero-Overhead Hybrid Execution**: Keeps Tcl managing high-level application state, event loops, and logic, while executing Python object-heavy operations smoothly.
37
+ - **Minimalist Design Philosophy**: Avoids unnecessary AST bloat by providing `py_exec` for inline Python edge cases rather than polluting the core grammar.
38
+
39
+ ---
40
+
41
+ ## Recent Features & Capabilities
42
+
43
+ - **TCP Socket Support**: Full support for client connections (`socket host port`) and background server listeners (`socket -server callback port`) using multithreading and environment-bound callback execution.
44
+ - **Channel & Flush Operations**: Interoperable channel management (`_open_channels`) supporting `open`, `gets`, `puts`, `close`, and `flush` across both files and network streams.
45
+ - **Extended String Command Suite**: Comprehensive implementation of Tcl `string` subcommands including `length`, `index`, `range`, `compare`, `equal`, `first`, `last`, `match`, `map`, `toupper`, `tolower`, `trim`, `replace`, and `is`.
46
+
47
+ ---
48
+
49
+ ## Core Command Set
50
+
51
+ | Category | Commands |
52
+ | :--- | :--- |
53
+ | **Variables & Data** | `set`, `unset`, `incr` |
54
+ | **Control Flow** | `if` / `elseif` / `else`, `while`, `foreach`, `break`, `continue` |
55
+ | **Procedures & Logic** | `proc`, `return`, `expr` |
56
+ | **Collections** | `llength`, `lindex`, `lappend` |
57
+ | **I/O & Output** | `puts`, `read`, `gets`, `open`, `close`, `socket`, `flush` |
58
+ | **Python Bridge** | `py::import` (access Python libraries), `py_exec` (run inline Python code) |
59
+
60
+ ---
61
+
62
+ ### String Operations Quick Reference
63
+
64
+ | Operation | Syntax Example | Description | Result |
65
+ | :--- | :--- | :--- | :--- |
66
+ | **length** | `string length "Hello"` | Returns the number of characters. | `5` |
67
+ | **index** | `string index "Tcl" 1` | Retrieves the character at a 0-based index. | `c` |
68
+ | **range** | `string range "Python" 0 2` | Extracts a substring from start to end index. | `Pyt` |
69
+ | **compare** | `string compare "abc" "def"` | Lexicographically compares two strings (-1, 0, 1). | `-1` |
70
+ | **equal** | `string equal -nocase "A" "a"` | Returns 1 if identical, 0 otherwise. | `1` |
71
+ | **first** | `string first "bc" "abcde"` | Finds first index of a substring. | `1` |
72
+ | **last** | `string last "a" "banana"` | Finds last index of a substring. | `5` |
73
+ | **match** | `string match "test*" "testing"` | Performs glob-style wildcard pattern matching. | `1` |
74
+ | **map** | `string map {a 1 b 2} "abab"` | Replaces substrings based on key-value pairs. | `1212` |
75
+ | **replace** | `string replace "I like Java" 7 10 "Tcl"` | Replaces a range of characters. | `"I like Tcl"` |
76
+ | **tolower** | `string tolower "HELLO"` | Converts string to lowercase. | `"hello"` |
77
+ | **toupper** | `string toupper "hello"` | Converts string to uppercase. | `"HELLO"` |
78
+ | **trim** | `string trim " abc "` | Strips leading/trailing whitespaces. | `"abc"` |
79
+ | **is** | `string is integer -strict "123"` | Validates character classes. | `1` |
80
+
81
+ ---
82
+
83
+ ## Quickstart & Installation
84
+
85
+ ```bash
86
+ git clone [https://github.com/TCLpy/TCLpy.git](https://github.com/TCLpy/TCLpy.git)
87
+ cd tclpy
88
+ pip install -e .
@@ -0,0 +1,16 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/ASTpytcl.egg-info/PKG-INFO
4
+ src/ASTpytcl.egg-info/SOURCES.txt
5
+ src/ASTpytcl.egg-info/dependency_links.txt
6
+ src/ASTpytcl.egg-info/entry_points.txt
7
+ src/ASTpytcl.egg-info/requires.txt
8
+ src/ASTpytcl.egg-info/top_level.txt
9
+ src/tclpy/__init__.py
10
+ src/tclpy/cli.py
11
+ src/tclpy/compiler.py
12
+ src/tclpy/runtime.py
13
+ src/tclpy/tcl_lexer.py
14
+ tests/test_compiler.py
15
+ tests/test_lexer.py
16
+ tests/test_runtime.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ tclpy = tclpy.cli:main
@@ -0,0 +1,4 @@
1
+
2
+ [dev]
3
+ pytest>=7.0.0
4
+ pyinstaller>=5.0.0
@@ -0,0 +1 @@
1
+ tclpy
@@ -0,0 +1,21 @@
1
+ # src/tclpy/__init__.py
2
+ from .runtime import execute_tcl
3
+
4
+ def eval(source: str, env: dict = None) -> any:
5
+ """
6
+ Evaluate a Tcl string or expression within an optional Python environment dict.
7
+ Returns the resulting Python object from the execution.
8
+ """
9
+ if env is None:
10
+ env = {}
11
+ return execute_tcl(source, env)
12
+
13
+ def source(filepath: str, env: dict = None) -> any:
14
+ """
15
+ Load and execute a .tcl script file within an optional Python environment dict.
16
+ """
17
+ if env is None:
18
+ env = {}
19
+ with open(filepath, "r", encoding="utf-8") as f:
20
+ content = f.read()
21
+ return execute_tcl(content, env)
@@ -0,0 +1,116 @@
1
+ # src/cli.py
2
+ import sys
3
+ import os
4
+
5
+ try:
6
+ import readline
7
+ except ImportError:
8
+ readline = None # Fallback gracefully on Windows where readline isn't standard
9
+
10
+ # Ensure current working directory is in sys.path for local module imports (e.g. windows_h.py)
11
+ current_dir = os.getcwd()
12
+ if current_dir not in sys.path:
13
+ sys.path.insert(0, current_dir)
14
+
15
+ try:
16
+ # When running as part of the installed tclpy package or PyInstaller bundle
17
+ from tclpy.runtime import execute_tcl
18
+ except ImportError:
19
+ try:
20
+ # Relative import fallback if running inside package context
21
+ from .runtime import execute_tcl
22
+ except ImportError:
23
+ # Fallback for direct local script execution
24
+ from runtime import execute_tcl
25
+
26
+ def is_balanced(source: str) -> bool:
27
+ """Check if Tcl braces {} and brackets [] are balanced to support multi-line input."""
28
+ brace_depth = 0
29
+ bracket_depth = 0
30
+ in_quote = False
31
+ escaped = False
32
+
33
+ for char in source:
34
+ if escaped:
35
+ escaped = False
36
+ continue
37
+ if char == '\\':
38
+ escaped = True
39
+ continue
40
+ if char == '"' and not escaped:
41
+ in_quote = not in_quote
42
+ continue
43
+ if in_quote:
44
+ continue
45
+
46
+ if char == '{':
47
+ brace_depth += 1
48
+ elif char == '}':
49
+ brace_depth -= 1
50
+ elif char == '[':
51
+ bracket_depth += 1
52
+ elif char == ']':
53
+ bracket_depth -= 1
54
+
55
+ return brace_depth <= 0 and bracket_depth <= 0
56
+
57
+ def run_repl():
58
+ """Run an interactive Tcl REPL shell with persistent environment and multi-line support."""
59
+ print("tclpy Interactive Shell (Powered by CPython AST & Tkinter Tcl)")
60
+ print("Type 'exit' or 'quit' to leave the shell.\n")
61
+
62
+ env = {}
63
+ buffer = []
64
+
65
+ while True:
66
+ try:
67
+ prompt = "... " if buffer else "tclpy> "
68
+ line = input(prompt)
69
+ except (KeyboardInterrupt, EOFError):
70
+ print("\nExiting tclpy shell. Goodbye!")
71
+ break
72
+
73
+ stripped = line.strip()
74
+ if not buffer and stripped in ("exit", "quit"):
75
+ print("Goodbye!")
76
+ break
77
+
78
+ if not buffer and not stripped:
79
+ continue
80
+
81
+ buffer.append(line)
82
+ full_source = "\n".join(buffer)
83
+
84
+ if is_balanced(full_source):
85
+ try:
86
+ execute_tcl(full_source, env)
87
+ except Exception as e:
88
+ print(f"Error: {e}")
89
+ buffer.clear()
90
+
91
+ def main():
92
+ if len(sys.argv) > 1:
93
+ script_path = sys.argv[1]
94
+ if not os.path.exists(script_path):
95
+ print(f"Error: script '{script_path}' not found.", file=sys.stderr)
96
+ sys.exit(1)
97
+
98
+ # Add the script's own directory to sys.path so local modules (e.g. testdump) resolve
99
+ script_dir = os.path.abspath(os.path.dirname(script_path))
100
+ if script_dir not in sys.path:
101
+ sys.path.insert(0, script_dir)
102
+
103
+ with open(script_path, "r", encoding="utf-8") as f:
104
+ source = f.read()
105
+
106
+ env = {}
107
+ try:
108
+ execute_tcl(source, env)
109
+ except Exception as e:
110
+ print(f"Error: {e}", file=sys.stderr)
111
+ sys.exit(1)
112
+ else:
113
+ run_repl()
114
+
115
+ if __name__ == "__main__":
116
+ main()