A simple, rule-based DSL that interprets Eyal-style directives to Python code.
Project description
EyalLang Core
๐ก A simple, rule-based DSL that interprets Eyal-style directives to Python code.
Features
- Simple Syntax: Direct commands without boilerplate
- Fast & Reliable: No external dependencies or API calls
- Predictable: Deterministic interpretation to Python
- Extensible: Easy to add new commands and syntax
- Lightweight: Uses only Python standard library
- Great Error Reporting: Helpful error messages with suggestions
- Fail Fast: Stops execution on first error
Quick Start
1. No Dependencies Required!
# Just clone and run - no pip install needed!
git clone <your-repo>
cd eyal-lang
2. Basic Usage
from eyal_lang import translate_line, translate_file, translate_lines
# Interpret a single directive
result = translate_line("say hello world")
print(result) # Output: print("hello world")
# Interpret multiple directives
lines = ["say hello world", "set name to 'Eyal'"]
python_code = translate_lines(lines)
print(python_code) # Output: ['print("hello world")', "name = 'Eyal'"]
# Interpret an entire file
python_code = translate_file("examples/hello.eyal")
CLI Usage
Interpret a File
python -m eyal_lang --file examples/hello.eyal
Interactive Mode
python -m eyal_lang
# Then type EyalLang directives interactively
Single Line Interpretation
python -m eyal_lang --line "say hello world"
Save Output to File
python -m eyal_lang --file examples/hello.eyal --output hello.py
Development
Setup Development Environment
# Install with development dependencies
pip install -e .[dev]
# Install pre-commit hooks
pre-commit install
Code Quality Tools
The project uses pre-commit hooks to ensure code quality:
- Black: Code formatting
- isort: Import sorting
- flake8: Linting
- mypy: Type checking
- bandit: Security analysis
Running Quality Checks
# Run all pre-commit hooks
pre-commit run --all-files
# Run individual tools
black .
isort .
flake8 .
mypy .
bandit -r .
EyalLang Syntax Reference
Output Commands
say hello world # print("hello world")
Variables
set name to "Eyal" # name = "Eyal"
set count to 42 # count = 42
set result to a + b # result = a + b
Comments
# This is a comment
Project Structure
eyal-lang/
โโโ eyal_lang/ # Core package
โ โโโ __init__.py # Package exports
โ โโโ __main__.py # CLI entry point
โ โโโ interpreter.py # High-level API
โ โโโ parser.py # Rule-based parser
โโโ examples/
โ โโโ hello.eyal # Basic output example
โ โโโ simple.eyal # Variables example
โ โโโ calculator.eyal # Math operations
โ โโโ greeting.eyal # String handling
โโโ .pre-commit-config.yaml # Pre-commit hooks
โโโ pyproject.toml # Build configuration
โโโ LICENSE # MIT license
โโโ .gitignore # Git ignore rules
โโโ README.md # This file
API Reference
translate_line(eyal_directive: str) -> str
Interpret a single EyalLang directive to Python code.
Raises: ValueError if the directive cannot be parsed
translate_lines(eyal_lines: List[str]) -> List[str]
Interpret multiple EyalLang directives to Python code.
Raises: ValueError if any line fails to parse
translate_file(file_path: str) -> List[str]
Interpret an entire EyalLang file to Python code.
Raises: FileNotFoundError if the file doesn't exist, ValueError if any line fails to parse
EyalLangInterpreter
Rule-based interpreter class.
Example Interpretations
Basic Output (hello.eyal)
# Hello World in EyalLang
say hello world
say welcome to EyalLang
Interprets to:
print("hello world")
print("welcome to EyalLang")
Variables (simple.eyal)
# Simple Variables Example
set name to "Eyal"
set greeting to "Hello"
say greeting name
say nice to meet you
Interprets to:
name = "Eyal"
greeting = "Hello"
print("greeting name")
print("nice to meet you")
Calculator (calculator.eyal)
# Calculator Example
set a to 10
set b to 5
set sum to a + b
set product to a * b
say the sum is sum
say the product is product
Interprets to:
a = 10
b = 5
sum = a + b
product = a * b
print("the sum is sum")
print("the product is product")
Greeting (greeting.eyal)
# Greeting Example
set first_name to "Alice"
set last_name to "Smith"
set time_of_day to "morning"
say good time_of_day first_name
say welcome to our program
Interprets to:
first_name = "Alice"
last_name = "Smith"
time_of_day = "morning"
print("good time_of_day first_name")
print("welcome to our program")
Error Handling
The interpreter stops execution on the first error and provides detailed error messages:
# This will raise ValueError and stop execution
try:
result = translate_line("invalid command")
except ValueError as e:
print(e)
# Output: โ Error on line 1: Unknown command 'invalid command'
# ๐ก Suggestions:
# 'say' needs a message. Try: 'say hello world'
# ๐ Available commands:
# say hello world - say <message> - prints a message
# set name to "Eyal" - set <variable> to <value> - creates a variable
CLI Error Handling
# File interpretation stops on first error
python -m eyal_lang --file invalid.eyal
# โ Error: Line 2: โ Error on line 2: Unknown command 'invalid command'
# Interactive mode shows errors but continues
python -m eyal_lang
eyal> invalid command
โ Error: โ Error on line 1: Unknown command 'invalid command'
eyal> say hello
๐ print("hello")
Integration Examples
Flask API
from flask import Flask, request, jsonify
from eyal_lang import translate_lines
app = Flask(__name__)
@app.route("/api/interpret", methods=["POST"])
def interpret():
try:
data = request.get_json()
lines = data.get("lines", [])
interpretations = translate_lines(lines)
return jsonify({"output": interpretations})
except ValueError as e:
return jsonify({"error": str(e)}), 400
Custom Interpreter
from eyal_lang import EyalLangInterpreter
interpreter = EyalLangInterpreter()
try:
result = interpreter.interpret("say hello world")
print(result)
except Exception as e:
print(f"Error: {e}")
Advantages of Rule-Based Approach
- โก Instant: No model loading or API calls
- ๐ฏ Predictable: Same input always produces same output
- ๐ง Debuggable: Clear error messages for invalid syntax
- ๐ฐ Free: No external dependencies or costs
- ๐ Fast: Immediate interpretation
- ๐ Learnable: Clear syntax rules to follow
- ๐ ๏ธ Extensible: Easy to add new commands
- ๐ Fail Fast: Stops on first error for better debugging
- ๐ฏ Simple: No boilerplate, direct commands
Publishing to PyPI
The project uses GitHub Actions to automatically publish to PyPI. To set this up:
-
Create PyPI API Token:
- Go to PyPI Account Settings
- Create an API token with "Entire account" scope
- Copy the token
-
Add GitHub Secret:
- Go to your GitHub repository settings
- Navigate to "Secrets and variables" โ "Actions"
- Add a new secret named
PYPI_API_TOKENwith your PyPI token
-
Publishing:
- PyPI: Publishes when you create a release or push a tag (e.g.,
v1.0.0)
- PyPI: Publishes when you create a release or push a tag (e.g.,
-
Create a Release:
git tag v1.0.0 git push origin v1.0.0
Then create a release on GitHub with the same tag.
License
MIT License - Feel free to use and modify!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file eyal_lang-0.1.0.tar.gz.
File metadata
- Download URL: eyal_lang-0.1.0.tar.gz
- Upload date:
- Size: 14.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
94ef4a46ea19d3a740fdf0728dce4f43e4a77d74c9836afd2de78094c1880b1e
|
|
| MD5 |
e4c52547896f38aa8c54179cf2f7cb6d
|
|
| BLAKE2b-256 |
d0a6df0e18803501764e4d81cc393cf2ebb2f257ba2a48db717c1a6c70d748e3
|
File details
Details for the file eyal_lang-0.1.0-py3-none-any.whl.
File metadata
- Download URL: eyal_lang-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3edc39686b95ca907d14e0df6c95e22202209f2abe7b0c6e70aab492f0b6eb61
|
|
| MD5 |
e1f2bdd9185aafc85d624b06f07386c0
|
|
| BLAKE2b-256 |
c5d91dfed573f502b91ad85110d8334e8e6b187a48e0fff284e95eefe8bd2ed0
|