cwg 0.1.0__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.
cwg-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,322 @@
1
+ Metadata-Version: 2.4
2
+ Name: cwg
3
+ Version: 0.1.0
4
+ Summary: CWG — a Git-based programming language interpreter
5
+ License-Expression: GPL-3.0-only
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: docs/LICENSE
9
+ Requires-Dist: gitpython<4,>=3
10
+ Provides-Extra: dev
11
+ Requires-Dist: pytest; extra == "dev"
12
+ Dynamic: license-file
13
+
14
+ <img width="1622" height="669" alt="image" src="https://github.com/user-attachments/assets/1c015b26-30bf-4f6b-9023-d2ba5ccc7714" />
15
+
16
+
17
+ # Coding With Git
18
+
19
+ > **Work in progress.** This project is in early draft stage. Syntax and semantics are subject to change.
20
+
21
+ CWG is a programming language where the source code *is* the git history. Commit messages are statements, branches are control flow blocks, and merges close those blocks. The interpreter walks the commit DAG and executes it as a program.
22
+
23
+ The goal is to use git as a genuine programming medium. Readable syntax, real execution, built entirely on top of version control primitives.
24
+
25
+ ---
26
+
27
+ ## Concept
28
+
29
+ | Git construct | Language construct |
30
+ |---|---|
31
+ | `git commit -m "..."` | Statement / instruction |
32
+ | Branch | Conditional block or loop |
33
+ | Merge | Close a block, return to parent scope |
34
+ | Tag | Function definition |
35
+ | `cherry-pick` | Function call |
36
+ | `revert` | Exception handler / undo |
37
+ | `git stash` | Push to memory stack |
38
+ | `git stash pop` | Pop from memory stack |
39
+
40
+ ---
41
+
42
+ ## Syntax
43
+
44
+ CWG executes Python syntax inside commit messages. Commit messages must be valid Python statements for the interpreter to recognize and run them.
45
+
46
+ ### Variables, int, string, bool, int operator
47
+
48
+ ```bash
49
+ git commit -m "x = 5"
50
+ git commit -m "name = 'world'"
51
+ git commit -m "active = True"
52
+ git commit -m "x = x + 1"
53
+ ```
54
+
55
+ ### If / Else
56
+
57
+ Branches named `if/<name>` and `else/<name>` define conditional blocks. The condition is the first commit of the `if/` branch.
58
+
59
+ ```bash
60
+ git branch if/large
61
+ git commit -m "if x > 10:"
62
+ git commit -m " print('x is large')"
63
+ git checkout main
64
+ git branch else/small
65
+ git commit -m " print('x is small')"
66
+ git checkout main
67
+ git merge if/large
68
+ git merge else/small
69
+ ```
70
+
71
+ ### While Loops
72
+
73
+ Branches named `while/<name>` define while loops. The first commit in the branch is the `while` condition.
74
+
75
+ ```bash
76
+ git commit -m "i = 10"
77
+ git branch while/countdown
78
+ git commit -m "while i > 0:"
79
+ git commit -m " print(i)"
80
+ git commit -m " i = i - 1"
81
+ git checkout main
82
+ git merge while/countdown
83
+ git commit -m "print('blastoff')"
84
+ ```
85
+
86
+ ### For Loops
87
+
88
+ Branches named `for/<name>` define for loops. The first commit in the branch is the `for` header — both `for x in iterable:` and tuple-unpacking forms like `for x, y in pairs:` are supported.
89
+
90
+ ```bash
91
+ git commit -m "total = 0"
92
+ git branch for/sum
93
+ git commit -m "for i in [1, 2, 3, 4, 5]:"
94
+ git commit -m " total = total + i"
95
+ git checkout main
96
+ git merge for/sum -m "return total"
97
+ ```
98
+
99
+ ### Functions
100
+
101
+ Functions are defined as tagged commit ranges and called via `cherry-pick`.
102
+
103
+ ```bash
104
+ git tag -a "fn/greet"
105
+ git commit -m " print('hello ' + name)"
106
+ git commit -m " return"
107
+ git tag -a "end-fn/greet"
108
+
109
+ # call the function
110
+ git cherry-pick fn/greet
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Branch Naming Conventions
116
+
117
+ | Prefix | Purpose |
118
+ |---|---|
119
+ | `main` / `master` | Global scope |
120
+ | `if/<name>` | Conditional true block |
121
+ | `else/<name>` | Conditional false block |
122
+ | `while/<name>` | While loop |
123
+ | `for/<name>` | For loop |
124
+ | `fn/<name>` | Function definition |
125
+ | `check/<name>` | Inline conditional (if/elif/else one-liners) |
126
+
127
+ ---
128
+
129
+ ## Scoping
130
+
131
+ - `main` holds global scope
132
+ - `if/`, `else/`, `while/`, and `for/` branches each receive a copy of the parent scope at the moment they start
133
+ - `else/` always starts from the parent scope — never from the `if/` branch's scope
134
+ - `check/` branches run directly in the parent scope with no isolation
135
+ - Variables modified inside a branch are discarded on merge unless explicitly returned
136
+ - Returned values are promoted back into the parent scope
137
+
138
+ ## Execution Model
139
+
140
+ CWG uses a **first-parent walk** to traverse the commit DAG. When `cwg run` is called, the interpreter walks `main` from the first commit to HEAD, oldest to newest, applying these rules at every level:
141
+
142
+ 1. **Regular commit** — execute the message as a Python statement, save a state snapshot
143
+ 2. **Merge commit** — pause, walk the branch's commits as a self-contained block (oldest to newest), execute the block, apply any returned values to parent scope, continue on `main`
144
+ 3. **Revert commit** — restore the state snapshot from before the reverted commit, continue
145
+
146
+ Because branches can contain branches, rule 2 is recursive. The same three rules apply at every level of nesting.
147
+
148
+ Nothing executes as commits are written. The full history is read first, then executed in one pass.
149
+
150
+ ---
151
+
152
+ ## Merging
153
+
154
+ When a branch merges back into `main`, any variables modified inside the branch are discarded unless explicitly returned via the merge commit message.
155
+
156
+ Multiple variables can be returned comma-separated:
157
+
158
+ ```bash
159
+ git merge while/countdown -m "return i"
160
+ git merge while/multi -m "return i, j, k"
161
+ ```
162
+
163
+ Only the variables named in the return are promoted back into the parent scope. Everything else is dropped.
164
+
165
+ If no return is specified, the branch is treated as side-effects only — prints and other output still happen, but no state is promoted back. This is valid and intentional, not an error.
166
+
167
+ ---
168
+
169
+ ## Revert and Exception Handling
170
+
171
+ `git revert` serves two purposes in CWG: undoing a coding mistake, and handling exceptions.
172
+
173
+ ### Pure undo
174
+
175
+ A revert with no added message restores the scope to what it was just before the target commit ran. This is how you "edit" a mistake without rewriting history.
176
+
177
+ ```bash
178
+ git commit -m "x = 1"
179
+ git commit -m "x = 99" # oops
180
+ git revert HEAD # x is now back to 1
181
+ ```
182
+
183
+ The target can be any commit by SHA, not just the previous one:
184
+
185
+ ```bash
186
+ git revert abc1234 # rolls back state to before abc1234 ran
187
+ ```
188
+
189
+ ### Exception handler
190
+
191
+ If you add code to the revert commit message (via `git revert <sha> --edit`), that code runs only if the target commit raised an error. If the target succeeded, the revert is a no-op.
192
+
193
+ ```bash
194
+ git commit -m "result = 1 / x" # might fail if x == 0
195
+ git revert HEAD --edit
196
+ # message becomes:
197
+ # result = -1
198
+ #
199
+ # This reverts commit abc1234.
200
+ ```
201
+
202
+ When `x == 0` the original commit raises `ZeroDivisionError`, the handler runs, and `result = -1`. When `x != 0` the original succeeds and the handler is skipped.
203
+
204
+ ### Detection
205
+
206
+ CWG detects reverts by the auto-generated `This reverts commit <sha>.` line that `git revert` produces. Manually writing a commit with a message starting with "revert" does not trigger revert behaviour — you must use the `git revert` command.
207
+
208
+ ---
209
+
210
+ ## Sample Programs
211
+
212
+ ### Hello World
213
+
214
+ ```bash
215
+ git init hello-world
216
+ git commit -m "message = 'hello world'"
217
+ git commit -m "print(message)"
218
+ # output: hello world
219
+ ```
220
+
221
+ ### Countdown
222
+
223
+ ```bash
224
+ git init countdown
225
+ git commit -m "i = 10"
226
+ git branch while/countdown
227
+ git commit -m "while i > 0:"
228
+ git commit -m " print(i)"
229
+ git commit -m " i = i - 1"
230
+ git checkout main
231
+ git merge while/countdown
232
+ git commit -m "print('blastoff')"
233
+ # output: 10 9 8 7 6 5 4 3 2 1 blastoff
234
+ ```
235
+
236
+ ### FizzBuzz
237
+
238
+ ```bash
239
+ git init fizzbuzz
240
+ git commit -m "i = 1"
241
+ git branch while/fizzbuzz
242
+ git commit -m "while i <= 20:"
243
+ git branch check/fizzbuzz
244
+ git commit -m " if i % 15 == 0: print('FizzBuzz')"
245
+ git checkout while/fizzbuzz
246
+ git merge check/fizzbuzz
247
+ git branch check/fizz
248
+ git commit -m " elif i % 3 == 0: print('Fizz')"
249
+ git checkout while/fizzbuzz
250
+ git merge check/fizz
251
+ git branch check/buzz
252
+ git commit -m " elif i % 5 == 0: print('Buzz')"
253
+ git checkout while/fizzbuzz
254
+ git merge check/buzz
255
+ git branch check/default
256
+ git commit -m " else: print(i)"
257
+ git checkout while/fizzbuzz
258
+ git merge check/default
259
+ git commit -m " i = i + 1"
260
+ git checkout main
261
+ git merge while/fizzbuzz
262
+ ```
263
+
264
+ ---
265
+
266
+ ## Data Types
267
+
268
+ | Type | Example |
269
+ |---|---|
270
+ | int | `x = 5` |
271
+ | float | `pi = 3.14` |
272
+ | string | `name = 'alice'` |
273
+ | bool | `flag = True` |
274
+ | list | `nums = [1, 2, 3]` |
275
+
276
+ ---
277
+
278
+ ## Installation
279
+
280
+ ### Prerequisites
281
+
282
+ - Python 3.10 or newer
283
+ - Git
284
+
285
+ ### Setup
286
+
287
+ Clone the repo, create a virtual environment, and install CWG in editable mode:
288
+
289
+ ```bash
290
+ git clone <repo-url>
291
+ cd CWG-Coding_with_Git
292
+ python3 -m venv .venv
293
+ source .venv/bin/activate # macOS / Linux
294
+ # .venv\Scripts\activate # Windows
295
+ pip install -e .
296
+ ```
297
+
298
+ The `pip install -e .` step installs CWG itself, makes the `cwg` command available on your `PATH`, and pulls in the runtime dependency (GitPython).
299
+
300
+ To also run the test suite:
301
+
302
+ ```bash
303
+ pip install pytest pytest-cov
304
+ pytest
305
+ ```
306
+
307
+ ### Hello world
308
+
309
+ ```bash
310
+ mkdir hello && cd hello
311
+ git init
312
+ git commit --allow-empty -m "message = 'hello world'"
313
+ git commit --allow-empty -m "print(message)"
314
+ cwg run .
315
+ # output: hello world
316
+ ```
317
+
318
+ ---
319
+
320
+ ## Status
321
+
322
+ This project is a work in progress. See [CONTRIBUTING.md](CONTRIBUTING.md) for how to get involved.
@@ -0,0 +1,16 @@
1
+ from .gpScraper import scrape, GpScrapeResult, CommitNode, FunctionDef, StashEntry
2
+ from .interpreter import run, build_exec_tree, StatementNode, IfNode, WhileNode, ForNode
3
+
4
+ __all__ = [
5
+ "scrape",
6
+ "GpScrapeResult",
7
+ "CommitNode",
8
+ "FunctionDef",
9
+ "StashEntry",
10
+ "run",
11
+ "build_exec_tree",
12
+ "StatementNode",
13
+ "IfNode",
14
+ "WhileNode",
15
+ "ForNode",
16
+ ]
cwg-0.1.0/core/cli.py ADDED
@@ -0,0 +1,26 @@
1
+ """
2
+ CWG command-line dispatcher.
3
+
4
+ cwg run [target] — execute a CWG program
5
+ target = GitHub URL or .cwg file; empty = current repo
6
+ """
7
+
8
+ import sys
9
+
10
+ _USAGE = (
11
+ "usage: cwg run [target]\n"
12
+ " target GitHub repo URL or .cwg file; omit to run the current repo's "
13
+ "git history"
14
+ )
15
+
16
+
17
+ def main() -> None:
18
+ args = sys.argv[1:]
19
+
20
+ if not args or args[0] != "run":
21
+ print(_USAGE, file=sys.stderr)
22
+ sys.exit(0 if not args else 2)
23
+
24
+ sys.argv = [sys.argv[0]] + args[1:]
25
+ from .runner import main as run_main
26
+ run_main()