Complete reference guide for all 91+ built-in functions in the Solisp LISP interpreter.
Version: 1.0.0 Last Updated: 2025-10-27 Test Coverage: 100% (356/356 tests passing)
- Control Flow
- Variables & Assignment
- Functions & Closures
- Macros & Code Generation
- Logical Operations
- Type Predicates
- Assertions
- Cryptography & Encoding
- String Operations
- Math Operations
- Collection Operations (Map-Reduce Stack)
- Object Operations
- Advanced Features
- Error Handling
- Utilities
- Syntax Reference
Signature: (if condition then-expr else-expr)
Description: Conditional execution - always returns a value
Returns: Value of then-expr if condition is truthy, otherwise else-expr
(if (> x 10)
"large"
"small")Signature: (when condition body...)
Description: Execute body only if condition is true
Returns: Result of last expression in body, or null if condition is false
(when (> balance 1000)
(log :message "High balance")
(send-alert))Signature: (unless condition body...)
Description: Execute body only if condition is false (inverse of when)
Returns: Result of last expression in body, or null if condition is true
(unless (null? data)
(process-data data))Signature: (cond (test1 expr1) (test2 expr2) ... (else default))
Description: Multi-way conditional branching
Returns: Result of first matching clause
(cond
((>= score 90) "A")
((>= score 80) "B")
((>= score 70) "C")
(else "F"))Signature: (case value (pattern1 result1) (pattern2 result2) ... (else default))
Description: Pattern matching by value equality
Returns: Result of first matching pattern
Note: Supports multiple values in patterns [val1 val2 ...]
(case day
(1 "Monday")
(2 "Tuesday")
([6 7] "Weekend")
(else "Weekday"))Signature: (typecase value (type1 result1) (type2 result2) ... (else default))
Description: Pattern matching by type
Returns: Result of first matching type
Types: int, float, string, bool, array, object, function, null
(typecase x
(int "integer")
(string "text")
([float int] "numeric")
(else "other"))Signature: (while condition body...)
Description: Loop while condition is true
Returns: null
(define i 0)
(while (< i 10)
(log :value i)
(set! i (+ i 1)))Signature: (for (var collection) body...)
Description: Iterate over arrays, ranges, or sequences
Returns: null
;; Iterate over array
(for (num [1 2 3 4 5])
(log :value (* num num)))
;; Iterate over range
(for (i (range 1 11))
(log :value i))Signature: (do expr1 expr2 ... exprN)
Description: Sequential execution of expressions
Returns: Value of last expression
Alias: progn
(do
(define x 10)
(set! x (* x 2))
(+ x 5)) ; Returns 25Signature: (prog1 expr1 expr2 ... exprN)
Description: Execute all expressions, return value of first
Returns: Value of first expression
(prog1
(+ 1 2) ; Returns 3
(log :message "after"))Signature: (prog2 expr1 expr2 expr3 ... exprN)
Description: Execute all expressions, return value of second
Returns: Value of second expression
(prog2
(log :message "first")
(+ 10 20) ; Returns 30
(log :message "third"))Signature: (define name value)
Description: Define a new immutable variable (can be shadowed in nested scopes)
Returns: The defined value
(define x 10)
(define greeting "Hello")
(define factorial (lambda (n) ...))Signature: (set! name value)
Description: Mutate an existing variable
Returns: The new value
Error: Throws error if variable is not defined
(define counter 0)
(set! counter (+ counter 1))Signature: (setf place value)
Description: Generalized assignment (can set fields, indices, variables)
Returns: The new value
;; Set variable
(setf x 10)
;; Set object field
(setf (get obj :field) "new value")
;; Set array element
(setf (nth arr 0) 42)Signature: (const name value)
Description: Define a constant (same as define, naming convention)
Returns: The defined value
(const PI 3.14159)
(const MAX_RETRIES 5)Signature: (defvar name value)
Description: Define a dynamic (special) variable
Returns: The defined value
Note: Dynamic variables have special scoping in Common Lisp tradition
(defvar *debug-mode* false)Signature: (defun name (params...) body...)
Description: Define a named function
Returns: The function value
Alias: defn
(defun factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))))Signature: (lambda (params...) body...)
Description: Create an anonymous function (closure)
Returns: Function value capturing current environment
(define square (lambda (x) (* x x)))
(map (lambda (x) (* x 2)) [1 2 3 4 5])Signature: (let ((var1 val1) (var2 val2) ...) body...)
Description: Create local bindings (parallel - vars can't reference each other)
Returns: Value of last expression in body
(let ((x 10)
(y 20))
(+ x y)) ; Returns 30Signature: (let* ((var1 val1) (var2 val2) ...) body...)
Description: Create local bindings (sequential - later vars can reference earlier ones)
Returns: Value of last expression in body
(let* ((x 10)
(y (* x 2)) ; y can reference x
(z (+ x y))) ; z can reference x and y
z) ; Returns 30Signature: (flet ((name1 (params...) body...) (name2 ...)) body...)
Description: Define local functions (non-recursive)
Returns: Value of last expression in body
(flet ((square (x) (* x x))
(double (x) (* x 2)))
(+ (square 3) (double 4))) ; Returns 17Signature: (labels ((name1 (params...) body...) (name2 ...)) body...)
Description: Define local recursive functions
Returns: Value of last expression in body
(labels ((factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1))))))
(factorial 5)) ; Returns 120Signature: (defmacro name (params...) body...)
Description: Define a macro for code generation
Returns: The macro value
(defmacro when (condition &rest body)
`(if ,condition
(do ,@body)
null))Signature: (gensym) or (gensym prefix)
Description: Generate a unique symbol for hygienic macros
Returns: Unique symbol string
(define temp (gensym)) ; "G__1"
(define temp (gensym "X")) ; "X__1"Signature: (macroexpand form)
Description: Expand a macro call to see generated code
Returns: Expanded form
(macroexpand '(when (> x 10) (log :value x)))Signature: (eval expression)
Description: Evaluate an expression at runtime
Returns: Result of evaluation
(eval '(+ 1 2 3)) ; Returns 6Signature: (not expr)
Description: Logical negation
Returns: true if expr is falsy, false otherwise
(not true) ; => false
(not false) ; => true
(not null) ; => true
(not 0) ; => false (0 is truthy in Solisp)Signature: (and expr1 expr2 ...)
Description: Logical AND (short-circuits on first falsy value)
Returns: First falsy value, or last value if all truthy
(and true true true) ; => true
(and true false true) ; => false
(and (> x 0) (< x 100)) ; Range checkSignature: (or expr1 expr2 ...)
Description: Logical OR (short-circuits on first truthy value)
Returns: First truthy value, or last value if all falsy
(or false false true) ; => true
(or null false 42) ; => 42
(or (null? x) (empty? x)) ; Null or empty checkAll type predicates return true or false.
Signature: (null? value)
Description: Check if value is null
(null? null) ; => true
(null? 0) ; => falseSignature: (empty? collection)
Description: Check if array or string is empty
(empty? []) ; => true
(empty? "") ; => true
(empty? [1 2 3]) ; => falseSignature: (int? value)
Description: Check if value is an integer
(int? 42) ; => true
(int? 3.14) ; => falseSignature: (float? value)
Description: Check if value is a float
(float? 3.14) ; => true
(float? 42) ; => falseSignature: (number? value)
Description: Check if value is either int or float
(number? 42) ; => true
(number? 3.14) ; => true
(number? "text") ; => falseSignature: (string? value)
Description: Check if value is a string
(string? "hello") ; => true
(string? 42) ; => falseSignature: (bool? value)
Description: Check if value is a boolean
(bool? true) ; => true
(bool? false) ; => true
(bool? 1) ; => falseSignature: (array? value)
Description: Check if value is an array
(array? [1 2 3]) ; => true
(array? "text") ; => falseSignature: (object? value)
Description: Check if value is an object
(object? {:name "Alice"}) ; => true
(object? [1 2 3]) ; => falseSignature: (function? value)
Description: Check if value is a function
(function? (lambda (x) x)) ; => true
(function? 42) ; => falseSignature: (assert condition message)
Description: Assert condition is true, throw error with message if false
Returns: true if assertion passes
Error: Throws error with message if condition is false
(assert (> x 0) "x must be positive")
(assert (not (empty? data)) "data cannot be empty")Signature: (assert-type value expected-type message)
Description: Assert value has expected type
Returns: true if type matches
Error: Throws error with message if type doesn't match
(assert-type age "int" "age must be an integer")
(assert-type name "string" "name must be a string")Signature: (base58-encode string)
Description: Encode string to Base58 format (Solana address encoding)
Returns: Base58-encoded string
(base58-encode "HelloSolana")
; => "JxF12TsNv5tEWpp"Signature: (base58-decode base58-string)
Description: Decode Base58 string back to original
Returns: Decoded string
Error: Throws error if invalid Base58 format
(base58-decode "JxF12TsNv5tEWpp")
; => "HelloSolana"Signature: (base64-encode string)
Description: Encode string to Base64 format
Returns: Base64-encoded string
(base64-encode "Hello Solana")
; => "SGVsbG8gU29sYW5h"Signature: (base64-decode base64-string)
Description: Decode Base64 string back to original
Returns: Decoded string
Error: Throws error if invalid Base64 format
(base64-decode "SGVsbG8gU29sYW5h")
; => "Hello Solana"Signature: (hex-encode string)
Description: Encode string to hexadecimal format
Returns: Hex-encoded string (lowercase)
(hex-encode "solana")
; => "736f6c616e61"Signature: (hex-decode hex-string)
Description: Decode hex string back to original
Returns: Decoded string
Error: Throws error if invalid hex format
(hex-decode "736f6c616e61")
; => "solana"Signature: (sha256 string)
Description: Compute SHA-256 cryptographic hash
Returns: 64-character hex string
(sha256 "test transaction data")
; => "5e304fe75c1bd8dab6e975bcf8f160d95a04b2a1b8119be88feef0e5506561be"Signature: (sha512 string)
Description: Compute SHA-512 cryptographic hash
Returns: 128-character hex string
(sha512 "test data")
; => "8aa66c657b7ff40d0238f4ce9f1ae951a240374390b2f8e821b7153447ad8778..."Signature: (str value1 value2 ...)
Description: Convert values to strings and concatenate
Returns: Concatenated string
(str "Balance: " balance " SOL")
; => "Balance: 1000 SOL"Signature: (format template args...)
Description: Format string with placeholders
Returns: Formatted string
(format "User {} has {} points" "Alice" 100)
; => "User Alice has 100 points"Signature: (split string delimiter)
Description: Split string by delimiter
Returns: Array of substrings
(split "a,b,c,d" ",")
; => ["a" "b" "c" "d"]Signature: (join array separator)
Description: Join array elements into string with separator
Returns: Joined string
(join ["a" "b" "c"] ", ")
; => "a, b, c"Signature: (replace string old new)
Description: Replace all occurrences of substring
Returns: String with replacements
(replace "hello world" "world" "Solisp")
; => "hello Solisp"Signature: (trim string)
Description: Remove leading and trailing whitespace
Returns: Trimmed string
(trim " hello ")
; => "hello"Signature: (upper string)
Description: Convert string to uppercase
Returns: Uppercase string
(upper "hello")
; => "HELLO"Signature: (lower string)
Description: Convert string to lowercase
Returns: Lowercase string
(lower "HELLO")
; => "hello"All arithmetic operators are variadic (accept multiple arguments).
Signature: (+ num1 num2 ...)
Description: Add numbers together
Returns: Sum
(+ 1 2 3 4 5) ; => 15Signature: (- num1 num2 ...)
Description: Subtract numbers sequentially
Returns: Difference
(- 100 20 10) ; => 70Signature: (* num1 num2 ...)
Description: Multiply numbers together
Returns: Product
(* 2 3 4) ; => 24Signature: (/ num1 num2 ...)
Description: Divide numbers sequentially
Returns: Quotient
Error: Division by zero
(/ 100 2 5) ; => 10Signature: (% num1 num2)
Description: Get remainder of division
Returns: Remainder
Error: Division by zero
(% 17 5) ; => 2Signature: (= val1 val2)
Description: Check equality
Returns: Boolean
(= 5 5) ; => true
(= "a" "a") ; => trueSignature: (!= val1 val2)
Description: Check inequality
Returns: Boolean
(!= 5 10) ; => trueSignature: (< num1 num2)
Description: Check if first is less than second
Returns: Boolean
(< 5 10) ; => trueSignature: (<= num1 num2)
Description: Check if first is less than or equal to second
Returns: Boolean
(<= 5 5) ; => trueSignature: (> num1 num2)
Description: Check if first is greater than second
Returns: Boolean
(> 10 5) ; => trueSignature: (>= num1 num2)
Description: Check if first is greater than or equal to second
Returns: Boolean
(>= 10 10) ; => trueSignature: (abs number)
Description: Absolute value
Returns: Non-negative number
(abs -42) ; => 42
(abs 3.14) ; => 3.14Signature: (sqrt number)
Description: Square root
Returns: Square root as float
(sqrt 16) ; => 4.0
(sqrt 2) ; => 1.414...Signature: (pow base exponent)
Description: Exponentiation (base^exponent)
Returns: Power result
(pow 2 8) ; => 256
(pow 10 -2) ; => 0.01Signature: (min num1 num2 ...)
Description: Find minimum value
Returns: Smallest number
(min 5 2 8 1) ; => 1Signature: (max num1 num2 ...)
Description: Find maximum value
Returns: Largest number
(max 5 2 8 1) ; => 8Signature: (map function array)
Description: Transform each element in array
Returns: New array with transformed elements
(map (lambda (x) (* x 2)) [1 2 3 4 5])
; => [2 4 6 8 10]Signature: (filter function array)
Description: Keep elements that satisfy predicate
Returns: New array with filtered elements
(filter (lambda (x) (> x 5)) [1 3 5 7 9])
; => [7 9]Signature: (reduce function array initial)
Description: Accumulate array into single value
Returns: Accumulated result
(reduce + [1 2 3 4 5] 0)
; => 15
(reduce (lambda (acc x) (+ acc x)) [1 2 3] 0)
; => 6Signature: (first array)
Description: Get first element
Returns: First element or null if empty
Alias: car (Common Lisp)
(first [1 2 3]) ; => 1
(first []) ; => nullSignature: (rest array)
Description: Get all elements except first
Returns: Array without first element
Alias: cdr (Common Lisp)
(rest [1 2 3 4]) ; => [2 3 4]
(rest [1]) ; => []Signature: (last array)
Description: Get last element
Returns: Last element or null if empty
(last [1 2 3]) ; => 3
(last []) ; => nullSignature: (nth array index)
Description: Get element at index (0-based)
Returns: Element at index
Error: Index out of bounds
(nth [10 20 30] 1) ; => 20Signature: (slice array start end)
Description: Extract subarray from start to end (exclusive)
Returns: New array with sliced elements
(slice [1 2 3 4 5] 1 4) ; => [2 3 4]Signature: (cons element array)
Description: Prepend element to array
Returns: New array with element at front
(cons 0 [1 2 3]) ; => [0 1 2 3]Signature: (append array1 array2 ...)
Description: Concatenate arrays
Returns: New combined array
(append [1 2] [3 4] [5]) ; => [1 2 3 4 5]Signature: (range start end) or (range end)
Description: Generate array of integers from start to end (exclusive)
Returns: Array of integers
Note: (range n) is shorthand for (range 0 n)
(range 1 5) ; => [1 2 3 4] (5 is excluded!)
(range 5) ; => [0 1 2 3 4]Signature: (find array predicate)
Description: Find first element satisfying predicate
Returns: First matching element or null
(find [1 2 3 4 5] (lambda (x) (> x 3)))
; => 4Signature: (distinct array)
Description: Remove duplicate elements
Returns: New array with unique elements
(distinct [1 2 2 3 3 3 4])
; => [1 2 3 4]Signature: (flatten array)
Description: Flatten nested arrays one level
Returns: Flattened array
(flatten [[1 2] [3 4] [5 6]])
; => [1 2 3 4 5 6]Signature: (reverse array)
Description: Reverse array order
Returns: New reversed array
(reverse [1 2 3 4 5])
; => [5 4 3 2 1]Signature: (some array predicate)
Description: Check if any element satisfies predicate
Returns: Boolean
(some [1 2 3 4] (lambda (x) (> x 3)))
; => trueSignature: (every array predicate)
Description: Check if all elements satisfy predicate
Returns: Boolean
(every [2 4 6 8] (lambda (x) (= (% x 2) 0)))
; => trueSignature: (partition array predicate)
Description: Split array into [matching, non-matching]
Returns: Two-element array [matches non-matches]
(partition [1 2 3 4 5 6] (lambda (x) (= (% x 2) 0)))
; => [[2 4 6] [1 3 5]]Signature: (take n array)
Description: Take first n elements
Returns: Array with first n elements
(take 3 [1 2 3 4 5])
; => [1 2 3]Signature: (drop n array)
Description: Drop first n elements
Returns: Array without first n elements
(drop 2 [1 2 3 4 5])
; => [3 4 5]Signature: (zip array1 array2)
Description: Combine two arrays into array of pairs
Returns: Array of two-element arrays
(zip [1 2 3] ["a" "b" "c"])
; => [[1 "a"] [2 "b"] [3 "c"]]Signature: (compact array)
Description: Remove null values from array
Returns: Array without nulls
(compact [1 null 2 null 3])
; => [1 2 3]Signature: (pluck array field)
Description: Extract field from array of objects
Returns: Array of field values
(pluck [
{:name "Alice" :age 30}
{:name "Bob" :age 25}
] "name")
; => ["Alice" "Bob"]Signature: (group-by array key-fn)
Description: Group elements by key function result
Returns: Object mapping keys to arrays of elements
(group-by [
{:type "A" :val 1}
{:type "B" :val 2}
{:type "A" :val 3}
] (lambda (x) (. x type)))
; => {:A [{:type "A" :val 1} {:type "A" :val 3}]
; :B [{:type "B" :val 2}]}Signature: (count-by array key-fn)
Description: Count elements by key function result
Returns: Object mapping keys to counts
(count-by ["apple" "banana" "apricot" "berry"]
(lambda (s) (first s)))
; => {"a" 2 "b" 2}Signature: (length collection)
Description: Get length of array or string
Returns: Integer length
(length [1 2 3]) ; => 3
(length "hello") ; => 5Signature: (sort array) or (sort array comparator)
Description: Sort array (ascending by default)
Returns: New sorted array
(sort [3 1 4 1 5])
; => [1 1 3 4 5]
(sort [3 1 4] (lambda (a b) (> a b)))
; => [4 3 1]Signature: (get object key) or (get object key default)
Description: Get value from object by key
Returns: Value or default if key not found
(get {:name "Alice" :age 30} :name)
; => "Alice"
(get {:x 10} :y 0)
; => 0 (default)Signature: (keys object)
Description: Get all keys from object
Returns: Array of keys
(keys {:name "Alice" :age 30 :active true})
; => ["name" "age" "active"]Signature: (merge obj1 obj2 ...)
Description: Merge objects (right-most wins on conflicts)
Returns: New merged object
(merge {:a 1 :b 2} {:b 3 :c 4})
; => {:a 1 :b 3 :c 4}Syntax: (. object field)
Description: Access object field
Returns: Field value
(define user {:name "Alice" :age 30})
(. user name) ; => "Alice"
(. user age) ; => 30Signature: (values val1 val2 ...)
Description: Return multiple values
Returns: Multiple values container
(defun divmod (a b)
(values (/ a b) (% a b)))Signature: (multiple-value-bind (var1 var2 ...) values-expr body...)
Description: Bind multiple return values to variables
Returns: Result of body
(multiple-value-bind (quot rem) (values 17 5)
(log :message "Quotient:" :value quot)
(log :message "Remainder:" :value rem))Signature: (try body... catch body...)
Description: Try-catch error handling
Returns: Result of body, or catch block if error occurs
(try
(/ 10 x)
(catch
(log :message "Division error")
0))Signature: (error message)
Description: Throw an error with message
Returns: Never returns (throws error)
(if (< x 0)
(error "x must be non-negative")
(process x))Signature: (log :message msg) or (log :value val) or (log :message msg :value val)
Description: Log message or value for debugging
Returns: null
(log :message "Processing transaction")
(log :value balance)
(log :message "Balance:" :value balance)Signature: (now)
Description: Get current Unix timestamp
Returns: Integer timestamp (seconds since epoch)
(define cutoff (- (now) 3600)) ; 1 hour ago;; Numbers
42 ; Integer
3.14159 ; Float
-100 ; Negative
;; Strings
"hello world" ; String
"multi\nline" ; With escape sequences
;; Booleans
true ; Boolean true
false ; Boolean false
;; Null
null ; Null value
;; Arrays
[1 2 3 4 5] ; Array of integers
["a" "b" "c"] ; Array of strings
[] ; Empty array
;; Objects
{:name "Alice" :age 30 :active true} ; Object with keywords
{} ; Empty object
;; Ranges
(range 1 10) ; [1 2 3 4 5 6 7 8 9] (10 excluded)
(range 5) ; [0 1 2 3 4];; Single-line comment
; Also valid
;; Multi-line: use multiple semicolons
;; on each lineKeywords start with : and evaluate to themselves as strings.
:name ; => "name"
:message ; => "message"
:value ; => "value"Used for object keys and named parameters:
(log :message "Hello" :value 42)
(get obj :name);; Quote (prevent evaluation)
'(+ 1 2) ; => Expression, not evaluated
;; Quasiquote (template with evaluation)
`(list ,x ,(+ 1 2)) ; Evaluate x and (+ 1 2), but not list
;; Unquote (evaluate within quasiquote)
`(+ 1 ,x) ; Evaluates x
;; Splice (unquote and splice array)
`(list ,@items) ; Splices items array into listSolisp distinguishes between:
- Special forms: Evaluated with special rules (e.g.,
if,define,lambda) - Functions: All arguments evaluated before application (e.g.,
+,map,filter)
All Solisp data structures are immutable by default:
- Operations return new copies
- Original values are never modified
- Use
set!to rebind variables
-
Cache expensive operations:
(define len (length large-array)) ; Calculate once (for (i (range 0 len)) ...) ; Use cached value
-
Use map-reduce stack for clarity:
;; Clear and functional (map transform (filter predicate data))
-
Early exit in loops:
;; Break early when found (for (item items) (if (match? item) (do (set! result item) (break)) null))
(define total
(reduce +
(map (lambda (x) (. x amount))
(filter (lambda (x) (. x active))
transactions))
0))(define user
(or (find users (lambda (u) (= (. u id) target-id)))
{:id target-id :name "Unknown"}))(define average
(if (> count 0)
(/ total count)
0))(define sum 0)
(for (num numbers)
(set! sum (+ sum num)))
sumSolisp previously used Python-style syntax. It now uses LISP S-expressions exclusively.
OLD (Python-style - REMOVED):
$x = 10
IF $x > 5 THEN
RETURN "large"NEW (LISP - CURRENT):
(define x 10)
(if (> x 5)
"large"
"small")# Run Solisp script
solisp run script.solisp
# Evaluate inline
solisp eval '(+ 1 2 3)'
# Check syntax
solisp check script.solisp
# Interactive REPL
solisp repl- README.md - Overview and quick start
- USAGE_GUIDE.md - Comprehensive usage guide
- COMMON_PATTERNS.md - Idiomatic patterns (needs update for LISP)
- API Documentation - Full Rust API reference
- Example Scripts - Real-world examples
| Category | Count | Functions |
|---|---|---|
| Control Flow | 10 | if, when, unless, cond, case, typecase, while, for, do, prog1, prog2 |
| Variables | 5 | define, set!, setf, const, defvar |
| Functions | 5 | defun, defn, lambda, let, let*, flet, labels |
| Macros | 4 | defmacro, gensym, macroexpand, eval |
| Logical | 3 | not, and, or |
| Type Predicates | 10 | null?, empty?, int?, float?, number?, string?, bool?, array?, object?, function? |
| Assertions | 2 | assert, assert-type |
| Crypto/Encoding | 8 | base58-encode/decode, base64-encode/decode, hex-encode/decode, sha256, sha512 |
| String Ops | 8 | str, format, split, join, replace, trim, upper, lower |
| Math | 12 | +, -, *, /, %, =, !=, <, <=, >, >=, abs, sqrt, pow, min, max |
| Collections | 28 | map, filter, reduce, first, rest, last, nth, slice, cons, append, range, find, distinct, flatten, reverse, some, every, partition, take, drop, zip, compact, pluck, group-by, count-by, length, sort |
| Objects | 3 | get, keys, merge |
| Advanced | 2 | values, multiple-value-bind |
| Error Handling | 2 | try, error |
| Utilities | 2 | log, now |
| Total | 91+ | Production-ready blockchain scripting language |
Last Updated: 2025-10-27 Solisp Version: 1.0.0 Test Coverage: 100% (356/356 tests passing)
Made with ❤️ by the OpenSVM team
Solisp: Where blockchain meets LISP elegance 🚀