A General Purpose Compiled Programming Language that compiles to x86-64 ELF object file or Nasm compatable asm text file. This compiler can directly generate x86-64 Elf file using it's internal assembler whitout any thirdparty tool or library!
Language is in alpha and in the current state it lacks any standard library for making real world applications but feel free to check out the examples and tests that shows Some of the Nmet programming language capabilities.
Checkout similar projects:
Chap programming language: https://github.com/ali77gh/Chap
30 C Compiler: https://github.com/keyvank/30cc
The Project is in development state and dose not come with a package yet and It is Only available fot linux but you can use wsl in windows!
For getting started clone the repository and build the project using Rust toolchain
Install Nasm using your package manager or by downloading it from it's official website
For installing in Gnu/Linux system make this projectl.
$ make install
Create a file like hello.nmt
extention and write a simple program insde it:
lets start with a classic application that prints hello world to the standard output
fun main() {
print "Hello World!\n";
}
now you can run the following commands:
$ nmet ./hello.nmt
$ nemt -nasm ./hello.nmt #or
$ nmet ./hello.nmt
$ ./build/hello
In this section we are showcasing different aspects of Nmet syntax
Every program starts with a function named main. usally this function has no arguments but you can define one with the type list-of-string to gain access to command line arguments.
p.s: Comments are starting with "~" because we hate this character so we made it into a comment
~~ No Arguments
func main() {
...
}
~~ With Arguments
func main(args @[str,?]) {
...
}
Expressions are grammars that can be used in every kind of operation; from mathematical to lists and function calls These expressions are just like in other languages.
Unlike other system level programming languages Nmet comes with an internal print function, This function dose not require Parentheses and can have as many arguments as you supply it to.
print "Hello world!";
print 12 + 6;
Every programming languages has a way to abstract away direct memory access with variables. In Nmet we define variables with "var" keyword followed by a name. All types in Nmet are indicated by the at-sign symbol. Adding type to variables is optional as long as you provide an initial value. Nmet also supports const variables which can be declared by adding a colon behind the question mark.
var list @[char,12];
var x @int = 10
~~ auto casting and const
var is_true := true;
Assigning values to a variable is a process which you can transfer result of your processes to a predefined memory In Nmet we have different types of assignments including add and assign or divide and assign which is represented in the code below:
a = 10; ~~ a <- 10
a += 10; ~~ a <- a + 10
a -= 10; ~~ a <- a - 10
a *= 10; ~~ a <- a * 10
a /= 10; ~~ a <- a / 10
a %= 10; ~~ a <- a % 10
loops are one of the most important parts of any programming language. Nmet loops are defined using the while keyword followed by a condition which indicates when the looping ends pretenses surrounding the condition is optional.
while a < 10 {
...
}
Nemt also supports For loops:
for i to 10 {
...
}
if statements allow the user of the programming language to run some parts of the code conditionally. You can use if statements by writing the if keyword followed by the condition and with optional else and else if.
if a < 10 {
...
} else if a > 10 {
...
} else {
...
}
because Nmet is a low level language having a way to write in line assembly is essential for the usability of it. Inline assembly codes can be defined in a block marked by asm keyword. each assembly line is surrounded by double quotes. You can use Nmet declared variables inside the assembly lines by using the percentage sign. Make sure to use correct registers for different variable types .
asm {
"mov rax, %my_u64_variable"
"inc rax"
}
Forien Function Interface or (FFI) allows programmers to link with external libraries by making a wrapper around imported functions
ffi "add" func nmt_add(a @int, b @int) @int
ffi "multi" func nmt_multi(a @int, b @int) @int
ffi "sub" func nmt_sub(a @int, b @int) @int
func main() {
print nmt_add(2,1);
print nmt_multi(2,1);
print nmt_sub(2,1);
}
Structs address multiple variables with different types that share a common porperty
struct Human {
age @int,
height @int,
}
func main() {
var a @Human;
a.age = 69;
a.height = 65;
print a.height;
}
Defer is a modern feature in programming languges like golanf or zig witch primary allows programmes to dref or free variables before exiting the function even if the functions has multiple return statements
func main() {
var x @ptr;
x = malloc(4);
defer free(x);
...
}
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE.txt
for more information.