Python Project Skeleton
This commit is contained in:
parent
58f41e6bda
commit
3dc5455323
|
|
@ -1 +1,2 @@
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
.venv/
|
||||||
|
|
|
||||||
|
|
@ -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).
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
pytest
|
||||||
|
click
|
||||||
|
mypy
|
||||||
|
black
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
"""sls — Python skeleton for SLS reimplementation
|
||||||
|
|
||||||
|
Expose package version and small helpers here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__all__ = ["__version__", "cli"]
|
||||||
|
|
||||||
|
__version__ = "0.0.1"
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
"""Builtins and native functions for SLS."""
|
||||||
|
|
||||||
|
def load_builtins():
|
||||||
|
"""Return a dict of builtin names to callables."""
|
||||||
|
return {
|
||||||
|
"print": print,
|
||||||
|
}
|
||||||
|
|
@ -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)")
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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")
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
def test_import_package():
|
||||||
|
import sls
|
||||||
|
|
||||||
|
assert hasattr(sls, "__version__")
|
||||||
|
assert isinstance(sls.__version__, str)
|
||||||
Loading…
Reference in New Issue