Structural, Embeddable, Minimal Interpreter
Semi is a minimalist programming language designed for embedding within applications.
fn fib(n) {
if n < 2 {
return 1
}
return fib(n-1) + fib(n-2)
}
before := now()
defer {
print("elapsed (ms):", now() - before)
}
print(fib(30)) Built-ins for this demo
- print(...args): print arguments to output.
- now(): get the current time in milliseconds.
- len(value): get the length of a string or collection.
- max(...args): get the maximum value among the arguments.
- min(...args): get the minimum value among the arguments.
Semi is Predictable
The syntax is designed to be concise and easy to understand. Variable shadowing is prohibited. Errors must be handled explicitly, not buried in exception blocks.
Semi is Data-Oriented
Semi encourages a data-centric approach with first-class support for algebraic data types and structural typing. By favoring composition over inheritance, it helps you write code that is more flexible and resilient to change.
Semi is Minimal
Semi keeps the builds lean by making the standard library optional. The entire runtime, including the compiler and virtual machine, is under 50KiB when compiled to WebAssembly and gzipped.
Semi is Portable
Semi is C11-compliant and is designed to be compiled and run anywhere
Quick Tour
Literals
# Number
i := 10
f := 42.0
# String
str := "Hello, Semi!"
# Boolean
flag := true
# List Collection
list := List[1, 2, 3, 4, 5]
# Dictionary Collection
dict := Dict[
"key": "value",
"number": 123,
] Definition & Assignment
# Variable definition
x := 10
# Variable assignment
x = 20
# Assignment without definition is not allowed
# y = 30 # Error: 'y' is not defined
# Variable shadowing is prohibited
# x := 40 # Error: 'x' is already defined
#
# if true {
# x := 50 # Error: 'x' is already defined
# } Struct & Type
# We are still figuring out the details about
# how types interact with other language features.
# Define a struct planned
struct Point {
x: Int,
y: Int,
}
# Struct Initializer planned
point := Point{ x: 10, y: 20 } Condition
if condition {
# do something
} elif other_condition {
# do something else
} else {
# fallback
} Iteration
# Range-based
for i in 0..10 step 2 {
print(i)
}
# Iterator-based planned
for item in collection {
print(item)
}
# Infinite loop
for {
# do something
} Functions
fn add(a, b) {
return a + b
}
# Defer block
fn example() {
defer {
print("This runs at the end of the function")
}
print("Function body")
} Import & Export
# Import a module without aliasing it planned
import "semi/math"
# Import a module with an alias planned
import "semi/io" as io
# Import specific symbols from a module planned
import "semi/io" { print, readFile }
# Export a variable or function definition planned
export pi := 3.14
export fn add(a, b) {
return a + b
}