diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-06-09 21:28:30 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-06-09 21:28:30 +0200 |
commit | cc1cd3f8f48dc506086715bb207dfbf175c11575 (patch) | |
tree | 8625d6ab13d4c5374b880b935bc1c1e15aca24ef | |
parent | 31f95ee266e507a3155a82899531851c7202f0a3 (diff) | |
download | bxgen-cc1cd3f8f48dc506086715bb207dfbf175c11575.zip |
Cleanup; docs
-rwxr-xr-x | bxgen.c (renamed from binary_code_generation.c) | 152 |
1 files changed, 117 insertions, 35 deletions
diff --git a/binary_code_generation.c b/bxgen.c index 053baa6..d672b2f 100755 --- a/binary_code_generation.c +++ b/bxgen.c @@ -7,15 +7,18 @@ exit $? // ================================================================ // -// Binary code generation compiler backend +// bxgen.c +// Binary executable code generation - compiler backend // // Qualities // -// - Single source file +// - Single source file (for now) // - Simple and flexible API // - No external dependencies // - No configuration required // - No dynamic memory management +// - Easy cross-compilation +// - Platform-independent host // // To-Do list // @@ -23,34 +26,43 @@ exit $? // - x86_64 object file // - Linking libraries // - Proper error handling +// - Proper prefixes for identifiers // - Effective entity allocation // - Linked lists for large entities // - Sea of Nodes // - Optimization layers // - Multithreading // - Memory reallocation when necessary +// - JIT // - COFF, PE, OMF, Mach-O // - i386, RISC-V, ARM +// - Built-in standard library // -// Done +// Bugs +// +// - ... +// +// Done features // // - ELF header // // ================================================================ // +// Compilation options +// +// ================================================================ + +//#define DISABLE_IMPLEMENTATION +//#define DISABLE_HELPERS +//#define DISABLE_EXAMPLE + +// ================================================================ +// // Basic declarations // // ================================================================ #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#ifdef __unix__ -#include <sys/types.h> -#include <sys/stat.h> -#endif typedef signed char i8; typedef signed short i16; @@ -62,19 +74,17 @@ typedef unsigned int u32; typedef unsigned long long u64; typedef float f32; typedef double f64; -typedef signed char b8; -typedef int b32; -typedef char c8; +typedef signed char b8; // 8-bit boolean +typedef int b32; // 32-bit boolean +typedef int s32; // 32-bit status code +typedef char c8; // 8-bit character // ================================================================ // -// Intermediate representation +// IR data declarations // // ================================================================ -// Declarations -// - enum { // For indices UNDEFINED = -1, @@ -192,16 +202,84 @@ typedef struct { // typedef struct { - i64 entity_count; - entity_t entities[MAX_ENTITY_COUNT]; + i64 entity_count; + i64 entities_capacity; + entity_t *entities; } entity_pool_t; +// ================================================================ +// +// API declarations +// +// ================================================================ + +#ifdef __cplusplus +extern "C" { +#endif + +i64 pool_entity_add(entity_pool_t *pool, entity_t data); +void pool_entity_remove(entity_pool_t *pool, i64 entity, i16 type); + +i64 node_init(entity_pool_t *pool, node_t data); +void node_destroy(entity_pool_t *pool, i64 node); +i64 node_op_i64(entity_pool_t *pool, i64 value); +i64 node_op_ret(entity_pool_t *pool, i64 node_return_value); + +i64 proc_init(entity_pool_t *pool); +void proc_destroy(entity_pool_t *pool, i64 proc); +void proc_set_name(entity_pool_t *pool, i64 proc, i64 name_size, c8 const *name); +void proc_node_add(entity_pool_t *pool, i64 proc, i64 node); +void proc_node_remove(entity_pool_t *pool, i64 proc, i64 node); + +i64 unit_init(entity_pool_t *pool); +void unit_destroy(entity_pool_t *pool, i64 unit); +void unit_proc_add(entity_pool_t *pool, i64 unit, i64 proc); +void unit_proc_remove(entity_pool_t *pool, i64 unit, i64 proc); +void unit_set_entry_point(entity_pool_t *pool, i64 unit, i64 entry_point_proc); +void unit_write(entity_pool_t *pool, i64 unit, u16 target, FILE *out); + +#ifndef DISABLE_HELPERS +i64 n_i64(i64 value); +i64 n_ret(i64 node_return_value); +i64 p_new(c8 const *name); +void p_add(i64 proc, i64 node); +i64 u_new(); +void u_add(i64 unit, i64 proc); +void u_entry_point(i64 unit, i64 proc); +void u_elf_x86_64(i64 unit, c8 const *output_file_name); +#endif + +#ifdef __cplusplus +} +#endif + +// ================================================================ +// +// Implementation +// +// ================================================================ + +#ifndef DISABLE_IMPLEMENTATION + +#ifdef __cplusplus +#error Implementation code should be compiled with a C compiler! +#endif + +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#ifdef __unix__ +#include <sys/types.h> +#include <sys/stat.h> +#endif + // IR building procs // i64 pool_entity_add(entity_pool_t *pool, entity_t data) { assert(pool != NULL); - assert(pool->entity_count < MAX_ENTITY_COUNT); + assert(pool->entity_count < pool->entities_capacity); i64 id = pool->entity_count++; data.is_enabled = 1, @@ -345,13 +423,10 @@ void unit_set_entry_point(entity_pool_t *pool, i64 unit, i64 entry_point_proc) { pool->entities[unit].unit.entry_point = entry_point_proc; } -// ================================================================ -// -// Code generation proc +// Code generation proc // -// ================================================================ -void unit_write(entity_pool_t *pool, i64 unit, i16 target, FILE *out) { +void unit_write(entity_pool_t *pool, i64 unit, u16 target, FILE *out) { assert(pool != NULL); assert(pool->entities[unit].is_enabled); assert(pool->entities[unit].unit.entry_point != UNDEFINED); @@ -439,16 +514,18 @@ void unit_write(entity_pool_t *pool, i64 unit, i16 target, FILE *out) { fwrite(code, 1, code_size, out); } -// ================================================================ +// Helpers implementation // -// Helpers -// -// ================================================================ + +#ifndef DISABLE_HELPERS // Global state // -static entity_pool_t g_pool = { 0 }; +static entity_pool_t g_pool = { + .entities_capacity = MAX_ENTITY_COUNT, + .entities = (entity_t[MAX_ENTITY_COUNT]) { 0 }, +}; // Handy procedures // @@ -493,11 +570,12 @@ void u_elf_x86_64(i64 unit, c8 const *output_file_name) { fclose(f); } -// ================================================================ -// -// Example +#endif + +// Example // -// ================================================================ + +#ifndef DISABLE_EXAMPLE int main(int argc, char **argv) { printf("node - %d bytes\n", (i32) sizeof(node_t)); @@ -517,3 +595,7 @@ int main(int argc, char **argv) { printf("\nBye!\n"); return 0; } + +#endif + +#endif |