Skip to main content

Natural Language Source Compiler - Compile .nl specs to executable code

Project description

Natural Language Source (NLS)

PyPI Tests CI Python License Docs

The source code is English. The compiled artifact is Python.

NLS is a programming language where specifications are written in plain English that anyone can read—managers, auditors, domain experts—not just programmers. The nlsc compiler translates .nl files into executable Python with full type hints, validation, and documentation.

Installation

# Install from PyPI
pip install nlsc

# With tree-sitter parser (faster, better error recovery)
pip install "nlsc[treesitter]"

# For development (from source)
git clone https://github.com/Mnehmos/mnehmos.nls.lang.git
cd mnehmos.nls.lang
pip install -e ".[dev,treesitter]"

Windows File Association

Get custom icons for .nl files in Windows Explorer:

# Download and run the installer from GitHub Releases
# Or use the CLI:
nlsc assoc --user   # Current user (no admin)
nlsc assoc          # System-wide (requires admin)

Then right-click any .nl file → Open with → select the NLS launcher and check "Always use this app".

Quick Start

# Initialize a new project
nlsc init my-project
cd my-project

# Create your first .nl file
cat > src/calculator.nl << 'EOF'
@module calculator
@target python

[add]
PURPOSE: Add two numbers together
INPUTS:
  - a: number
  - b: number
RETURNS: a + b

[divide]
PURPOSE: Divide two numbers safely
INPUTS:
  - numerator: number
  - divisor: number
GUARDS:
  - divisor must not be zero -> ValueError("Cannot divide by zero")
RETURNS: numerator / divisor

@test [add] {
  add(2, 3) == 5
  add(-1, 1) == 0
}
EOF

# Compile to Python
nlsc compile src/calculator.nl

# Run the tests
nlsc test src/calculator.nl

Example

Input: math.nl

@module math
@version 1.0.0
@target python

@type Point {
  x: number
  y: number
}

[distance]
PURPOSE: Calculate distance between two points
INPUTS:
  - p1: Point
  - p2: Point
LOGIC:
  1. dx = p2.x - p1.x
  2. dy = p2.y - p1.y
  3. squared = dx * dx + dy * dy
RETURNS: sqrt(squared)
DEPENDS: [sqrt]

@test [distance] {
  distance(Point(0, 0), Point(3, 4)) == 5.0
}

Output: math.py

"""math module - Generated by nlsc"""
from dataclasses import dataclass
from math import sqrt

@dataclass
class Point:
    """Point type"""
    x: float
    y: float

def distance(p1: Point, p2: Point) -> float:
    """Calculate distance between two points"""
    dx = p2.x - p1.x
    dy = p2.y - p1.y
    squared = dx * dx + dy * dy
    return sqrt(squared)

CLI Reference

Command Description
nlsc init <path> Initialize new NLS project
nlsc compile <file> Compile .nl to Python
nlsc verify <file> Validate syntax and dependencies
nlsc test <file> Run @test specifications
nlsc graph <file> Generate dependency diagrams
nlsc diff <file> Show changes since last compile
nlsc watch <dir> Continuous compilation on file changes
nlsc atomize <file.py> Extract ANLUs from existing Python
nlsc assoc Install Windows file association
nlsc lsp Start the NLS language server

Global Options

--parser {regex,treesitter}  # Parser backend (default: regex)
--version                     # Show version
--help                        # Show help

Examples

# Compile with tree-sitter parser
nlsc --parser treesitter compile src/auth.nl

# Generate Mermaid dependency diagram
nlsc graph src/order.nl --format mermaid

# Visualize dataflow for specific function
nlsc graph src/order.nl --anlu process-order --dataflow

# Watch directory and run tests on changes
nlsc watch src/ --test

# Show what changed since last compile
nlsc diff src/api.nl --full

GitHub Action

Use the NLS Compiler Action in your CI/CD pipelines for zero-config validation:

# .github/workflows/nls.yml
name: NLS Validation

on: [push, pull_request]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: Mnehmos/mnehmos.nls.lang/action@master
        with:
          verify: 'true'       # Verify all .nl files parse correctly
          compile: 'false'     # Compile .nl files to Python
          test: 'false'        # Run @test blocks
          lock-check: 'false'  # Verify lockfiles are current
          path: '.'            # Path to search for .nl files

Action Inputs

Input Default Description
verify true Verify all .nl files parse correctly
compile false Compile .nl files to target language
test false Run @test blocks from .nl files
lock-check false Check that lockfiles are up to date
path . Path to search for .nl files
python-version 3.12 Python version to use
fail-on-warning false Fail the action if there are warnings

