Skip to content

egecanakincioglu/arimo

Repository files navigation

Arimo

version license compiler extension memory IR native

A statically-typed, object-oriented systems programming language with its own IR, three-layer memory safety, and native code generation — no LLVM, no GCC required.

📖 Documentation · Quick Start · Roadmap Gaps · Changelog


What is Arimo?

Arimo is a systems programming language designed to be usable at every level of the software stack — from OS kernels and game engines to enterprise OOP applications — without switching languages or compromising on safety.

package hello;

public class Application {
    public static main() : Void {
        IO.println("Hello, Arimo!");
    }
}
arc run Main.arm
# Hello, Arimo!

Arimo compiles .arm source files directly to native executables through its own intermediate representation (ArimoIR). No LLVM toolchain. No external C compiler. One binary, zero runtime dependencies.


Why Arimo?

Own IR — No External Toolchain

Most languages that target native code depend on LLVM or GCC. Arimo has its own IR pipeline:

.arm  →  AST  →  ArimoIR  →  x86-64 machine code  →  PE32+ / ELF executable

The arc compiler produces a working native executable without any installed toolchain. This means:

  • Reproducible builds on any machine
  • No version mismatches between LLVM releases
  • Full control over every compilation stage
  • The compiler itself is self-hosting (arc compiles arc)

Three-Layer Memory Safety

Most languages choose one approach. Arimo layers three:

Layer Mechanism When
BorrowChecker Compile-time static analysis Always — catches use-after-move, mutation-while-borrowed
ARC Automatic Reference Counting Class instances — no GC pauses, deterministic cleanup
Manual Memory.alloc / Memory.free @ManualMemory — zero-overhead, kernel/driver code

You choose the layer per class. Safety by default, manual control on demand.

// ARC — default, automatic
public class HttpServer { ... }

// Manual — zero overhead, kernel code
@ManualMemory
public class DmaBuffer {
    private ptr : RawPtr<u8>;
    public constructor(size: Integer) { this.ptr = Memory.alloc(size); }
    public dispose() : Void { Memory.free(this.ptr); }
}

Null Safety Built In

Non-nullable types are the default. Null is explicit and compiler-enforced:

String  name   = "Alice";     // cannot be null — compiler error if assigned null
String? title  = null;        // explicitly nullable

String safe  = title ?? "unknown";   // null coalescing
Integer? len = title?.length();      // null-safe call — len is null if title is null

Unlike Java's Optional<T> boilerplate or C++'s std::optional, null safety in Arimo is built into the type system at zero cost.

High-Level OOP + Low-Level Control in One Language

Arimo is not a systems language with OOP bolted on, nor a high-level language that leaks when you need performance. Both exist natively:

// High-level enterprise OOP
public class OrderService {
    private repo : OrderRepository;

    public placeOrder(order: Order) : Result<OrderId, OrderError> {
        if (!order.isValid()) {
            return Result.err(OrderError.INVALID);
        }
        return repo.save(order);
    }
}

// Low-level hardware access
@Freestanding
@CallingConvention("Interrupt")
public static irqHandler() : Void {
    volatile u32 status = 0;
    asm { "mov eax, [0xFEE00100]" };
}

Use Cases

Operating Systems / Kernels

@Freestanding          // no stdlib, no malloc
package kernel.boot;

@Section(".boot")
@CallingConvention("C")
public static kernelMain(multiboot: RawPtr<MultibootInfo>) : noreturn {
    VGA.clear();
    VGA.print("Arimo kernel booting...");

    GDT.init();
    IDT.init();
    Memory.initPaging();

    asm { "sti" };     // enable interrupts

    while (true) { asm { "hlt" }; }
}
  • @Freestanding — no standard library linked
  • @Section(".name") — precise linker control
  • @CallingConvention("Interrupt") — CPU-correct interrupt handlers
  • volatile — MMIO reads/writes not optimized away
  • asm {} — inline x86 assembly
  • RawPtr<T> — unmanaged pointer arithmetic
  • noreturn — compiler knows this function never returns

Game Engines

