implemented Entity_Type_File_Contents
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 20 Apr 2021 00:51:44 +0000 (19:51 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 20 Apr 2021 00:51:44 +0000 (19:51 -0500)
include/onyxc.h
src/onyxc.c
src/onyxc_output.c

index b82e450f1de0f6b5f1154f031c7ad188e2b8adb2..25902420b1e129d281036fb6879fa94c11949e9e 100644 (file)
@@ -16,6 +16,12 @@ typedef struct CStringLiteral {
     char* data;
 } CStringLiteral;
 
+typedef struct LoadedFileInfo {
+    i32   number;
+    i32   size;
+    char* data;
+} LoadedFileInfo;
+
 typedef struct OnyxCFile {
     
     bh_arr(CMemoryReservation) memory_reservations;
@@ -23,6 +29,8 @@ typedef struct OnyxCFile {
     u32 next_string_literal_idx;
     bh_table(CStringLiteral) string_literals;
 
+    u32 next_file_contents_idx;
+    bh_table(LoadedFileInfo) loaded_file_info;
 
 } OnyxCFile;
 
index b24d1c27703ed9cfa75924d8fe0c65a07731f472..807866890f28114721a4f949f688684efbfd393f 100644 (file)
@@ -1,8 +1,9 @@
 #include "onyxc.h"
 #include "onyxutils.h"
+#include "onyxerrors.h"
 
+// :Duplicated
 static void emit_string_literal(OnyxCFile* c_file, AstStrLit* strlit) {
-    
     i8* strdata = bh_alloc_array(global_heap_allocator, i8, strlit->token->length + 1);
     i32 length  = string_process_escape_seqs(strdata, strlit->token->text, strlit->token->length);
 
@@ -28,6 +29,48 @@ static void emit_string_literal(OnyxCFile* c_file, AstStrLit* strlit) {
     bh_table_put(CStringLiteral, c_file->string_literals, (char *) strdata, csl);
 }
 
+// :Duplicated
+static void emit_file_contents(OnyxCFile* c_file, AstFileContents* fc) {
+    token_toggle_end(fc->filename);
+
+    if (bh_table_has(LoadedFileInfo, c_file->loaded_file_info, fc->filename->text)) {
+        LoadedFileInfo info = bh_table_get(LoadedFileInfo, c_file->loaded_file_info, fc->filename->text);
+        fc->addr = info.number;
+        fc->size = info.size;
+
+        token_toggle_end(fc->filename);
+        return;
+    }
+
+    if (!bh_file_exists(fc->filename->text)) {
+        onyx_report_error(fc->filename->pos,
+                "Unable to open file for reading, '%s'.",
+                fc->filename->text);
+
+        token_toggle_end(fc->filename);
+        return;
+    }
+
+    bh_file_contents contents = bh_file_read_contents(global_heap_allocator, fc->filename->text);
+    u8* actual_data = bh_alloc(global_heap_allocator, contents.length + 1);
+    u32 length = contents.length + 1;
+    memcpy(actual_data, contents.data, contents.length);
+    actual_data[contents.length] = 0;
+    bh_file_contents_free(&contents);
+
+    LoadedFileInfo lfi = {
+        .number = c_file->next_file_contents_idx,
+        .size   = length,
+        .data   = actual_data,
+    };
+    c_file->next_file_contents_idx++;
+
+    bh_table_put(LoadedFileInfo, c_file->loaded_file_info, fc->filename->text, lfi);
+
+    fc->addr = lfi.number;
+    fc->size = length - 1;
+}
+
 void emit_c_entity(Entity *ent) {
     OnyxCFile* c_file = context.c_file;
 
@@ -36,6 +79,11 @@ void emit_c_entity(Entity *ent) {
             emit_string_literal(c_file, ent->strlit);
             break;
         }
+
+        case Entity_Type_File_Contents: {
+            emit_file_contents(c_file, ent->file_contents);
+            break;
+        }
     }
 
     ent->state = Entity_State_Finalized;
@@ -50,7 +98,11 @@ OnyxCFile onyx_c_file_create(bh_allocator alloc) {
 
     cfile.next_string_literal_idx = 0;
     cfile.string_literals = NULL;
-    bh_table_init(alloc, cfile.string_literals, 4);
+    bh_table_init(alloc, cfile.string_literals, 16);
+
+    cfile.next_file_contents_idx = 0;
+    cfile.loaded_file_info = NULL;
+    bh_table_init(alloc, cfile.loaded_file_info, 4);
 
     return cfile;
 }
index cb1d357584612cf6be8520f09921c1b822bbc0e3..40cc4894e807ab4d81f8037d5d2ea32e0594b9d1 100644 (file)
@@ -4,6 +4,8 @@
 static char* BOILERPLATE_TOP =
     "#include <stdlib.h>\n"
     "#include <stdint.h>\n"
+    "\n"
+    "// Base types\n"
     "typedef uint8_t  u8;\n"
     "typedef uint16_t u16;\n"
     "typedef uint32_t u32;\n"
@@ -14,9 +16,10 @@ static char* BOILERPLATE_TOP =
     "typedef int64_t  i64;\n"
     "typedef float    f32;\n"
     "typedef double   f64;\n"
-    "typedef void    *rawptr;\n";
+    "typedef void    *rawptr;\n\n";
 
 static char* REGISTER_DEFINITION =
+    "// The core Register type\n"
     "typedef union Register {\n"
     "    u8 u8;\n"
     "    i8 i8;\n"
@@ -29,15 +32,16 @@ static char* REGISTER_DEFINITION =
     "    f32 f32;\n"
     "    f64 f64;\n"
     "    rawptr rawptr;\n"
-    "} Register;\n";
+    "} Register;\n\n";
 
 static char* ENTRYPOINT =
     "int main(int argc, char* argv[]) {\n"
-    "    puts(\"Nothing so far!\");\n"
+    "    puts(__string1);\n"
     "    return 0;\n"
-    "}\n";
+    "}\n\n";
 
 static void output_string_literals(OnyxCFile* c_file, bh_file file) {
+    bh_fprintf(&file, "// String Literals\n");
     bh_table_each_start(CStringLiteral, c_file->string_literals);
         bh_fprintf(&file, "static const char __string%d[] = {", value.number);
         fori (i, 0, value.size) {
@@ -45,6 +49,19 @@ static void output_string_literals(OnyxCFile* c_file, bh_file file) {
         }
         bh_fprintf(&file, "0};\n");
     bh_table_each_end;
+    bh_fprintf(&file, "\n");
+}
+
+static void output_file_contents(OnyxCFile* c_file, bh_file file) {
+    bh_fprintf(&file, "// File Contents\n");
+    bh_table_each_start(LoadedFileInfo, c_file->loaded_file_info);
+        bh_fprintf(&file, "static const char __file_contents%d[] = {", value.number);
+        fori (i, 0, value.size) {
+            bh_fprintf(&file, "%d,", (u32) value.data[i]);
+        }
+        bh_fprintf(&file, "0};\n");
+    bh_table_each_end;
+    bh_fprintf(&file, "\n");
 }
 
 void onyx_output_c_file(OnyxCFile* c_file, bh_file file) {
@@ -52,6 +69,7 @@ void onyx_output_c_file(OnyxCFile* c_file, bh_file file) {
     bh_file_write(&file, REGISTER_DEFINITION, strlen(REGISTER_DEFINITION));
 
     output_string_literals(c_file, file);
+    output_file_contents(c_file, file);
 
     bh_file_write(&file, ENTRYPOINT, strlen(ENTRYPOINT));
 }