From 3dc545532305124ea195a52c2b8dd285925b9a3e Mon Sep 17 00:00:00 2001 From: Kyler Date: Tue, 2 Dec 2025 19:10:11 -0700 Subject: [PATCH] Python Project Skeleton --- SLS_Python/.gitignore | 1 + SLS_Python/README.md | 41 ++++++++++++++++++++++++++++++++- SLS_Python/pyproject.toml | 18 +++++++++++++++ SLS_Python/requirements-dev.txt | 4 ++++ SLS_Python/sls/__init__.py | 8 +++++++ SLS_Python/sls/builtin.py | 7 ++++++ SLS_Python/sls/cli.py | 29 +++++++++++++++++++++++ SLS_Python/sls/interpreter.py | 12 ++++++++++ SLS_Python/sls/lexer.py | 25 ++++++++++++++++++++ SLS_Python/sls/repl.py | 25 ++++++++++++++++++++ SLS_Python/tests/test_import.py | 5 ++++ 11 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 SLS_Python/pyproject.toml create mode 100644 SLS_Python/requirements-dev.txt create mode 100644 SLS_Python/sls/__init__.py create mode 100644 SLS_Python/sls/builtin.py create mode 100644 SLS_Python/sls/cli.py create mode 100644 SLS_Python/sls/interpreter.py create mode 100644 SLS_Python/sls/lexer.py create mode 100644 SLS_Python/sls/repl.py create mode 100644 SLS_Python/tests/test_import.py diff --git a/SLS_Python/.gitignore b/SLS_Python/.gitignore index c18dd8d..670a936 100644 --- a/SLS_Python/.gitignore +++ b/SLS_Python/.gitignore @@ -1 +1,2 @@ __pycache__/ +.venv/ diff --git a/SLS_Python/README.md b/SLS_Python/README.md index 7648a83..019c290 100644 --- a/SLS_Python/README.md +++ b/SLS_Python/README.md @@ -1,3 +1,42 @@ # SLS Python -This is the Python implementation for the YREA SLS interpreter. +This directory contains a minimal Python project skeleton intended to reimplement +functionality from the C `SLS` project found at the repository root. + +Layout +- `src/sls/` — Python package with module skeletons: `lexer`, `parser`, `interpreter`, `builtin`, `repl`, and `cli`. +- `tests/` — pytest tests (start with `test_import.py`). +- `pyproject.toml` — project metadata and `sls` console script entrypoint. +- `requirements-dev.txt` — developer/test tools. + +Quick start + +Create a venv and install editable package + dev requirements: + +```bash +python -m venv .venv +source .venv/bin/activate +pip install -e SLS_Python +pip install -r SLS_Python/requirements-dev.txt +``` + +Run tests: + +```bash +pytest -q +``` + +Run the REPL: + +```bash +sls repl +``` + +Next steps (suggested) +- Port `lexer.c` to `src/sls/lexer.py` and add comprehensive tokenization tests. +- Port `parser` and `interpreter` incrementally, keeping tests for parity. +- Add CI (GitHub Actions) and type checking (`mypy`). + +If you want, I can now: +- Run the tests in this environment (if you want me to configure the Python env), or +- Start porting a specific module from the C implementation (lexer is a good first target). diff --git a/SLS_Python/pyproject.toml b/SLS_Python/pyproject.toml new file mode 100644 index 0000000..74cc7f9 --- /dev/null +++ b/SLS_Python/pyproject.toml @@ -0,0 +1,18 @@ +[build-system] +requires = ["setuptools>=61.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "sls-python" +version = "0.1.0" +description = "Python reimplementation skeleton of the SLS C project" +authors = [ { name = "Your Name" } ] +readme = "README.md" +license = { text = "MIT" } +requires-python = ">=3.10" +dependencies = [ + "click>=8.0" +] + +[project.scripts] +sls = "sls.cli:main" diff --git a/SLS_Python/requirements-dev.txt b/SLS_Python/requirements-dev.txt new file mode 100644 index 0000000..726db5c --- /dev/null +++ b/SLS_Python/requirements-dev.txt @@ -0,0 +1,4 @@ +pytest +click +mypy +black diff --git a/SLS_Python/sls/__init__.py b/SLS_Python/sls/__init__.py new file mode 100644 index 0000000..29117f6 --- /dev/null +++ b/SLS_Python/sls/__init__.py @@ -0,0 +1,8 @@ +"""sls — Python skeleton for SLS reimplementation + +Expose package version and small helpers here. +""" + +__all__ = ["__version__", "cli"] + +__version__ = "0.0.1" diff --git a/SLS_Python/sls/builtin.py b/SLS_Python/sls/builtin.py new file mode 100644 index 0000000..8be1bbe --- /dev/null +++ b/SLS_Python/sls/builtin.py @@ -0,0 +1,7 @@ +"""Builtins and native functions for SLS.""" + +def load_builtins(): + """Return a dict of builtin names to callables.""" + return { + "print": print, + } diff --git a/SLS_Python/sls/cli.py b/SLS_Python/sls/cli.py new file mode 100644 index 0000000..fd052d7 --- /dev/null +++ b/SLS_Python/sls/cli.py @@ -0,0 +1,29 @@ +"""Command-line entry point for SLS Python.""" +import click + +from . import __version__ + + +@click.group() +@click.version_option(__version__) +def main(): + """sls: Small Lisp-like language (Python reimplementation).""" + pass + + +@main.command() +def repl(): + """Start a minimal REPL.""" + from .repl import repl_loop + + repl_loop() + + +@main.command() +@click.argument("file", required=False) +def run(file): + """Run an SLS source file (placeholder).""" + if not file: + click.echo("No file provided; start with `sls repl`") + return + click.echo(f"Would run: {file} (not implemented yet)") diff --git a/SLS_Python/sls/interpreter.py b/SLS_Python/sls/interpreter.py new file mode 100644 index 0000000..5b6c63a --- /dev/null +++ b/SLS_Python/sls/interpreter.py @@ -0,0 +1,12 @@ +"""Interpreter module placeholder for SLS.""" + +from typing import Any + + +class Interpreter: + def __init__(self): + self.env = {} + + def eval(self, ast: Any): + """Evaluate the AST and return a result. Not implemented yet.""" + return None diff --git a/SLS_Python/sls/lexer.py b/SLS_Python/sls/lexer.py new file mode 100644 index 0000000..23efb90 --- /dev/null +++ b/SLS_Python/sls/lexer.py @@ -0,0 +1,25 @@ +"""Lexer module placeholder for SLS. + +Provide a Lexer class that will later be expanded to match the C implementation. +""" + +from dataclasses import dataclass +from typing import Iterator, NamedTuple + + +class Token(NamedTuple): + type: str + value: str + lineno: int + col: int + + +@dataclass +class Lexer: + source: str + + def tokenize(self) -> Iterator[Token]: + """Yield tokens from `source`. Currently yields a single EOF token. + Replace with full logic when porting the C lexer. + """ + yield Token("EOF", "", 1, 0) diff --git a/SLS_Python/sls/repl.py b/SLS_Python/sls/repl.py new file mode 100644 index 0000000..68b98c0 --- /dev/null +++ b/SLS_Python/sls/repl.py @@ -0,0 +1,25 @@ +"""Simple REPL for SLS skeleton.""" + +from .lexer import Lexer +from .parser import Parser +from .interpreter import Interpreter + + +def repl_loop(): + interp = Interpreter() + print("sls-python REPL (very minimal). Type 'quit' or Ctrl-D to exit.") + try: + while True: + src = input("sls> ") + if not src or src.strip() in ("quit", "exit"): + break + # minimal echo behaviour for now + lexer = Lexer(src) + tokens = list(lexer.tokenize()) + ast = Parser(tokens).parse() + result = interp.eval(ast) + if result is not None: + print(result) + except (EOFError, KeyboardInterrupt): + print() + print("Bye") diff --git a/SLS_Python/tests/test_import.py b/SLS_Python/tests/test_import.py new file mode 100644 index 0000000..add2468 --- /dev/null +++ b/SLS_Python/tests/test_import.py @@ -0,0 +1,5 @@ +def test_import_package(): + import sls + + assert hasattr(sls, "__version__") + assert isinstance(sls.__version__, str)