Skip to content

mathiassol/mpplang

Repository files navigation

M++ — A Low-Level Systems Language

M++ is a statically-typed compiled language targeting LLVM IR. It has a C++-like feel with a clean modern syntax — structs, enums, generics, traits, closures, C FFI, and manual memory control. The compiler is self-hosted: written in M++ and compiled by itself.

Part of the R2ND ecosystem — a project to rebuild the entire software stack from scratch with zero external dependencies.


struct Point { x: float, y: float }

fn distance(a: Point, b: Point) -> float {
    let dx = a.x - b.x;
    let dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
}

fn main() {
    let p1 = Point { x: 0.0, y: 0.0 };
    let p2 = Point { x: 3.0, y: 4.0 };
    print("distance: " + to_string(distance(p1, p2)));
    // Output: distance: 5.0
}

Features

Category Features
Types int, float, bool, string, ptr, structs, enums, generics
Abstractions Functions, closures/lambdas, traits, type aliases
Collections Arrays [T], maps map[K,V], slices
Control flow if/else, while, for..in, match, break, continue
Error handling Result[T], Option<T>, ok(), err(), unwrap()
Memory Manual (alloc/free), reference counting (rc<T>), slices, defer
Low-level Bitwise ops, casting (as), sizeof, raw pointers, *ptr deref
Modules import "file.mpp" — multi-file compilation
C interop extern fn — link against any C library
Self-hosted The compiler is written in M++ and compiles itself

Quick Start

Prerequisites

  • LLVM/Clang 14+ — needed to compile the LLVM IR output to a native binary
  • Windows x86_64 (Linux support in progress)
  • mpp.exe — pre-built bootstrap binary included in this repo

1. Clone and compile a program

git clone https://github.com/mathiassol/mpp
cd mpp

.\mpp.exe examples\hello.mpp --llvm
.\hello.exe
# Output: Hello R2ND

2. Write your own program

Create myprogram.mpp:

fn main() {
    let name = input("What is your name? ");
    print("Hello, " + name + "!");
}

Compile and run:

.\mpp.exe myprogram.mpp --llvm
.\myprogram.exe

3. Try more examples

.\mpp.exe examples\structs.mpp --llvm && .\structs.exe
.\mpp.exe examples\generics.mpp --llvm && .\generics.exe
.\mpp.exe examples\closures.mpp --llvm && .\closures.exe
.\mpp.exe examples\memory.mpp --llvm && .\memory.exe

Language Highlights

Structs and Methods

struct Person {
    name: string,
    age: int
}

fn Person.greet(self: Person) -> string {
    return "Hi, I'm " + self.name + " and I'm " + to_string(self.age);
}

fn main() {
    let p = Person { name: "Alice", age: 30 };
    print(p.greet());
}

Enums with Pattern Matching

enum Shape {
    Circle(float),
    Rect(float, float),
    Point
}

fn area(s: Shape) -> float {
    match s {
        Shape::Circle(r)    => { return 3.14159 * r * r; }
        Shape::Rect(w, h)   => { return w * h; }
        Shape::Point        => { return 0.0; }
    }
}

Generics and Traits

trait Describable {
    fn describe(self) -> string;
}

fn print_all<T: Describable>(items: [T]) {
    for item in items {
        print(item.describe());
    }
}

Error Handling

fn divide(a: int, b: int) -> Result[int] {
    if b == 0 { return err("division by zero"); }
    return ok(a / b);
}

fn main() {
    let r = divide(10, 0);
    if is_ok(r) {
        print(to_string(unwrap(r)));
    } else {
        print("Error: " + unwrap_err(r));
    }
}

Manual Memory and Defer

fn process_data() {
    let buf: ptr = alloc(1024);
    defer { free(buf); }       // guaranteed cleanup on any exit path

    // ... use buf ...
    memset(buf, 0, 1024);
}

Closures

fn apply(f: fn(int) -> int, x: int) -> int {
    return f(x);
}

