Skip to content

MoritzGoeckel/MLang

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

205 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

MLang

MLang is my strictly typed programming language with full type inference that compiles to a custom byte code. This project is hand crafted with zero dependencies. The language uses a custom recursive descent parser as the front-end and targets a custom byte code vm as the backend. This is a multiplatform project targeting both Linux and Windows.

This language is build solely for fun and educational purposes, so maybe you should not use this in production 🐴

You can download the executables for Windows and Linux in the release section.

Features

  • Type inference
  • Strictly typed
  • Functions
  • Arithmetic operations
  • Boolean operations
  • Branching (if)
  • Loops (while)
  • Integer type
  • Boolean type
  • Float type
  • Operator precedence
  • Linux support
  • Windows support
  • Error reporting
  • Structs (on the heap)
  • C-calls (FFI) to dynamic libraries (x64 Win & x86_64 Linux)
  • Strings
  • Printing
  • Arrays
  • Closures
  • Garbage collection

Examples

For more examples refer to the mfiles folder

# Loops let i = 0; let j = 1; while(i < 10){ j = j * 2; i = i + 1; } ret j; 
# Infix notation let i = 1 + 2; # Prefix notation let j = +(1, 2); 
# Functions let f(x) = x + 2; ret f(11); 
# Multi-line functions let f(x) = { let y = x + 2; ret y + 3; }; ret f(10); 
# Branching let x = 1; if(x < 3){ ret true; } ret false; 
# Operator precedence let x = 3 + 10 + 6 / 3 - 2 * 5; ret x; # is 5 
# FFI to dynamic c libraries (libtest.so) let mul = extern test::mul(a: Int, b: Int): Int; let result = mul(5, 3); 
# Structs struct Point { let x: Int; let y: Int; } struct Line { let begin: Point; let someInt: Int; let end: Point; } let l: Line; l.begin.x = 3; l.begin.y = 4; l.end.x = 8; l.end.y = 9; ret l.begin.x + l.end.y; 
# Strings let print = extern test::print(s: String): Void; let str = "Hello, World!"; print(str); 
# Using external library (raylib) let str = "Hello, World!"; let InitWindow = extern raylib::InitWindow(w: Int, h: Int, s: String): Void; InitWindow(800, 600, str); let SetTargetFPS = extern raylib::SetTargetFPS(fps: Int): Void; SetTargetFPS(60); let WindowShouldClose = extern raylib::WindowShouldClose(): Bool; let CloseWindow = extern raylib::CloseWindow(): Void; let BeginDrawing = extern raylib::BeginDrawing(): Void; let ClearBackground = extern raylib::ClearBackground(color: Int): Void; let EndDrawing = extern raylib::EndDrawing(): Void; let DrawText = extern raylib::DrawText(text: String, x: Int, y: Int, fontSize: Int, color: Int): Void; while(WindowShouldClose() == false) { BeginDrawing(); ClearBackground(1); DrawText(str, 190, 200, 20, 1); EndDrawing(); } CloseWindow(); 

Error reporting

Following you find an example on how parsing errors are reported to the user

Parsing failed: Expecting ';' but found 'ret' @3:17 1: let f(x) = { 2: let y = x + 2 3: ^ Consider adding a semicolon to the end of the statement 

Dependencies

None

Getting started

If you want to build this yourself, refere to this guide INSTALL.md