#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);
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;
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;
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;
}
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"
"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"
" 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) {
}
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) {
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));
}