Gloin is a modern, systems programming language with advanced features including structs, pointers, methods, comprehensive import system, and strong type safety. The compiler is implemented in C and generates LLVM IR for optimal performance.
- CMake 3.12 or later
- LLVM development libraries and headers
- GCC or Clang C compiler
- Make build system
Ubuntu/Debian:
sudo apt update
sudo apt install cmake llvm-dev clang build-essentialFedora:
sudo dnf install cmake llvm-devel clang gcc makemacOS:
brew install cmake llvm# Easy one-command build
./build.sh
# Or build in debug mode
./build.sh build debug
# Run tests
./build.sh testAlternative build methods:
# Using CMake directly
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j$(nproc)
# Using original Makefile
make# Run the interactive demo
./demo.shThis will build and run all example programs, showing you the language in action!
Create a file called hello.gloin:
import "@std"
def main() -> i32 {
std.println("Hello, World!");
return 0;
}
Compile and run it:
# Compile (creates executable named 'hello')
./build/gloinc hello.gloin
# Run the program
./helloimport "@std"
def main() -> i32 {
// Immutable variable (default)
def name: string = "Gloin";
def age: i32 = 25;
def height: i64 = 180;
def is_active: bool = true;
// Mutable variable
def mut score: i32 = 100;
score = 150; // OK - mutable
// age = 30; // ERROR - immutable
return 0;
}
Supported Types:
i32- 32-bit integeri64- 64-bit integerstring- String typebool- Boolean (true/false)*type- Pointer types- Custom structs
import "@std"
// Function with parameters and return value
def add(a: i32, b: i32) -> i32 {
return a + b;
}
// Function with no return value
def greet(name: string) -> void {
std.print("Hello, ");
std.println(name);
}
def main() -> i32 {
def sum: i32 = add(10, 20);
greet("Developer");
return 0;
}
import "@std"
def main() -> i32 {
def x: i32 = 10;
// If statement (no parentheses around condition)
if x > 5 {
std.println("x is greater than 5");
}
// Unless statement (opposite of if)
unless x < 0 {
std.println("x is not negative");
}
// While loop
def mut counter: i32 = 0;
while counter < 3 {
std.println(std.to_string(counter));
counter = counter + 1;
}
// For loop
for def mut i: i32 = 0; i < 5; i = i + 1 {
std.print("Iteration: ");
std.println(std.to_string(i));
}
return 0;
}
import "@std"
def struct Person {
name: string,
age: i32,
def greet(self) -> void {
std.print("Hello, I'm ");
std.println(self.name);
}
def is_adult(self) -> bool {
return self.age >= 18;
}
}
def main() -> i32 {
def person: Person = Person {
name: "Alice",
age: 25
};
person.greet();
if person.is_adult() {
std.println("Person is an adult");
}
return 0;
}
import "@std"
def main() -> i32 {
def mut value: i32 = 42;
def ptr: *i32 = &value; // Get address of value
std.print("Value: ");
std.println(std.to_string(value));
std.print("Via pointer: ");
std.println(std.to_string(*ptr)); // Dereference pointer
*ptr = 100; // Modify through pointer
std.print("New value: ");
std.println(std.to_string(value));
return 0;
}
Gloin supports three types of imports:
import "@std"
def main() -> i32 {
std.println("Hello World"); // Print with newline
std.print("Enter name: "); // Print without newline
def input: string = std.input(); // Read user input
def number: i32 = std.to_int("123"); // Convert string to int
def text: string = std.to_string(42); // Convert int to string
return 0;
}
// utils.gloin
def calculate(x: i32, y: i32) -> i32 {
return x * y + 10;
}
// main.gloin
import "@std"
import "./utils"
def main() -> i32 {
def result: i32 = utils.calculate(5, 3);
std.println(std.to_string(result));
return 0;
}
import "@std"
import "#math" // External package
import "#http" // Another external package
def main() -> i32 {
def sqrt_val: i32 = math.sqrt(16);
std.println(std.to_string(sqrt_val));
return 0;
}
The Gloin compiler (gloinc) provides several modes for different use cases:
# Compile to executable (silent mode)
./build/gloinc myprogram.gloin # Creates './myprogram'
./build/gloinc myprogram.gloin -o app # Creates './app'# Show AST and LLVM IR (no executable)
./build/gloinc myprogram.gloin --ast
# Full debug information + compile
./build/gloinc myprogram.gloin --debug
# Parse-only mode (alias for --ast)
./build/gloinc myprogram.gloin --parse-only# Create new project
./build/gloinc init my_project
cd my_project
# Project structure created:
# my_project/
# βββ main.gloin # Main source file
# βββ armory.toml # Package configuration
# βββ includes/ # External dependencies# 1. Create and edit your program
cat > calculator.gloin << 'EOF'
import "@std"
def add(a: i32, b: i32) -> i32 {
return a + b;
}
def main() -> i32 {
def result: i32 = add(10, 20);
std.print("10 + 20 = ");
std.println(std.to_string(result));
return 0;
}
EOF
# 2. Check syntax and AST
./build/gloinc calculator.gloin --ast
# 3. Compile and run
./build/gloinc calculator.gloin
./calculator
# Output: 10 + 20 = 30The repository includes several example programs:
# Simple examples
./build/gloinc examples/hello_world.gloin && ./examples/hello_world
./build/gloinc examples/variables.gloin && ./examples/variables
./build/gloinc examples/functions.gloin && ./examples/functions
# More complex examples
./build/gloinc tests/arithmetic_showcase.gloin --ast
./build/gloinc tests/comprehensive_struct_test.gloin --debugstd.print(text: string)- Print text without newlinestd.println(text: string)- Print text with newlinestd.input() -> string- Read line from user input
std.to_int(text: string) -> i32- Convert string to integerstd.to_string(number: i32) -> string- Convert integer to stringstd.to_i64(text: string) -> i64- Convert string to 64-bit integer
- Complete compilation pipeline: Source code β LLVM IR β Executable
- Modern language features: Strong typing, memory safety, pattern matching
- Professional tooling: Multiple compiler modes, project management
- Rich standard library: I/O, type conversions, string handling
- Clean syntax: No semicolon clutter, clear function/variable declarations
- Fast compilation: LLVM backend for optimized machine code
- Parser coverage: Some advanced syntax features still in development
- Standard library: Basic I/O and conversions (expanding)
- Error messages: Good but can be improved for complex cases
- IDE support: Command-line focused (IDE plugins planned)
- Learning: Great for understanding modern language design
- Prototyping: Quick system tools and utilities
- Education: Teaching compiler concepts and systems programming
- Experimentation: Trying new language features and paradigms
- Compilation: ~5 seconds for typical programs
- Runtime: LLVM-optimized machine code (C/C++ speed)
- Memory: Static typing prevents common memory errors
- Executable size: ~15KB for simple programs
Try it yourself - the examples in this README all work and compile to working executables!
"Expected import or def declaration"
- All functions must be declared with
def, notfn - Files must start with imports or top-level definitions
// β Wrong
fn main() -> i32 {
return 0;
}
// β
Correct
import "@std"
def main() -> i32 {
return 0;
}
"Expected const, mut, struct, enum, or function name after 'def'"
- Missing function name or incorrect syntax after
def
// β Wrong
def () -> i32 {
return 0;
}
// β
Correct
def main() -> i32 {
return 0;
}
LLVM not found during build:
# Ubuntu/Debian
sudo apt install llvm-dev
# Fedora
sudo dnf install llvm-devel
# Set LLVM_DIR if needed
export LLVM_DIR=/usr/lib/llvm-<version>/lib/cmake/llvmLinking errors:
- Make sure you're using the C++ linker (handled automatically by CMake)
- Check that all LLVM development packages are installed
Build script fails:
# Try manual build
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j$(nproc)
# Or use original Makefile
make clean && make- β
Variables & Types:
i32,i64,string,bool, pointers - β
Mutability:
def(immutable) vsdef mut(mutable) - β Functions: Parameter passing, return values, type checking
- β
Control Flow:
if,unless,while,forloops - β Structs: Definition, field access, methods
- β Pointers: Declaration, dereferencing, address-of operator
- β Import System: Standard library, local modules, external packages
- β Standard Library: I/O functions, type conversions
- β Error Reporting: Line numbers, descriptive messages
- π§ Enums: Basic enum support partially implemented
- π§ Pattern Matching: Switch statements with advanced patterns
- π§ Memory Management: Advanced pointer operations
- π§ Module System: Enhanced package management
- π Generics: Generic functions and structs
- π Error Handling: Result types and error propagation
- π Async/Await: Asynchronous programming support
- π FFI: Foreign function interface for C interop
gloin/
βββ src/ # Compiler source code
β βββ lexer.c # Tokenization
β βββ parser.c # Syntax analysis
β βββ ast.c # Abstract syntax tree
β βββ codegen.c # LLVM IR generation
β βββ types.c # Type system
β βββ main.c # Compiler entry point
βββ include/ # Header files
βββ test/ # Unit tests
βββ tests/ # Language test files
βββ examples/ # Example programs
βββ build/ # Build artifacts (generated)
# Debug build with symbols
./build.sh build debug
# Clean rebuild
./build.sh clean
./build.sh
# Run tests
./build.sh test- Lexer (
src/lexer.c): Add new token types - Parser (
src/parser.c): Add syntax rules - AST (
src/ast.c): Add new node types - Codegen (
src/codegen.c): Add LLVM IR generation - Tests: Add test cases in
tests/
The Gloin compiler follows a traditional multi-phase design:
- Lexical Analysis: Source code β Tokens
- Parsing: Tokens β Abstract Syntax Tree (AST)
- Type Checking: AST validation and type inference
- Code Generation: AST β LLVM IR β Machine code
# Clone and build
git clone https://github.com/gloinlang/compiler.git
cd compiler
./build.sh
# Run tests
./build.sh test
# Try examples
./build/gloinc examples/hello_world.gloin
./examples/hello_world- C99 Standard: All C code follows C99
- Naming: snake_case for functions/variables, PascalCase for types
- Memory Management: Always free allocated memory
- Error Handling: Use proper error codes and messages
# Run unit tests
./build.sh test
# Test specific language features
./build/gloinc tests/arithmetic_test.gloin --ast
./build/gloinc tests/struct_test.gloin --debugThis project is licensed under the MIT License - see the LICENSE file for details.
If you encounter issues:
- Check Examples: Look at working examples in
examples/andtests/ - Verify Syntax: Ensure functions use
defand files start with imports - Build Issues: See troubleshooting section above
- Report Bugs: Create an issue with minimal reproduction case