@Align(16)
public struct Transform {
    public position : Vec4f;
    public rotation : Vec4f;
    public scale    : Vec4f;

    public modelMatrix() : Vec4f {
        return position * rotation * scale;
    }
}

public class PhysicsSystem {
    private bodies : List<RigidBody>;

    public step(dt: Float) : Void {
        this.bodies.forEach((body) -> {
            body.integrate(dt);
            body.resolveCollisions(this.bodies);
        });
    }
}
  • Built-in SIMD types: Vec4f, Vec8f, Vec4i, Vec8i with dot(), normalize(), length()
  • @Align(16) / @Packed structs for cache-friendly layouts
  • @Pure methods for optimizer hints
  • @ForceInline for hot-path elimination
  • Lambdas + closures for event systems and callbacks
  • Stack-allocated structs — no heap allocation for math types

Enterprise / High-Level OOP

public class UserService {
    private users : HashMap<String, User>;

    public findByEmail(email: String) : User? {
        return users.get(email);
    }

    public register(dto: RegisterDto) : Result<User, ValidationError> {
        if (users.containsKey(dto.email)) {
            return Result.err(ValidationError.EMAIL_TAKEN);
        }
        User user = User(dto.name, dto.email);
        users.set(dto.email, user);
        return Result.ok(user);
    }
}

public interface Serializable {
    serialize()   : String;
    deserialize(s: String) : Void;
}

public abstract class BaseEntity implements Serializable {
    protected readonly id        : String;
    protected readonly createdAt : Integer;

    public constructor() {
        this.id        = Time.generateId();
        this.createdAt = Time.nowMillis();
    }
}
  • Generics with multiple bounds: <T extends Comparable<T> & Serializable>
  • Pattern matching: match, destructured enum variants
  • Exception hierarchy: RuntimeException, IllegalArgumentException, etc.
  • Result<T, E> for explicit error handling without exceptions
  • defer for deterministic cleanup
  • Extension methods to add behavior to existing types
  • @Deprecated, @Experimental, @Throws documentation annotations

Language Highlights

Pattern Matching

match (shape) {
    Circle c    -> IO.println("circle r=${c.r}");
    Rect(w, h)  -> IO.println("rect ${w}x${h}");
    _           -> IO.println("unknown");
}

// Match as expression with guard:
String label = match (score) {
    n if n >= 90 -> "A";
    n if n >= 80 -> "B";
    n if n >= 70 -> "C";
    _            -> "F";
};

Generics with Bounds

public class SortedSet<T extends Comparable<T> & Serializable> {
    private items : List<T>;

    public add(item: T) : Void {
        items.append(item);
        items = items.sortedBy((a, b) -> a.compareTo(b));
    }
}

Lambdas and Functional Collections

List<Order> urgent = orders
    .filter((o)  -> o.isPending() && o.value() > 1000)
    .sortedBy((a, b) -> a.deadline().compareTo(b.deadline()))
    .take(10);

String summary = urgent
    .map((o) -> "${o.id()}: $${o.value()}")
    .joinToString("\n");

Defer

public processFile(path: String) : Void {
    File f = File.open(path, FileMode.READ);
    defer f.close();   // runs on scope exit — even if exception thrown

    String content = f.readAll();
    IO.println(content);
}

Extension Methods

extend String {
    public toSlug() : String {
        return this.toLower().replace(" ", "-").trim();
    }
}

"Hello World".toSlug()   // "hello-world"

Enums with Data

public enum Shape {
    Circle(radius: Float),
    Rectangle(width: Float, height: Float),
    Triangle(base: Float, height: Float)
}

Float area = match (shape) {
    Circle(r)    -> Math.PI * r * r;
    Rectangle(w, h) -> w * h;
    Triangle(b, h)  -> 0.5 * b * h;
};

The arc Compiler

arc build Main.arm          # compile to native executable
arc run   Main.arm          # compile + run immediately
arc check Main.arm          # type-check only (no output)
arc init  myapp             # scaffold new project
arc clean                   # remove build artifacts

