Documentation

Complete reference for the Origin programming language v1.7.6.

Comments

Origin uses # for single-line comments. Everything after the # on that line is ignored by the lexer.

# This is a comment
let x: int = 10  # inline comment

# Multi-line comments are just
# multiple single-line comments

Data Types

Origin supports the following primitive data types. Type annotations are used with let and const declarations.

Integers

Whole numbers. Origin also supports hexadecimal literals with the 0x prefix.

let x: int = 42
let addr: int = 0x48      # hex literal → 72
let negative: int = -10

Floats

Decimal numbers.

let pi: float = 3.14159
let temp: float = 98.6

Strings

Text values wrapped in double or single quotes. Escape sequences like \", \', and \n are supported.

let name: str = "Origin"
let msg: str = 'Hello World'
let escaped: str = "He said \"hi\""

Booleans

Logical true/false values using the keywords true and false.

let active: bool = true
let done: bool = false

None

Represents the absence of a value.

let empty = none

Variables & Constants

Variables are declared with let and can include an optional type annotation. Constants use const and cannot be reassigned after declaration.

# Variable with type annotation
let x: int = 10
let name: str = "Origin"
let flag: bool = true

# Variable without type (inferred)
let count = 0

# Constants — immutable after assignment
const PI: float = 3.14159
const VERSION: str = "1.7.6"
const MAX_SERVOS: int = 6

# Reassignment
x = 20          # OK
# PI = 3.0      # ERROR: Cannot reassign constant

Compound Assignment

Origin supports shorthand assignment operators for arithmetic updates.

let score: int = 100
score += 10    # score is now 110
score -= 5     # score is now 105
score *= 2     # score is now 210
score /= 7     # score is now 30
score %= 4     # score is now 2

Operators

Arithmetic

let a = 10 + 3     # 13  (addition)
let b = 10 - 3     # 7   (subtraction)
let c = 10 * 3     # 30  (multiplication)
let d = 10 / 3     # 3.33 (division)
let e = 10 // 3    # 3   (floor division)
let f = 10 % 3     # 1   (modulo)
let g = 2 ** 8     # 256 (exponentiation)

Comparison

x == y     # equal
x != y     # not equal
x < y      # less than
x > y      # greater than
x <= y     # less or equal
x >= y     # greater or equal

Logical

# Word-style
if x > 0 and y > 0 { ... }
if x > 0 or y > 0 { ... }
if not done { ... }

# Symbol-style (also valid)
if x > 0 && y > 0 { ... }
if x > 0 || y > 0 { ... }
if !done { ... }

Unary

let neg = -x       # negation
x++                # increment
x--                # decrement

Smart String Concatenation

The + operator automatically converts to strings when either side is a string. No manual casting required.

let age: int = 17
print "I am " + age + " years old"
# Output: I am 17 years old

Lists, Tuples & Dictionaries

Lists

Ordered, mutable collections. Supports indexing and index assignment.

let numbers: list = [1, 2, 3, 4, 5]
let mixed = ["hello", 42, true]

# Access by index
print numbers[0]       # 1

# Assign by index
numbers[2] = 99

# Multi-line declaration
let servo_names: list = [
    "left_shoulder",
    "left_elbow",
    "right_shoulder",
    "right_elbow"
]

# call syntax for list access
let val = call[numbers, 0]

Tuples

Ordered, immutable collections created with parentheses and commas.

let point = (10, 20)
let rgb = (255, 128, 0)

Dictionaries

Key-value stores using curly braces.

let config: dict = {
    "speed": 100,
    "direction": "forward",
    "active": true
}

# Access
print config["speed"]

# Nested structures
let agents: list = [
    {"id": 0, "status": "active"},
    {"id": 1, "status": "idle"}
]

Control Flow

If / Elif / Else

Conditional branching. Bodies use curly braces { }.

let temp: int = 75

if temp > 100 {
    print "Too hot!"
} elif temp > 50 {
    print "Just right"
} else {
    print "Too cold"
}

While Loops

Repeat a block while a condition is true.

let count: int = 0
while count < 5 {
    print "Count: " + count
    count = count + 1
}

For Loops

Iterate over a range or any iterable.

# Iterate over a range
for i in range(0, 10) {
    print i
}

# Iterate over a list
let colors: list = ["red", "green", "blue"]
for color in colors {
    print color
}

Break & Continue

Control loop execution flow.

let i: int = 0
while i < 100 {
    if i == 10 {
        break          # exit the loop entirely
    }
    if i % 2 == 0 {
        i = i + 1
        continue       # skip to next iteration
    }
    print i
    i = i + 1
}

Pass

A no-op placeholder for empty blocks.

def placeholder() {
    pass
}

Functions

Define reusable blocks of code with def (or func as an alias). Functions use curly-brace blocks and support parameters and return values.

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

# 'func' is also supported
func welcome(name) {
    print "Welcome, " + name
}

greet("Origin")
# Output: Hello, Origin!

Return Values

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

let result = add(10, 20)
print result    # 30

Recursion

def factorial(n) {
    if n <= 1 {
        return 1
    }
    return n * factorial(n - 1)
}

print factorial(5)    # 120

Multi-line Parameters

Function definitions and calls support flexible newlines.

def calculate(
    x,
    y,
    z
) {
    return x + y + z
}

let val = calculate(
    10,
    20,
    30
)

Classes

Origin supports class definitions with constructor fields defined in parentheses, methods with self, and attribute access via dot notation.

class Drone(x, y) {
    def setPos(self, nx, ny) {
        self.x = nx
        self.y = ny
    }

    def show(self, label) {
        print label
        print self.x
        print self.y
    }
}

# Create instance with initial values
let d = Drone(100, 200)
d.show("Position:")

# Update via method
d.setPos(500, 600)
d.show("Updated:")

Attribute Access

Read and write object attributes with dot notation.

# Read
print d.x

# Write
d.x = 999

# Chained access
print obj.nested.value

Scope Management

Origin uses lexical scoping. Variables declared with let inside a function are local. To modify a variable from an outer scope, use global.

let x = 10

def local_test() {
    let x = 20          # local x — doesn't touch global
    print x             # 20
}

def global_test() {
    global x            # declares intent to modify global x
    x = 30
}

local_test()
print x                 # still 10

global_test()
print x                 # now 30

Constant Isolation

Constants declared inside a function do not leak to the outer scope.

const y = "Global Constant"

def test_const() {
    const y = 100       # local constant
    print y             # 100
}

test_const()
print y                 # "Global Constant"

Input / Output

Print

print is a statement in Origin — no parentheses needed. It takes a single expression.

print "Hello, World!"
print 42
print "Result: " + result

Input

input reads a line from the user. Provide an optional prompt string (no parentheses needed).

let name: str = input "What is your name? "
print "Hello, " + name

# Cast to number
let age: int = int(input "Enter your age: ")

Built-in Functions

Origin provides several built-in functions available without imports.

Math

let root = sqrt(16.0)          # 4.0
let r = rand_num(1, 100)       # random int between 1 and 100

Collections

let items = [1, 2, 3, 4, 5]
print len(items)               # 5

Type Casting

Convert between types using the type name as a function.

let s: str = "123"
let n: int = int(s)            # 123

let x: int = 42
let text: str = str(x)         # "42"

let f: float = float("3.14")  # 3.14
let b: bool = bool(1)          # true

Range

Generate a sequence of integers from start (inclusive) to end (exclusive). Commonly used with for loops.

# range(start, end)
for i in range(0, 5) {
    print i
}
# Output: 0 1 2 3 4

# Use with variables
let count: int = 10
for i in range(0, count) {
    print "Step " + i
}

Parallel Execution

Origin has native threading support with the parallel keyword. Each statement in the block runs on its own thread.

