https://github.com/mobskuchen/vault
Verified, Atomic, Uncomplicated, Low-level Toolkit
https://github.com/mobskuchen/vault
llvm-frontend programming-language
Last synced: 6 months ago
JSON representation
Verified, Atomic, Uncomplicated, Low-level Toolkit
- Host: GitHub
- URL: https://github.com/mobskuchen/vault
- Owner: MOBSkuchen
- Created: 2025-05-24T19:24:00.000Z (8 months ago)
- Default Branch: master
- Last Pushed: 2025-05-29T18:28:18.000Z (8 months ago)
- Last Synced: 2025-06-05T13:48:07.326Z (8 months ago)
- Topics: llvm-frontend, programming-language
- Language: Rust
- Homepage:
- Size: 180 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# VAULT
Stands for Verified, Atomic, Uncomplicated, Low-level Toolkit
and is a C-like, Rust-inspired and written optimized low level programming language
## Does the world really need this? Another C?
Well kind of. C is at its core a way to write low level code, without fiddling with registers.
Stupid as we programmers are, we have taken it to all kinds of places it was not made for - everything which is not a computer in the 70s or a bare metal machine. I think, that what makes C great, is the control it gives over the hardware and its *do what you want approach*. Its flaws are obvious tho: No namespaces, no easy way of obtaining packages and other libraries, and most importantly: **no compiler, that is made for humans**.
VAULT aims to change that. (currently most of it is not yet implemented lol). It features LLVMs amazing optimizations, C's control and the rust compilers *smartness*.
### Why not yet another C compiler?
Creating a C-spec adherent compiler that fulfills those desires is impossible. Due to the nature of the language, anything past some better error handling is impossible.
That's why I changed the things that needed changing and along the way also made some sensible improvements, because this language does not yet need to be backwards compatible 50 years.
### VAULT's philosophy
The programmer knows what they are doing. Give them the right tools and they can achieve greatness.
## Installation
Currently, the only way of obtaining the compiler is by cloning the repo and building it. This also means building LLVM on your machine.
Notice: Make sure to compile LLVM in release mode and also compile this project in release mode (or debug if that's what you want).
## The Syntax
First program: *Print "Hello World"*
````
import stdlib
def export main(): void {
stdlib::print("Hello World")
}
````
### Types
VAULT has the following types
- **i32**: 32-bit signed integer
- **i64**: 64-bit signed integer
- **u32**: 32-bit unsigned integer
- **u64**: 64-bit unsigned integer
- **u8**: 8-bit unsigned integer
- **f32**: 32-bit float
- **f64**: 64-bit float
- **bool**: 1-bit unsigned integer
- **void**: Function type exclusive void
- **struct**: A struct. Not actually a type, but you create your own types via structs
- **function**: A type representing a function
### Assignments
Assignment are similar to the ones in rust. However, types must always be clear. Mutability is by default and there is no const.
```
// Automatically infer a name
let name = "John";
// Annotated type
let last_name: u8* = "Doe";
// Declaration (must include a type)
let age: i32;
// Reassignment
age = 23;
name = "Chuck";
```
### Functions def / dec
Function definitions and declarations are similar to Python and C.
Function modes:
- export : Expose externally
- extern : Declared externally
- private : WIP
- *default* : WIP (public)
Note : The *main* function is not mandatory and can return anything, e.g. **unchecked**
```
// Return type i32
def export main(): i32 {
return 0
}
// Extern void function with param 'num' i32
def extern print_whatever(num: i32): void;
```
### Function calling
Calling a function is very simple and identical to many other languages.
Note: *void*-type functions can not be used as values. That will result in a compiler error
```
// `age`, `print_user_data` and `prompt_for_name` previously defined
let name = prompt_for_name("What's your name? ");
print_user_data(age, name);
```
### Malloc and free
Malloc and free are built in and have their own syntax.
Both will return the type `ptr` which is an untyped pointer. You might want to cast it or use type annotations.
Note: Free can be auto-detected for most things
```
// Allocate 256 bytes
let result: u8* = |> 256;
// Scanf to `result`
stdlib::ptr_input(result, 256);
```
Use `|> (amount)` for malloc and `|< (expr)` for free
### Structs
Struct definitions are a like the ones in rust, but simpler.
```
struct Point {
x: i32,
y: i32
}
```
#### Initialization
Use the `new` keyword to create a struct. The arguments must be in the order that the struct has.
```
// x = 0; y = 1
let point = new Point(0, 1);
```
To reassign a property, you must have a pointer to the property (like shown before)
```
&point~x = 160;
```
#### Properties
Literal and pointer access are possible. However, they must occur on a pointer to the struct.
```
// Access literal value of `Point->x`
let x: i32 = &point.x;
// Access pointer to value of `Point->x`
let x: i32* = &point~x;
```
To reassign a property, you must have a pointer to the property (like shown before)
```
&point~x = 160;
```
#### Member functions on structs
Declaring member functions for structs is also possible:
```
def draw_point(p: Point*) Point : void {
...
}
```
First param of the method must be of type *struct* pointer.
They are called like so:
```
// The value to call on must be a pointer to the struct
&point.draw_point();
```
### Conditionals
If-*elif*-else statements are possible and a combination of C and python syntax.
```
let error_code = do_something_dangerous();
if error_code != 0 {
stdlib::print("An error has occured!")
} else {
stdlib::print("Everything is fine")
};
// Note: ';' is required after the last block
```
### Conditional loops
While statements are possible and a combination of C and python syntax.
```
let a = 100;
while a > 10 {
a = a - 1;
};
// Note: ';' is required after the block
```
### Casts
You may cast all primitive types (all types except structs and functions).
However, you must be careful as casts are **NOT** safe and purely change the *perceived type*.
```
// Ext cast.
let num: i32 = 0;
let other = num => i64;
// Trunc cast. (lossy)
num = other => i32;
...
// Very useful: Cast a typed pointer into an untyped one
let p = "abc" => ptr;
```
### Imports
You may import code from other files.
Once you import a file (aka module), you carry over all symbols to the MAV (Module Access Variant) named after the module. Import compiles the file in between the previous and following code.
```
// Import the file 'stdlib.vt' to 'stdlib'
import stdlib
...
// Import the file 'stdlib.vt' to 'std'
import stdlib => std
...
// Import the file 'stdlib-other.vt' to 'std'
import "stdlib-other" => std
...
// Invalid syntax! String imports require a module name
import "stdlib-other"
```
Then use as follows:
```
std::imported_function("this is neat");
```
### Directives
Directives are compile time instructions. They may enable you to link something for specific users or enable / disable creating a function.
```
// Windows only function
#(OS "windows")
def func();
```
Directives are declared with `#`. They follow the layout `( NAME <...> )`. They always return a boolean.
Putting them over a statement will disable / enable it depending on the return value of the directive.
Here is a list of directives:
- AND
- OR
- XOR
- NOT
- ALWAYS => Always returns *true*
- NEVER => Always returns *false*
- DEBUG => Returns whether debug mode is on
- LINK => Link with a library; Always returns *true*
- OS => Is on os
- ARCH => Is on arch
- IF => Runs and returns value of exe if condition is true
- IFI => Runs exe if condition is true; Always returns *true*
- IFE => Runs exe if condition is true, otherwise else; Returns the corresponding value
- IFEI => Runs exe if condition is true, otherwise else; Always returns *true*
- ERR => Creates a compiler error at the directive with a footer
- ERRN => Creates a compiler error at the directive with a footer and a note
- WARN => Creates a compiler warning at the directive with a footer; Always returns *true*
- WARNF => Creates a compiler warning at the directive with footer; Always returns *false*
## Concepts
### 1. (Built-in) free means destruction
When using the built-in free method, the compiler will forget about the variable to protect against *use after free* exceptions
### 2. Data types should match their memory layout
There are no built-in arrays or hashmaps or such, because they abstract how data is stored in memory and how the CPU handles it