# Natural Language Source (NLS)

[![Tests](https://img.shields.io/badge/tests-228%20passing-brightgreen)](https://github.com/Mnehmos/mnehmos.nls.lang)
[![CI](https://github.com/Mnehmos/mnehmos.nls.lang/actions/workflows/ci.yml/badge.svg)](https://github.com/Mnehmos/mnehmos.nls.lang/actions/workflows/ci.yml)
[![Python](https://img.shields.io/badge/python-3.11+-blue)](https://www.python.org)
[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
[![Docs](https://img.shields.io/badge/docs-GitHub%20Pages-blue)](https://mnehmos.github.io/mnehmos.nls.lang/)

> **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

```bash
# Basic install
pip install -e .

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

# With development tools
pip install -e ".[dev]"
```

## Quick Start

```bash
# 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`

```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`

```python
"""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     |

### Global Options

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

### Examples

```bash
# 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:

```yaml
# .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)

```nl
[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

```nl
@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

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

### Directives

```nl
@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 |
| Watch mode           | ✅ Complete |
| GitHub Action        | ✅ Complete |
| VS Code extension    | 🔜 Planned  |
| TypeScript target    | 🔜 Planned  |
| LSP server           | 🔜 Planned  |

**228 tests passing** — Production-ready for Python target. See [GitHub Issues](https://github.com/Mnehmos/mnehmos.nls.lang/issues) for roadmap.

## Documentation

📚 **[Full Documentation](https://mnehmos.github.io/mnehmos.nls.lang/)** — Hosted on GitHub Pages

- [Getting Started](docs/getting-started.md)
- [Language Specification](docs/language-spec.md)
- [CLI Reference](docs/cli-reference.md)
- [Architecture](docs/architecture.md)

## Contributing

```bash
# 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