Auto-parallel

Without a thread count, each statement in the block gets its own thread.

parallel {
    step(0)    # runs on thread 1
    step(1)    # runs on thread 2
}
# Both threads are joined before continuing

Fixed Thread Count

Specify the number of threads to spawn. The entire block runs on each thread.

parallel (4) {
    print "Worker running"
    process_data()
}
# Spawns 4 threads, each running the full block

Module System

Origin supports importing other .or files as modules. Imported modules are automatically transpiled and cached in __origin_cache__/.

Basic Import

import math_utils
print math_utils.square(4)     # 16

Import with Alias

import math_utils as mu
print mu.square(4)             # 16
print mu.cube(3)               # 27

From Import

from math_utils import square
print square(5)                # 25

Python Library Imports

You can also import standard Python libraries directly.

import math
let val = math.cos(0)          # 1.0

Hardware Control

Origin provides first-class support for robotics hardware. The set namespace handles servos and GPIO pins with native safety clamping (0–180°).

Servo Control

# Set servo 1 to 90 degrees
set servo.angle 1, 90

# Safety clamping — values outside 0-180 are clamped automatically
set servo.angle 0, 250    # clamped to 180°
set servo.angle 2, -10    # clamped to 0°

GPIO Pin Control

# Set BCM pin 12 to HIGH
set pin 12, 1

# Set BCM pin 12 to LOW
set pin 12, 0

Hardware Protocols

Origin has built-in protocol primitives for I2C, SPI, and UART communication. These use dot-notation syntax and work natively on Raspberry Pi. On non-Pi systems, they simulate or fail gracefully.

I2C

let addr: int = 0x48
let reg: int = 0x01

# Read a byte
let val: int = i2c.read(addr, reg)

# Write a byte
i2c.write(0x48, 0x01, 0xFF)

SPI

# Transfer data over SPI
spi.transfer([0x01, 0x02, 0x03])

UART

# Write a string over UART
uart.write("Hello UART")

Raw Python Blocks

Embed raw Python code directly into Origin scripts using py { }. The code inside is passed through to the Python runtime verbatim. This gives you full access to Python's ecosystem.

py {
    import math
    print("Direct Python:", math.cos(0))

    # Any valid Python works here
    for i in range(3):
        print(f"Python loop: {i}")
}

Variables defined in py blocks share the same runtime scope, so Origin variables are accessible inside and vice versa.

Binary Builder

Origin can compile your scripts into standalone executables using PyInstaller. The resulting binary runs without needing Python or Origin installed on the target machine.

# From your terminal:
origin build my_robot.or

# This produces:
# my_robot.exe (Windows)
# my_robot     (Linux/Mac)

The builder transpiles your Origin code to Python, bundles it with all dependencies, and creates a single-file executable. Imported .or modules are automatically included.

Error Handling

Use try, except, and else blocks to catch and recover from runtime errors. Origin translates Python exceptions into friendly, human-readable messages.

Basic Try/Except

try {
    set servo.angle 5, 45
} except {
    print "Servo connection failed"
}

Try/Except/Else

The else block runs only when no exception was raised.

try {
    let val = i2c.read(0x48, 0x01)
    print "Read: " + val
} except {
    print "Hardware read failed"
} else {
    print "Read completed successfully"
}

Friendly Error Messages

Origin automatically converts Python errors into clear messages:

# NameError → "Unknown Variable: I don't recognize 'x'.
#              Did you forget to define it with 'let'?"

# ZeroDivisionError → "Math Error: You tried to divide
#                       by zero! Math doesn't like that."

# IndexError → "Range Error: You tried to access an item
#               that doesn't exist in that List."

# TypeError → "Type Mismatch: You're trying to add a
#              Number to a Piece of Text."

Exec

Run an external Origin file as a subprocess using the exec keyword.

exec "other_script.or"

This spawns a separate process to run the target file. Useful for orchestrating multi-file workflows.