smc-lang 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.
smc_lang-0.1.0/LICENSE ADDED
@@ -0,0 +1,42 @@
1
+ SMC Fair-Source License (Version 1.0)
2
+ Copyright (c) 2026 Jason Rezek. All rights reserved.
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software subject to the following conditions:
7
+
8
+ 1. INDIVIDUAL, ACADEMIC & NON-COMMERCIAL USE
9
+ Use, copying, modification, merging, publishing, and distribution of the Software
10
+ for personal, educational, academic, non-commercial, or hobbyist purposes is
11
+ completely free of charge and permitted in perpetuity.
12
+
13
+ 2. SMALL BUSINESS SAFE HARBOR
14
+ Use of the Software by any business entity whose gross annual revenues (or total
15
+ funding raised) do not exceed $1,000,000 USD (one million United States dollars)
16
+ and employs fewer than 10 full-time equivalent employees is completely free of charge.
17
+
18
+ 3. ENTERPRISE COMMERCIAL USE
19
+ Any use of the Software by or on behalf of any commercial entity that exceeds the
20
+ Small Business Safe Harbor threshold, or any use of the Software to provide a paid
21
+ hosted cloud service, SaaS runtime, or managed execution platform, requires a paid
22
+ Commercial License Agreement executed with the Copyright Holder.
23
+
24
+ 4. INTELLECTUAL PROPERTY & ATTRIBUTION
25
+ The above copyright notice and this permission notice shall be included in all
26
+ copies or substantial portions of the Software.
27
+
28
+ DISCLAIMER OF WARRANTY:
29
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35
+ SOFTWARE.
36
+
37
+ ================================================================================
38
+ For Enterprise Licensing, Commercial Inquiries, and Custom Integrations:
39
+ Contact: Jason Rezek
40
+ Email: zekvftb@gmail.com
41
+ GitHub: https://github.com/zekvftb/smc-lang
42
+ ================================================================================
@@ -0,0 +1,128 @@
1
+ Metadata-Version: 2.4
2
+ Name: smc-lang
3
+ Version: 0.1.0
4
+ Summary: Saturday Morning Cartoons (SMC): A biologically inspired, fault-tolerant programming language and VM
5
+ Author-email: Jason Rezek <zekvftb@gmail.com>
6
+ License: Fair-Source-1.0 (Free for Individuals, Commercial for Enterprise)
7
+ Keywords: programming-language,virtual-machine,biology-inspired,fault-tolerant,cartoons
8
+ Requires-Python: >=3.11
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Dynamic: license-file
12
+
13
+ # 📺 SMC (Saturday Morning Cartoons) Programming Language
14
+
15
+ **SMC (Saturday Morning Cartoons)** is a biologically inspired, fault-tolerant programming language and standalone virtual machine.
16
+
17
+ It translates the fundamental computational principles of **DNA and RNA** into modern, license-free software architecture, paired with subtle 90s cartoon and anime nostalgia!
18
+
19
+ ---
20
+
21
+ ## 📖 Complete Documentation & Tutorial
22
+ 👉 **Read the comprehensive guide and manual in [docs/GUIDE.md](docs/GUIDE.md)**!
23
+
24
+ ---
25
+
26
+ ## 🧬 Biological Principles to SMC Software Architecture
27
+
28
+ | Real Biological Mechanism (DNA/RNA) | Computer Science Problem | SMC Language Solution |
29
+ | :--- | :--- | :--- |
30
+ | **Codon Degeneracy** (64 codons map to 20 amino acids; 3rd base wobble absorbs mutations) | Rigid syntax: a single missing letter or typo halts the compiler with a fatal error. | **Wobble Typo-Tolerance**: Synonyms map to identical opcodes. Minor spelling mistakes are smoothly repaired via Levenshtein edit-distance without halting. |
31
+ | **Overlapping Genes** (PhiX174 reading two different proteins from the same sequence) | 1D sequential execution: every routine requires its own separate memory footprint. | **CatDog Multi-Framing**: Interleave two complete programs on the exact same line of code; read at offset 0 (Cat) or offset 1 (Dog) for 2x memory density. |
32
+ | **mRNA Half-Life Decay** (Poly-A tail shortens on each translation until transcript dissolves) | Memory leaks in C/C++; periodic CPU freezes from Garbage Collectors in Java/Python. | **Acme Anvil TTL**: Ephemeral variables carry an auto-decrementing `acme(ttl=N)` timer. Once expired, it vaporizes from RAM with zero memory leaks and 0% GC pauses. |
33
+ | **Lock-and-Key Receptors** (Proteins find targets by 3D physical pocket shape, not pointers) | Fragile numeric memory pointers (`0x7FFF`) and hard-coded network IP endpoints. | **Planetary Shape Dispatch**: Functions bind to elemental and planetary rings (`MERCURY`, `MARS`, `JUPITER`, `VENUS`, `MOON`). Callers emit ring keys to trigger matching handlers. |
34
+ | **p53 DNA Repair Checkpoint** ("Guardian of the genome" catching unrouted sequences) | Unhandled exceptions and crash cascades. | **Tuxedo Mask Watchdog**: Catches unrouted dispatches with a graceful fallback block ("My work here is done!"). |
35
+ | **Cellular Differentiation** (Stem cells differentiating into specialized tissue states) | State evolution and polymorphic typing. | **Sailor Moon Transformation**: `transform` / `MOON_PRISM_POWER` blocks explicitly evolve state objects. |
36
+
37
+ ---
38
+
39
+ ## ⚡ Quickstart
40
+
41
+ ### 1. Installation (100% Free & MIT/Public Domain)
42
+ ```powershell
43
+ pip install -e D:\smc_lang\
44
+ ```
45
+
46
+ ### 2. Launching the Live Interactive REPL
47
+ ```powershell
48
+ smc
49
+ # or: python -m smc.cli repl
50
+ ```
51
+
52
+ ### 3. Running an SMC Script
53
+ ```powershell
54
+ python -m smc.cli run D:\smc_lang\examples\advanced_functions.smc
55
+ ```
56
+
57
+ ### 4. Running CatDog Dual-Frame Overlapping Code
58
+ ```powershell
59
+ python -m smc.cli catdog D:\smc_lang\examples\catdog_dual_frame.smc
60
+ ```
61
+
62
+ ### 5. Inspecting Repaired Mutations & Tokens
63
+ ```powershell
64
+ python -m smc.cli tokens D:\smc_lang\examples\sailor_moon_battle.smc
65
+ ```
66
+
67
+ ---
68
+
69
+ ## 🎨 Modern Professional Syntax (with Degenerate Aliases)
70
+
71
+ SMC prioritizes clean, modern, professional keywords, while preserving nostalgic aliases under the hood:
72
+
73
+ ```smc
74
+ experiment "Planetary_Defense"
75
+
76
+ # 1. Full arithmetic expressions with order of operations (* and / before + and -)
77
+ let enemy_hp = 100
78
+ let attack_power = (15 * 2) - 5 # Evaluates to 25
79
+
80
+ # 2. Tuxedo Mask watchdog fallback
81
+ fallback {
82
+ print "Tuxedo Mask throws a red rose! (Graceful fallback executed)"
83
+ }
84
+
85
+ # 3. Planetary Senshi ring binding
86
+ bind(ring="MARS") {
87
+ print "Sailor Mars: Flame blast triggered!"
88
+ }
89
+
90
+ # 4. Turn-based combat loop (while loop & conditionals)
91
+ while (enemy_hp > 0) {
92
+ # Acme Anvil ephemeral shield (auto-vaporizes after 2 cycles without GC pauses)
93
+ acme(ttl=2) defense_shield = "Active_Barrier"
94
+
95
+ dispatch "MARS"
96
+ let enemy_hp = enemy_hp - attack_power
97
+ }
98
+
99
+ # 5. Sailor Moon State Transformation (Cellular Differentiation)
100
+ let guardian = "Usagi_Tsukino"
101
+ transform guardian = "Princess_Serenity" {
102
+ print "State transformed to royal tier!"
103
+ }
104
+
105
+ halt
106
+ ```
107
+
108
+ ---
109
+
110
+ ## 🧪 Automated Testing
111
+ Run the comprehensive test suite:
112
+ ```powershell
113
+ python -m pytest D:\smc_lang\tests/
114
+ ```
115
+ **All 15 tests pass in 0.12 seconds!**
116
+
117
+ ---
118
+
119
+ ## 📜 License & Enterprise Commercial Terms
120
+
121
+ SMC is distributed under the **SMC Fair-Source License 1.0**:
122
+
123
+ * 🎓 **100% Free for Individuals, Students, & Non-Commercial Use:** You can learn, play, modify, and build personal or academic projects completely free forever.
124
+ * 🚀 **Small Business Safe Harbor:** 100% free for startups and companies with **gross annual revenues under $1,000,000 USD** and fewer than 10 employees.
125
+ * 🏢 **Enterprise Commercial License:** Commercial use by large entities exceeding the threshold, or use as a paid hosted cloud service, requires an Enterprise Commercial License.
126
+
127
+ For commercial licensing agreements and enterprise integration inquiries, contact:
128
+ **Jason Rezek** — [`zekvftb@gmail.com`](mailto:zekvftb@gmail.com)
@@ -0,0 +1,116 @@
1
+ # 📺 SMC (Saturday Morning Cartoons) Programming Language
2
+
3
+ **SMC (Saturday Morning Cartoons)** is a biologically inspired, fault-tolerant programming language and standalone virtual machine.
4
+
5
+ It translates the fundamental computational principles of **DNA and RNA** into modern, license-free software architecture, paired with subtle 90s cartoon and anime nostalgia!
6
+
7
+ ---
8
+
9
+ ## 📖 Complete Documentation & Tutorial
10
+ 👉 **Read the comprehensive guide and manual in [docs/GUIDE.md](docs/GUIDE.md)**!
11
+
12
+ ---
13
+
14
+ ## 🧬 Biological Principles to SMC Software Architecture
15
+
16
+ | Real Biological Mechanism (DNA/RNA) | Computer Science Problem | SMC Language Solution |
17
+ | :--- | :--- | :--- |
18
+ | **Codon Degeneracy** (64 codons map to 20 amino acids; 3rd base wobble absorbs mutations) | Rigid syntax: a single missing letter or typo halts the compiler with a fatal error. | **Wobble Typo-Tolerance**: Synonyms map to identical opcodes. Minor spelling mistakes are smoothly repaired via Levenshtein edit-distance without halting. |
19
+ | **Overlapping Genes** (PhiX174 reading two different proteins from the same sequence) | 1D sequential execution: every routine requires its own separate memory footprint. | **CatDog Multi-Framing**: Interleave two complete programs on the exact same line of code; read at offset 0 (Cat) or offset 1 (Dog) for 2x memory density. |
20
+ | **mRNA Half-Life Decay** (Poly-A tail shortens on each translation until transcript dissolves) | Memory leaks in C/C++; periodic CPU freezes from Garbage Collectors in Java/Python. | **Acme Anvil TTL**: Ephemeral variables carry an auto-decrementing `acme(ttl=N)` timer. Once expired, it vaporizes from RAM with zero memory leaks and 0% GC pauses. |
21
+ | **Lock-and-Key Receptors** (Proteins find targets by 3D physical pocket shape, not pointers) | Fragile numeric memory pointers (`0x7FFF`) and hard-coded network IP endpoints. | **Planetary Shape Dispatch**: Functions bind to elemental and planetary rings (`MERCURY`, `MARS`, `JUPITER`, `VENUS`, `MOON`). Callers emit ring keys to trigger matching handlers. |
22
+ | **p53 DNA Repair Checkpoint** ("Guardian of the genome" catching unrouted sequences) | Unhandled exceptions and crash cascades. | **Tuxedo Mask Watchdog**: Catches unrouted dispatches with a graceful fallback block ("My work here is done!"). |
23
+ | **Cellular Differentiation** (Stem cells differentiating into specialized tissue states) | State evolution and polymorphic typing. | **Sailor Moon Transformation**: `transform` / `MOON_PRISM_POWER` blocks explicitly evolve state objects. |
24
+
25
+ ---
26
+
27
+ ## ⚡ Quickstart
28
+
29
+ ### 1. Installation (100% Free & MIT/Public Domain)
30
+ ```powershell
31
+ pip install -e D:\smc_lang\
32
+ ```
33
+
34
+ ### 2. Launching the Live Interactive REPL
35
+ ```powershell
36
+ smc
37
+ # or: python -m smc.cli repl
38
+ ```
39
+
40
+ ### 3. Running an SMC Script
41
+ ```powershell
42
+ python -m smc.cli run D:\smc_lang\examples\advanced_functions.smc
43
+ ```
44
+
45
+ ### 4. Running CatDog Dual-Frame Overlapping Code
46
+ ```powershell
47
+ python -m smc.cli catdog D:\smc_lang\examples\catdog_dual_frame.smc
48
+ ```
49
+
50
+ ### 5. Inspecting Repaired Mutations & Tokens
51
+ ```powershell
52
+ python -m smc.cli tokens D:\smc_lang\examples\sailor_moon_battle.smc
53
+ ```
54
+
55
+ ---
56
+
57
+ ## 🎨 Modern Professional Syntax (with Degenerate Aliases)
58
+
59
+ SMC prioritizes clean, modern, professional keywords, while preserving nostalgic aliases under the hood:
60
+
61
+ ```smc
62
+ experiment "Planetary_Defense"
63
+
64
+ # 1. Full arithmetic expressions with order of operations (* and / before + and -)
65
+ let enemy_hp = 100
66
+ let attack_power = (15 * 2) - 5 # Evaluates to 25
67
+
68
+ # 2. Tuxedo Mask watchdog fallback
69
+ fallback {
70
+ print "Tuxedo Mask throws a red rose! (Graceful fallback executed)"
71
+ }
72
+
73
+ # 3. Planetary Senshi ring binding
74
+ bind(ring="MARS") {
75
+ print "Sailor Mars: Flame blast triggered!"
76
+ }
77
+
78
+ # 4. Turn-based combat loop (while loop & conditionals)
79
+ while (enemy_hp > 0) {
80
+ # Acme Anvil ephemeral shield (auto-vaporizes after 2 cycles without GC pauses)
81
+ acme(ttl=2) defense_shield = "Active_Barrier"
82
+
83
+ dispatch "MARS"
84
+ let enemy_hp = enemy_hp - attack_power
85
+ }
86
+
87
+ # 5. Sailor Moon State Transformation (Cellular Differentiation)
88
+ let guardian = "Usagi_Tsukino"
89
+ transform guardian = "Princess_Serenity" {
90
+ print "State transformed to royal tier!"
91
+ }
92
+
93
+ halt
94
+ ```
95
+
96
+ ---
97
+
98
+ ## 🧪 Automated Testing
99
+ Run the comprehensive test suite:
100
+ ```powershell
101
+ python -m pytest D:\smc_lang\tests/
102
+ ```
103
+ **All 15 tests pass in 0.12 seconds!**
104
+
105
+ ---
106
+
107
+ ## 📜 License & Enterprise Commercial Terms
108
+
109
+ SMC is distributed under the **SMC Fair-Source License 1.0**:
110
+
111
+ * 🎓 **100% Free for Individuals, Students, & Non-Commercial Use:** You can learn, play, modify, and build personal or academic projects completely free forever.
112
+ * 🚀 **Small Business Safe Harbor:** 100% free for startups and companies with **gross annual revenues under $1,000,000 USD** and fewer than 10 employees.
113
+ * 🏢 **Enterprise Commercial License:** Commercial use by large entities exceeding the threshold, or use as a paid hosted cloud service, requires an Enterprise Commercial License.
114
+
115
+ For commercial licensing agreements and enterprise integration inquiries, contact:
116
+ **Jason Rezek** — [`zekvftb@gmail.com`](mailto:zekvftb@gmail.com)
@@ -0,0 +1,25 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "smc-lang"
7
+ version = "0.1.0"
8
+ description = "Saturday Morning Cartoons (SMC): A biologically inspired, fault-tolerant programming language and VM"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ authors = [
12
+ { name = "Jason Rezek", email = "zekvftb@gmail.com" }
13
+ ]
14
+ license = { text = "Fair-Source-1.0 (Free for Individuals, Commercial for Enterprise)" }
15
+ keywords = ["programming-language", "virtual-machine", "biology-inspired", "fault-tolerant", "cartoons"]
16
+ dependencies = []
17
+
18
+ [project.scripts]
19
+ smc = "smc.cli:main"
20
+
21
+ [tool.pytest.ini_options]
22
+ pythonpath = ["src"]
23
+ testpaths = ["tests"]
24
+ python_files = ["test_*.py"]
25
+ addopts = "-v --tb=short"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,22 @@
1
+ """Saturday Morning Cartoons (SMC) Language.
2
+
3
+ A biologically inspired, fault-tolerant programming language and virtual machine
4
+ featuring degenerate opcodes, CatDog multi-framing, Acme-TTL ephemeral memory,
5
+ and Captain Planet content-addressable dispatch.
6
+ """
7
+
8
+ __version__ = "0.1.0"
9
+
10
+ from smc.tokens import Opcode, CanonicalToken, TokenType
11
+ from smc.lexer import SmcLexer
12
+ from smc.parser import SmcParser
13
+ from smc.vm import DexterVM
14
+
15
+ __all__ = [
16
+ "Opcode",
17
+ "CanonicalToken",
18
+ "TokenType",
19
+ "SmcLexer",
20
+ "SmcParser",
21
+ "DexterVM",
22
+ ]
@@ -0,0 +1,132 @@
1
+ """Command-Line Interface for SMC (Saturday Morning Cartoons) Language.
2
+
3
+ Usage:
4
+ smc # Launch the interactive live REPL shell
5
+ smc repl # Launch the interactive live REPL shell
6
+ smc run <file.smc> # Execute script in DexterVM
7
+ smc catdog <file.smc> # Execute CatDog dual-frame interleaved routines
8
+ smc tokens <file.smc> # Inspect token stream and degenerate opcode mappings
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import argparse
14
+ from pathlib import Path
15
+ import sys
16
+
17
+ from smc.lexer import SmcLexer
18
+ from smc.parser import CatDogSlicer, SmcParser
19
+ from smc.repl import start_repl
20
+ from smc.vm import DexterVM
21
+
22
+
23
+ def run_file(file_path: Path | str) -> None:
24
+ path = Path(file_path)
25
+ if not path.is_file():
26
+ print(f"Error: File not found at '{path}'")
27
+ sys.exit(1)
28
+
29
+ source = path.read_text(encoding="utf-8")
30
+ lexer = SmcLexer(source)
31
+ tokens = lexer.tokenize()
32
+
33
+ parser = SmcParser(tokens)
34
+ ast = parser.parse()
35
+
36
+ vm = DexterVM()
37
+ res = vm.run(ast)
38
+
39
+ print("\n--- DEXTER_VM EXECUTION OUTPUT ---")
40
+ for line in res["stdout"]:
41
+ print(line)
42
+ print("----------------------------------\n")
43
+ print(f"Steps: {res['execution_steps']} | Anvils Dropped: {res['anvils_dropped']} | Mutations Survived: {res['mutations_survived']}")
44
+
45
+
46
+ def run_catdog(file_path: Path | str) -> None:
47
+ path = Path(file_path)
48
+ if not path.is_file():
49
+ print(f"Error: File not found at '{path}'")
50
+ sys.exit(1)
51
+
52
+ source = path.read_text(encoding="utf-8")
53
+ lexer = SmcLexer(source)
54
+ tokens = lexer.tokenize()
55
+
56
+ cat_tokens, dog_tokens = CatDogSlicer.slice_frames(tokens)
57
+
58
+ print("\n[CAT FRAME] ==================== (OFFSET +0) ====================")
59
+ cat_ast = SmcParser(cat_tokens).parse()
60
+ cat_vm = DexterVM()
61
+ cat_res = cat_vm.run(cat_ast)
62
+ for line in cat_res["stdout"]:
63
+ print(line)
64
+
65
+ print("\n[DOG FRAME] ==================== (OFFSET +1) ====================")
66
+ dog_ast = SmcParser(dog_tokens).parse()
67
+ dog_vm = DexterVM()
68
+ dog_res = dog_vm.run(dog_ast)
69
+ for line in dog_res["stdout"]:
70
+ print(line)
71
+ print("===================================================================\n")
72
+
73
+
74
+ def print_tokens(file_path: Path | str) -> None:
75
+ path = Path(file_path)
76
+ if not path.is_file():
77
+ print(f"Error: File not found at '{path}'")
78
+ sys.exit(1)
79
+
80
+ source = path.read_text(encoding="utf-8")
81
+ lexer = SmcLexer(source)
82
+ tokens = lexer.tokenize()
83
+
84
+ print(f"\n--- TOKEN STREAM FOR {path.name} ---")
85
+ for t in tokens:
86
+ mut_flag = " [MUTATION REPAIRED!]" if t.was_mutated else ""
87
+ op_str = f" -> Opcode.{t.resolved_opcode.value}" if t.resolved_opcode else ""
88
+ print(f"Line {t.line:02d}:{t.column:02d} | {t.token_type.value:<12} | '{t.value}'{op_str}{mut_flag}")
89
+ print("------------------------------------\n")
90
+
91
+
92
+ def main() -> None:
93
+ # If invoked with no arguments, launch REPL directly
94
+ if len(sys.argv) == 1:
95
+ start_repl()
96
+ return
97
+
98
+ parser = argparse.ArgumentParser(
99
+ description="SMC (Saturday Morning Cartoons) Language CLI",
100
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
101
+ )
102
+ subparsers = parser.add_subparsers(dest="command", required=True)
103
+
104
+ # repl command
105
+ subparsers.add_parser("repl", help="Launch interactive live REPL shell")
106
+
107
+ # run command
108
+ run_parser = subparsers.add_parser("run", help="Execute an SMC script")
109
+ run_parser.add_argument("file", type=str, help="Path to .smc file")
110
+
111
+ # catdog command
112
+ catdog_parser = subparsers.add_parser("catdog", help="Execute dual-frame CatDog interleaved program")
113
+ catdog_parser.add_argument("file", type=str, help="Path to .smc file")
114
+
115
+ # tokens command
116
+ tokens_parser = subparsers.add_parser("tokens", help="Inspect tokens and degenerate wobble mappings")
117
+ tokens_parser.add_argument("file", type=str, help="Path to .smc file")
118
+
119
+ args = parser.parse_args()
120
+
121
+ if args.command == "repl":
122
+ start_repl()
123
+ elif args.command == "run":
124
+ run_file(args.file)
125
+ elif args.command == "catdog":
126
+ run_catdog(args.file)
127
+ elif args.command == "tokens":
128
+ print_tokens(args.file)
129
+
130
+
131
+ if __name__ == "__main__":
132
+ main()
@@ -0,0 +1,192 @@
1
+ """Fault-Tolerant Lexer for SMC ("Saturday Morning Cartoons") Language.
2
+
3
+ Tokenizes source text and applies biological codon degeneracy to resolve
4
+ synonyms and mutated keywords without throwing fatal syntax errors.
5
+ Supports arithmetic operators, logical comparisons, and control flow tokens.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from smc.tokens import (
11
+ CanonicalToken,
12
+ KEYWORD_TO_OPCODE,
13
+ Opcode,
14
+ TokenType,
15
+ resolve_wobble_opcode,
16
+ )
17
+
18
+
19
+ class SmcLexer:
20
+ """Tokenizes SMC source code with codon wobble tolerancing."""
21
+
22
+ def __init__(self, source_text: str) -> None:
23
+ self.source = source_text
24
+ self.pos = 0
25
+ self.line = 1
26
+ self.col = 1
27
+ self.length = len(source_text)
28
+
29
+ def _peek(self, offset: int = 0) -> str:
30
+ idx = self.pos + offset
31
+ return self.source[idx] if idx < self.length else "\0"
32
+
33
+ def _advance(self) -> str:
34
+ ch = self._peek()
35
+ self.pos += 1
36
+ if ch == "\n":
37
+ self.line += 1
38
+ self.col = 1
39
+ else:
40
+ self.col += 1
41
+ return ch
42
+
43
+ def _skip_whitespace_and_comments(self) -> None:
44
+ while self.pos < self.length:
45
+ ch = self._peek()
46
+ if ch in " \t\r\n":
47
+ self._advance()
48
+ elif ch == "#":
49
+ # Comment until end of line
50
+ while self.pos < self.length and self._peek() != "\n":
51
+ self._advance()
52
+ else:
53
+ break
54
+
55
+ def tokenize(self) -> list[CanonicalToken]:
56
+ """Convert full source into a list of CanonicalToken objects."""
57
+ tokens: list[CanonicalToken] = []
58
+
59
+ while self.pos < self.length:
60
+ self._skip_whitespace_and_comments()
61
+ if self.pos >= self.length:
62
+ break
63
+
64
+ ch = self._peek()
65
+ start_line = self.line
66
+ start_col = self.col
67
+
68
+ # Multi-character comparison operators
69
+ if ch == "=" and self._peek(1) == "=":
70
+ self._advance()
71
+ self._advance()
72
+ tokens.append(CanonicalToken(TokenType.EQ_EQ, "==", start_line, start_col))
73
+ elif ch == "!" and self._peek(1) == "=":
74
+ self._advance()
75
+ self._advance()
76
+ tokens.append(CanonicalToken(TokenType.NOT_EQ, "!=", start_line, start_col))
77
+ elif ch == "<" and self._peek(1) == "=":
78
+ self._advance()
79
+ self._advance()
80
+ tokens.append(CanonicalToken(TokenType.LTE, "<=", start_line, start_col))
81
+ elif ch == ">" and self._peek(1) == "=":
82
+ self._advance()
83
+ self._advance()
84
+ tokens.append(CanonicalToken(TokenType.GTE, ">=", start_line, start_col))
85
+
86
+ # Single-character delimiters and operators
87
+ elif ch == "(":
88
+ self._advance()
89
+ tokens.append(CanonicalToken(TokenType.LPAREN, "(", start_line, start_col))
90
+ elif ch == ")":
91
+ self._advance()
92
+ tokens.append(CanonicalToken(TokenType.RPAREN, ")", start_line, start_col))
93
+ elif ch == "[":
94
+ self._advance()
95
+ tokens.append(CanonicalToken(TokenType.LBRACKET, "[", start_line, start_col))
96
+ elif ch == "]":
97
+ self._advance()
98
+ tokens.append(CanonicalToken(TokenType.RBRACKET, "]", start_line, start_col))
99
+ elif ch == "{":
100
+ self._advance()
101
+ tokens.append(CanonicalToken(TokenType.LBRACE, "{", start_line, start_col))
102
+ elif ch == "}":
103
+ self._advance()
104
+ tokens.append(CanonicalToken(TokenType.RBRACE, "}", start_line, start_col))
105
+ elif ch == "=":
106
+ self._advance()
107
+ tokens.append(CanonicalToken(TokenType.EQUALS, "=", start_line, start_col))
108
+ elif ch == ",":
109
+ self._advance()
110
+ tokens.append(CanonicalToken(TokenType.COMMA, ",", start_line, start_col))
111
+ elif ch == "+":
112
+ self._advance()
113
+ tokens.append(CanonicalToken(TokenType.PLUS, "+", start_line, start_col))
114
+ elif ch == "-":
115
+ self._advance()
116
+ tokens.append(CanonicalToken(TokenType.MINUS, "-", start_line, start_col))
117
+ elif ch == "*":
118
+ self._advance()
119
+ tokens.append(CanonicalToken(TokenType.STAR, "*", start_line, start_col))
120
+ elif ch == "/":
121
+ self._advance()
122
+ tokens.append(CanonicalToken(TokenType.SLASH, "/", start_line, start_col))
123
+ elif ch == "%":
124
+ self._advance()
125
+ tokens.append(CanonicalToken(TokenType.PERCENT, "%", start_line, start_col))
126
+ elif ch == "<":
127
+ self._advance()
128
+ tokens.append(CanonicalToken(TokenType.LT, "<", start_line, start_col))
129
+ elif ch == ">":
130
+ self._advance()
131
+ tokens.append(CanonicalToken(TokenType.GT, ">", start_line, start_col))
132
+ elif ch == "!":
133
+ self._advance()
134
+ tokens.append(CanonicalToken(TokenType.NOT, "!", start_line, start_col))
135
+
136
+ # String literals
137
+ elif ch in ('"', "'"):
138
+ quote_char = self._advance()
139
+ val_chars = []
140
+ while self.pos < self.length and self._peek() != quote_char:
141
+ val_chars.append(self._advance())
142
+ if self._peek() == quote_char:
143
+ self._advance() # closing quote
144
+ tokens.append(CanonicalToken(TokenType.STRING, "".join(val_chars), start_line, start_col))
145
+
146
+ # Numbers
147
+ elif ch.isdigit():
148
+ num_chars = []
149
+ while self.pos < self.length and (self._peek().isdigit() or self._peek() == "."):
150
+ num_chars.append(self._advance())
151
+ num_str = "".join(num_chars)
152
+ val = float(num_str) if "." in num_str else int(num_str)
153
+ tokens.append(CanonicalToken(TokenType.NUMBER, val, start_line, start_col))
154
+
155
+ # Identifiers and Opcode Keywords
156
+ elif ch.isalpha() or ch == "_":
157
+ ident_chars = []
158
+ while self.pos < self.length and (self._peek().isalnum() or self._peek() == "_"):
159
+ ident_chars.append(self._advance())
160
+ ident_str = "".join(ident_chars)
161
+
162
+ # Attempt wobble opcode resolution
163
+ resolved_op = resolve_wobble_opcode(ident_str, max_distance=2)
164
+ if resolved_op:
165
+ was_mut = (ident_str.upper() not in KEYWORD_TO_OPCODE)
166
+ tokens.append(
167
+ CanonicalToken(
168
+ token_type=TokenType.KEYWORD,
169
+ value=ident_str,
170
+ line=start_line,
171
+ column=start_col,
172
+ resolved_opcode=resolved_op,
173
+ was_mutated=was_mut,
174
+ original_text=ident_str,
175
+ )
176
+ )
177
+ else:
178
+ tokens.append(
179
+ CanonicalToken(
180
+ token_type=TokenType.IDENTIFIER,
181
+ value=ident_str,
182
+ line=start_line,
183
+ column=start_col,
184
+ original_text=ident_str,
185
+ )
186
+ )
187
+ else:
188
+ # Unknown character, advance gracefully (biological neutral mutation)
189
+ self._advance()
190
+
191
+ tokens.append(CanonicalToken(TokenType.EOF, "", self.line, self.col))
192
+ return tokens