summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-06-09 21:28:30 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-06-09 21:28:30 +0200
commitcc1cd3f8f48dc506086715bb207dfbf175c11575 (patch)
tree8625d6ab13d4c5374b880b935bc1c1e15aca24ef
parent31f95ee266e507a3155a82899531851c7202f0a3 (diff)
downloadbxgen-cc1cd3f8f48dc506086715bb207dfbf175c11575.zip
Cleanup; docs
-rwxr-xr-xbxgen.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