Action Outputs

Output Description
verified-files Number of verified .nl files
compiled-files List of compiled output files
test-results Test pass/fail summary
warnings Number of warnings

Language Features

ANLU Blocks (Functions)

[function-name]
PURPOSE: What this function does
INPUTS:
  - param1: type
  - param2: type, optional
GUARDS:
  - validation condition -> ErrorType("message")
LOGIC:
  1. step description -> variable
  2. another step
EDGE CASES:
  - condition -> behavior
RETURNS: expression
DEPENDS: [other-function], [another]

Type Definitions

@type Order {
  id: string, required
  items: list of OrderItem
  total: number, "Order total in cents"
  status: string
}

@type OrderItem extends BaseItem {
  quantity: number
  price: number
}

Test Specifications

@test [add] {
  add(1, 2) == 3
  add(0, 0) == 0
  add(-5, 5) == 0
}

Property-Based Testing

@property [add] {
  add(a, b) == add(b, a)           # commutativity
  add(a, 0) == a                   # identity
  forall x: number -> add(x, -x) == 0
}

Type Invariants

@type Account {
  balance: number
  owner: string
}

@invariant Account {
  balance >= 0
  len(owner) > 0
}

Directives

@module name           # Module name
@version 1.0.0         # Semantic version
@target python         # Target language
@imports other_module  # Import dependencies

The Philosophy

"The conversation is the programming. The .nl file is the receipt. The code is the artifact."

  • .nl files — Human-readable specifications anyone can review
  • .py files — Compiled artifacts (like assembly from C)
  • .nl.lock files — Deterministic hashes for reproducible builds

Why NLS?

  1. Readable by everyone — Non-programmers can review business logic
  2. Auditable — Clear mapping from intent to implementation
  3. Testable — Specifications include test cases
  4. Versionable — Lock files ensure reproducibility
  5. Toolable — Tree-sitter grammar enables IDE support

Project Status

Component Status
Parser (regex) ✅ Complete
Parser (tree-sitter) ✅ Complete
Python emitter ✅ Complete
Type generation ✅ Complete
Guard validation ✅ Complete
Dataflow analysis ✅ Complete
Test runner ✅ Complete
Property-based testing ✅ Complete
Type invariants ✅ Complete
Watch mode ✅ Complete
GitHub Action ✅ Complete
PyPI distribution ✅ Complete
VS Code extension ✅ Complete
LSP server ✅ Complete
Windows installer ✅ Complete
TypeScript target 🔜 Planned

239 tests passing — Production-ready for Python target. See GitHub Issues for roadmap.

Documentation

📚 Full Documentation — Hosted on GitHub Pages

Contributing

# Clone and install
git clone https://github.com/Mnehmos/mnehmos.nls.lang.git
cd mnehmos.nls.lang
pip install -e ".[dev,treesitter]"

# Run tests
pytest tests/ -v

# Run tree-sitter grammar tests
cd tree-sitter-nl && npx tree-sitter test

License

MIT

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

nlsc-0.2.1.tar.gz (108.9 kB view details)

Uploaded Source

Built Distribution

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

nlsc-0.2.1-py3-none-any.whl (78.3 kB view details)

Uploaded Python 3

File details

Details for the file nlsc-0.2.1.tar.gz.

File metadata

  • Download URL: nlsc-0.2.1.tar.gz
  • Upload date:
  • Size: 108.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nlsc-0.2.1.tar.gz
Algorithm Hash digest
SHA256 ad3342dcc09d1c012921fc52eeddc65629e2ec476a583aed9beee35fd97bec19
MD5 938e6b33c4c13b6b91b8b20872849d80
BLAKE2b-256 27d274f4649191aa7af2422e6beb97dd3d87ba69414d58244e2e177174f2b5c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for nlsc-0.2.1.tar.gz:

Publisher: publish.yml on Mnehmos/mnehmos.nls.lang

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nlsc-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: nlsc-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 78.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nlsc-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 87a9a34c8fc921a4f866da2387d72ed17f9beea1dda0f530c34c1030e7e82a35
MD5 3e73b76ddd4f7ee22c8086a333a0dcad
BLAKE2b-256 65bdcd6f91141348902ec81698e81b3a8682e541b8f0345c571be27d8325f18f

See more details on using hashes here.

Provenance

The following attestation bundles were made for nlsc-0.2.1-py3-none-any.whl:

Publisher: publish.yml on Mnehmos/mnehmos.nls.lang

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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