Skip to main content

A simple, rule-based DSL that interprets Eyal-style directives to Python code.

Project description

EyalLang Core

CI PyPI version Python 3.11+

๐Ÿ’ก 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:

  1. Create PyPI API Token:

  2. Add GitHub Secret:

    • Go to your GitHub repository settings
    • Navigate to "Secrets and variables" โ†’ "Actions"
    • Add a new secret named PYPI_API_TOKEN with your PyPI token
  3. Publishing:

    • PyPI: Publishes when you create a release or push a tag (e.g., v1.0.0)
  4. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

eyal_lang-0.1.0.tar.gz (14.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

eyal_lang-0.1.0-py3-none-any.whl (14.3 kB view details)

Uploaded Python 3

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

Hashes for eyal_lang-0.1.0.tar.gz
Algorithm Hash digest
SHA256 94ef4a46ea19d3a740fdf0728dce4f43e4a77d74c9836afd2de78094c1880b1e
MD5 e4c52547896f38aa8c54179cf2f7cb6d
BLAKE2b-256 d0a6df0e18803501764e4d81cc393cf2ebb2f257ba2a48db717c1a6c70d748e3

See more details on using hashes here.

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

Hashes for eyal_lang-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3edc39686b95ca907d14e0df6c95e22202209f2abe7b0c6e70aab492f0b6eb61
MD5 e1f2bdd9185aafc85d624b06f07386c0
BLAKE2b-256 c5d91dfed573f502b91ad85110d8334e8e6b187a48e0fff284e95eefe8bd2ed0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page