| Crates.io | lucia-lasm |
| lib.rs | lucia-lasm |
| version | 1.0.4 |
| created_at | 2025-12-25 18:04:31.698916+00 |
| updated_at | 2025-12-26 17:38:00.929669+00 |
| description | LASM - Lucia Assembly Language |
| homepage | https://github.com/SirPigari/lasm |
| repository | https://github.com/SirPigari/lasm |
| max_upload_size | |
| id | 2004811 |
| size | 195,220 |
LASM (Lucia Assembly) is a Rust crate that provides JIT (Just-In-Time) compilation of a custom assembly language to native machine code via Cranelift. Its key features are high-performance JIT execution and seamless variable interaction between Rust and LASM code.
JIT Compilation: Unlike interpreted languages, LASM compiles to native machine code at runtime using Cranelift, providing near-native performance with minimal overhead.
Variable Bridge: Seamlessly pass data between high-level Rust code and low-level assembly, enabling performance-critical sections while maintaining safety.
Modern Assembly: Register-based architecture with convenient syscalls, eliminating the boilerplate of traditional assembly programming.
Rust Integration: Drop LASM code anywhere in your Rust application for instant performance boosts.
Purpose: LASM was developed as the low-level execution backend for the Lucia Programming Language. It powers the lasm module, allowing performance-critical sections of an otherwise interpreted language to execute at near-native speed through JIT compilation.
Add to your Cargo.toml:
[dependencies]
lasm = { version = "1", package = "lucia-lasm" }
Or use the latest version from crates.io:
cargo add lucia-lasm
git clone https://github.com/SirPigari/lasm
cd lasm
cargo build --release
use lasm::{compile, call, Target};
use std::collections::HashMap;
fn main() {
let code = r#"
mov 42, r0
syscall print_int
mov "\n", r1
mov 1, r0
mov 1, r2
syscall write
mov 0, r0
syscall exit
"#;
let target = Target::Native;
let compiled = compile(code, target).expect("Compilation failed");
let variables = HashMap::new();
let (exit_code, _) = call(&compiled, &variables).expect("Execution failed");
assert_eq!(exit_code, 0);
}
The crate includes a CLI binary for testing and development:
cargo run --bin lasm -- examples/hello.lasm
Or after building:
./target/release/lasm examples/hello.lasm
use lasm::{compile, call, Target};
use std::collections::HashMap;
fn main() {
let code = r#"
mov 42, r0
syscall print_int
mov "\n", r1
mov 1, r0
mov 1, r2
syscall write
mov 0, r0
syscall exit
"#;
let target = Target::Native;
let compiled = compile(code, target).expect("Compilation failed");
let variables = HashMap::new();
let (exit_code, _) = call(&compiled, &variables).expect("Execution failed");
assert_eq!(exit_code, 0);
}
One of LASM's most powerful features is seamless variable passing between Rust and LASM code:
use lasm::{compile, call, Target, Value};
use std::collections::HashMap;
fn main() {
let code = r#"
; Load input variables
load input, r0 ; Load 'input' variable into r0
add r0, 10 ; Add 10 to it
push r0, output ; Store result in 'output' variable
mov 0, r0
syscall exit
"#;
let target = Target::Native;
let compiled = compile(code, target).expect("Compiling failed");
let mut variables = HashMap::new();
variables.insert("input".to_string(), Value::Int(42));
let (exit_code, updated_vars) = call(&compiled, &variables).expect("Execution failed");
if let Some(Value::Int(result)) = updated_vars.get("output") {
assert_eq!(*result, 52);
}
}
load "var_name", reg - Load a variable from Rust into a registerpush reg, "var_name" - Store a register value back to a Rust variableVariables can be of type Int, Float, String, Ptr, or Null.
mov <src>, <dst> - Move value from source to destinationldr <reg>, [<reg>] - Load from memory address in registerstr <reg>, [<reg>] - Store to memory address in registerload "var", <reg> - Load Rust variable into registerpush <reg>, "var" - Store register value to Rust variableadd <dst>, <src> - Addsub <dst>, <src> - Subtractmul <dst>, <src> - Multiplydiv <dst>, <src> - Dividemod <dst>, <src> - Modulofadd <dst>, <src> - Add floatsfsub <dst>, <src> - Subtract floatsfmul <dst>, <src> - Multiply floatsfdiv <dst>, <src> - Divide floatsfmod <dst>, <src> - Modulo floatsand <dst>, <src> - Bitwise ANDor <dst>, <src> - Bitwise ORxor <dst>, <src> - Bitwise XORnot <dst> - Bitwise NOTshl <dst>, <src> - Shift leftshr <dst>, <src> - Shift rightcmp <left>, <right> - Compare registers/valuesbeq <label> - Branch if equalbne <label> - Branch if not equalblt <label> - Branch if less thanbgt <label> - Branch if greater thanble <label> - Branch if less or equalbge <label> - Branch if greater or equaljmp <label> - Unconditional jumpcall <label> - Call subroutineret - Return from subroutinepushr <reg> - Push register onto stackpopr <reg> - Pop from stack into registerInstructions can take:
42 or strings like "hello"r0, r1, etc.LASM provides high-level syscalls that abstract away low-level system calls:
syscall write - Write to file descriptor (fd in r0, buffer in r1, count in r2)syscall read - Read from file descriptorsyscall print_int - Print integer (value in r0)syscall print_float - Print float (bits in r0)syscall print_str - Print null-terminated string (pointer in r0)syscall flush - Flush output stream (fd in r0)syscall malloc - Allocate memory (size in r0, returns pointer in r0)syscall free - Free memory (pointer in r0)syscall memcpy - Copy memory (dst in r0, src in r1, len in r2)syscall memset - Set memory (dst in r0, val in r1, len in r2)syscall strcmp - Compare strings (str1 in r0, str2 in r1, returns comparison in r0)syscall strcpy - Copy string (dst in r0, src in r1, returns dst in r0)syscall strlen - Get string length (str in r0, returns length in r0)syscall starts_with - Check if string starts with prefix (str in r0, prefix in r1, returns 1/0 in r0)syscall streq - Check if strings are equal (str1 in r0, str2 in r1, returns 1/0 in r0)syscall ends_with - Check if string ends with suffix (str in r0, suffix in r1, returns 1/0 in r0)syscall trim - Trim whitespace (str in r0, out in r1, returns length in r0)syscall trim_start - Trim leading whitespace (str in r0, out in r1, returns length in r0)syscall trim_end - Trim trailing whitespace (str in r0, out in r1, returns length in r0)syscall isws - Check if string is all whitespace (str in r0, returns 1/0 in r0)syscall atoi - String to integer (str in r0, returns int in r0)syscall atof - String to float (str in r0, returns float bits in r0)syscall itoa - Integer to string (int in r0, buffer in r1, size in r2, returns length in r0)syscall ftoa - Float to string (bits in r0, buffer in r1, size in r2, returns length in r0)syscall itof - Integer to float (int in r0, returns float bits in r0)syscall ftoi - Float to integer (bits in r0, returns int in r0)syscall fadd - Add floats (a bits in r0, b bits in r1, returns result bits in r0)syscall fsub - Subtract floatssyscall fmul - Multiply floatssyscall fdiv - Divide floatssyscall fmod - Modulo floatssyscall time - Get current time (returns nanoseconds in r0)syscall fmt_time - Format time (total_nanos in r0, format in r1, buffer in r2, returns length in r0)syscall rand - Generate random float (seed in r0, returns float bits in r0)syscall sleep - Sleep for milliseconds (ms in r0)syscall system - Execute system command (cmd in r0, returns exit code in r0)syscall exit - Exit program (status in r0); Hello World
mov "Hello, World!\n", r1
mov 1, r0
mov 14, r2
syscall write
mov 0, r0
syscall exit
; Simple calculator
mov 10, r0
mov 20, r1
add r0, r1 ; r0 = 30
syscall print_int
mov "\n", r1
mov 1, r0
mov 1, r2
syscall write
mov 0, r0
syscall exit
The repository includes example LASM programs in the examples/ directory:
# Hello World
cargo run -- examples/hello.lasm
# Calculator
cargo run -- examples/calculator.lasm
# Time display
cargo run -- examples/time.lasm
# Interactive shell
cargo run -- examples/shell.lasm
Or after building the release binary:
./target/release/lasm examples/hello.lasm
; and continue to end of line: and can be jumped toLASM provides clear error messages for:
LASM's JIT compilation provides significant performance advantages for compute-intensive tasks:
use lasm::{compile, call, Target, Value};
use std::collections::HashMap;
fn main() {
// Simple variable manipulation example
let simple_lasm = r#"
load "input", r0 ; Load input value
add r0, 100 ; Add 100
push r0, "output" ; Store result
mov 0, r0
syscall exit
"#;
// Compile once, reuse for multiple runs
let target = Target::Native;
let compiled = compile(simple_lasm, target).expect("Compile failed");
// Execute with different inputs
for input in 0..10 {
let mut vars = HashMap::new();
vars.insert("input".to_string(), Value::Int(input));
let (exit_code, result_vars) = call(&compiled, &vars).expect("Execution failed");
if let Some(Value::Int(result)) = result_vars.get("output") {
println!("Input: {}, Output: {}", input, result);
}
}
}
JIT compilation enables dynamic code generation while maintaining high performance.
Run the test suite:
cargo test
The tests include various LASM programs demonstrating different features and syscalls.
Contributions are welcome! This is a Rust crate that can be extended in several ways:
git clone https://github.com/SirPigari/lasm
cd lasm
cargo build
cargo test
To publish to crates.io:
cargo publish
Make sure to update the version in Cargo.toml and tag the release.