Tutorials

Walk through real Origin programs — from hello world to hardware control.

Hello, World

Origin scripts use the .or extension. Save this as hello.or:

print "Hello, World!"

Run it:

$ origin hello.or
Hello, World!

print is a statement in Origin, not a function — no parentheses needed. Strings can use double or single quotes.

Variables and types

Variables are declared with let and can include an optional type annotation. If you omit the type, Origin infers it automatically (with a warning nudging you toward strict typing):

let name: str  = "Origin"
let year: int  = 2026
let e:  float = 2.71828
let ok:  bool  = true

# Type is inferred when omitted
let count = 0

Constants use const and can't be reassigned:

const app_name: str = "Origin"
# app_name = "Something else"  ← compile error

A simple calculator

Origin supports standard arithmetic. Here's a calculator that reads user input:

print "WELCOME TO THE CALCULATOR"

let x: float = float(input "Enter a number: ")
let y: float = float(input "Enter another number: ")
let op: str = input "Enter the operation (+, -, *, /): "

print "Your result is..."
if op == "+" {
    print x + y
} elif op == "-" {
    print x - y
} elif op == "*" {
    print x * y
} elif op == "/" {
    print x / y
}
$ origin calc.or
WELCOME TO THE CALCULATOR
Enter a number: 10
Enter another number: 3
Enter the operation (+, -, *, /): *
Your result is...
30.0

input reads a line of text. float() casts the string to a number. Type casting uses postfix syntax — float(input "...") chains naturally left to right.

Control flow

Origin's if / elif / else works like you'd expect. Conditions don't need parentheses:

let temp: int = 75

if temp > 80 {
    print "Too hot"
} elif temp > 60 {
    print "Just right"
} else {
    print "Too cold"
}

Loops

Use for ... in range() for counted iteration and while for condition-based:

for i in range(0, 5) {
    print "Iteration"
}

let count: int = 0
while count < 3 {
    print count
    count = count + 1
}

Functions

Functions are defined with def (or func as an alias). Type annotations on parameters are optional but recommended:

def add(a: int, b: int) {
    return a + b
}

def greet(name: str) {
    print "Hello, " + name
}

let result: int = add(5, 3)
print result
greet("Origin")

Controlling a servo (Raspberry Pi)

Origin's hardware syntax is the main reason it exists. On a Raspberry Pi with a servo on channel 0 of a PCA9685 driver:

set servo.angle 0, 90
py {
    import time
    time.sleep(1)
}
set servo.angle 0, 180
py {
    import time
    time.sleep(1)
}
set servo.angle 0, 0

The servo angle is automatically clamped to 0-180° — if you try to set 200, Origin silently caps it to 180. This prevents physical gear damage. Use py { import time; time.sleep(...) } for delays.

GPIO output

Drive a BCM pin high or low:

set pin 17, 1    # HIGH
py {
    import time
    time.sleep(0.5)
}
set pin 17, 0    # LOW

When hardware isn't available (e.g., on a laptop), Origin falls back to [SIM] stubs — the same code runs without modification.

Calling Python libraries

Use py {} blocks to drop into Python for anything Origin doesn't handle natively:

py {
    import math
    import os
    print("Python process ID:", os.getpid())
    print("Sine of 90 degrees:", math.sin(math.pi / 2))
}

Variables defined in py {} blocks are accessible from Origin code after the block exits, so you can use Python libraries and pass results back to Origin.

Using the standard library

Origin ships with calc.or (and graph.or) in lib/. Import them by name:

import calc

let c = calc()
print c.sin(0, "r")
print c.cos(0, "d")
print floor(3.7)   # 3
print 7 // 2       # 3

Libraries are just .or files. You can write your own and put them next to your script — import mylib will pick them up automatically.

Building a standalone binary

Compile any .or script into a standalone executable with build:

$ origin build my_app.or
Building standalone binary...
Output: dist/my_app.exe

The output is a zero-dependency executable — no Python or Origin install needed on the target machine.