ring-lang-rs
Rust bindings for the Ring programming language.
Use Cases
- Write Ring extensions in Rust - Create native extensions with Rust's safety and performance
- Embed Ring in Rust applications - Run Ring scripts from your Rust programs
- Wrap Rust crates for Ring - Expose any Rust library to Ring applications
How It Works
flowchart LR
subgraph ext["<b>Extensions</b>"]
direction LR
A["Ring Program<br/><code>.ring</code>"] -->|"loadlib()"| B["Rust Extension<br/><code>.dll/.so/.dylib</code>"]
B -->|"return values"| A
end
subgraph emb["<b>Embedding</b>"]
direction LR
C["Rust Application<br/><code>binary</code>"] -->|"ring_state_*()"| D["Ring VM<br/><code>embedded</code>"]
D -->|"results"| C
end
Code Generation Tools
Two approaches to generate Ring extensions from Rust code:
| Approach | Location | Best For |
|---|---|---|
| Proc Macro | macros/ |
New projects, pure Rust workflow |
| Ring Script | tools/codegen/ |
Similar to C/C++ Ring codegen workflow |
Proc Macro (ring_extension!) - Zero config, just cargo build:
ring_extension!
Ring Script (parsec.ring) - Uses .rf config files:
Both generate the same Ring-callable functions. See each README for details.
Using Extensions
If you have a Rust extension (.dll/.so/.dylib), using it is simple:
# Load the library (OS-specific)
if iswindows()
loadlib("myextension.dll")
elseif ismacosx()
loadlib("libmyextension.dylib")
else
loadlib("libmyextension.so")
ok
# Call functions just like native Ring functions
? rust_hello() # Hello from Rust!
? rust_add(10, 20) # 30
? rust_greet("Ring") # Hello, Ring!
That's it! No Rust knowledge required.
Creating Extensions
The rest of this document covers how to create Ring extensions in Rust or embed Ring in Rust applications.
Supported Platforms
Linux, macOS, Windows, FreeBSD
Requirements
- Rust (stable)
- Ring language installed
Installation
Add to your Cargo.toml:
[]
= ["cdylib"]
[]
= "0.1"
Or clone and use locally:
Environment Variables
Optional: Set RING (or ring) to your Ring installation directory:
# Linux/macOS
# Windows (PowerShell)
# Windows (CMD)
If not set, the system's libring will be used.
Quick Start
Extension example:
Embedding example:
Basic Function
use *;
ring_func!;
ring_libinit!
Working with Numbers
ring_func!;
Working with Strings
ring_func!;
Working with Lists
ring_func!;
ring_func!;
Working with C Pointers (Rust Structs)
use c_void;
const MY_TYPE: & = b"MyStruct\0";
ring_func!;
ring_func!;
Managed Pointers (Auto-freed by Ring GC)
extern "C"
ring_func!;
Available Macros
| Macro | Description |
|---|---|
ring_libinit! |
Register functions with Ring |
ring_func! |
Define a Ring function with boilerplate |
ring_check_paracount! |
Validate parameter count |
ring_check_paracount_range! |
Validate parameter count within range |
ring_check_string! |
Validate string parameter |
ring_check_number! |
Validate number parameter |
ring_check_list! |
Validate list parameter |
ring_check_pointer! |
Validate pointer parameter |
ring_check_cpointer! |
Validate C pointer parameter |
ring_get_string! |
Get string parameter |
ring_get_number! |
Get number parameter (f64) |
ring_get_int! |
Get integer parameter (i32) |
ring_get_list! |
Get list parameter |
ring_get_pointer! |
Get typed pointer as Option<&mut T> |
ring_get_cpointer! |
Get raw C pointer |
ring_new_list! |
Create new list |
ring_ret_number! |
Return number |
ring_ret_string! |
Return string |
ring_ret_list! |
Return list |
ring_ret_cpointer! |
Return C pointer |
ring_ret_managed_cpointer! |
Return managed C pointer |
ring_error! |
Raise Ring error |
Module Structure
| Module | Description |
|---|---|
ffi |
Raw FFI bindings + struct definitions (VM, List, Item, String) |
api |
Ring VM API wrappers (58 functions) |
list |
List manipulation (66 functions) |
string |
String operations (15 functions) |
state |
State management (31 functions) |
vm |
VM control and execution (44 functions) |
item |
Item/value operations (23 functions) |
general |
File/directory utilities (14 functions) |
macros |
Ergonomic helper macros |
API Coverage
192 / 456 functions (42%) of Ring's public C API.
| Header | Coverage |
|---|---|
vm.h |
29/29 (100%) |
state.h |
19/20 (95%) |
rstring.h |
11/22 (50%) |
ritem.h |
17/34 (50%) |
general.h |
12/28 (43%) |
rlist.h |
54/131 (41%) |
ringapi.h |
39/111 (35%) |
vmgc.h |
4/81 (5%) |
We focused on functions useful for writing extensions. ringapi.h has many type-check macros (bound separately). rlist.h and vmgc.h have _gc variants we skip.
Embedding Ring
To embed Ring in a Rust application:
Cargo.toml:
[]
= "0.1"
Running Code
use *;
Sharing Variables
use *;
API Reference
| Function | Requires | Description |
|---|---|---|
ring_state_init() |
- | Create state with initialized VM |
ring_state_new() |
- | Create state for compilation |
ring_state_runcode_str() |
ring_state_init() |
Execute code on initialized VM |
ring_state_runfile_str() |
ring_state_new() |
Compile and run a file |
ring_state_runstring_str() |
ring_state_new() |
Compile and run a string |
ring_state_findvar_str() |
ring_state_init() |
Find a variable by name |
ring_state_delete() |
- | Clean up and free the state |
See examples/embed/ for a complete working example.
License
This project is licensed under the MIT License - see the LICENSE file for details.