Skip to content

Instantly share code, notes, and snippets.

@Lucrecious
Last active February 7, 2025 21:56
Show Gist options
  • Save Lucrecious/d9ee0fd07c1981c37cbd5330943d8a6b to your computer and use it in GitHub Desktop.
Save Lucrecious/d9ee0fd07c1981c37cbd5330943d8a6b to your computer and use it in GitHub Desktop.
the first ever program written in orso that proves it's a turing-complete language; the game of life. the first of many iterations as the language progresses.
// odin file extension used for syntax highlighting
do:gol {
// no strings yet so not printing anything yet
width := readint();
height := readint();
tile_count := width*height;
// exit immediately if board has no dimensions
if tile_count == 0 {
printint(0); // no strings, so only printing integers for now
println(); // no strings, so a specific function needed for new line
break:gol 1; // returning non-zero means error
};
// only available memory functions right now are just system calls for reserving virtual memory
// '<<'' is casting operator
board := &u8 << mreserve(size_t << tile_count*2);
buffer := board + (ptrdiff_t << tile_count);
// you need to mark the memory as read/write
mmarkrw(board, size_t << tile_count*2);
printint(1); // indicating successful board creation
println();
println();
// no arrays yet, function for getting ptr at index
at :: (board: &u8, index: ptrdiff_t) -> &u8 {
return (board + index);
};
// no arrays yet, function for getting ptr in terms of x and y
atxy :: (board: &u8, x: int, y: int, width: int) -> &u8 {
return board + ptrdiff_t << y*width + x;
};
board_clear :: (board: &u8, count: int) -> void {
// only ptrdiff_t types are allowed to be used for arithmetics with pointers
i := 0pd;
while i < ptrdiff_t << count {
*at(board, i) = 0;
// no += operator yet
i = i + 1;
};
// all functions need a return even if void right now
return;
};
board_clear(board, tile_count);
// set tiles in a loop until user doesn't want anymore
initx := readint();
inity := readint();
until initx*inity == 0 {
x := initx - 1;
y := inity - 1;
if x < 0 or y < 0 or x >= width or y >= height {
printint(0); // printing 0 indicates invalid tile position
println();
} else {
*atxy(board, x, y, width) = 1;
printint(1); // printing 1 indicates valid tile position
println();
};
println();
initx = readint();
inity = readint();
};
println();
render_board :: (board: &u8, width: int, height: int) -> void {
w := 0;
h := 0;
while h < height {
while w < width {
tile := int << *atxy(board, w, h, width);
printint(tile);
w = w + 1;
};
w = 0;
h = h + 1;
println();
};
println();
return;
};
render_board(board, width, height);
neighbors :: (board: &u8, x: int, y: int, w: int, h: int) -> int {
sum := 0;
xi := 0;
yi := 0;
xs := x - 1;
ys := y - 1;
while yi < 3 {
while xi < 3 {
xn := xs + xi;
yn := ys + yi;
xi = xi + 1;
if xn == x and yn == y then continue;
if xn < 0 or yn < 0 or xn >= w or yn >= h then continue;
sum = sum + int << *atxy(board, xn, yn, w);
};
xi = 0;
yi = yi + 1;
};
return sum;
};
while readint() != 0 {
board_clear(buffer, tile_count);
x := 0;
y := 0;
while y < height {
while x < width {
n := neighbors(board, x, y, width, height);
alive := *atxy(board, x, y, width);
// death by underpopulation
if alive > 0 and n < 2 then
*atxy(buffer, x, y, width) = 0
// lives to next generation
else if alive > 0 and (n == 2 or n == 3) then
*atxy(buffer, x, y, width) = 1
// death by overpopulation
else if alive > 0 and n > 3 then
*atxy(buffer, x, y, width) = 0
// reproduction
else if alive < 1 and n == 3 then
*atxy(buffer, x, y, width) = 1;
x = x + 1;
};
x = 0;
y = y + 1;
};
tmp := board;
board = buffer;
buffer = tmp;
render_board(board, width, height);
};
mfree(board, size_t << tile_count*2);
0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment