summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-07-24 04:43:57 +0200
committerkdx <kikoodx@paranoici.org>2023-07-24 04:43:57 +0200
commit2fc7013751708afbf668a61b7e492d9e58057652 (patch)
treea07c677aa2b8022e3a43614edb854428e79ce92d
downloadegecs-2fc7013751708afbf668a61b7e492d9e58057652.tar.gz
initial commit
-rw-r--r--.gitignore1
-rw-r--r--board.golem110
-rw-r--r--color.golem39
-rw-r--r--egecs.golem76
-rw-r--r--iron.golem771
-rw-r--r--pieces.golem32
-rwxr-xr-xrun.sh5
7 files changed, 1034 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a699c8b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/tmp.*
diff --git a/board.golem b/board.golem
new file mode 100644
index 0000000..6b858b9
--- /dev/null
+++ b/board.golem
@@ -0,0 +1,110 @@
+define BOARD_SIZE = 64;
+global gBoard[BOARD_SIZE] = 0;
+
+board_init() {
+ memset(gBoard, EMPTY, BOARD_SIZE);
+ board_set("a1", piece(WHITE, ROOK));
+ board_set("b1", piece(WHITE, KNIGHT));
+ board_set("c1", piece(WHITE, BISHOP));
+ board_set("d1", piece(WHITE, QUEEN));
+ board_set("e1", piece(WHITE, KING));
+ board_set("f1", piece(WHITE, BISHOP));
+ board_set("g1", piece(WHITE, KNIGHT));
+ board_set("h1", piece(WHITE, ROOK));
+ board_set("a2", piece(WHITE, PAWN));
+ board_set("b2", piece(WHITE, PAWN));
+ board_set("c2", piece(WHITE, PAWN));
+ board_set("d2", piece(WHITE, PAWN));
+ board_set("e2", piece(WHITE, PAWN));
+ board_set("f2", piece(WHITE, PAWN));
+ board_set("g2", piece(WHITE, PAWN));
+ board_set("h2", piece(WHITE, PAWN));
+ board_set("a8", piece(BLACK, ROOK));
+ board_set("b8", piece(BLACK, KNIGHT));
+ board_set("c8", piece(BLACK, BISHOP));
+ board_set("d8", piece(BLACK, QUEEN));
+ board_set("e8", piece(BLACK, KING));
+ board_set("f8", piece(BLACK, BISHOP));
+ board_set("g8", piece(BLACK, KNIGHT));
+ board_set("h8", piece(BLACK, ROOK));
+ board_set("a7", piece(BLACK, PAWN));
+ board_set("b7", piece(BLACK, PAWN));
+ board_set("c7", piece(BLACK, PAWN));
+ board_set("d7", piece(BLACK, PAWN));
+ board_set("e7", piece(BLACK, PAWN));
+ board_set("f7", piece(BLACK, PAWN));
+ board_set("g7", piece(BLACK, PAWN));
+ board_set("h7", piece(BLACK, PAWN));
+}
+
+board_pos(pos, x, y) {
+ [x] = [pos + 0] - 'a';
+ [y] = 7 - ([pos + 1] - '1');
+}
+
+board_set(pos, v) {
+ local x, y;
+ if (pos == NULL)
+ return putstr("pos is NULL\n");
+ board_pos(pos, &x, &y);
+ if ((x > 7) | (y > 7)) {
+ putstr("wrong pos ");
+ putstr(pos);
+ wrt '\n';
+ return;
+ }
+ [gBoard + x + y * 8] = v;
+}
+
+board_get(pos) {
+ local x, y;
+ if (pos == NULL)
+ return putstr("pos is NULL\n");
+ board_pos(pos, &x, &y);
+ if ((x > 7) | (y > 7)) {
+ putstr("wrong pos ");
+ putstr(pos);
+ wrt '\n';
+ return INVALID;
+ }
+ return [gBoard + x + y * 8];
+}
+
+board_display(highlight) {
+ local x = 0xffff, y = 0xffff, i = 0, p;
+ if (highlight != NULL)
+ board_pos(highlight, &x, &y);
+ cls();
+ col_reset();
+ putstr("\n a b c d e f g h\n\n");
+ loop {
+ if (i % 8 == 0) {
+ col_reset();
+ wrt ' ';
+ wrt ' ';
+ wrt '1' + 7 - i / 8;
+ wrt ' ';
+ wrt ' ';
+ wrt ' ';
+ }
+
+ p = [gBoard + i];
+ if (x + y * 8 == i)
+ col_swap();
+ if black(p)
+ col_red();
+ else if p
+ col_green();
+ else
+ col_blue();
+ putstr([str_pieces + p]);
+ col_reset();
+
+ i = i + 1;
+ if (i % 8 == 0)
+ wrt '\n';
+ if (i >= BOARD_SIZE)
+ break;
+ }
+ wrt '\n';
+}
diff --git a/color.golem b/color.golem
new file mode 100644
index 0000000..bc95276
--- /dev/null
+++ b/color.golem
@@ -0,0 +1,39 @@
+col_red() {
+ wrt 0x1b;
+ return putstr("[31m");
+}
+
+col_green() {
+ wrt 0x1b;
+ return putstr("[32m");
+}
+
+col_yellow() {
+ wrt 0x1b;
+ return putstr("[33m");
+}
+
+col_blue() {
+ wrt 0x1b;
+ return putstr("[34m");
+}
+
+col_magenta() {
+ wrt 0x1b;
+ return putstr("[35m");
+}
+
+col_cyan() {
+ wrt 0x1b;
+ return putstr("[36m");
+}
+
+col_reset() {
+ wrt 0x1b;
+ return putstr("[0m");
+}
+
+col_swap() {
+ wrt 0x1b;
+ return putstr("[7m");
+}
diff --git a/egecs.golem b/egecs.golem
new file mode 100644
index 0000000..3dcc3de
--- /dev/null
+++ b/egecs.golem
@@ -0,0 +1,76 @@
+main() {
+ init_str_pieces();
+ return egecs();
+}
+
+egecs() {
+ board_init();
+ loop {
+ egecs_cycle();
+ }
+}
+
+cls() {
+ wrt 0x1b;
+ wrt 'c';
+}
+
+egecs_cycle() {
+ local from, to;
+
+ loop {
+ board_display(NULL);
+ col_green();
+ from = geadline("> ");
+ if (white(board_get(from)))
+ break;
+ if (from) {
+ free(from);
+ from = NULL;
+ }
+ }
+ loop {
+ board_display(from);
+ col_green();
+ to = geadline("> ");
+ if ((board_get(to) != INVALID) & (white(board_get(to)) == 0))
+ break;
+ if (to) {
+ free(to);
+ to = NULL;
+ }
+ }
+
+ board_set(to, board_get(from));
+ board_set(from, EMPTY);
+ free(to); to = NULL;
+ free(from); from = NULL;
+
+ loop {
+ board_display(NULL);
+ col_red();
+ from = geadline("> ");
+ if (black(board_get(from)))
+ break;
+ if (from) {
+ free(from);
+ from = NULL;
+ }
+ }
+ loop {
+ board_display(from);
+ col_red();
+ to = geadline("> ");
+ if ((board_get(to) != INVALID) & (black(board_get(to)) == 0))
+ break;
+ if (to) {
+ free(to);
+ to = NULL;
+ }
+ }
+
+ board_set(to, board_get(from));
+ board_set(from, EMPTY);
+ free(to);
+ free(from);
+}
diff --git a/iron.golem b/iron.golem
new file mode 100644
index 0000000..997c70e
--- /dev/null
+++ b/iron.golem
@@ -0,0 +1,771 @@
+aton(str)
+{
+ local i = 0;
+ local out = 0;
+
+ loop {
+ if ([str + i] != '+')
+ break;
+ i++;
+ }
+ loop {
+ if ([str + i] == 0 | isdigit([str + i]) == 0)
+ break;
+ out = out * 10 + [str + i] - '0';
+ i++;
+ }
+ return out;
+}
+aton_s(str)
+{
+ local i = 0;
+ local sign = 0;
+ local out = 0;
+
+ loop {
+ if ([str + i] == '-')
+ sign = sign == 0;
+ else if ([str + i] != '+')
+ break;
+ i++;
+ }
+ loop {
+ if ([str + i] == 0 | isdigit([str + i]) == 0)
+ break;
+ out = out * 10 + [str + i] - '0';
+ i++;
+ }
+ if (sign)
+ return (0 - out);
+ return out;
+}
+bzero(tab, size) memset(tab, size, 0);
+define NUM_MAX = 0xffff;
+define NUM_MIN = 0x0000;
+define NUM_S_MIN = 0x8000;
+define NUM_S_MAX = 0x7fff;
+define NULL = 0;
+define ZIED = NUM_MAX;
+free_tab(tab)
+{
+ local tmp = tab;
+
+ loop
+ {
+ if ([tmp] == 0)
+ return;
+ free([tmp]);
+ tmp++;
+ }
+ free(tab);
+}
+define HEAP_SIZE = 0x8000;
+global heap[HEAP_SIZE] = 0;
+
+define PADDING_SIZE = 4;
+define HEADER_SIZE = 5;
+
+πŸ—ΏHEADER REPRESENTATION
+πŸ—Ώ+-------------+--------+--------+-------------------------------+---------------------------+---------+---------+---------+
+πŸ—Ώ| initialised | used | size | pointer to the previous block | pointer to the next block | padding | data | padding |
+πŸ—Ώ| 1 case | 1 case | 1 case | 1 case | 1 case | 4 cases | n cases | 4 cases |
+πŸ—Ώ+-------------+--------+--------+-------------------------------+---------------------------+---------+---------+---------+
+
+πŸ—Ώ INITIALISED
+πŸ—Ώ a boolean to state if the block is initialised
+
+πŸ—Ώ USED
+πŸ—Ώ a boolean to state if the block is used
+
+πŸ—Ώ SIZE
+πŸ—Ώ The size of the data
+
+πŸ—Ώ POINTER
+πŸ—Ώ The address of block
+
+πŸ—Ώ PADDING
+πŸ—Ώ Is used to check invalid write
+πŸ—Ώ If a case doesn't equal to 0 it is an invalid write
+
+define LOCATION_INITIALISED = 0;
+define LOCATION_USED = 1;
+define LOCATION_SIZE = 2;
+define LOCATION_PREV = 3;
+define LOCATION_NEXT = 4;
+define LOCATION_DATA = HEADER_SIZE + PADDING_SIZE;
+
+galloc_setup_header(ptr, used, size, next_block, prev_block)
+{
+ local i;
+
+ [ptr + LOCATION_INITIALISED] = 1;
+ [ptr + LOCATION_USED] = used;
+ [ptr + LOCATION_SIZE] = size;
+ [ptr + LOCATION_PREV] = prev_block;
+ [ptr + LOCATION_NEXT] = next_block;
+
+ i = HEADER_SIZE;
+ loop
+ {
+ if (i == HEADER_SIZE + PADDING_SIZE)
+ break;
+ [ptr + i] = 0; πŸ—Ώ INITIALISE TOP PADDING
+ [ptr + i + PADDING_SIZE + size] = 0; πŸ—Ώ INITIALISE BOT PADDING
+ i++;
+ }
+}
+
+galloc_find_next_space(size)
+{
+ local current;
+
+ current = heap;
+ loop
+ {
+ if ([current + LOCATION_USED] == 0
+ & [current + LOCATION_SIZE] >= size)
+ return (current);
+ current = [current + LOCATION_NEXT];
+ if (current == 0)
+ return (0);
+ }
+}
+
+galloc_print_heap()
+{
+ local i;
+
+ i = 0;
+ loop
+ {
+ if (i == HEAP_SIZE)
+ return (0);
+ dbg [heap + i];
+ i++;
+ }
+}
+
+galloc_split_block(ptr, size)
+{
+ local old_next;
+ local next;
+ local prev;
+ local old_size;
+
+ old_size = [ptr + LOCATION_SIZE];
+ if (size + HEADER_SIZE + PADDING_SIZE * 2 > old_size) πŸ—Ώ if the block is to small to be split
+ {
+ [ptr + LOCATION_USED] = 1;
+ return (ptr);
+ }
+ old_next = [ptr + LOCATION_NEXT];
+ next = ptr + size + HEADER_SIZE + PADDING_SIZE * 2;
+ prev = [ptr + LOCATION_PREV];
+πŸ—Ώ galloc_setup_header(ptr, used, size, next_block, prev_block);
+ galloc_setup_header(ptr, 1, size, ptr + HEADER_SIZE + PADDING_SIZE * 2 + size, prev);
+ galloc_setup_header(next, 0, old_size - size - HEADER_SIZE - PADDING_SIZE * 2, old_next, ptr);
+ return (0);
+}
+
+galloc(size)
+{
+ local ptr;
+
+ if ([heap] == 0) πŸ—Ώ if the heap is not initialised
+ galloc_setup_header(heap, 0, HEAP_SIZE - HEADER_SIZE - PADDING_SIZE * 2, 0, 0); πŸ—Ώ initialised all the heap
+ ptr = galloc_find_next_space(size);
+ if (ptr == 0)
+ return (0);
+ if ([ptr + LOCATION_SIZE] == size)
+ {
+ [ptr + LOCATION_USED] = 1;
+ return (ptr + LOCATION_DATA);
+ }
+ galloc_split_block(ptr, size);
+ return (ptr + LOCATION_DATA);
+}
+
+galloc_merge_blocks(first_block, last_block)
+{
+ local size;
+
+ if (last_block == first_block)
+ {
+ galloc_setup_header(first_block, 0, [first_block + LOCATION_SIZE], [first_block + LOCATION_NEXT], [first_block + LOCATION_PREV]);
+ }
+ size = last_block - first_block + [last_block + LOCATION_SIZE];
+ galloc_setup_header(first_block, 0, size, [last_block + LOCATION_NEXT], [first_block + LOCATION_PREV]);
+}
+
+free(ptr)
+{
+ local block;
+ local prev_block;
+ local next_block;
+ local first_block;
+ local last_block;
+
+ if (ptr > heap + HEAP_SIZE | heap > ptr)
+ {
+ putstr("Error: free: invalid ptr\n");
+ return;
+ }
+ block = ptr - LOCATION_DATA;
+ prev_block = [block + LOCATION_PREV];
+ if (prev_block == 0 | [prev_block + LOCATION_USED])
+ first_block = block;
+ else
+ first_block = prev_block;
+ next_block = [block + LOCATION_NEXT];
+ if (next_block == 0 | [next_block + LOCATION_USED])
+ last_block = block;
+ else
+ last_block = next_block;
+ galloc_merge_blocks(first_block, last_block);
+}
+
+leaks()
+{
+ return ([heap + LOCATION_NEXT] != 0);
+}
+geadline(prompt) {
+ local capacity = 64,
+ size = 0,
+ i = 0,
+ c,
+ buf = galloc(capacity);
+ if (prompt)
+ putstr(prompt);
+ if (buf == NULL)
+ return NULL;
+
+ loop {
+ red &c;
+ if ((c == 0xffff) | (c == 0x04)) {
+ if ((size == 0) | (c == 0xffff)) {
+ free(buf);
+ return 0;
+ }
+ } else if (c == 0x007f) {
+ if (size) {
+ size = size - 1;
+ i = i - 1;
+ [buf + size] = 0;
+
+ wrt 0x1b;
+ wrt 0x5b;
+ wrt 0x44;
+ wrt ' ';
+ wrt 0x1b;
+ wrt 0x5b;
+ wrt 0x44;
+ }
+ } else {
+ size = size + 1;
+ if (size > capacity) {
+ buf = reallocarray(buf, capacity, capacity * 2);
+ if (buf == NULL)
+ return NULL;
+ capacity = capacity * 2;
+ }
+ [buf + i] = c;
+ i = i + 1;
+ [buf + i] = 0;
+ wrt c;
+ if (c == '\n')
+ return buf;
+ }
+ }
+}
+define GET_LINE_BUFFER=100;
+
+get_line()
+{
+ local tmp;
+ local out;
+ local c;
+ local i;
+
+ out = NULL;
+ i = 0;
+ loop
+ {
+ if (i % GET_LINE_BUFFER == 0)
+ {
+ tmp = reallocarray(out, i, i + GET_LINE_BUFFER + 1);
+ if (tmp == NULL)
+ return NULL;
+ }
+ red &c;
+ if (c == 0xffff)
+ return NULL;
+ [tmp + i] = c;
+ i++;
+ if (c == '\n')
+ break;
+ }
+ [tmp + i] = 0;
+ out = strdup(tmp);
+ free(tmp);
+ return out;
+}
+get_raw_bit(number)
+{
+ local tab = galloc(16);
+ if (tab == NULL)
+ return (NULL);
+ [tab] = number & 0x8000;
+ [tab + 1] = number & 0x4000;
+ [tab + 2] = number & 0x2000;
+ [tab + 3] = number & 0x1000;
+ [tab + 4] = number & 0x800;
+ [tab + 5] = number & 0x400;
+ [tab + 6] = number & 0x200;
+ [tab + 7] = number & 0x100;
+ [tab + 8] = number & 0x80;
+ [tab + 9] = number & 0x40;
+ [tab + 10] = number & 0x20;
+ [tab + 11] = number & 0x10;
+ [tab + 12] = number & 0x8;
+ [tab + 13] = number & 0x4;
+ [tab + 14] = number & 0x2;
+ [tab + 15] = number & 0x1;
+ return tab;
+}
+isalpha(c) return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z');
+isascii(c) return c < 128;
+isdigit(c) return c >= '0' & c <= '9';
+isalnum(c) return isalpha(c) | isdigit(c);
+isprint(c) return c >= ' ' & c <= '~';
+memset(tab, size, value)
+{
+ local i = 0;
+
+ loop {
+ if (i == size)
+ return (tab);
+ [tab + i++] = value;
+ }
+}
+ntoa_get_size(number)
+{
+ local size = 0;
+
+ if (number == 0)
+ size++;
+ loop
+ {
+ if (number == 0)
+ return (size);
+ number = number / 10;
+ size++;
+ }
+}
+
+ntoa(number)
+{
+ local str;
+ local size;
+
+ size = ntoa_get_size(number);
+ str = galloc(size + 1);
+ if (str == 0)
+ return (0);
+ [str + size] = 0;
+ if (number == 0)
+ [str] = '0';
+ loop
+ {
+ if (number == 0)
+ return (str);
+ [str + size - 1] = number % 10 + '0';
+ number = number / 10;
+ size--;
+ }
+}
+ntoa_get_size(number)
+{
+ local size = 0;
+
+ if (number == 0)
+ size++;
+ loop
+ {
+ if (number == 0)
+ return (size);
+ number = number / 10;
+ size++;
+ }
+}
+
+ntoa_s(number)
+{
+ local str, sign, size;
+
+ if (number >= 0x8000)
+ {
+ number = 0 - number;
+ sign = 1;
+ }
+ size = ntoa_get_size(number);
+ if (sign)
+ size++;
+ str = galloc(size + 1);
+ if (str == 0)
+ return (0);
+ [str + size] = 0;
+ if (sign)
+ [str] = '-';
+ else if (number == 0)
+ [str] = '0';
+ loop
+ {
+ if (number == 0)
+ return (str);
+ [str + size - 1] = number % 10 + '0';
+ number = number / 10;
+ size--;
+ }
+}
+print_raw_bit(number)
+{
+ local tab = get_raw_bit(number), i = 0;
+ puttab_num(tab, 16);
+ free(tab);
+}
+putchar(c) wrt c;
+putnum(number)
+{
+ local str;
+ str = ntoa(number);
+ if (str == 0)
+ return;
+ putstr(str);
+ free(str);
+}
+putnum_s(num_s)
+{
+ local str = ntoa_s(num_s);
+ putstr(str);
+ free(str);
+}
+putstr(str)
+{
+ local i = 0;
+ loop {
+ if ([str + i] == 0)
+ return;
+ putchar([str + i]);
+ i++;
+ }
+}
+puttab_str(tab)
+{
+ local tmp = tab;
+
+ putchar('[');
+ loop
+ {
+ if ([tmp] == 0)
+ break;
+ putchar('"');
+ putstr([tmp]);
+ putchar('"');
+ if ([tmp + 1] != 0)
+ putstr(", ");
+ tmp++;
+ }
+ putchar(']');
+}
+
+puttab_num(tab, size)
+{
+ local i = 0;
+
+ putchar('[');
+ loop
+ {
+ if (i == size)
+ break;
+ putnum([tab + i]);
+ i++;
+ if (i != size)
+ putstr(", ");
+ }
+ putchar(']');
+}
+reallocarray(ptr, nmemb, size)
+{
+ local tmp;
+ local start;
+
+ start = ptr;
+ tmp = galloc(size);
+ if (tmp == NULL)
+ return NULL;
+ if (ptr == NULL)
+ return tmp;
+ loop
+ {
+ if (start - ptr == nmemb)
+ break;
+ [tmp + start - ptr] = [start];
+ start++;
+ }
+ free(ptr);
+ return tmp;
+}
+replace(str, fill, start, stop)
+{
+ local out;
+ local sum;
+
+ out = galloc(strlen(str) + strlen(fill) - (stop - start) + 1);
+ if (out == NULL)
+ return (NULL);
+ strncpy(out, str, start);
+ strncpy(out + start, fill, strlen(fill));
+ sum = start + strlen(fill);
+ strncpy(out + sum, str + stop, strlen(str) - stop);
+ [out + sum + strlen(str) - stop] = 0;
+ return (out);
+}
+split_delimiter_size(str, delimiter, delimiter_len)
+{
+ local i = 0;
+ loop
+ {
+ if (strncmp(str + i, delimiter, delimiter_len) != 0 | delimiter_len == 0)
+ return (i);
+ i = i + delimiter_len;
+ }
+}
+
+split_get_size_need(str, delimiter)
+{
+ local tmp = str;
+ local len = 0;
+ local delimiter_len = strlen(delimiter);
+
+ loop
+ {
+ len++;
+ tmp = strstr(tmp, delimiter);
+ if (tmp == 0 | [tmp] == 0)
+ return (len);
+ tmp = tmp + split_delimiter_size(tmp, delimiter, delimiter_len);
+ }
+}
+
+split_fill_tab(tab, str, delimiter, delimiter_len)
+{
+ local tab_tmp = tab;
+ local tmp = str;
+ local next;
+
+ loop
+ {
+ next = strstr(tmp, delimiter);
+ if (next != 0)
+ [tab_tmp] = strndup(tmp, next - tmp);
+ else
+ [tab_tmp] = strdup(tmp);
+ if ([tab_tmp] == 0)
+ {
+ free_tab(tab);
+ return (1);
+ }
+ if (next == 0 | [next] == 0)
+ return (0);
+ tmp = next + split_delimiter_size(next, delimiter, delimiter_len);
+ tab_tmp++;
+ }
+}
+
+split(str, delimiter)
+{
+ local len, tab, delimiter_len;
+
+ delimiter_len = strlen(delimiter);
+ len = split_get_size_need(str, delimiter);
+ tab = galloc(len + 1);
+ if (tab == 0)
+ return (0);
+ [tab + len] = 0;
+ if (split_fill_tab(tab, str, delimiter, delimiter_len))
+ {
+ free(tab);
+ return (0);
+ }
+ return (tab);
+}
+strcat(dst, src)
+{
+ local i = 0;
+ local j = 0;
+
+ loop {
+ if ([dst + i] == 0)
+ break;
+ i++;
+ }
+ loop {
+ if ([src + j] == 0)
+ break;
+ [dst + i + j] = [src + j];
+ j++;
+ }
+ [dst + i + j] = 0;
+ return j;
+}
+strchr(str, c)
+{
+ local i = 0;
+
+ loop {
+ if ([str + i] == c)
+ return (str + i);
+ if ([str + i] == 0)
+ return (0);
+ i++;
+ }
+}
+strchri(str, c)
+{
+ local i = 0;
+
+ loop {
+ if ([str + i] == c)
+ return (i);
+ if ([str + i] == 0)
+ return (0 - 1);
+ i++;
+ }
+}
+strcmp(s1, s2)
+{
+ local i = 0;
+
+ loop {
+ if ([s1 + i] != [s2 + i] | [s1 + i] == 0 | [s2 + i] == 0)
+ return ([s1 + i] - [s2 + i]);
+ i++;
+ }
+}
+strcpy(dst, src)
+{
+ local i = 0;
+
+ loop {
+ if ([src + i] == 0)
+ break;
+ [dst + i] = [src + i];
+ i++;
+ }
+ [dst + i] = 0;
+ return i;
+}
+strdup(str)
+{
+ local out;
+
+ out = galloc(strlen(str) + 1);
+ if (out == 0)
+ return (0);
+ strcpy(out, str);
+ return (out);
+}
+strlen(str) {
+ local i = 0;
+
+ loop {
+ if ([str + i] == 0)
+ return (i);
+ i++;
+ }
+}
+strncmp(s1, s2, n)
+{
+ local i;
+
+ if (n-- == 0)
+ return (0);
+ i = 0;
+ loop
+ {
+ if (i == n | [s1 + i] != [s2 + i] | [s1 + i] == 0 | [s2 + i] == 0)
+ return ([s1 + i] - [s2 + i]);
+ i++;
+ }
+}
+strncpy(dst, src, size)
+{
+ local i = 0;
+
+ loop {
+ if ([src + i] == 0 | i >= size)
+ break;
+ [dst + i] = [src + i];
+ i++;
+ }
+ [dst + i] = 0;
+ return i;
+}
+strndup(str, n)
+{
+ local i = 0;
+ local out;
+ local size;
+
+ size = strlen(str);
+ if (size > n)
+ size = n;
+ out = galloc(size + 1);
+ if (out == 0)
+ return (0);
+ [out + size] = 0;
+ strncpy(out, str, size);
+ return (out);
+}
+strstr(str, to_find)
+{
+ local to_find_size;
+ local tmp;
+
+ to_find_size = strlen(to_find);
+ loop
+ {
+ tmp = strchr(str, [to_find]);
+ if (tmp == 0)
+ return (0);
+ if (strncmp(tmp, to_find, to_find_size) == 0)
+ return (tmp);
+ }
+}
+tabcmp_str(tab1, tab2)
+{
+ local i = 0;
+
+ loop
+ {
+ if (strcmp([tab1 + i], [tab2 + i]) | [tab1 + i] == 0)
+ return ([tab1 + i] - [tab2 + i]);
+ i++;
+ }
+}
+
+tabcmp_num(tab1, tab2, size)
+{
+ local i = 0;
+
+ if (size == 0)
+ return (0);
+ loop
+ {
+ if (i == size & [tab1 + i] == [tab2 + i])
+ return ([tab1 + i] - [tab2 + i]);
+ i++;
+ }
+}
+tolower(c) return c + 32 * (c >= 'A' & c <= 'Z');
+toupper(c) return c - 32 * (c >= 'a' & c <= 'z');
diff --git a/pieces.golem b/pieces.golem
new file mode 100644
index 0000000..5952344
--- /dev/null
+++ b/pieces.golem
@@ -0,0 +1,32 @@
+global str_pieces[16] = 0;
+init_str_pieces() {
+ [str_pieces + EMPTY] = "β–‘ ";
+ [str_pieces + (WHITE | KING)] = "β™” ";
+ [str_pieces + (WHITE | QUEEN)] = "β™• ";
+ [str_pieces + (WHITE | ROOK)] = "β™– ";
+ [str_pieces + (WHITE | BISHOP)] = "β™— ";
+ [str_pieces + (WHITE | KNIGHT)] = "β™˜ ";
+ [str_pieces + (WHITE | PAWN)] = "β™™ ";
+ [str_pieces + (BLACK | KING)] = "β™š ";
+ [str_pieces + (BLACK | QUEEN)] = "β™› ";
+ [str_pieces + (BLACK | ROOK)] = "β™œ ";
+ [str_pieces + (BLACK | BISHOP)] = "♝ ";
+ [str_pieces + (BLACK | KNIGHT)] = "β™ž ";
+ [str_pieces + (BLACK | PAWN)] = "β™Ÿ ";
+}
+
+define EMPTY = 0;
+define KING = 1;
+define QUEEN = 2;
+define ROOK = 3;
+define BISHOP = 4;
+define KNIGHT = 5;
+define PAWN = 6;
+define TYPE = 7;
+define WHITE = 0;
+define BLACK = 8;
+define INVALID = 0xffff;
+
+piece(color, type) => color | type;
+black(piece) => (piece & BLACK) != 0;
+white(piece) => piece != 0 & ((piece & BLACK) == 0);
diff --git a/run.sh b/run.sh
new file mode 100755
index 0000000..c11879f
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,5 @@
+rm -f tmp.*
+cat *.golem >tmp.golem
+golemc tmp.golem >tmp.asm
+orgaasm tmp.asm tmp.rom
+orgaemu tmp.rom