Key flags:

Flag Effect
--release Optimized build
--emit-ir Output ArimoIR text and exit
-O2 / -O3 Optimization level
-c Compile to object file only
--stdlib-path <dir> Override stdlib location
# arc.toml
[project]
name    = "myapp"
version = "0.1.0"
entry   = "Main.arm"

Annotations

Arimo's annotation system covers the full range from high-level OOP to bare-metal:

// Optimization
@ForceInline          // always inline — no call overhead
@Pure                 // no side effects — optimizer hint

// Memory layout
@Packed               // remove struct padding
@Align(16)            // minimum alignment

// Memory management
@ManualMemory         // disable ARC — full manual control
@Immutable            // all fields readonly

// Low-level
@Section(".rodata")            // place in specific linker section
@CallingConvention("C")        // C ABI
@CallingConvention("Interrupt") // CPU interrupt handler

// Bare-metal
@Freestanding         // no stdlib — OS/kernel/embedded use

// Developer intent
@Deprecated("msg")    // usage warning
@Experimental         // API may change
@Sealed               // subclassable within same package only
@Throws(IOException)  // documents possible exceptions
@FunctionalInterface  // enforce single-abstract-method

// Branch prediction
@Likely               // branch usually taken
@Unlikely             // branch rarely taken

Standard Library

All arimo.lang classes are available without import:

Package Contents
arimo.lang (auto) IO, Math, String, Integer, Float, Boolean, Char, StringBuilder, Time, Memory, System, exception hierarchy
arimo.fs File, Path, Directory, FileMode, IOException
arimo.io InputStream, BufferedReader
arimo.util ArrayList, Optional, Scanner, Random
arimo.env Env, Process

Collections (List<T>, HashMap<K,V>, TreeMap<K,V>, Array<T,N>, Slice<T>, Pair<A,B>, Result<T,E>) are built-in.


Quick Comparison

Arimo Java C++ Rust Go
Memory model ARC + BorrowChecker + Manual GC Manual Ownership GC
Null safety Built-in (?) Optional (verbose) None Option<T> None
Own IR ✅ ArimoIR JVM bytecode LLVM/direct LLVM Go IR
No GC pauses
OS/kernel target @Freestanding Limited
SIMD built-in Vec4f etc. Partial Partial
Inline assembly asm {}
Pattern matching Java 21+ Limited
Null-safe chaining ?. ?? ?
OOP + functional Partial Partial Partial

Getting Started

Install

# Download arc for your platform from Releases
# Place arc.exe (Windows) or arc (Linux/macOS) on your PATH
arc --version
# arc 1.0.0 (arimo-language)

Hello World

package hello;

public class Application {
    public static main() : Void {
        IO.println("Hello, Arimo!");
    }
}
arc run Main.arm
# Hello, Arimo!

New Project

arc init myapp
cd myapp
arc run

Documentation

Full language reference: documentation/index.md

Section Contents
Getting Started Installation, hello world, arc.toml
Language Types, operators, control flow, OOP, generics, pattern matching, async
Memory BorrowChecker, ARC, manual memory, RawPtr
Collections List, HashMap, Array, Slice, Result
Standard Library arimo.lang, arimo.fs, arimo.io, arimo.util, arimo.env
CLI arc build, run, check, clean, init
Missing Features What's not in v1.0.0 and why

Versioning

Version Status Highlights
v1.0.0 ✅ Released Full OOP, generics, pattern matching, ARC, BorrowChecker, ArimoIR, native codegen
v1.1.0 Planned stdlib expansion, Math trig, regex
v1.2.0 Planned async/await runtime, coroutine scheduler
v2.0.0 Future Dependency management, package registry

License

GNU Affero General Public License v3.0 — see LICENSE

Any use, modification, or distribution — including network services — must be released under the same AGPL-3.0 terms.


Built with arc · Written in .arm · Read the docs

About

Arimo is a self-hosting programming language for systems and apps. Features native binary compilation (no LLVM/GCC), hybrid memory management (Borrow Checker + GC), and bare-metal support.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages