docs.rs failed to build h2lang-0.2.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
H2 Language
H2 Language (h2lang) is a programming language compiler fully compatible with the Herbert Online Judge (HOJ) H language specification, extended with multi-agent support for robot swarm control.
Features
- HOJ Compatible - Full support for Herbert Online Judge syntax including macros, functions, and recursion
- Multi-Agent Support - Control multiple robots simultaneously with parallel scheduling
- WebAssembly Ready - Runs in browsers via wasm-bindgen
- Zero Dependencies Runtime - Lightweight compiled output
- Type-Safe - Written in Rust with comprehensive error handling
- Well Documented - Extensive documentation following Rust API guidelines
Quick Start
# Single robot drawing a square
0: f(X):XXXX f(sssr)
# Two robots moving in parallel
0: srl
1: lrs
# Recursive pattern with numeric argument
0: a(X):sra(X-1) a(4)
Installation
From crates.io (Rust)
From npm (WebAssembly)
From Source
# Clone the repository
# Build WebAssembly package
# Or build native library
# Run tests
Requirements
- Rust 1.70+
- wasm-pack (for WebAssembly builds)
- Node.js 16+ (for npm usage)
Language Specification
Basic Commands
| Command | Description | Action |
|---|---|---|
s |
Straight | Move forward one step |
r |
Right | Rotate 90° clockwise |
l |
Left | Rotate 90° counter-clockwise |
Agent Definition
Each line defines commands for a specific robot (agent):
agent_id: commands
# Examples
0: srl # Agent 0: straight, right, left
1: llss # Agent 1: left, left, straight, straight
Macros
Define reusable command sequences with single lowercase letters:
# Syntax: name:body
x:ss # Define macro 'x' as 'ss'
xrx # Expands to: ssrss
# Full example
0: x:sssr xrxrxrx # Square pattern using macro
Functions
Functions support parameters (uppercase letters) and recursion:
# Syntax: name(PARAMS):body
f(X):XXX f(s) # Repeats argument 3 times → sss
f(X):XXXX f(sssr) # Square pattern → sssrsssrsssrsssr
# Multiple parameters
a(X,Y):Ya(X-1,Y) a(4,s) # Repeat 's' four times → ssss
# Numeric arguments with recursion
a(X):sra(X-1) a(4) # Spiral pattern (terminates when X ≤ 0)
Numeric Expressions
Functions support numeric arguments and arithmetic:
a(X):sa(X-1) a(4) # X decrements: 4→3→2→1→0(stop)
a(X):sa(X+1) a(-2) # X increments: -2→-1→0(stop)
Termination Rule: When a numeric argument is ≤ 0, the function returns empty (recursion stops).
Comments
# This is a comment
0: srl # Inline comment
// C-style comments also work
Implementation Notes
Whitespace Handling
- Agent ID: Agent IDs must appear at the start of a line. Leading spaces/tabs before the agent ID are permitted and treated as line-start context.
- Function/Macro Definitions: No whitespace is allowed between the identifier and
(in function definitions (e.g.,f(X):...is valid,f (X):...is not). - Spaces: Spaces and tabs between tokens are generally ignored except where they affect line-start detection.
Recursion and Termination
- Maximum Recursion Depth: The expander has a maximum recursion depth of 100 to prevent stack overflow from deeply nested macro/function calls. Exceeding this limit results in an expansion error.
- Numeric Termination: When any numeric argument becomes ≤ 0, the function call returns an empty sequence (no commands). This applies to all numeric parameters in the function.
- Expansion Limit: There is no explicit limit on the total number of expanded commands, but deeply recursive patterns may hit the depth limit first.
Error Handling
Compilation errors include:
- Line and column information for precise error location
- Expected vs. found tokens for parse errors
- Undefined macro/function references
- Maximum recursion depth exceeded
Examples
Drawing Shapes
# Square (4 sides)
0: f(X):XXXX f(sssr)
# Triangle (3 sides)
0: f(X):XXX f(ssssrr)
# Spiral
0: a(X):sra(X-1) a(8)
Multi-Robot Choreography
# Two robots moving in mirror pattern
0: srlsrl
1: slrslr
# Three robots with different patterns
0: f(X):XXXX f(sr)
1: f(X):XXXX f(sl)
2: ssssssss
Complex Recursion
# Nested function calls
0: f(X):XX f(f(s)) # f(s)=ss, f(ss)=ssss → 4 commands
# Parameterized repetition
0: a(X,Y):Ya(X-1,Y) a(3,sr) # srsrsr (repeat 'sr' 3 times)
API Reference
Rust (Native)
use compile_native;
use CompileResult;
let result = compile_native;
match result
JavaScript/TypeScript (WebAssembly)
import init from 'h2lang';
await ;
// Compile source code
const result = ;
if
// Validate without compiling
const validation = ;
console.log; // true or false
// Get compiler version
console.log; // "0.1.0"
Output Format
The compiler produces a JSON structure:
Building from Source
WebAssembly Build
# Install wasm-pack if not already installed
# Build for web
# or
# Build for Node.js
Native Build
# Debug build
# Release build
# Run tests
# Generate documentation
Testing
# Run all tests (241 tests)
# Run tests with output
# Run specific test module
# WebAssembly tests (requires Chrome)
Project Structure
h2lang/
├── .github/
│ ├── workflows/
│ │ └── ci.yml # CI pipeline (fmt, clippy, test, wasm)
│ ├── ISSUE_TEMPLATE/ # Issue templates
│ └── PULL_REQUEST_TEMPLATE.md
├── src/
│ ├── lib.rs # Main entry point, WASM bindings
│ ├── lexer.rs # Tokenizer
│ ├── parser.rs # Recursive descent parser
│ ├── ast.rs # Abstract Syntax Tree definitions
│ ├── expander.rs # Macro/function expansion
│ ├── scheduler.rs # Multi-agent parallel scheduling
│ ├── output.rs # JSON output structures
│ ├── token.rs # Token definitions
│ └── error.rs # Error types
├── tests/
│ └── h_language_compatibility.rs # 145 HOJ compatibility tests
├── Cargo.toml # Rust dependencies
├── package.json # npm configuration
├── rust-toolchain.toml # Rust toolchain configuration
├── CONTRIBUTING.md # Contribution guidelines
├── CODE_OF_CONDUCT.md # Community guidelines (Contributor Covenant)
├── CHANGELOG.md # Version history
└── LICENSE # MIT License
Architecture
Source Code → Lexer → Parser → AST → Expander → Scheduler → Output
↓ ↓ ↓ ↓ ↓ ↓ ↓
"0:srl" Tokens Parse Tree Commands Timeline JSON
Tree (expanded) (parallel)
Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
Quick Contribution Guide
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for new functionality
- Ensure all tests pass (
cargo test) - Format code (
cargo fmt) - Run linter (
cargo clippy) - Commit with clear messages following Conventional Commits
- Open a Pull Request
Development Commands
# Format code
# Run linter
# Run all checks before PR
&& &&
Community
- GitHub Issues - Bug reports and feature requests
- GitHub Discussions - Questions and ideas
License
This project is licensed under the MIT License - see the LICENSE file for details.
Related Links
- Herbert Online Judge - Original HOJ platform
- HOJ GitHub - HOJ source code
- Codeforces Discussion - Community discussion
- wasm-bindgen - Rust/WebAssembly bindings
Acknowledgments
- Herbert Online Judge by @quolc
- Microsoft ImagineCup for the original Herbert game concept
- The Rust community for excellent tooling