Compare commits

...

16 Commits

15 changed files with 199 additions and 23 deletions

5
.gitignore vendored
View File

@ -1,3 +1,2 @@
tmp.rom IronGolem.asm
tmp.asm IronGolem.🗿
tmp.🗿

4
run.sh
View File

@ -1,4 +1,4 @@
cat src/* >tmp.🗿 cat src/* > IronGolem.🗿
golemc tmp.🗿 >tmp.asm golemc IronGolem.🗿 > IronGolem.asm
# orgaasm tmp.asm tmp.rom # orgaasm tmp.asm tmp.rom
# orgaemu tmp.rom # orgaemu tmp.rom

View File

@ -33,7 +33,7 @@ define LOCATION_PREV = 3;
define LOCATION_NEXT = 4; define LOCATION_NEXT = 4;
define LOCATION_DATA = HEADER_SIZE + PADDING_SIZE; define LOCATION_DATA = HEADER_SIZE + PADDING_SIZE;
setup_header(ptr, used, size, next_block, prev_block) galloc_setup_header(ptr, used, size, next_block, prev_block)
{ {
local i; local i;
@ -54,7 +54,7 @@ setup_header(ptr, used, size, next_block, prev_block)
} }
} }
find_next_space(size) galloc_find_next_space(size)
{ {
local current; local current;
@ -70,7 +70,7 @@ find_next_space(size)
} }
} }
print_heap() galloc_print_heap()
{ {
local i; local i;
@ -84,7 +84,7 @@ print_heap()
} }
} }
split_block(ptr, size) galloc_split_block(ptr, size)
{ {
local old_next; local old_next;
local next; local next;
@ -100,9 +100,9 @@ split_block(ptr, size)
old_next = [ptr + LOCATION_NEXT]; old_next = [ptr + LOCATION_NEXT];
next = ptr + size + HEADER_SIZE + PADDING_SIZE * 2; next = ptr + size + HEADER_SIZE + PADDING_SIZE * 2;
prev = [ptr + LOCATION_PREV]; prev = [ptr + LOCATION_PREV];
🗿 setup_header(ptr, used, size, next_block, prev_block); 🗿 galloc_setup_header(ptr, used, size, next_block, prev_block);
setup_header(ptr, 1, size, ptr + HEADER_SIZE + PADDING_SIZE * 2 + size, prev); galloc_setup_header(ptr, 1, size, ptr + HEADER_SIZE + PADDING_SIZE * 2 + size, prev);
setup_header(next, 0, old_size - size - HEADER_SIZE - PADDING_SIZE * 2, old_next, ptr); galloc_setup_header(next, 0, old_size - size - HEADER_SIZE - PADDING_SIZE * 2, old_next, ptr);
return (0); return (0);
} }
@ -111,8 +111,8 @@ galloc(size)
local ptr; local ptr;
if ([heap] == 0) 🗿 if the heap is not initialised if ([heap] == 0) 🗿 if the heap is not initialised
setup_header(heap, 0, HEAP_SIZE - HEADER_SIZE - PADDING_SIZE * 2, 0, 0); 🗿 initialised all the heap galloc_setup_header(heap, 0, HEAP_SIZE - HEADER_SIZE - PADDING_SIZE * 2, 0, 0); 🗿 initialised all the heap
ptr = find_next_space(size); ptr = galloc_find_next_space(size);
if (ptr == 0) if (ptr == 0)
return (0); return (0);
if ([ptr + LOCATION_SIZE] == size) if ([ptr + LOCATION_SIZE] == size)
@ -120,20 +120,20 @@ galloc(size)
[ptr + LOCATION_USED] = 1; [ptr + LOCATION_USED] = 1;
return (ptr + LOCATION_DATA); return (ptr + LOCATION_DATA);
} }
split_block(ptr, size); galloc_split_block(ptr, size);
return (ptr + LOCATION_DATA); return (ptr + LOCATION_DATA);
} }
merge_blocks(first_block, last_block) galloc_merge_blocks(first_block, last_block)
{ {
local size; local size;
if (last_block == first_block) if (last_block == first_block)
{ {
setup_header(first_block, 0, [first_block + LOCATION_SIZE], [first_block + LOCATION_NEXT], [first_block + LOCATION_PREV]); 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]; size = last_block - first_block + [last_block + LOCATION_SIZE];
setup_header(first_block, 0, size, [last_block + LOCATION_NEXT], [first_block + LOCATION_PREV]); galloc_setup_header(first_block, 0, size, [last_block + LOCATION_NEXT], [first_block + LOCATION_PREV]);
} }
free(ptr) free(ptr)
@ -144,6 +144,11 @@ free(ptr)
local first_block; local first_block;
local last_block; local last_block;
if (ptr > heap + HEAP_SIZE | heap > ptr)
{
putstr("Error: free: invalid ptr\n");
return;
}
block = ptr - LOCATION_DATA; block = ptr - LOCATION_DATA;
prev_block = [block + LOCATION_PREV]; prev_block = [block + LOCATION_PREV];
if (prev_block == 0 | [prev_block + LOCATION_USED]) if (prev_block == 0 | [prev_block + LOCATION_USED])
@ -155,5 +160,10 @@ free(ptr)
last_block = block; last_block = block;
else else
last_block = next_block; last_block = next_block;
merge_blocks(first_block, last_block); galloc_merge_blocks(first_block, last_block);
}
leaks()
{
return ([heap + LOCATION_NEXT] != 0);
} }

49
src/geadline.🗿 Normal file
View File

@ -0,0 +1,49 @@
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 = realloc(buf, 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;
}
}
}

26
src/realloc.🗿 Normal file
View 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 - LOCATION_DATA;
i = 0;
loop
{
if (i == new_size | i == [block_ptr + LOCATION_SIZE])
break;
[new_space + i] = [ptr + i];
i++;
}
free(ptr);
return new_space;
}

15
src/replace.🗿 Normal file
View File

@ -0,0 +1,15 @@
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);
}

View File

@ -10,8 +10,10 @@ strcat(dst, src)
} }
loop { loop {
if ([src + j] == 0) if ([src + j] == 0)
return (dst); break;
[dst + i + j] = [src + j]; [dst + i + j] = [src + j];
j++; j++;
} }
[dst + i + j] = 0;
return j;
} }

View File

@ -4,8 +4,10 @@ strcpy(dst, src)
loop { loop {
if ([src + i] == 0) if ([src + i] == 0)
return (dst); break;
[dst + i] = [src + i]; [dst + i] = [src + i];
i++; i++;
} }
[dst + i] = 0;
return i;
} }

View File

@ -1,6 +1,8 @@
strlen(str) { strlen(str) {
local i = 0; local i = 0;
if (str == NULL)
return 0;
loop { loop {
if ([str + i] == 0) if ([str + i] == 0)
return (i); return (i);

View File

@ -3,9 +3,11 @@ strncpy(dst, src, size)
local i = 0; local i = 0;
loop { loop {
if ([src + i] == 0 | i == size) if ([src + i] == 0 | i >= size)
return (dst); break;
[dst + i] = [src + i]; [dst + i] = [src + i];
i++; i++;
} }
[dst + i] = 0;
return i;
} }

View File

@ -16,4 +16,9 @@ main()
ptr2 = galloc(0x9000); ptr2 = galloc(0x9000);
test_num(ptr2, 0, "alloc too big"); test_num(ptr2, 0, "alloc too big");
test_num(leaks(), 0, "leaks");
ptr1 = galloc(1);
test_num(leaks(), 1, "leaks");
free(ptr1);
} }

24
tests/realloc.🗿 Normal file
View 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 + LOCATION_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");
}

11
tests/reallocarray.🗿 Normal file
View File

@ -0,0 +1,11 @@
main()
{
local tmp;
name = "reallocarray";
tmp = strdup("yo");
if (tmp == NULL)
return 1;
tmp = reallocarray(tmp, strlen(tmp), 5);
test_str(tmp, "yo", "");
}

9
tests/replace.🗿 Normal file
View File

@ -0,0 +1,9 @@
main()
{
name = "replace";
test_str(replace("yo ca va ?", "t", 2, 3), "yotca va ?", "");
test_str(replace("yo ca va ?", "", 2, 3), "yoca va ?", "empty fill");
test_str(replace("yo ca va ?", "aaaaa", 2, 3), "yoaaaaaca va ?", "");
test_str(replace("", "aaaaa", 0, 0), "aaaaa", "");
}

20
tests/strcpy.🗿 Normal file
View 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);
}