- No strict type checker
- No C-like pointer arithmetic
- No function-like macros
- No
break
,continue
stmt. Usegoto
- Allows
13 <= age < 20
instead of13 <= age && age < 20
- Variable length args
func(...)
can be accessed with built-in variablesargc i64
andargv *i64
- Default function args. Default args don't have to be on the end. (WIP)
#include "std.ibu"
func main() i32 {
let age i32 = 19;
if 13 <= age < 20 {
printf("Teen-ager\n");
}
printf("Hello, world!\n");
return 0;
}
Note Supports Linux x86-64 only.
$ git clone [email protected]:v420v/ibu.git
$ cd ibu
$ docker build ./ -t ibulang
# Linux or MacOS:
$ docker run --rm -it -v "$(pwd)":/root/env ibulang
# Windows (CMD):
$ docker run --rm -it -v "%cd%":/root/env ibulang
# Windows (PowerShell):
$ docker run --rm -it -v "${pwd}:/root/env" ibulang
# To leave the environment, enter `exit`.
Since the language is selfhosted you need to bootstrap the compiler first.
To build the compiler, run the following command below or just run make
$ make
$ make self
$ ./ibuc <filename>.ibu | as - -o <filename>.o
$ as -o lib/syscall-amd64.o lib/syscall-amd64.s
$ ld -o <filename> <filename>.o lib/syscall-amd64.o
#include "std.ibu"
func main() i32 {
printf("Hello, world!\n");
return 0;
}
#include "std.ibu"
func main() i32 {
let name *u8 = "Ibuki";
let age i8 = 19;
printf("name: %s, age: %d\n", name, age);
return 0;
}
i8, i16, i32, i64, u0, u8, u16, u32, u64
#include "std.ibu"
// Allows "13 <= age < 20" instead of "13 <= age && age < 20"
func main() i32 {
let age i32 = 19;
if 13 <= age < 20 {
printf("Teen-ager\n");
}
return 0;
}
1 < 2 < 3 < 4 < 5; // 1 < 2 && 2 < 3 && 3 < 4 && 4 < 5;
1 < 2 >= 3 < 4 > 5; // 1 < 2 && 2 >= 3 && 3 < 4 && 4 > 5;
1 && 8 || 7 || 6 < 2 < 3; // 1 && 8 || 7 || 6 < 2 && 2 < 3;
6 == 1 == 1 && 8 || 7 || 6 < 2 < 3; // 6 == 1 && 1 == 1 && 8 || 7 || 6 < 2 && 2 < 3;
1 == 1 == 1 == 2; // 1 == 1 && 1 == 1 && 1 == 2;
2 != 2 != 3 != 4 < 3 <= 5 <= 6; // 2 != 2 && 2 != 3 && 3 != 4 && 4 < 3 && 3 <= 5 && 5 <= 6;
4 || 2 || 8 || 9 && 4 < 2 < 3; // 4 || 2 || 8 || 9 && 4 < 2 && 2 < 3;
2 != 2 != 3 != 4 < !3 <= 5 <= 6; // 2 != 2 && 2 != 3 && 3 != 4 && 4 < !(3) && !(3) <= 5 && 5 <= 6;
#include "std.ibu"
// Variable-length arguments can be accessed using the built-in variable argv, argc
func add_nums(...) i32 {
let n i32 = 0;
let idx i32 = 0;
while idx < argc {
n = n + argv[idx];
idx++;
}
return n;
}
func main() i32 {
let d i32 = add_nums(1, 2, 3);
printf("%d\n", d);
return 0;
}
#include "std.ibu"
func main() i32 {
// Like go's for loop, the condition is true if it is empty.
while {
printf("IBUKI\n");
}
let i i32 = 0;
while i < 100 {
printf("%d\n", i);
i++;
}
return 0;
}
#include "std.ibu"
func main() i32 {
let arr [4]i32 = {1, 2, 3, 4};
let arr2 [2][3][2][4]i32 = {
{
{
{1, 2, 3, 4}, {1, 2, 3, 4}
},
{
{1, 2, 9, 4}, {1, 2, 3, 4}
},
{
{1, 2, 3, 4}, {1, 2, 3, 4}
}
},
{
{
{11, 22, 3, 4}, {14, 24, 3, 4}
},
{
{11, 22, 3, 4}, {11, 27, 3, 4}
},
{
{11, 22, 3, 4}, {11, 2, 3, 4}
}
}
};
let buffer [10]u8 = {};
let test3 [2][2][2]i32 = {
{
{}, {}
},
{
{}, {}
}
};
printf("arr[3] -> %d\n", arr[3]);
printf("arr2[1][1][1][1] -> %d\n", arr2[1][1][1][1]);
return 0;
}
#include "std.ibu"
struct Person {
name *u8,
age i8,
}
func main() i32 {
let p Person = {
"Ibuki",
19
};
printf("name: %s age: %d\n", p.name, p.age);
return 0;
}
#include "std.ibu"
struct Person {
name *u8,
age i8,
}
func main() i32 {
let p *Person = alloc(typesize(Person));
p.name = "Ibuki";
p.age = 19;
printf("name: %s age: %d\n", p.name, p.age);
return 0;
}
make self
will compile src/main.ibu
using the ./ibuc executable
$ make self