fn main() {
    let base = 10;
    let add_base = |x: int| -> int { return x + base; };  // captures base
    print(to_string(apply(add_base, 5)));   // 15
}

C FFI

extern fn printf(fmt: string, val: int) -> int;
extern fn sqrt(x: float) -> float;

fn main() {
    let result = sqrt(2.0);
    printf("sqrt(2) = %f\n", result as int);
}

Examples

File What it demonstrates
hello.mpp Basic I/O, entry point
variables.mpp Variables, types, type inference
functions.mpp Functions, default arguments
structs.mpp Structs, methods, field access
enums.mpp Enums with payloads, pattern matching
generics.mpp Generic functions and structs
traits.mpp Trait definitions and implementations
closures.mpp Lambdas, higher-order functions, capturing
error_handling.mpp Result[T] and Option<T>
modules.mpp Multi-file imports
defer.mpp Defer / RAII-style cleanup
lowlevel.mpp Bitwise ops, casting, sizeof, raw pointers
memory.mpp alloc/free, rc<T> reference counting, slices
ffi.mpp Calling C functions via extern fn
maps.mpp map[K, V] — hash maps
arrays.mpp Arrays, append, pop, slicing
string_interp.mpp String operations and formatting

Project Layout

bootstrap/              Self-hosted compiler source (written in M++)
  tokens.mpp            Token type definitions
  ast.mpp               AST node types
  lexer.mpp             Tokenizer / lexer
  parser.mpp            Recursive descent parser
  typechecker.mpp       Type checker and inference
  codegen.mpp           LLVM IR code generator
  main.mpp              Compiler entry point and CLI
  mpp.ll                Last compiled IR (bootstrap artifact)

src/
  runtime/
    mpp_runtime_llvm.c  Runtime library: strings, arrays, maps, I/O, memory

examples/               One example file per major language feature
tests/                  Test runner and expected output files
docs/
  LANGUAGE.md           Full language reference
ROADMAP.md              Development roadmap and planned features

Build the Compiler from Source

The M++ compiler is self-hosted — it compiles itself.

# Rebuild the compiler using the existing mpp.exe
.\mpp.exe bootstrap\mpp.mpp --llvm
# This produces a new mpp.exe

# Run the test suite
powershell -ExecutionPolicy Bypass -File tests\run_bootstrap_tests.ps1

Type System

Type Description Size
int 64-bit signed integer 8 bytes
float 64-bit floating point 8 bytes
bool Boolean (true / false) 1 byte
string UTF-8 string (heap-allocated)
ptr Raw untyped pointer 8 bytes
[T] Dynamic array of T
map[K, V] Hash map
Option<T> Value or None
Result[T] Value or error string
rc<T> Reference-counted pointer

Memory Model

M++ uses structured manual memory — no garbage collector, no runtime overhead:

Kind Lifetime Cleanup
Stack values (int, float, bool) Automatic None needed
Structs with drop() Scope-based Called automatically
Raw pointers (ptr) Manual free() required
Reference counts (rc<T>) Ref-counted Freed at count 0
Arrays [T] Runtime-managed Currently leaked (planned fix)
Strings Runtime-managed Currently leaked (planned fix)

Use defer { free(p); } for deterministic, RAII-style cleanup.


Standard Library

All standard library functions are built-in — no import required.

I/O: print, input
Strings: len, substr, split, contains, trim, replace, to_upper, to_lower, index_of, join, char_at
Conversion: to_string, to_int, to_float, int_to_char, char_to_int
Arrays: len, append, pop, arr_copy
Maps: map_set, map_get, map_has, map_del, map_keys
Math: sqrt, abs, min, max, pow, floor, ceil, round, sin, cos, log
Files: file_read, file_write, file_append, file_exists
Memory: alloc, realloc, free, memcpy, memset, rc_new, rc_clone, rc_release
System: exit, assert

→ Full reference: docs/LANGUAGE.md


Documentation


License

Educational project by Mathias.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages