Python Project Skeleton

This commit is contained in:
Kyler Olsen 2025-12-02 19:10:11 -07:00
parent 58f41e6bda
commit 3dc5455323
11 changed files with 174 additions and 1 deletions

View File

@ -1 +1,2 @@
__pycache__/ __pycache__/
.venv/

View File

@ -1,3 +1,42 @@
# SLS Python # 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).

18
SLS_Python/pyproject.toml Normal file
View File

@ -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"

View File

@ -0,0 +1,4 @@
pytest
click
mypy
black

View File

@ -0,0 +1,8 @@
"""sls — Python skeleton for SLS reimplementation
Expose package version and small helpers here.
"""
__all__ = ["__version__", "cli"]
__version__ = "0.0.1"

View File

@ -0,0 +1,7 @@
"""Builtins and native functions for SLS."""
def load_builtins():
"""Return a dict of builtin names to callables."""
return {
"print": print,
}

29
SLS_Python/sls/cli.py Normal file
View File

@ -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)")

View File

@ -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

25
SLS_Python/sls/lexer.py Normal file
View File

@ -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)

25
SLS_Python/sls/repl.py Normal file
View File

@ -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")

View File

@ -0,0 +1,5 @@
def test_import_package():
import sls
assert hasattr(sls, "__version__")
assert isinstance(sls.__version__, str)