Skip to content

plops/cl-rust-generator

Repository files navigation

## Overview

`cl-rust-generator` is a Common Lisp metaprogramming system that generates Rust source code from S-expressions. The system translates Lisp-based syntax trees into syntactically correct, type-safe Rust code, enabling developers to write Rust programs using Lisp’s symbolic programming capabilities while maintaining Rust’s type system, ownership model, and idiomatic patterns.

## Supported Lisp Expressions

The following table lists all supported Common Lisp expressions and their corresponding Rust translations:

### Basic Operations

Lisp ExpressionRust OutputExample
`(+ a b)``(a + b)``(emit-rs :code ‘(+ 1 2))` → `(1 + 2)`
`(- a b)``(a - b)``(emit-rs :code ‘(- 5 3))` → `(5 - 3)`
`(* a b)``(a * b)``(emit-rs :code ‘(* 2 3))` → `((2) * (3))`
`(/ a b)``(a / b)``(emit-rs :code ‘(/ 10 2))` → `((10) / (2))`

### Comparison and Logical Operations

Lisp ExpressionRust OutputExample
`(= a b)``a=b``(emit-rs :code ‘(= x 5))` → `x=5`
`(!= a b)``(a)!=(b)``(emit-rs :code ‘(!= x 5))` → `(x)!=(5)`
`(== a b)``(a)==(b)``(emit-rs :code ‘(== x 5))` → `(x)==(5)`
`(< a b)``a<b``(emit-rs :code ‘(< 3 5))` → `3<5`
`(and a b)``(a)&&(b)``(emit-rs :code ‘(and true false))` → `(true)&&(false)`
`(or a b)``(a)(b)``(emit-rs :code ‘(or true false))` → `(true)(false)`

### Control Flow

Lisp ExpressionRust OutputExample
`(if condition true-branch false-branch)``if condition { true-branch } else { false-branch }``(emit-rs :code ‘(if (> x 0) (return x) (return 0)))`
`(when condition body…)``if condition { body… }``(emit-rs :code ‘(when (> x 0) (return x)))`
`(unless condition body…)``if (!condition) { body… }``(emit-rs :code ‘(unless (> x 0) (return 0)))`
`(while condition body…)``while (condition) { body… }``(emit-rs :code ‘(while (> i 0) (decf i)))`
`(for (item collection) body…)``for item in collection { body… }``(emit-rs :code ‘(for (x vec) (print x)))`
`(case keyform (key body…) (t default-body…))``match keyform { key => { body… }, _ => { default-body… } }``(emit-rs :code ‘(case x (1 (print “one”)) (t (print “other”))))`

### Variable Declarations and Bindings

Lisp ExpressionRust OutputExample
`(let ((var value)) body…)``let var = value; body…``(emit-rs :code ‘(let ((x 5)) (print x)))`
`(let* ((var value)) body…)``let mut var = value; body…``(emit-rs :code ‘(let* ((x 5)) (setf x 10)))`
`(setf var value)``var = value;``(emit-rs :code ‘(setf x 10))`

### Function Definitions

Lisp ExpressionRust OutputExample
`(defun name (args) (declare (type type arg)) (declare (values return-type)) body…)``fn name(arg: type) -> return_type { body… }``(emit-rs :code ‘(defun gcd (n m) (declare (type u64 n m) (values u64)) (return n)))`
`(lambda (args) body…)``args{ body… }``(emit-rs :code ‘(lambda (x) (* x 2)))`

### Data Structures

Lisp ExpressionRust OutputExample
`(defstruct0 name (slot1 type1) (slot2 type2))``struct name { slot1: type1, slot2: type2, }``(emit-rs :code ‘(defstruct0 Point (x f64) (y f64)))`
`(make-instance Point :x 1.0 :y 2.0)``Point { x: 1.0, y: 2.0 }``(emit-rs :code ‘(make-instance Point :x 1.0 :y 2.0))`
`(aref array index)``array[index]``(emit-rs :code ‘(aref arr 0))`

### Special Forms and Modules

Lisp ExpressionRust OutputExample
`(use ((std io)))``use std::io;``(emit-rs :code ‘(use ((std io))))`
`(mod module1 module2)``mod module1; mod module2;``(emit-rs :code ‘(mod utils main))`
`(unsafe body…)``unsafe { body… }``(emit-rs :code ‘(unsafe (setf x 5)))`
`(extern body…)``extern { body… }``(emit-rs :code ‘(extern (defun printf (s string))))`

### String and Character Operations

Lisp ExpressionRust OutputExample
`(string “hello”)``”hello”``(emit-rs :code ‘(string “hello”))`
`(char ‘a’)``’a’``(emit-rs :code ‘(char ‘a’))`
`(hex 255)``0xff``(emit-rs :code ‘(hex 255))`

## Examples

### Basic Function Example

“`lisp (defun gcd (n m) (declare (type u64 n m) (values u64)) (if (= m 0) (return n) (gcd m (% n m)))) “`

Generates: “`rust fn gcd(n: u64, m: u64) -> u64 { if m == 0 { return n; } gcd(m, (n % m)) } “`

### Struct Example

“`lisp (defstruct0 Point (x f64) (y f64))

(defun distance (p1 p2) (declare (type Point p1 p2) (values f64)) (let ((dx (- (dot p1 x) (dot p2 x))) (dy (- (dot p1 y) (dot p2 y)))) (declare (type f64 dx dy)) (return (sqrt (+ (* dx dx) (* dy dy)))))) “`

Generates: “`rust struct Point { x: f64, y: f64, }

fn distance(p1: Point, p2: Point) -> f64 { let dx = (p1.x - p2.x); let dy = (p1.y - p2.y); return sqrt(((dx * dx) + (dy * dy))); } “`

## Installation and Usage

  1. Install the ASDF system: “`lisp (ql:quickload :cl-rust-generator) “`
  2. Use the `emit-rs` function to generate Rust code: “`lisp (emit-rs :code ‘(defun main () (declare (values i32)) (return 0))) “`
  3. Write generated code to files: “`lisp (write-source “src/main.rs” (emit-rs :code ‘(defun main () (declare (values i32)) (return 0)))) “`

## Project Structure

The system consists of:

  • `rs.lisp` - Core translation engine with `emit-rs` function
  • `cl-rust-generator.asd` - ASDF system definition
  • `examples/` - Collection of example projects demonstrating various patterns

## Example Projects

ExampleDescriptionStatus
`01_gcd`Basic GCD function with testsFinished
`02_webgcd`Web server with GCD calculationFinished
`06_parallel_text`Multi-file project with threadingFinished
`08_glfw`GLFW windowing with ImGuiFinished
`09_wasm`WebAssembly exampleBasic
`11_cuda`CUDA GPU computingBasic

## Notes

  • The system uses hash-based change detection to avoid unnecessary file rewrites
  • Generated code is automatically formatted using `rustfmt`
  • Type declarations are processed through `consume-declare` function for type safety
  • The readtable case is inverted to preserve Rust naming conventions

Wiki pages you might want to explore:

  • [Overview (plops/cl-rust-generator)](/wiki/plops/cl-rust-generator#1)

About

Common Lisp based converter from s-expressions to Rust language source code

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors