Contributing to JugaadLang
First time? Read
CONTRIBUTING.mdat the project root for the quick-start guide.
This document provides deeper technical guidance for contributors.
Development Setup
Prerequisites
- Python 3.10 or later
- pip, uv, or your preferred Python package manager
Installation
# Clone your fork
git clone https://github.com/YOUR_USERNAME/jugaadlang.git
cd jugaadlang
# Editable install with all extras
pip install -e .[dev,all]
# Or with uv
uv sync --dev
Verify Setup
jug --version
jug run examples/01_namaste_duniya.jug
jug repl
Project Architecture
See docs/architecture.md for detailed architecture documentation.
Quick Overview
Source (.jug)
→ Lexer (tokens)
→ Parser (JL AST)
→ Transformer (Python AST)
→ compile() (bytecode)
→ exec() (execute)
Key Modules
| Module | Purpose |
|---|---|
jugaadlang/lexer/ |
Tokenizer with indentation tracking |
jugaadlang/ast_nodes/ |
AST node definitions (dataclasses) |
jugaadlang/parser/ |
Recursive-descent parser |
jugaadlang/transformer/ |
JL AST → Python AST converter |
jugaadlang/runtime/ |
Execution engine + built-in functions |
jugaadlang/errors/ |
Funny Hindi error formatter |
jugaadlang/stdlib/ |
Standard library modules |
jugaadlang/package_manager/ |
Package manager (pip wrapper) |
jugaadlang/repl/ |
Interactive REPL |
jug_cli/ |
Command-line interface |
Coding Standards
Code Style
- Line length: 100 characters
- Formatter:
ruff(replaces black/isort/flake8) - Type hints: Required for all function signatures (
from __future__ import annotations) - Docstrings: Required for public modules, classes, and functions
Running the Formatter
ruff check .
ruff check --fix .
Running Type Checks
mypy jugaadlang/ jug_cli/
Running Tests
pytest
pytest -v # verbose
pytest --cov # with coverage
pytest tests/test_lexer.py # single test file
Test Structure
Tests are in the tests/ directory using pytest:
| File | Tests |
|---|---|
tests/test_lexer.py |
Lexer tokenization |
tests/test_parser.py |
Parser AST generation |
tests/test_runtime.py |
Full execution pipeline |
tests/test_errors.py |
Error formatting |
Adding a New Keyword
- Token type: Add to
TokenTypeenum injugaadlang/lexer/tokens.py - Keyword mapping: Add to
KEYWORDSdict injugaadlang/lexer/tokens.py - Lexer: Ensure the lexer tokenizes the keyword (should work automatically via
_scan_identifier) - AST node: If a new statement/expression type, add node class in
jugaadlang/ast_nodes/nodes.py - Parser: Add parse method in
jugaadlang/parser/parser.pyand dispatch inparse_statement()orparse_expression() - Transformer: Add
visit_{NodeType}method injugaadlang/transformer/to_python.py - Built-in mapping: If a built-in function, add to
globalsdict injugaadlang/runtime/interpreter.py - REPL: Add to
KEYWORDS_LISTinjugaadlang/repl/repl.pyfor auto-completion - Pygments lexer: Add to
JugaadPygmentsLexerinjugaadlang/repl/repl.pyfor syntax highlighting - Tests: Add test cases in the appropriate test file
- Docs: Update
docs/keywords.mdanddocs/spec.md
Adding a Standard Library Module
- Create a new
.pyfile injugaadlang/stdlib/ - Import and register it in
jugaadlang/stdlib/__init__.py - Add to the
local_stdlibslist injugaadlang/package_manager/manager.pyfor search support - Add tests for the module
- Document in
docs/stdlib.md
Release Process
Version Bumping
Version is defined in two places:
- pyproject.toml → [project] version
- jugaadlang/__init__.py → __version__
Update both using:
./update_version.sh 1.1.1
Building
python -m build
Creates dist/jugaadlang-{version}.tar.gz and dist/jugaadlang-{version}-py3-none-any.whl.
Publishing to PyPI
twine check dist/*
twine upload dist/*
Creating a GitHub Release
- Tag the release:
git tag v1.1.1 - Push tags:
git push --tags - Create a release on GitHub → triggers automated
release.ymlworkflow
Pull Request Guidelines
- Branch from
mainwith a descriptive name (e.g.,feature/pattern-matching,fix/parser-error) - Keep PRs focused on a single concern
- Include tests for new features and bug fixes
- Ensure CI passes (runs tests on Python 3.10–3.15 + ruff linting)
- Update documentation if changing behavior or adding features
- Write meaningful commit messages
Commit Message Format
<type>: <short description>
<optional body>
Types: feat:, fix:, docs:, test:, refactor:, style:, chore:, ci:
Example:
feat: add kismat() built-in for random number generation
Debugging Tips
- Use
jug check file.jugto validate syntax without execution - Use
jug compile file.jugto see the transpiled Python output - Use
debug(variable)inside JugaadLang code to inspect values - Set
PYTHONDEVMODE=1for extra Python runtime checks
Working on the documentation website
The documentation portal is a static site at website/docs/. Its HTML and search index are generated from the Markdown files in docs/ and docs/guides/. Navigation and page order are defined in scripts/build_docs.py; the shared layout lives in docs/site/template.html. Styles and browser behavior live in website/docs/docs.css, theme.js, and docs.js.
Install the build dependency and regenerate after editing Markdown or the template:
python -m pip install -e ".[dev]" -r docs/requirements.txt
python scripts/build_docs.py
python scripts/build_docs.py --check
python -m pytest tests/test_documentation.py
python -m http.server 8000 --directory website
Open http://localhost:8000/docs/. Commit the generated HTML and search index along with source changes, so existing static hosting can serve the portal without a build step. CI checks that generated files match their sources. Do not edit generated HTML directly.
Guide code blocks marked jugaadlang followed by an expected text output block are executed in the documentation tests. Keep these examples deterministic and independent of network access. Check navigation, search, copy buttons, keyboard access, light/dark themes, and narrow screens when changing the portal UI.
Related: architecture, internal API, and coding guidelines.
Getting Help
- Issues: https://github.com/JugaadLang/jugaadlang/issues
- Discussions: GitHub Discussions page
- Email: jugaadlang@atomicmail.io