diff --git a/lang/.asm-lsp.toml b/lang/.asm-lsp.toml new file mode 100644 index 0000000..154d02c --- /dev/null +++ b/lang/.asm-lsp.toml @@ -0,0 +1,9 @@ +[[project]] +path = "./" +version = "0.10.0" +assembler = "nasm" +instruction_set = "x86-64" + +[project.opts] +diagnostics = true +default_diagnostics = true diff --git a/lang/Makefile b/lang/Makefile new file mode 100644 index 0000000..8b4ffd8 --- /dev/null +++ b/lang/Makefile @@ -0,0 +1,9 @@ +SRC := asem.s + + +OBJDIR := obj +OBJ := $(OBJDIR)/$(SRC:.s=.o) + +all: + nasm -felf64 -g $(SRC) -o $(OBJ) + ld -o debug $(OBJ) -nostdlib -static diff --git a/lang/asem.s b/lang/asem.s new file mode 100644 index 0000000..3834db9 --- /dev/null +++ b/lang/asem.s @@ -0,0 +1,49 @@ +%define DEF_BUFFER_LEN 4096 +%define INPUT_LENGTH 64 + +; rax -- syscall + +; type widths + +section .data + message: db "Hello World!", 0xA, 0 ; hello + message_length: equ $-message + +section .bss + arr: resb DEF_BUFFER_LEN + +section .text + global _start + +print_string: + push rbp + push rdx + mov rbp, rsp ; set up stack frame + + mov rax, 1 ; sys_write + + pop rdx + pop rbp + +exit: + mov rax, 60 + syscall + +strlen: + push rcx + xor rcx, rcx +.loop: + cmp byte [rdi + rcx], 0 + jz .done + inc rcx + jmp .loop +.done: + mov rax, rcx + pop rcx + ret + +_start: + mov rdi, message ; prepare first arg -> string addr to rdi + call strlen + mov rdi, rax + call exit diff --git a/lang/debug b/lang/debug new file mode 100755 index 0000000..583635e Binary files /dev/null and b/lang/debug differ diff --git a/lang/obj/asem.o b/lang/obj/asem.o new file mode 100644 index 0000000..a4b0676 Binary files /dev/null and b/lang/obj/asem.o differ diff --git a/lang/out b/lang/out new file mode 100755 index 0000000..7573671 Binary files /dev/null and b/lang/out differ diff --git a/lang/test.c b/lang/test.c new file mode 100644 index 0000000..0a282ea --- /dev/null +++ b/lang/test.c @@ -0,0 +1,5 @@ +extern int write(); + +int main() { + write(); +} diff --git a/memory/allocator/allocator.h b/memory/allocator/allocator.h new file mode 100644 index 0000000..0e5d194 --- /dev/null +++ b/memory/allocator/allocator.h @@ -0,0 +1,204 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* allocator.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: victor +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/05 17:04:18 by victor #+# #+# */ +/* Updated: 2025/04/06 16:30:24 by victor ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ALLOCATOR_H +# define ALLOCATOR_H + + +# include "inc/arena.h" + +typedef struct s_alloc { + void *mem; + size_t size; +} t_alloc; + +typedef t_arena t_vector ; + +typedef struct s_allocator { + void *mem; + t_vector allocs; + size_t cap; + t_vector free; // this will be used as Array of t_alloc +} t_allocator; + +//global allocator that will be used by this lib +static t_allocator *allocator_get(void) { + static t_allocator a = { 0 }; + return &a; +} + +void allocator_init(size_t base_mem); +void *alloc(uint64_t size); +void *zalloc(uint32_t size); +void dealloc(void *ptr); +void allocator_shutdown(void); + +#ifdef ALLOCATOR_IMPLEMENTATION + +#include +#include +#include +#include "allocator.h" +#include + +void allocator_init(size_t base_mem) { + t_allocator *allocator = allocator_get(); + + allocator->free = arena_create_growing(sizeof(t_alloc) * 1000); + allocator->mem = calloc(base_mem, sizeof((char)0)); + allocator->allocs = arena_create_growing(sizeof(t_alloc) * 1000); + allocator->cap = base_mem; +} + +void vector_push(t_vector *vec, void *mem, size_t memsize) { + assert(memsize < (vec->cap - vec->used)); + void *ptr = arena_alloc(vec, memsize); + assert(ptr); + memmove(ptr, mem, memsize); +} + +void vector_pop(t_vector *vec, size_t memsize) { + assert(memsize <= vec->used); + memset(&((uint8_t *)vec->mem)[vec->used - memsize], 0, memsize); +} + +// offset is used to know where to dereference the memory to find the value to be sorted by +void vector_insert_sorted(t_vector *vec, void *mem, uint32_t memsize, uint32_t offset) { + uint32_t low_pos = 0; + uint32_t high_pos = vec->count - (vec->count > 0); + int32_t position = 0; + t_alloc *cursor = &((t_alloc *)vec->mem)[high_pos]; + uint32_t new_alloc_size = *((uint8_t *)mem + offset); + + if (new_alloc_size > cursor->size || vec->count == 0) { + vector_push(vec, mem, memsize); + } else { + while (low_pos < high_pos) { + position = low_pos + (high_pos - low_pos) / 2; + cursor = &((t_alloc *)vec->mem)[position]; + assert((uint8_t *)cursor - (uint8_t *)vec->mem >= 0); + assert((uint8_t *)vec->mem + vec->used - (uint8_t *)cursor >= 0); + if (cursor->size < new_alloc_size) { + low_pos = position + 1; + } else if (cursor->size > new_alloc_size) { + high_pos = position - 1; + } else { + break ; + } + } + void *ptr = arena_alloc(vec, memsize); + memmove(ptr, &cursor, sizeof(*cursor) * (vec->count - low_pos)); + memmove(&cursor, mem, memsize); + } +} + +void vector_remove(t_vector *vec, uint32_t index, size_t memsize) { + assert(index <= vec->count); + void *item = (void *)&((uint8_t *)vec->mem)[index * memsize]; + memmove(item, (uint8_t *)item + memsize, (vec->count - index) * memsize); + vec->count--; + vec->used -= memsize; +} + +void *alloc(uint64_t size) { + void *ptr = NULL; + t_allocator *allocator = allocator_get(); + + if (size > 0) { + t_alloc *tail = &((t_alloc *)allocator->free.mem)[allocator->free.count - (allocator->free.count > 0)]; + if (allocator->free.count > 0 && tail->size >= size) { + assert(tail->mem); + uint32_t position = allocator->free.count / 2; + t_alloc *candidate = NULL; + uint32_t range = size / 20; + uint32_t last_pos = position; + while (1) { + t_alloc *cursor = &((t_alloc *)allocator->free.mem)[position]; + if (cursor->size > size + range) { + if (cursor->size < candidate->size) { + candidate = cursor; + } + position <<= 1; + } else if (cursor->size < size) { + position += position >> 1; + } else if ((cursor->size >= size && cursor->size <= size + range) || position == last_pos) { + ptr = cursor->mem; + t_alloc new = { ptr, size }; + t_alloc old = { (uint8_t *)ptr + size, cursor->size - size }; + vector_insert_sorted(&allocator->allocs, &new, sizeof(new), offsetof(t_alloc, size)); + vector_insert_sorted(&allocator->allocs, &old, sizeof(old), offsetof(t_alloc, size)); + vector_insert_sorted(&allocator->free, &old, sizeof(old), offsetof(t_alloc, size)); + vector_remove(&allocator->free, position, sizeof(*cursor)); + break ; + } + } + } else { + t_alloc *tail = &((t_alloc *)allocator->allocs.mem)[allocator->allocs.count - (allocator->allocs.count > 0)]; + if (tail->mem == NULL) { + ptr = allocator->mem; + } else { + ptr = (uint8_t *)tail->mem + tail->size; + } + t_alloc new = (t_alloc){ ptr, size }; + vector_push(&allocator->allocs, &new, sizeof(new)); + } + } + return ptr; +} + +void *zalloc(uint32_t size) { + uint8_t *ptr = NULL; + + ptr = alloc(size); + for (uint i = 0; i < size; ++i) { + ptr[i] = 0; + } + return ptr; +} + +void dealloc(void *ptr) { + t_allocator *allocator = allocator_get(); + for (uint32_t i = 0; i < allocator->allocs.count; ++i) { + if (((t_alloc *)allocator->allocs.mem)[i].mem == ptr) { + t_alloc move = ((t_alloc *)allocator->allocs.mem)[i]; + memset(move.mem, 'X', move.size); + vector_remove(&allocator->allocs, i, sizeof(move)); + vector_insert_sorted(&allocator->free, &move, sizeof(move), offsetof(t_alloc, size)); + break ; + } + } +} + +void allocator_print(void) { + t_allocator *allocator = allocator_get(); + printf( "---- Allocator ----\n" + "capacity: %lu\n", allocator->cap); + printf("currently used mem: \n"); + arena_print(&allocator->allocs); + printf("currently freed mem: \n"); + arena_print(&allocator->free); + printf("alloc mem start: %p\n", allocator->mem); + + print_memory(allocator->mem, 0, allocator->cap); +} + +void allocator_shutdown() { + t_allocator *allocator = allocator_get(); + + arena_destroy(&allocator->free); + arena_destroy(&allocator->allocs); + free(allocator->mem); + memset(allocator, 0, sizeof(*allocator)); +} + +#endif // ALLOCATOR_IMPLEMENTATION +#endif // !ALLOCATOR_H diff --git a/memory/allocator/inc/arena.h b/memory/allocator/inc/arena.h new file mode 100644 index 0000000..c10572c --- /dev/null +++ b/memory/allocator/inc/arena.h @@ -0,0 +1,152 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* arena.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: victor +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/05 12:45:17 by victor #+# #+# */ +/* Updated: 2025/04/06 16:05:54 by victor ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ARENA_H +# define ARENA_H + +# include +# include +# include +# include +# include +# include +# include + +# define BYTE_WIDTH 8 +# define DISPLAY_WIDTH sizeof((void *)0) * 2 + +typedef struct s_arena { + void *mem; + size_t cap; + size_t used; + bool grow; + uint32_t count; +} t_arena; + +t_arena arena_create(size_t size); +t_arena arena_create_growing(size_t size); +void *arena_alloc(t_arena *arena, size_t size); +void arena_destroy(t_arena *arena); +void arena_clear(t_arena *arena); +void arena_reset(t_arena *arena); +void arena_grow(t_arena *arena, size_t size); +void arena_print(t_arena *arena); +void print_memory(void *mem, size_t memstart, size_t memend); + +#define ARENA_IMPLEMENTATION + +# ifdef ARENA_IMPLEMENTATION + + +t_arena arena_create_growing(size_t size) { + t_arena arena = {0}; + + arena.cap = size; + arena.used = 0; + arena.mem = calloc(1, size); + arena.grow = true; + if (!arena.mem) { + return (t_arena){0}; + } + return (arena); +} + +t_arena arena_create(size_t size) { + t_arena arena = {0}; + + arena.cap = size; + arena.used = 0; + arena.mem = calloc(1, size); + arena.grow = false; + if (!arena.mem) { + return (t_arena){0}; + } + return (arena); +} + +void arena_grow(t_arena *arena, size_t size) { + void *new_mem; + uint new_size; + + new_size = arena->cap * (size / arena->cap + 1); + + new_mem = realloc(arena->mem, new_size); + arena->mem = new_mem; + assert(new_mem != NULL); + arena->cap = new_size; + + // size = 58, cap = 8 +} + +void *arena_alloc(t_arena *arena, size_t size) { + void *ptr = NULL; + + if (arena->used + size > arena->cap) { + if (arena->grow == true) { + arena_grow(arena, size); + } else { + assert(false && "Arena overflow detected"); + } + } + + ptr = (uint8_t *)arena->mem + arena->used; + arena->used += size; + arena->count++; + return ptr; +} + +void arena_clear(t_arena *arena) { + arena->used = 0; + arena->count = 0; +} + +void arena_reset(t_arena *arena) { + arena_clear(arena); + memset(arena->mem, 0, arena->cap); +} + +void arena_destroy(t_arena *arena) { + free(arena->mem); + memset(arena, 0, sizeof(*arena)); +} + +void print_memory(void *mem, size_t memstart, size_t memend) { + printf("---- Memory Section Start ----\n"); + for (uint32_t i = memstart; i < memend; i += DISPLAY_WIDTH) { + printf("%p:", &((uint8_t *)mem)[i]); + for (uint32_t j = 0; j < DISPLAY_WIDTH / 2; ++j) { + uint16_t val = ((uint16_t *)&(((uint8_t *)mem)[i]))[j]; + printf(" %04x", val); + } + printf(" "); + printf("|"); + for (uint32_t j = 0; j < DISPLAY_WIDTH; ++j) { + uint8_t value = ((uint8_t *)mem)[i + j]; + if (isalnum(value)) { + printf("%c", value); + } + else{ + printf("."); + } + } + printf("|"); + printf("\n"); + } + printf("---- Memory Section End ----\n"); +} + +void arena_print(t_arena *arena) { + print_memory(arena->mem, 0, arena->cap); +} + +# endif // !ARENA_IMPLEMENTATION +#endif // !ARENA_H diff --git a/memory/arena/arena.h b/memory/arena/arena.h new file mode 100644 index 0000000..993ca96 --- /dev/null +++ b/memory/arena/arena.h @@ -0,0 +1,144 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* arena.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: victor +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/05 12:45:17 by victor #+# #+# */ +/* Updated: 2025/04/05 17:07:03 by victor ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ARENA_H +# define ARENA_H + +# include +# include +# include +# include +# include +# include +# include + +# define BYTE_WIDTH 8 +# define DISPLAY_WIDTH sizeof((void *)0) * 2 + +typedef struct s_alloc { + void *ptr; + size_t size; +} t_alloc; + +typedef struct s_arena { + void *mem; + size_t cap; + size_t used; + bool grow; +} t_arena; + +t_arena arena_create(size_t size); +t_arena arena_create_growing(size_t size); +void *arena_alloc(t_arena *arena, size_t size); +void arena_destroy(t_arena *arena); +void arena_clear(t_arena *arena); +void arena_reset(t_arena *arena); +void arena_grow(t_arena *arena, size_t size); +void arena_print(t_arena *arena); + +# ifdef ARENA_IMPLEMENTATION + +t_arena arena_create_growing(size_t size) { + t_arena arena; + + arena.cap = size; + arena.used = 0; + arena.mem = calloc(1, size); + arena.grow = true; + if (!arena.mem) { + return (t_arena){0}; + } + return (arena); +} + +t_arena arena_create(size_t size) { + t_arena arena = {0}; + + arena.cap = size; + arena.used = 0; + arena.mem = calloc(1, size); + arena.grow = false; + if (!arena.mem) { + return (t_arena){0}; + } + return (arena); +} + +void arena_grow(t_arena *arena, size_t size) { + void *new_mem; + uint new_size; + + new_size = arena->cap * (size / arena->cap + 1); + + new_mem = realloc(arena->mem, new_size); + arena->mem = new_mem; + assert(new_mem != NULL); + arena->cap = new_size; + + // size = 58, cap = 8 +} + +void *arena_alloc(t_arena *arena, size_t size) { + void *ptr = NULL; + + if (arena->used + size > arena->cap) { + if (arena->grow == true) { + arena_grow(arena, size); + } else { + assert(false && "Arena overflow detected"); + } + } + + ptr = arena->mem + arena->used; + arena->used += size; + return ptr; +} + +void arena_clear(t_arena *arena) { + arena->used = 0; +} + +void arena_reset(t_arena *arena) { + arena_clear(arena); + memset(arena->mem, 0, arena->cap); +} + +void arena_destroy(t_arena *arena) { + free(arena->mem); + memset(arena, 0, sizeof(*arena)); +} + +void arena_print(t_arena *arena) { + printf("---- Arena Start ----\n"); + for (uint i = 0; i < arena->cap; i += DISPLAY_WIDTH) { + printf("%p\t", arena->mem + i); + for (uint j = 0; j < DISPLAY_WIDTH; ++j) { + printf("%02x ", *(char *)(arena->mem + i + j)); + } + printf("\t"); + printf("|"); + for (uint j = 0; j < DISPLAY_WIDTH; ++j) { + uint8_t value = *(char *)(arena->mem + i + j); + if (isalnum(value)) { + printf("%c", value); + } else { + printf("."); + } + } + printf("|"); + printf("\n"); + } + printf("---- Arena End ----\n"); +} + +# endif // !ARENA_IMPLEMENTATION +#endif // !ARENA_H diff --git a/memory/Makefile b/memory/lst_memory/Makefile similarity index 100% rename from memory/Makefile rename to memory/lst_memory/Makefile diff --git a/memory/ft_free.c b/memory/lst_memory/ft_free.c similarity index 100% rename from memory/ft_free.c rename to memory/lst_memory/ft_free.c diff --git a/memory/list.c b/memory/lst_memory/list.c similarity index 100% rename from memory/list.c rename to memory/lst_memory/list.c diff --git a/memory/list.h b/memory/lst_memory/list.h similarity index 100% rename from memory/list.h rename to memory/lst_memory/list.h diff --git a/memory/memory.c b/memory/lst_memory/lst_memory.c similarity index 95% rename from memory/memory.c rename to memory/lst_memory/lst_memory.c index 7bf9ede..b03f5f5 100644 --- a/memory/memory.c +++ b/memory/lst_memory/lst_memory.c @@ -1,7 +1,7 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* memory.c :+: :+: :+: */ +/* lst_memory.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: vvobis +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ diff --git a/memory/memory.h b/memory/lst_memory/lst_memory.h similarity index 100% rename from memory/memory.h rename to memory/lst_memory/lst_memory.h diff --git a/strings/strings.h b/strings/strings.h new file mode 100644 index 0000000..1a2c865 --- /dev/null +++ b/strings/strings.h @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* strings.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: victor +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/05 12:40:51 by victor #+# #+# */ +/* Updated: 2025/04/05 13:11:53 by victor ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef STRINGS_H +# define STRINGS_H + +#include +#include +#include + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; + +typedef struct s_string { + char *str; + u64 len; + u64 capacity; +} t_string; + +#endif