Compare commits
91 Commits
6ff71db96a
...
master
Author | SHA1 | Date | |
---|---|---|---|
e417a01f9a | |||
21c78421a4 | |||
f05f3945fe | |||
ba9c1f8c11 | |||
7f6225d8dd | |||
0b09f0d262 | |||
69a044b3fa | |||
e9bf776069 | |||
ed23a887f9 | |||
4bd9f50bd4 | |||
58f9c0cf9e | |||
cc965024d6 | |||
2421c51116 | |||
78bc62c044 | |||
57de93e799 | |||
9a23536491 | |||
54370e872e | |||
106d2da5a0 | |||
c41ebf6ff5 | |||
a84415a953 | |||
470b97446b | |||
09e0d32c15 | |||
2b97d38b7e | |||
cb41e69bdb | |||
cc53b0cda5 | |||
a432fd32c5 | |||
15d00356e4 | |||
c4ce5b8566 | |||
1452a70b85 | |||
575ed7aa64 | |||
46d7e9c85c | |||
ee80b05d10 | |||
2fab31d822 | |||
a7e050c351 | |||
a39e4a780d | |||
0c782738cc | |||
1a1251b512 | |||
d3e788868a | |||
5dcace0cbe | |||
85aeaebc7a | |||
3443ed76e8 | |||
6051375f6a | |||
fa5a7755e4 | |||
3c39d72bbe | |||
1d9de5df65 | |||
c688cfc4b1 | |||
f9fa2a5a12 | |||
c6608ad4eb | |||
7e0c7180d3 | |||
1f60f4eab0 | |||
357da752fc | |||
f79262b803 | |||
ff389a1719 | |||
4020de85e2 | |||
752d4bcbd1 | |||
8c9e218e86 | |||
57e78cb70a | |||
0a152b9bef | |||
7d6e6c79db | |||
85a5b567b2 | |||
1b878db8fe | |||
8c972a3096 | |||
764761a58f | |||
c6728cfe49 | |||
a49499e78e | |||
22c500564a | |||
d0f4398f78 | |||
e7a752458f | |||
370657c291 | |||
3e51e2f661 | |||
889006903b | |||
4f0d18ee68 | |||
29c3992343 | |||
879d6f3ea2 | |||
54523b29c0 | |||
000c324568 | |||
5984847cfe | |||
8eea6251ce | |||
8e437695a0 | |||
7ad95aa11e | |||
9961196e0f | |||
8966db1c22 | |||
496b92aed9 | |||
60ca301082 | |||
cea014d97b | |||
15c3f07692 | |||
9d349d1528 | |||
a69a870d49 | |||
137eaac64f | |||
1df3e20531 | |||
76c659e6a3 |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
IronGolem.asm
|
||||
IronGolem.🗿
|
||||
tmp.*
|
36
README.md
Normal file
36
README.md
Normal file
@ -0,0 +1,36 @@
|
||||
# IronGOLEM
|
||||
librairy for [Golem Programming Language](https://golem.re)
|
||||
|
||||
## How to use in your projet
|
||||
You can simply add the [latest release](https://git.chauvet.pro/starnakin/IronGOLEM/releases) to your golem projet and merge IronGolem.asm with your own .asm
|
||||
|
||||
## Requirements
|
||||
- [orga](https://kdx.re/cgit/orga/)
|
||||
- [golem](https://kdx.re/cgit/golem/)
|
||||
|
||||
## Build
|
||||
``` bash
|
||||
./run.sh
|
||||
```
|
||||
|
||||
## Fonctions list
|
||||
- [aton](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/aton)
|
||||
- [aton_s](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/aton_s)
|
||||
- [bzero](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/bzero)
|
||||
- [galloc](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/galloc)
|
||||
- [free](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/free)
|
||||
- [leaks](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/leaks)
|
||||
- [ntoa](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/ntoa)
|
||||
- [ntoa_s](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/ntoa_s)
|
||||
- [geadline](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/geadline)
|
||||
- [geadline2](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/geadline2)
|
||||
- [strcat](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/strcat)
|
||||
- [strcpy](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/strcpy)
|
||||
- [strncpy](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/strncpy)
|
||||
- [strlen](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/strlen)
|
||||
- [strncmp](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/strncmp)
|
||||
- [strcmp](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/strcmp)
|
||||
- [strchr](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/strchr)
|
||||
- [strstr](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/strstr)
|
||||
- [strndup](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/strndup)
|
||||
- [strdup](https://git.chauvet.pro/starnakin/IronGOLEM/wiki/strdup)
|
8
run.sh
8
run.sh
@ -1,4 +1,4 @@
|
||||
cat src/* >tmp.🗿
|
||||
golemc tmp.🗿 >tmp.asm
|
||||
orgaasm tmp.asm tmp.rom
|
||||
orgaemu tmp.rom
|
||||
cat src/* > IronGolem.🗿
|
||||
golemc IronGolem.🗿 > IronGolem.asm
|
||||
# orgaasm tmp.asm tmp.rom
|
||||
# orgaemu tmp.rom
|
||||
|
25
src/atoi.🗿
25
src/atoi.🗿
@ -1,25 +0,0 @@
|
||||
atoi(str)
|
||||
{
|
||||
local i;
|
||||
local sign;
|
||||
local out;
|
||||
out = 0;
|
||||
sign = 0;
|
||||
i = 0;
|
||||
loop {
|
||||
if ([str + i] == '-')
|
||||
sign = sign == 0;
|
||||
else if ([str + i] != '+')
|
||||
break;
|
||||
i = i + 1;
|
||||
}
|
||||
loop {
|
||||
if ([str + i] == 0 | isdigit([str + i]) == 0)
|
||||
break;
|
||||
out = out * 10 + [str + i] - '0';
|
||||
i = i + 1;
|
||||
}
|
||||
if (sign)
|
||||
return (0 - out);
|
||||
return out;
|
||||
}
|
16
src/aton.🗿
Normal file
16
src/aton.🗿
Normal file
@ -0,0 +1,16 @@
|
||||
aton(str)
|
||||
{
|
||||
local out = 0;
|
||||
|
||||
loop {
|
||||
if ([str] != '+')
|
||||
break;
|
||||
str++;
|
||||
}
|
||||
loop {
|
||||
if ([str] == 0 | isdigit([str]) == 0)
|
||||
return out;
|
||||
out = out * 10 + [str] - '0';
|
||||
str++;
|
||||
}
|
||||
}
|
19
src/aton_s.🗿
Normal file
19
src/aton_s.🗿
Normal file
@ -0,0 +1,19 @@
|
||||
aton_s(str)
|
||||
{
|
||||
local sign = 0;
|
||||
local out = 0;
|
||||
|
||||
loop {
|
||||
if ([str] == '-')
|
||||
sign = sign == 0;
|
||||
else if ([str] != '+')
|
||||
break;
|
||||
str++;
|
||||
}
|
||||
loop {
|
||||
if ([str] == 0 | isdigit([str]) == 0)
|
||||
return (sign * (0 - out)) | ((sign == 0) * out);
|
||||
out = out * 10 + [str] - '0';
|
||||
str++;
|
||||
}
|
||||
}
|
@ -1 +1 @@
|
||||
bzero(tab, size) memset(tab, size, 0);
|
||||
bzero(tab, size) => memset(tab, size, 0);
|
||||
|
11
src/contain_only.🗿
Normal file
11
src/contain_only.🗿
Normal file
@ -0,0 +1,11 @@
|
||||
contain_only(to_big, to_find)
|
||||
{
|
||||
loop
|
||||
{
|
||||
if ([to_big] == 0)
|
||||
return 1;
|
||||
if (strchr(to_find, [to_big]) == 0)
|
||||
return 0;
|
||||
to_big++;
|
||||
}
|
||||
}
|
9
src/define.🗿
Normal file
9
src/define.🗿
Normal file
@ -0,0 +1,9 @@
|
||||
enum MAP_KEY, MAP_VALUE;
|
||||
define MAP_SIZE=2;
|
||||
|
||||
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;
|
13
src/free_tab.🗿
Normal file
13
src/free_tab.🗿
Normal file
@ -0,0 +1,13 @@
|
||||
free_tab(tab)
|
||||
{
|
||||
local tmp = tab;
|
||||
|
||||
loop
|
||||
{
|
||||
if ([tmp] == 0)
|
||||
return;
|
||||
free([tmp]);
|
||||
tmp++;
|
||||
}
|
||||
return free(tab);
|
||||
}
|
51
src/galgrind.🗿
Normal file
51
src/galgrind.🗿
Normal file
@ -0,0 +1,51 @@
|
||||
invalid_write(ptr, i)
|
||||
{
|
||||
if (i < GALLOC_PADDING_SIZE & [ptr + GALLOC_HEADER_SIZE + i])
|
||||
return ptr + GALLOC_HEADER_SIZE + i;
|
||||
if (i >= GALLOC_PADDING_SIZE & [ptr + GALLOC_DATA + i - GALLOC_PADDING_SIZE + [ptr + GALLOC_SIZE]])
|
||||
return ptr + GALLOC_DATA + i - GALLOC_PADDING_SIZE + [ptr + GALLOC_SIZE];
|
||||
return 0;
|
||||
}
|
||||
|
||||
galgrind()
|
||||
{
|
||||
local ptr = heap;
|
||||
local i;
|
||||
|
||||
loop
|
||||
{
|
||||
if (ptr == NULL)
|
||||
return 0;
|
||||
if ([ptr + GALLOC_USED] == 1)
|
||||
{
|
||||
putstr("block: ");
|
||||
putnum(ptr - heap);
|
||||
putstr(", size: ");
|
||||
putnum([ptr + GALLOC_SIZE]);
|
||||
putstr("cases");
|
||||
putstr(", start: ");
|
||||
putnum(ptr - heap + GALLOC_DATA);
|
||||
putstr(", end: ");
|
||||
putnum(ptr - heap + GALLOC_DATA + [ptr + GALLOC_SIZE]);
|
||||
putstr(", start galloc block: ");
|
||||
putnum(ptr - heap);
|
||||
putstr(", end galloc block: ");
|
||||
putnum(ptr - heap + GALLOC_DATA + [ptr + GALLOC_SIZE] + GALLOC_PADDING_SIZE);
|
||||
putchar('\n');
|
||||
i = 0;
|
||||
loop
|
||||
{
|
||||
if (i == GALLOC_PADDING_SIZE * 2)
|
||||
break;
|
||||
if (invalid_write(ptr, i))
|
||||
{
|
||||
putnum(invalid_write(ptr, i) - heap);
|
||||
putchar('\n');
|
||||
}
|
||||
i++;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
ptr = [ptr + GALLOC_NEXT];
|
||||
}
|
||||
}
|
151
src/galloc.🗿
151
src/galloc.🗿
@ -1,14 +1,14 @@
|
||||
define PADDING_SIZE = 4;
|
||||
define HEADER_SIZE = 13; 🗿 PADDING_SIZE * 2 + 5
|
||||
define HEAP_SIZE = 0x4000;
|
||||
global heap[HEAP_SIZE] = 0;
|
||||
|
||||
define HEAP_SIZE = 65536;
|
||||
global heap[65536] = 0;
|
||||
define GALLOC_PADDING_SIZE = 4;
|
||||
define GALLOC_HEADER_SIZE = 5;
|
||||
|
||||
🗿HEADER REPRESENTATION
|
||||
🗿+-------------+--------+--------+---------------------------+-------------------------------+---------+---------+---------+
|
||||
🗿| initialised | used | size | pointer to the next block | pointer to the previous block | padding | data | padding |
|
||||
🗿+-------------+--------+--------+-------------------------------+---------------------------+---------+---------+---------+
|
||||
🗿| 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
|
||||
@ -26,81 +26,140 @@ global heap[65536] = 0;
|
||||
🗿 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_NEXT = 3;
|
||||
define LOCATION_PREV = 4;
|
||||
define LOCATION_DATA = 9;
|
||||
enum GALLOC_INITIALISED, GALLOC_USED, GALLOC_SIZE, GALLOC_PREV, GALLOC_NEXT;
|
||||
define GALLOC_DATA = GALLOC_HEADER_SIZE + GALLOC_PADDING_SIZE;
|
||||
|
||||
setup_header(ptr, used, size, next_block, prev_block)
|
||||
galloc_setup_header(ptr, used, size, next_block, prev_block)
|
||||
{
|
||||
local i;
|
||||
|
||||
if (size + PADDING_SIZE * 2 + HEADER_SIZE)
|
||||
return (1);
|
||||
[ptr] = 1; 🗿 initialised
|
||||
[ptr + 1] = used; 🗿 used
|
||||
[ptr + 2] = size; 🗿 size
|
||||
[ptr + 3] = next_block; 🗿 next block
|
||||
[ptr + 4] = prev_block; 🗿 previous block
|
||||
[ptr + GALLOC_INITIALISED] = 1;
|
||||
[ptr + GALLOC_USED] = used;
|
||||
[ptr + GALLOC_SIZE] = size;
|
||||
[ptr + GALLOC_PREV] = prev_block;
|
||||
[ptr + GALLOC_NEXT] = next_block;
|
||||
|
||||
i = header_size;
|
||||
i = GALLOC_HEADER_SIZE;
|
||||
loop
|
||||
{
|
||||
if (i == protection_size)
|
||||
if (i == GALLOC_HEADER_SIZE + GALLOC_PADDING_SIZE)
|
||||
break;
|
||||
[ptr + i] = 0;
|
||||
[ptr + i + size] = 0;
|
||||
[ptr + i + GALLOC_HEADER_SIZE] = 0; 🗿 INITIALISE TOP PADDING
|
||||
[ptr + i + GALLOC_PADDING_SIZE + size] = 0; 🗿 INITIALISE BOT PADDING
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
find_next_space(size)
|
||||
galloc_find_next_space(size)
|
||||
{
|
||||
local current;
|
||||
|
||||
current = heap;
|
||||
loop
|
||||
{
|
||||
if ([current + LOCATION_USED] == 0
|
||||
& [current + LOCATION_SIZE] >= size)
|
||||
if ([current + GALLOC_USED] == 0
|
||||
& [current + GALLOC_SIZE] >= size)
|
||||
return (current);
|
||||
current = [current + LOCATION_NEXT];
|
||||
if ([current] == 0)
|
||||
current = [current + GALLOC_NEXT];
|
||||
if (current == 0)
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
divise_block(ptr, size)
|
||||
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;
|
||||
|
||||
if (size + HEADER_SIZE >= [ptr + LOCATION_SIZE])
|
||||
return (0);
|
||||
old_next = [ptr + LOCATION_NEXT];
|
||||
next = [ptr + size + HEADER_SIZE];
|
||||
setup_header(next, 0, [ptr + LOCATION_SIZE] - HEADER_SIZE * 2, [ptr + LOCATION_SIZE] + HEADER_SIZE, old_next, ptr);
|
||||
setup_header(ptr, 1, size, next, [ptr + LOCATION_PREV]);
|
||||
old_size = [ptr + GALLOC_SIZE];
|
||||
if (size + GALLOC_HEADER_SIZE + GALLOC_PADDING_SIZE * 2 > old_size) 🗿 if the block is to small to be split
|
||||
{
|
||||
[ptr + GALLOC_USED] = 1;
|
||||
return (ptr);
|
||||
}
|
||||
old_next = [ptr + GALLOC_NEXT];
|
||||
next = ptr + size + GALLOC_HEADER_SIZE + GALLOC_PADDING_SIZE * 2;
|
||||
prev = [ptr + GALLOC_PREV];
|
||||
🗿 galloc_setup_header(ptr, used, size, next_block, prev_block);
|
||||
galloc_setup_header(ptr, 1, size, ptr + GALLOC_HEADER_SIZE + GALLOC_PADDING_SIZE * 2 + size, prev);
|
||||
galloc_setup_header(next, 0, old_size - size - GALLOC_HEADER_SIZE - GALLOC_PADDING_SIZE * 2, old_next, ptr);
|
||||
return (0);
|
||||
}
|
||||
|
||||
salloc(size)
|
||||
galloc(size)
|
||||
{
|
||||
local ptr;
|
||||
|
||||
if ([heap] == 0) 🗿 if the heap is not initialised
|
||||
setup_header(HEAP_SIZE - 2 * PADDING_SIZE - HEADER_SIZE, 0, 0, 0); 🗿 initialised all the heap
|
||||
ptr = find_next_space(size);
|
||||
galloc_setup_header(heap, 0, HEAP_SIZE - GALLOC_HEADER_SIZE - GALLOC_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)
|
||||
if ([ptr + GALLOC_SIZE] == size)
|
||||
{
|
||||
[ptr + LOCATION_USED] = 1;
|
||||
return (ptr + LOCATION_DATA);
|
||||
[ptr + GALLOC_USED] = 1;
|
||||
return (ptr + GALLOC_DATA);
|
||||
}
|
||||
divise_block(ptr, size);
|
||||
return (ptr);
|
||||
galloc_split_block(ptr, size);
|
||||
return (ptr + GALLOC_DATA);
|
||||
}
|
||||
|
||||
galloc_merge_blocks(first_block, last_block)
|
||||
{
|
||||
local size;
|
||||
|
||||
if (last_block == first_block)
|
||||
{
|
||||
galloc_setup_header(first_block, 0, [first_block + GALLOC_SIZE], [first_block + GALLOC_NEXT], [first_block + GALLOC_PREV]);
|
||||
}
|
||||
size = last_block - first_block + [last_block + GALLOC_SIZE];
|
||||
galloc_setup_header(first_block, 0, size, [last_block + GALLOC_NEXT], [first_block + GALLOC_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 - GALLOC_DATA;
|
||||
prev_block = [block + GALLOC_PREV];
|
||||
if (prev_block == 0 | [prev_block + GALLOC_USED])
|
||||
first_block = block;
|
||||
else
|
||||
first_block = prev_block;
|
||||
next_block = [block + GALLOC_NEXT];
|
||||
if (next_block == 0 | [next_block + GALLOC_USED])
|
||||
last_block = block;
|
||||
else
|
||||
last_block = next_block;
|
||||
galloc_merge_blocks(first_block, last_block);
|
||||
}
|
||||
|
||||
leaks()
|
||||
{
|
||||
return ([heap + GALLOC_NEXT] != 0);
|
||||
}
|
||||
|
132
src/geadline.🗿
Normal file
132
src/geadline.🗿
Normal file
@ -0,0 +1,132 @@
|
||||
geadline2(prompt, text)
|
||||
{
|
||||
local capacity = 64,
|
||||
size = 0,
|
||||
i = 0,
|
||||
c,
|
||||
a,
|
||||
buf;
|
||||
if (text) {
|
||||
size = strlen(text);
|
||||
i = size;
|
||||
loop {
|
||||
if (capacity > size)
|
||||
break;
|
||||
capacity = capacity * 2;
|
||||
}
|
||||
buf = galloc(capacity);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
strcpy(buf, text);
|
||||
} else {
|
||||
buf = galloc(capacity);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
[buf] = 0;
|
||||
}
|
||||
if (prompt)
|
||||
putstr(prompt);
|
||||
putstr(buf);
|
||||
|
||||
loop {
|
||||
c = getchar();
|
||||
if ((c == 0xffff) | (c == 0x04)) {
|
||||
if ((size == 0) | (c == 0xffff)) {
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
} else if (c == 0x1b) {
|
||||
// ESC code
|
||||
getchar(); // skip [
|
||||
c = getchar(); // value
|
||||
|
||||
if ((c == 'A') & (size > 0)) {
|
||||
loop {
|
||||
if (i == 0)
|
||||
break;
|
||||
i = i - 1;
|
||||
esccode('D');
|
||||
}
|
||||
} else if ((c == 'B') & (i < size)) {
|
||||
loop {
|
||||
if (i >= size)
|
||||
break;
|
||||
i = i + 1;
|
||||
esccode('C');
|
||||
}
|
||||
} else if ((c == 'C') & (i < size)) {
|
||||
i = i + 1;
|
||||
esccode('C');
|
||||
} else if ((c == 'D') & (i > 0)) {
|
||||
i = i - 1;
|
||||
esccode('D');
|
||||
}
|
||||
wrt '\a';
|
||||
} else if (c == 0x7f) {
|
||||
if (i) {
|
||||
a = i - 1;
|
||||
loop {
|
||||
if (a >= size)
|
||||
break;
|
||||
[buf + a] = [buf + a + 1];
|
||||
a = a + 1;
|
||||
}
|
||||
size = size - 1;
|
||||
i = i - 1;
|
||||
[buf + size] = 0;
|
||||
|
||||
wrt '\r';
|
||||
if (prompt)
|
||||
putstr(prompt);
|
||||
putstr(buf);
|
||||
wrt ' ';
|
||||
esccode('D');
|
||||
a = size - i;
|
||||
loop {
|
||||
if (a == 0)
|
||||
break;
|
||||
a = a - 1;
|
||||
esccode('D');
|
||||
}
|
||||
}
|
||||
} else if (c == '\n') {
|
||||
wrt '\n';
|
||||
return buf;
|
||||
} else {
|
||||
size = size + 1;
|
||||
if (size >= capacity) {
|
||||
buf = realloc(buf, capacity * 2);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
capacity = capacity * 2;
|
||||
}
|
||||
a = size - i - 1;
|
||||
loop {
|
||||
if ((a == 0xffff) | (a == 0))
|
||||
break;
|
||||
[buf + i + a] = [buf + i + a - 1];
|
||||
a = a - 1;
|
||||
}
|
||||
[buf + i] = c;
|
||||
[buf + size] = 0;
|
||||
putstr(buf + i);
|
||||
a = strlen(buf + i) - 1;
|
||||
loop {
|
||||
if ((a == 0xffff) | (a == 0))
|
||||
break;
|
||||
a = a - 1;
|
||||
esccode('D');
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
geadline(prompt) => geadline2(prompt, NULL);
|
||||
|
||||
esccode(c)
|
||||
{
|
||||
wrt 0x1b;
|
||||
wrt '[';
|
||||
wrt c;
|
||||
}
|
23
src/get_raw_bit.🗿
Normal file
23
src/get_raw_bit.🗿
Normal file
@ -0,0 +1,23 @@
|
||||
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;
|
||||
}
|
6
src/getchar.🗿
Normal file
6
src/getchar.🗿
Normal file
@ -0,0 +1,6 @@
|
||||
getchar()
|
||||
{
|
||||
local c;
|
||||
red &c;
|
||||
return c;
|
||||
}
|
@ -1 +1 @@
|
||||
isalpha(c) return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z');
|
||||
isalpha(c) => (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z');
|
||||
|
@ -1 +1 @@
|
||||
isascii(c) return c < 128;
|
||||
isascii(c) => c < 128;
|
||||
|
@ -1 +1 @@
|
||||
isdigit(c) return c >= '0' & c <= '9';
|
||||
isdigit(c) => c >= '0' & c <= '9';
|
||||
|
@ -1 +1 @@
|
||||
isalnum(c) return isalpha(c) | isdigit(c);
|
||||
isalnum(c) => isalpha(c) | isdigit(c);
|
||||
|
@ -1 +1 @@
|
||||
isprint(c) return c >= ' ' & c <= '~';
|
||||
isprint(c) => c >= ' ' & c <= '~';
|
||||
|
@ -1,11 +1,11 @@
|
||||
memset(tab, size, value)
|
||||
{
|
||||
local i;
|
||||
i = 0;
|
||||
local i = 0;
|
||||
|
||||
loop {
|
||||
if (i == size)
|
||||
return (tab);
|
||||
[tab + i] = value;
|
||||
i = i + 1;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
36
src/ntoa.🗿
Normal file
36
src/ntoa.🗿
Normal file
@ -0,0 +1,36 @@
|
||||
ntoa_get_size(number)
|
||||
{
|
||||
local size = 0;
|
||||
|
||||
if (number == 0)
|
||||
return 1;
|
||||
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);
|
||||
size--;
|
||||
[str + size] = number % 10 + '0';
|
||||
number = number / 10;
|
||||
}
|
||||
}
|
29
src/ntoa_s.🗿
Normal file
29
src/ntoa_s.🗿
Normal file
@ -0,0 +1,29 @@
|
||||
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--;
|
||||
}
|
||||
}
|
6
src/print_raw_bit.🗿
Normal file
6
src/print_raw_bit.🗿
Normal file
@ -0,0 +1,6 @@
|
||||
print_raw_bit(number)
|
||||
{
|
||||
local tab = get_raw_bit(number);
|
||||
puttab_num(tab, 16);
|
||||
free(tab);
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
putchar(c){
|
||||
putchar(c)
|
||||
{
|
||||
wrt c;
|
||||
return c;
|
||||
}
|
||||
|
6
src/putnum.🗿
Normal file
6
src/putnum.🗿
Normal file
@ -0,0 +1,6 @@
|
||||
putnum(number)
|
||||
{
|
||||
local str = ntoa(number);
|
||||
putstr(str);
|
||||
free(str);
|
||||
}
|
6
src/putnum_s.🗿
Normal file
6
src/putnum_s.🗿
Normal file
@ -0,0 +1,6 @@
|
||||
putnum_s(num_s)
|
||||
{
|
||||
local str = ntoa_s(num_s);
|
||||
putstr(str);
|
||||
free(str);
|
||||
}
|
15
src/putstr.🗿
15
src/putstr.🗿
@ -1,11 +1,14 @@
|
||||
putstr(str)
|
||||
{
|
||||
local i;
|
||||
i = 0;
|
||||
local tmp = str;
|
||||
if (str == NULL) {
|
||||
putstr("(null)");
|
||||
return NULL;
|
||||
}
|
||||
loop {
|
||||
if ([str + i] == 0)
|
||||
return;
|
||||
putchar([str + i]);
|
||||
i = i + 1;
|
||||
if ([tmp] == 0)
|
||||
return str;
|
||||
putchar([tmp]);
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
|
35
src/puttab.🗿
Normal file
35
src/puttab.🗿
Normal file
@ -0,0 +1,35 @@
|
||||
puttab_str(tab)
|
||||
{
|
||||
putchar('[');
|
||||
loop
|
||||
{
|
||||
if ([tab] == 0) {
|
||||
putchar(']');
|
||||
return;
|
||||
}
|
||||
putchar('"');
|
||||
putstr([tab]);
|
||||
putchar('"');
|
||||
tab++;
|
||||
if ([tab] != 0)
|
||||
putstr(", ");
|
||||
}
|
||||
}
|
||||
|
||||
puttab_num(tab, size)
|
||||
{
|
||||
local i = 0;
|
||||
|
||||
putchar('[');
|
||||
loop
|
||||
{
|
||||
if (i == size) {
|
||||
putchar(']');
|
||||
return;
|
||||
}
|
||||
putnum([tab + i]);
|
||||
i++;
|
||||
if (i != size)
|
||||
putstr(", ");
|
||||
}
|
||||
}
|
26
src/realloc.🗿
Normal file
26
src/realloc.🗿
Normal file
@ -0,0 +1,26 @@
|
||||
realloc(ptr, new_size)
|
||||
{
|
||||
local block_ptr;
|
||||
local new_space;
|
||||
local i;
|
||||
|
||||
new_space = galloc(new_size);
|
||||
if (new_space == NULL)
|
||||
{
|
||||
free(ptr);
|
||||
return (NULL);
|
||||
}
|
||||
if (ptr == NULL)
|
||||
return new_space;
|
||||
block_ptr = ptr - GALLOC_DATA;
|
||||
i = 0;
|
||||
loop
|
||||
{
|
||||
if (i == new_size | i == [block_ptr + GALLOC_SIZE])
|
||||
break;
|
||||
[new_space + i] = [ptr + i];
|
||||
i++;
|
||||
}
|
||||
free(ptr);
|
||||
return new_space;
|
||||
}
|
15
src/replace_index.🗿
Normal file
15
src/replace_index.🗿
Normal file
@ -0,0 +1,15 @@
|
||||
replace_index(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);
|
||||
}
|
69
src/split.🗿
Normal file
69
src/split.🗿
Normal file
@ -0,0 +1,69 @@
|
||||
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);
|
||||
}
|
15
src/strcat.🗿
15
src/strcat.🗿
@ -1,18 +1,19 @@
|
||||
strcat(dst, src)
|
||||
{
|
||||
local i;
|
||||
local j;
|
||||
i = 0;
|
||||
local i = 0;
|
||||
local j = 0;
|
||||
|
||||
loop {
|
||||
if ([dst + i] == 0)
|
||||
break;
|
||||
i = i + 1;
|
||||
i++;
|
||||
}
|
||||
j = 0;
|
||||
loop {
|
||||
if ([src + j] == 0)
|
||||
return (dst);
|
||||
break;
|
||||
[dst + i + j] = [src + j];
|
||||
j = j + 1;
|
||||
j++;
|
||||
}
|
||||
[dst + i + j] = 0;
|
||||
return j;
|
||||
}
|
||||
|
12
src/strchr.🗿
12
src/strchr.🗿
@ -1,12 +1,12 @@
|
||||
strchr(str, c)
|
||||
{
|
||||
local i;
|
||||
i = 0;
|
||||
local start = str;
|
||||
|
||||
loop {
|
||||
if ([str + i] == c)
|
||||
return (str + i);
|
||||
if ([str + i] == 0)
|
||||
if ([start] == c)
|
||||
return (start);
|
||||
if ([start] == 0)
|
||||
return (0);
|
||||
i = i + 1;
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
10
src/strcmp.🗿
Normal file
10
src/strcmp.🗿
Normal file
@ -0,0 +1,10 @@
|
||||
strcmp(s1, s2)
|
||||
{
|
||||
local i = 0;
|
||||
|
||||
loop {
|
||||
if ([s1 + i] != [s2 + i] | [s1 + i] == 0 | [s2 + i] == 0)
|
||||
return ([s1 + i] - [s2 + i]);
|
||||
i++;
|
||||
}
|
||||
}
|
10
src/strcpy.🗿
10
src/strcpy.🗿
@ -1,11 +1,13 @@
|
||||
strcpy(dst, src)
|
||||
{
|
||||
local i;
|
||||
i = 0;
|
||||
local i = 0;
|
||||
|
||||
loop {
|
||||
if ([src + i] == 0)
|
||||
return (dst);
|
||||
break;
|
||||
[dst + i] = [src + i];
|
||||
i = i + 1;
|
||||
i++;
|
||||
}
|
||||
[dst + i] = 0;
|
||||
return i;
|
||||
}
|
||||
|
10
src/strdup.🗿
Normal file
10
src/strdup.🗿
Normal file
@ -0,0 +1,10 @@
|
||||
strdup(str)
|
||||
{
|
||||
local out;
|
||||
|
||||
out = galloc(strlen(str) + 1);
|
||||
if (out == 0)
|
||||
return (0);
|
||||
strcpy(out, str);
|
||||
return (out);
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
strlen(str) {
|
||||
local i;
|
||||
i = 0;
|
||||
local i = 0;
|
||||
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
loop {
|
||||
if ([str + i] == 0)
|
||||
return (i);
|
||||
i = i + 1;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
14
src/strncmp.🗿
Normal file
14
src/strncmp.🗿
Normal file
@ -0,0 +1,14 @@
|
||||
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++;
|
||||
}
|
||||
}
|
@ -1,11 +1,13 @@
|
||||
strncpy(dst, src, size)
|
||||
{
|
||||
local i;
|
||||
i = 0;
|
||||
local i = 0;
|
||||
|
||||
loop {
|
||||
if ([src + i] == 0 | i == size)
|
||||
return (dst);
|
||||
if ([src + i] == 0 | i >= size)
|
||||
break;
|
||||
[dst + i] = [src + i];
|
||||
i = i + 1;
|
||||
i++;
|
||||
}
|
||||
[dst + i] = 0;
|
||||
return i;
|
||||
}
|
||||
|
16
src/strndup.🗿
Normal file
16
src/strndup.🗿
Normal file
@ -0,0 +1,16 @@
|
||||
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);
|
||||
}
|
15
src/strstr.🗿
Normal file
15
src/strstr.🗿
Normal file
@ -0,0 +1,15 @@
|
||||
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);
|
||||
}
|
||||
}
|
25
src/tabcmp.🗿
Normal file
25
src/tabcmp.🗿
Normal file
@ -0,0 +1,25 @@
|
||||
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++;
|
||||
}
|
||||
}
|
21
test.sh
21
test.sh
@ -1,4 +1,23 @@
|
||||
cat src/*.🗿 tests/$1.🗿 tests/test.🗿 >tmp.🗿
|
||||
tester()
|
||||
{
|
||||
for val in $@
|
||||
do
|
||||
echo $val
|
||||
cat src/*.🗿 tests/$val.🗿 tests/test.🗿 >tmp.🗿
|
||||
golemc tmp.🗿 > tmp.asm
|
||||
orgaasm tmp.asm tmp.rom
|
||||
if [ -f tests/$val.input ]
|
||||
then
|
||||
orgaemu tmp.rom < tests/$val.input
|
||||
else
|
||||
orgaemu tmp.rom
|
||||
fi
|
||||
echo
|
||||
done
|
||||
}
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
tester $(ls tests/*.🗿 | grep -v 'test.🗿' | sed 's/^tests\///; s/\.🗿$//' | tr '\n' ' ' );
|
||||
else
|
||||
tester $@;
|
||||
fi
|
||||
|
9
tests/aton.🗿
Normal file
9
tests/aton.🗿
Normal file
@ -0,0 +1,9 @@
|
||||
main()
|
||||
{
|
||||
name = "aton";
|
||||
|
||||
test_num(aton("33"), 33, "");
|
||||
test_num(aton(""), 0, "");
|
||||
test_num(aton("40"), 40, "");
|
||||
test_num(aton("1"), 1, "");
|
||||
}
|
12
tests/aton_s.🗿
Normal file
12
tests/aton_s.🗿
Normal file
@ -0,0 +1,12 @@
|
||||
main()
|
||||
{
|
||||
name = "aton_s";
|
||||
|
||||
test_num_s(aton_s("33"), 33, "");
|
||||
test_num_s(aton_s(""), 0, "");
|
||||
test_num_s(aton_s("40"), 40, "");
|
||||
test_num_s(aton_s("1"), 1, "");
|
||||
test_num_s(aton_s("-"), 0, "");
|
||||
test_num_s(aton_s("-40"), 0 - 40, "");
|
||||
test_num_s(aton_s("-1"), 0 - 1, "");
|
||||
}
|
7
tests/contain_only.🗿
Normal file
7
tests/contain_only.🗿
Normal file
@ -0,0 +1,7 @@
|
||||
main()
|
||||
{
|
||||
name = "contain_only";
|
||||
|
||||
test_num(contain_only("17", "0123456789"), 1, "");
|
||||
test_num(contain_only("17a", "0123456789"), 0, "");
|
||||
}
|
11
tests/define.🗿
Normal file
11
tests/define.🗿
Normal file
@ -0,0 +1,11 @@
|
||||
main()
|
||||
{
|
||||
name = "define";
|
||||
|
||||
test_num_s(NUM_MAX, 0 - 1, "NUM_MAX");
|
||||
test_num_s(NUM_S_MAX, 0xffff / 2, "NUM_S_MAX");
|
||||
test_num_s(NUM_MIN, 0, "NUM_MAX");
|
||||
test_num_s(NUM_S_MIN, 0xffff / 2 + 1, "NUM_S_MAX");
|
||||
test_num_s(NULL, 0, "NULL");
|
||||
test_num_s(ZIED, NUM_MAX, "ZIED");
|
||||
}
|
@ -1,5 +1,24 @@
|
||||
|
||||
global HEAP_SIZE = 0x0030;
|
||||
main()
|
||||
{
|
||||
local ptr1;
|
||||
local ptr2;
|
||||
name = "galloc";
|
||||
test(galloc(1), heap + LOCATION_DATA, "");
|
||||
|
||||
ptr1 = galloc(1);
|
||||
test_num(ptr1, heap + GALLOC_DATA, "");
|
||||
free(ptr1);
|
||||
|
||||
ptr1 = galloc(1);
|
||||
test_num(ptr1, heap + GALLOC_DATA, "alloc after free");
|
||||
free(ptr1);
|
||||
|
||||
ptr2 = galloc(0x9000);
|
||||
test_num(ptr2, 0, "alloc too big");
|
||||
|
||||
test_num(leaks(), 0, "leaks");
|
||||
ptr1 = galloc(1);
|
||||
test_num(leaks(), 1, "leaks");
|
||||
free(ptr1);
|
||||
}
|
||||
|
3
tests/geadline.input
Normal file
3
tests/geadline.input
Normal file
@ -0,0 +1,3 @@
|
||||
yo
|
||||
bozo
|
||||
z[Dbo[C[C[Co
|
18
tests/geadline.🗿
Normal file
18
tests/geadline.🗿
Normal file
@ -0,0 +1,18 @@
|
||||
main()
|
||||
{
|
||||
local ptr;
|
||||
|
||||
name = "geadline";
|
||||
|
||||
ptr = geadline("");
|
||||
test_str(ptr, "yo", "");
|
||||
|
||||
ptr = geadline("");
|
||||
test_str(ptr, "bozo", "");
|
||||
|
||||
ptr = geadline("");
|
||||
test_str(ptr, "bozo", "arrow");
|
||||
|
||||
ptr = geadline("");
|
||||
test_num(ptr, 0, "");
|
||||
}
|
18
tests/get_raw_bit.🗿
Normal file
18
tests/get_raw_bit.🗿
Normal file
@ -0,0 +1,18 @@
|
||||
main()
|
||||
{
|
||||
local tab;
|
||||
|
||||
name = "get_raw_bit";
|
||||
|
||||
tab = get_raw_bit(1);
|
||||
test_tab_num(tab, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, 16, "");
|
||||
free(tab);
|
||||
|
||||
tab = get_raw_bit(2);
|
||||
test_tab_num(tab, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, 16, "");
|
||||
free(tab);
|
||||
|
||||
tab = get_raw_bit(0x8000);
|
||||
test_tab_num(tab, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 16, "");
|
||||
free(tab);
|
||||
}
|
16
tests/ntoa.🗿
Normal file
16
tests/ntoa.🗿
Normal file
@ -0,0 +1,16 @@
|
||||
main()
|
||||
{
|
||||
local ptr;
|
||||
|
||||
name = "ntoa";
|
||||
|
||||
ptr = ntoa(9000);
|
||||
test_str(ptr, "9000", "");
|
||||
free(ptr);
|
||||
ptr = ntoa(55);
|
||||
test_str(ptr, "55", "");
|
||||
free(ptr);
|
||||
ptr = ntoa(0);
|
||||
test_str(ptr, "0", "");
|
||||
free(ptr);
|
||||
}
|
34
tests/ntoa_s.🗿
Normal file
34
tests/ntoa_s.🗿
Normal file
@ -0,0 +1,34 @@
|
||||
main()
|
||||
{
|
||||
local ptr;
|
||||
|
||||
name = "ntoa_s";
|
||||
|
||||
ptr = ntoa_s(9000);
|
||||
test_str(ptr, "9000", "");
|
||||
free(ptr);
|
||||
|
||||
ptr = ntoa_s(55);
|
||||
test_str(ptr, "55", "");
|
||||
free(ptr);
|
||||
|
||||
ptr = ntoa_s(0);
|
||||
test_str(ptr, "0", "");
|
||||
free(ptr);
|
||||
|
||||
ptr = ntoa_s(0 - 55);
|
||||
test_str(ptr, "-55", "");
|
||||
free(ptr);
|
||||
|
||||
ptr = ntoa_s(0 - 1);
|
||||
test_str(ptr, "-1", "");
|
||||
free(ptr);
|
||||
|
||||
ptr = ntoa_s(0 - 3);
|
||||
test_str(ptr, "-3", "");
|
||||
free(ptr);
|
||||
|
||||
ptr = ntoa_s(3);
|
||||
test_str(ptr, "3", "");
|
||||
free(ptr);
|
||||
}
|
24
tests/realloc.🗿
Normal file
24
tests/realloc.🗿
Normal file
@ -0,0 +1,24 @@
|
||||
main()
|
||||
{
|
||||
local ptr1;
|
||||
local ptr2;
|
||||
|
||||
name = "realloc";
|
||||
|
||||
ptr1 = strdup("yo");
|
||||
ptr2 = realloc(ptr1, 6);
|
||||
test_str("yo", ptr2, "standart: value");
|
||||
free(ptr2);
|
||||
test_num(leaks(), 0, "standart: leaks");
|
||||
|
||||
ptr2 = realloc(NULL, 6);
|
||||
test_num(heap + GALLOC_DATA, ptr2, "NULL: value");
|
||||
free(ptr2);
|
||||
test_num(leaks(), 0, "NULL: leaks");
|
||||
|
||||
ptr1 = strdup("bonjour");
|
||||
ptr2 = realloc(ptr1, 2);
|
||||
test_tab_num(ptr2, "bo", 2, "decrement size: value");
|
||||
free(ptr2);
|
||||
test_num(leaks(), 0, "decrement size: leaks");
|
||||
}
|
9
tests/replace_index.🗿
Normal file
9
tests/replace_index.🗿
Normal file
@ -0,0 +1,9 @@
|
||||
main()
|
||||
{
|
||||
name = "replace_index";
|
||||
|
||||
test_str(replace_index("yo ca va ?", "t", 2, 3), "yotca va ?", "");
|
||||
test_str(replace_index("yo ca va ?", "", 2, 3), "yoca va ?", "empty fill");
|
||||
test_str(replace_index("yo ca va ?", "aaaaa", 2, 3), "yoaaaaaca va ?", "");
|
||||
test_str(replace_index("", "aaaaa", 0, 0), "aaaaa", "");
|
||||
}
|
36
tests/split.🗿
Normal file
36
tests/split.🗿
Normal file
@ -0,0 +1,36 @@
|
||||
main()
|
||||
{
|
||||
local tab, reach_tab;
|
||||
name = "split";
|
||||
|
||||
reach_tab = galloc(4);
|
||||
[reach_tab] = "salut";
|
||||
[reach_tab + 1] = "ca";
|
||||
[reach_tab + 2] = "va";
|
||||
[reach_tab + 3] = 0;
|
||||
|
||||
tab = split("salut ca va", " ");
|
||||
test_tab_str(tab, reach_tab, "");
|
||||
|
||||
tab = split("salut ca va", " ");
|
||||
test_tab_str(tab, reach_tab, "multiple delimiter past");
|
||||
|
||||
tab = split("salutbozocabozova", "bozo");
|
||||
test_tab_str(tab, reach_tab, "mutiple char in delimiter");
|
||||
|
||||
[reach_tab] = "salut";
|
||||
[reach_tab + 1] = 0;
|
||||
|
||||
tab = split("salut", "bozo");
|
||||
test_tab_str(tab, reach_tab, "delimiter not in str");
|
||||
|
||||
[reach_tab] = "";
|
||||
[reach_tab + 1] = 0;
|
||||
tab = split("", "bozo");
|
||||
test_tab_str(tab, reach_tab, "empty str");
|
||||
|
||||
[reach_tab] = "";
|
||||
[reach_tab + 1] = 0;
|
||||
tab = split("", "");
|
||||
test_tab_str(tab, reach_tab, "empty delimiter and empty str🗿");
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
main()
|
||||
{
|
||||
local str;
|
||||
|
||||
name = "strchr";
|
||||
|
||||
str = "bozoman du 36";
|
||||
test(strchr(str, 'z'), str + 2, "");
|
||||
test(strchr(str, 0), str + 13, "");
|
||||
test(strchr(str, '5'), 0, "");
|
||||
test(strchr(str, '6'), str + 12, "");
|
||||
test_str(strchr(str, 'z'), str + 2, "");
|
||||
test_str(strchr(str, 0), str + 13, "");
|
||||
test_str(strchr(str, '5'), 0, "");
|
||||
test_str(strchr(str, '6'), str + 12, "");
|
||||
test_str(strchr("", 'q'), 0, "empty str");
|
||||
test_str(strchr("", 0), "", "empty str and \0 to find");
|
||||
}
|
||||
|
9
tests/strcmp.🗿
Normal file
9
tests/strcmp.🗿
Normal file
@ -0,0 +1,9 @@
|
||||
main()
|
||||
{
|
||||
name = "strcmp";
|
||||
|
||||
test_num(strcmp("test", "test"), 0, "same chars");
|
||||
test_num(strcmp("s", "b"), 17, "");
|
||||
test_num(strcmp("", ""), 0, "empty strings");
|
||||
test_num(strcmp("", "a"), 65439, "");
|
||||
}
|
20
tests/strcpy.🗿
Normal file
20
tests/strcpy.🗿
Normal file
@ -0,0 +1,20 @@
|
||||
main()
|
||||
{
|
||||
local str;
|
||||
|
||||
name = "strcpy";
|
||||
|
||||
str = galloc(10);
|
||||
|
||||
strcpy(str, "yo");
|
||||
test_str(str, "yo", "");
|
||||
|
||||
strcpy(str, "");
|
||||
test_str(str, "", "");
|
||||
|
||||
strcpy(str, "bonjorsss");
|
||||
strcpy(str, "bonjour");
|
||||
test_str(str, "bonjour", "set last \0");
|
||||
|
||||
free(str);
|
||||
}
|
14
tests/strdup.🗿
Normal file
14
tests/strdup.🗿
Normal file
@ -0,0 +1,14 @@
|
||||
main()
|
||||
{
|
||||
local ptr;
|
||||
name = "strdup";
|
||||
|
||||
ptr = "bozoman";
|
||||
test_str(strdup(ptr), ptr, "");
|
||||
|
||||
ptr = "";
|
||||
test_str(strdup(ptr), ptr, "");
|
||||
|
||||
ptr = "hello world!";
|
||||
test_str(strdup(ptr), ptr, "");
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
main()
|
||||
{
|
||||
local str;
|
||||
name = "strlen";
|
||||
str = "bozoman du 36";
|
||||
test(strlen(str), 13, "");
|
||||
test(strlen(""), 0, "Empty string");
|
||||
|
||||
test_num(strlen("bozoman du 36"), 13, "");
|
||||
test_num(strlen(""), 0, "Empty string");
|
||||
}
|
||||
|
12
tests/strncmp.🗿
Normal file
12
tests/strncmp.🗿
Normal file
@ -0,0 +1,12 @@
|
||||
main()
|
||||
{
|
||||
name = "strncmp";
|
||||
|
||||
test_num(strncmp("test", "test", 4), 0, "same chars");
|
||||
test_num(strncmp("s", "b", 4), 17, "");
|
||||
test_num(strncmp("", "", 4), 0, "empty strings");
|
||||
test_num(strncmp("", "a", 0), 0, "");
|
||||
test_num(strncmp("ab", "ac", 1), 0, "");
|
||||
test_num(strncmp("aq", "a", 1), 0, "");
|
||||
test_num(strncmp("aq", "a", 2), 113, "");
|
||||
}
|
21
tests/strndup.🗿
Normal file
21
tests/strndup.🗿
Normal file
@ -0,0 +1,21 @@
|
||||
main()
|
||||
{
|
||||
local ptr;
|
||||
name = "strndup";
|
||||
|
||||
ptr = strndup("bozoman", 7);
|
||||
test_str(ptr, "bozoman", "");
|
||||
free(ptr);
|
||||
|
||||
ptr = strndup("bozoman", 4);
|
||||
test_str(ptr, "bozo", "");
|
||||
free(ptr);
|
||||
|
||||
ptr = strndup("bozoman", 10);
|
||||
test_str(ptr, "bozoman", "");
|
||||
free(ptr);
|
||||
|
||||
ptr = strndup("bozoman", 0);
|
||||
test_str(ptr, "", "");
|
||||
free(ptr);
|
||||
}
|
10
tests/strstr.🗿
Normal file
10
tests/strstr.🗿
Normal file
@ -0,0 +1,10 @@
|
||||
main()
|
||||
{
|
||||
name = "strstr";
|
||||
|
||||
test_str(strstr("test", "t"), "test", "");
|
||||
test_str(strstr("test", "st"), "st", "");
|
||||
test_str(strstr("hello world!", "s"), 0, "non present to_find");
|
||||
test_str(strstr("", "s"), 0, "empty str");
|
||||
test_str(strstr("", ""), "", "empty str and empty to find");
|
||||
}
|
100
tests/test.🗿
100
tests/test.🗿
@ -1,20 +1,9 @@
|
||||
global name;
|
||||
|
||||
putstr(str){
|
||||
local i;
|
||||
i = 0;
|
||||
loop {
|
||||
if ([str + i] == 0)
|
||||
return;
|
||||
wrt [str + i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
test(value, reach_value, description)
|
||||
test_str(value, reach_value, description)
|
||||
{
|
||||
putstr(name);
|
||||
if (value != reach_value)
|
||||
if (strcmp(value, reach_value))
|
||||
{
|
||||
putstr(": ERROR: ");
|
||||
putstr(", ");
|
||||
@ -32,3 +21,88 @@ test(value, reach_value, description)
|
||||
}
|
||||
wrt '\n';
|
||||
}
|
||||
|
||||
test_num(value, reach_value, description)
|
||||
{
|
||||
putstr(name);
|
||||
if (value != reach_value)
|
||||
{
|
||||
putstr(": ERROR: ");
|
||||
putstr(", ");
|
||||
putstr(description);
|
||||
putstr(" [");
|
||||
putnum(reach_value);
|
||||
putstr(" != ");
|
||||
putnum(value);
|
||||
putstr("]");
|
||||
}
|
||||
else
|
||||
{
|
||||
putstr(": OK: ");
|
||||
putstr(description);
|
||||
}
|
||||
wrt '\n';
|
||||
}
|
||||
|
||||
test_num_s(value, reach_value, description)
|
||||
{
|
||||
putstr(name);
|
||||
if (value != reach_value)
|
||||
{
|
||||
putstr(": ERROR: ");
|
||||
putstr(", ");
|
||||
putstr(description);
|
||||
putstr(" [");
|
||||
putnum_s(reach_value);
|
||||
putstr(" != ");
|
||||
putnum_s(value);
|
||||
putstr("]");
|
||||
}
|
||||
else
|
||||
{
|
||||
putstr(": OK: ");
|
||||
putstr(description);
|
||||
}
|
||||
wrt '\n';
|
||||
}
|
||||
|
||||
test_tab_str(value, reach_value, description)
|
||||
{
|
||||
putstr(name);
|
||||
if (tabcmp_str(value, reach_value))
|
||||
{
|
||||
putstr(": ERROR: ");
|
||||
putstr(", ");
|
||||
putstr(description);
|
||||
puttab_str(reach_value);
|
||||
putstr(" != ");
|
||||
puttab_str(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
putstr(": OK: ");
|
||||
putstr(description);
|
||||
}
|
||||
wrt '\n';
|
||||
}
|
||||
|
||||
|
||||
test_tab_num(value, reach_value, size, description)
|
||||
{
|
||||
putstr(name);
|
||||
if (tabcmp_num(value, reach_value, size))
|
||||
{
|
||||
putstr(": ERROR: ");
|
||||
putstr(", ");
|
||||
putstr(description);
|
||||
puttab_num(reach_value, size);
|
||||
putstr(" != ");
|
||||
puttab_num(value, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
putstr(": OK: ");
|
||||
putstr(description);
|
||||
}
|
||||
wrt '\n';
|
||||
}
|
||||
|
14
wiki/strcat.md
Normal file
14
wiki/strcat.md
Normal file
@ -0,0 +1,14 @@
|
||||
# STRCAT
|
||||
Strcat (string concatenate) is a function that takes two chars lists as a parameter and write the second at this end of the first (like strcat in C)
|
||||
|
||||
## params
|
||||
1. chars list
|
||||
2. chars list
|
||||
|
||||
## example
|
||||
```
|
||||
strcat("y", "o") "y" => "yo"
|
||||
strcat("y", "") "y" => "y"
|
||||
strcat("", "o") "" => "o"
|
||||
strcat("hello ", "world!") => "hello world!"
|
||||
```
|
14
wiki/strcpy.md
Normal file
14
wiki/strcpy.md
Normal file
@ -0,0 +1,14 @@
|
||||
# STRCPY
|
||||
Strcpy (string copy) is a function that takes two chars lists as a parameter and write the second in the first (like strcpy in C)
|
||||
|
||||
## params
|
||||
1. chars list
|
||||
2. chars list
|
||||
|
||||
## example
|
||||
```
|
||||
strcpy("y", "o") "y" => "o"
|
||||
strcpy("y", "") "y" => ""
|
||||
strcpy("", "o") "" => "o"
|
||||
strcpy("hello ", "world!") => "world!"
|
||||
```
|
16
wiki/strlen.md
Normal file
16
wiki/strlen.md
Normal file
@ -0,0 +1,16 @@
|
||||
# STRLEN
|
||||
Strlen (string length) is a function that takes an chars list as a parameter and return an length (like strlen in C)
|
||||
|
||||
## params
|
||||
1. char list
|
||||
|
||||
## return
|
||||
number
|
||||
|
||||
## example
|
||||
```
|
||||
strlen("ab") => 2
|
||||
strlen(NULL) => 0
|
||||
strlen("") => 0
|
||||
strlen("j'ai les cramptés") => 17
|
||||
```
|
17
wiki/strncpy.md
Normal file
17
wiki/strncpy.md
Normal file
@ -0,0 +1,17 @@
|
||||
# STRNCPY
|
||||
Strncpy is a function that takes two chars lists and a number as a parameter and write the second in the first but only the n - 1 first char (like strncpy in C)
|
||||
|
||||
## params
|
||||
1. chars list
|
||||
2. chars list
|
||||
3. number
|
||||
|
||||
## example
|
||||
```
|
||||
strncpy("y", "o", 2) "y" => "o"
|
||||
strncpy("y", "", 1) "y" => ""
|
||||
strncpy("", "o", 2) "" => "o"
|
||||
strncpy("hello ", "world!", 7) => "world!"
|
||||
strncpy("hello ", "world!", 14) => "world!"
|
||||
strncpy("hello ", "world!", 0) => "hello "
|
||||
```
|
Reference in New Issue
Block a user