↓Skip to main content
  1. Projects/

Z-Lisp Programming Language

C Lisp MPC Parser WebAssembly
Table of Contents
AzzamAlsharafi/Z-Lisp

A Lisp-like programming language.

C
0
0

Try it out!

A Lisp-like programming language interpreter written in C, following Build Your Own Lisp and extended with additional features, including WebAssembly support for in-browser execution.

Overview
#

Z-Lisp is an interpreted Lisp-like programming language born from following the Build Your Own Lisp book, then extended with additional features and capabilities. The interpreter is implemented in C for performance and portability, with WebAssembly compilation support enabling execution directly in web browsers.

The language features a simple yet powerful syntax based on S-expressions, supporting fundamental data types including numbers, strings, symbols, lists, and functions. Built-in operators cover arithmetic operations, list manipulation, variable definition, control flow, and functions.

Features
#

  • S-expression syntax - Expressions use parentheses (), Lists use curly braces {}
  • Dynamic typing - Supports integers, floats, strings, lists, and functions
  • Function definitions - Anonymous functions with fun and variable binding with def
  • Built-in operations - Arithmetic, comparison, logical, and list manipulation functions
  • Control flow - Conditional statements with if and local variable binding with =
  • File loading - Load and execute Z-Lisp code from files using load
  • REPL environment - Interactive development and testing
  • WebAssembly support - Compiled with Emscripten for in-browser execution

Try It Live
#

Experience Z-Lisp directly in your browser with the interactive terminal:

Interactive Z-Lisp interpreter running in your browser via WebAssembly.

Language Syntax
#

Basic Components
#

Z-Lisp syntax follows simple rules:

42                           ; Numbers - integers and floats
3.14159                      ; Floating point numbers
"Hello, World!"              ; Strings - enclosed in double quotes
x                            ; Symbols - names for variables and functions
{1 2 3 4 5}                  ; Lists - use curly braces, not evaluated
(+ 1 2 3)                    ; Expressions - use parentheses, evaluated
(fun {x} {* x x})            ; Anonymous function definition
; This is a comment          ; Comments - anything after ; is ignored

Basic Operations
#

(+ 10 20 30)                 ; => 60.0 - Arithmetic addition
(- 100 25)                   ; => 75.0 - Subtraction
(* 5 5 5)                    ; => 125.0 - Multiplication
(/ 100 4)                    ; => 25.0 - Division
(% 7 3)                      ; => 1.0 - Modulo
(^ 2 3)                      ; => 8.0 - Power
(> 10 5)                     ; => 1 (true) - Greater than
(< 3 7)                      ; => 1 (true) - Less than
(== 5 5)                     ; => 1 (true) - Equality
(&& 1 0)                     ; => 0 (false) - Logical AND
(|| 0 1)                     ; => 1 (true) - Logical OR
(! 0)                        ; => 1 (true) - Logical NOT

Variables and Functions
#

(def {x name} 10 "Z-Lisp")        ; Define variables globally
(= {y} 20)                        ; Define local variables
(fun {x} {* x x})                 ; Define anonymous functions
(def {square} (fun {x} {* x x}))  ; Define named functions
(def {factorial} (fun {n} {if (== n 0) {1} {* n (factorial (- n 1))}}))  ; Recursive function
(square 5)                        ; => 25.0 - Use functions
(factorial 5)                     ; => 120.0 - Call factorial

Control Flow
#

(if (> x 0) {print "positive"} {print "non-positive"})     ; Conditional expressions
(= {x y} 10 20)              ; Local variable bindings
(+ x y)                      ; => 30.0 - Use local variables
(env)                        ; Returns current environment

List Operations
#

(def {nums} {1 2 3 4 5})     ; Create lists
(list 1 2 3 4 5)             ; Creates {1 2 3 4 5}
(get nums 0)                 ; => 1 (get element at index)
(remove nums 0)              ; => {2 3 4 5} (remove element at index)
(len nums)                   ; => 5 (list length)
(+ {1 2} {3 4})              ; => {1 2 3 4} - List concatenation
(+ nums 6)                   ; => {1 2 3 4 5 6} - Add element to list
(+ "Hello " "World")         ; => "Hello World" - String concatenation

Built-in Functions
#

Z-Lisp provides a comprehensive set of built-in functions covering arithmetic, list manipulation, control flow, and I/O operations:

FunctionDescriptionExample
+Addition (numbers), concatenation (strings/lists)(+ 1 2 3) → 6.0
-Subtraction or negation(- 10 3) → 7.0
*Multiplication(* 2 3 4) → 24.0
/Division(/ 10 2) → 5.0
%Modulo(% 7 3) → 1.0
^Power(^ 2 3) → 8.0
>Greater than(> 5 3) → 1
<Less than(< 3 5) → 1
==Equality(== 5 5) → 1
&&Logical AND(&& 1 1) → 1
||Logical OR(|| 0 1) → 1
!Logical NOT(! 0) → 1
listCreate list(list 1 2 3) → {1 2 3}
getGet element by index(get {a b c} 1) → b
removeRemove element by index(remove {a b c} 1) → {a c}
lenList length(len {1 2 3}) → 3
defDefine global variables(def {x} 10)
=Define local variables(= {y} 20)
funDefine anonymous function(fun {x} {* x x})
ifConditional expression(if (> x 0) {"pos"} {"neg"})
evalEvaluate list as expression(eval {+ 1 2}) → 3.0
loadLoad and execute file(load "script.zl")
printPrint to console(print "Hello")
errorPrint error message(error "Oops!")
exitExit program(exit())
envShow current environment(env())
typeofGet type as string(typeof 42) → "Integer"
stringConvert to string(string 42) → "42"
intConvert to integer(int "42") → 42
floatConvert to float(float "3.14") → 3.14

Implementation Details
#

Architecture
#

The Z-Lisp interpreter is built in C using the MPC (Micro Parser Combinators) library for parsing. The architecture follows a classic interpreter design:

  1. Lexical Analysis - Tokenizes input into meaningful symbols
  2. Parsing - Grammar-based parsing using MPC combinators
  3. AST Evaluation - Tree-walking interpreter with environment-based scoping
  4. Memory Management - Manual memory management with proper cleanup

WebAssembly Compilation
#

The interpreter compiles to WebAssembly using Emscripten, enabling:

  • Browser execution - Run Z-Lisp directly in web browsers
  • Portability - No server dependencies required
  • Interactive REPL - Full REPL functionality preserved in browser environment

Building from Source
#

Native Build
#

# Clone the repository
git clone https://github.com/AzzamAlsharafi/Z-Lisp.git
cd Z-Lisp

# Build the interpreter
make

# Run the REPL
./zlisp

# Run a Z-Lisp file
./zlisp program.zsp

WebAssembly Build
#

# Install Emscripten
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh

# Build WASM module
cd /path/to/Z-Lisp
make wasm

# Generated files: main.js, main.wasm, main.data

Example Programs
#

Fibonacci Sequence
#

(def {fib} (fun {n} {if (< n 2) {n} {+ (fib (- n 1)) (fib (- n 2))}}))   ; Define fibonacci function
(fib 0)                          ; => 0.0
(fib 1)                          ; => 1.0
(fib 5)                          ; => 5.0
(fib 10)                         ; => 55.0

Factorial Function
#

(def {factorial} (fun {n} {if (== n 0) {1} {* n (factorial (- n 1))}}))  ; Define factorial function
(factorial 5)                    ; => 120.0
(factorial 0)                    ; => 1.0

List Processing
#

(def {numbers} {1 2 3 4 5})      ; Define a list of numbers
(get numbers 0)                  ; => 1 - Get first element
(get numbers 2)                  ; => 3 - Get third element
(len numbers)                    ; => 5 - List length
(+ numbers 6)                    ; => {1 2 3 4 5 6} - Add element
(+ {0} numbers)                  ; => {0 1 2 3 4 5} - Prepend element
(remove numbers 0)               ; => {2 3 4 5} - Remove first element