Python Project Skeleton
This commit is contained in:
parent
58f41e6bda
commit
3dc5455323
|
|
@ -1 +1,2 @@
|
|||
__pycache__/
|
||||
.venv/
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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