From: Brendan Hansen Date: Sun, 23 May 2021 16:06:37 +0000 (-0500) Subject: added relative lookups on file_contents directives X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=fc42ccbfa29768aa6512b7e328ad8e06fcadf1a5;p=onyx.git added relative lookups on file_contents directives --- diff --git a/bin/onyx b/bin/onyx index 8b041462..b0d63f12 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index bd88b7fd..4db208e9 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -504,7 +504,14 @@ struct AstArrayAccess { AstTyped_base; AstTyped *addr; AstTyped *expr; u64 ele struct AstFieldAccess { AstTyped_base; AstTyped *expr; u32 offset; u32 idx; char* field; }; // If token is null, defer to field struct AstSizeOf { AstTyped_base; AstType *so_ast_type; Type *so_type; u64 size; }; struct AstAlignOf { AstTyped_base; AstType *ao_ast_type; Type *ao_type; u64 alignment; }; -struct AstFileContents { AstTyped_base; OnyxToken *filename; u32 addr, size; }; +struct AstFileContents { + AstTyped_base; + + OnyxToken *filename_token; + char *filename; // The parsed file name, with '\' sequences removed and resolved to a particular file if possible. + + u32 addr, size; +}; struct AstUnaryFieldAccess { AstTyped_base; diff --git a/include/onyxutils.h b/include/onyxutils.h index d1369e86..b9c9b219 100644 --- a/include/onyxutils.h +++ b/include/onyxutils.h @@ -30,3 +30,9 @@ u32 char_to_base16_value(char x); // Returns the length after processing the string. i32 string_process_escape_seqs(char* dest, char* src, i32 len); + +// NOTE: This should not be called until immediately before using the return value. +// This function can return a static variable which will change if this is called +// another time. -brendanfh 2020/10/09 +// :RelativeFiles This should lookup for the file relative to "relative_to" +char* lookup_included_file(char* filename, char* relative_to, b32 add_onyx_suffix, b32 search_included_folders); diff --git a/modules/immediate_mode/immediate_renderer.onyx b/modules/immediate_mode/immediate_renderer.onyx index 4fd88b2d..ba7d9259 100644 --- a/modules/immediate_mode/immediate_renderer.onyx +++ b/modules/immediate_mode/immediate_renderer.onyx @@ -3,62 +3,6 @@ package immediate_mode use package core #private_file gl :: package gl -// CLEANUP: Proper multi-line strings need to be added... -// This is a gross abuse of the lexer. -IMMEDIATE_VERTEX_SHADER :: "#version 300 es - -layout(location = 0) in vec2 a_vertex; -layout(location = 1) in vec4 a_color; -layout(location = 2) in vec2 a_texture; - -uniform mat4 u_view; -uniform mat4 u_world; - -out vec4 v_color; -out vec2 v_texture; - -void main() { - gl_Position = u_view * u_world * vec4(a_vertex, 0, 1); - - v_color = a_color; - v_texture = a_texture; -} -" - -IMMEDIATE_FRAGMENT_SHADER :: "#version 300 es - -precision mediump float; - -uniform sampler2D u_texture; - -in vec4 v_color; -in vec2 v_texture; - -out vec4 fragColor; - -void main() { - fragColor = v_color; -} -" - -IMMEDIATE_FRAGMENT_SHADER_TEXTURED :: "#version 300 es - -precision mediump float; - -uniform sampler2D u_texture; - -in vec4 v_color; -in vec2 v_texture; - -out vec4 fragColor; - -void main() { - fragColor = v_color * texture(u_texture, v_texture); -} -" - - - Vector2 :: struct { x, y: f32; } @@ -103,6 +47,10 @@ Immediate_Renderer :: struct { } init :: (use ir: ^Immediate_Renderer, max_verticies := Default_Max_Verticies) { + IMMEDIATE_VERTEX_SHADER :: #file_contents "./shaders/basic_vertex.glsl" + IMMEDIATE_FRAGMENT_SHADER :: #file_contents "./shaders/basic_fragment.glsl" + IMMEDIATE_FRAGMENT_SHADER_TEXTURED :: #file_contents "./shaders/textured_fragment.glsl" + simple_shader = Shader.make_from_source(IMMEDIATE_VERTEX_SHADER, IMMEDIATE_FRAGMENT_SHADER); textured_shader = Shader.make_from_source(IMMEDIATE_VERTEX_SHADER, IMMEDIATE_FRAGMENT_SHADER_TEXTURED); active_shader = ^simple_shader; diff --git a/modules/immediate_mode/shaders/basic_fragment.glsl b/modules/immediate_mode/shaders/basic_fragment.glsl new file mode 100644 index 00000000..f8bc23ca --- /dev/null +++ b/modules/immediate_mode/shaders/basic_fragment.glsl @@ -0,0 +1,14 @@ +#version 300 es + +precision mediump float; + +uniform sampler2D u_texture; + +in vec4 v_color; +in vec2 v_texture; + +out vec4 fragColor; + +void main() { + fragColor = v_color; +} \ No newline at end of file diff --git a/modules/immediate_mode/shaders/basic_vertex.glsl b/modules/immediate_mode/shaders/basic_vertex.glsl new file mode 100644 index 00000000..4c6edf42 --- /dev/null +++ b/modules/immediate_mode/shaders/basic_vertex.glsl @@ -0,0 +1,18 @@ +#version 300 es + +layout(location = 0) in vec2 a_vertex; +layout(location = 1) in vec4 a_color; +layout(location = 2) in vec2 a_texture; + +uniform mat4 u_view; +uniform mat4 u_world; + +out vec4 v_color; +out vec2 v_texture; + +void main() { + gl_Position = u_view * u_world * vec4(a_vertex, 0, 1); + + v_color = a_color; + v_texture = a_texture; +} \ No newline at end of file diff --git a/modules/immediate_mode/shaders/textured_fragment.glsl b/modules/immediate_mode/shaders/textured_fragment.glsl new file mode 100644 index 00000000..186e4c96 --- /dev/null +++ b/modules/immediate_mode/shaders/textured_fragment.glsl @@ -0,0 +1,14 @@ +#version 300 es + +precision mediump float; + +uniform sampler2D u_texture; + +in vec4 v_color; +in vec2 v_texture; + +out vec4 fragColor; + +void main() { + fragColor = v_color * texture(u_texture, v_texture); +} \ No newline at end of file diff --git a/src/onyx.c b/src/onyx.c index 01c5977c..ea6a5e58 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -206,58 +206,6 @@ static void context_free() { compile_opts_free(context.options); } -// NOTE: This should not be called until immediately before using the return value. -// This function can return a static variable which will change if this is called -// another time. -brendanfh 2020/10/09 -// :RelativeFiles This should lookup for the file relative to "relative_to" -static char* lookup_included_file(char* filename, char* relative_to) { - assert(relative_to != NULL); - - static char path[256]; - fori (i, 0, 256) path[i] = 0; - - static char fn[128]; - fori (i, 0, 128) fn[i] = 0; - - if (!bh_str_ends_with(filename, ".onyx")) { - bh_snprintf(fn, 128, "%s.onyx", filename); - } else { - bh_snprintf(fn, 128, "%s", filename); - } - -#if defined(_BH_LINUX) - #define DIR_SEPARATOR '/' -#elif defined(_BH_WINDOWS) - #define DIR_SEPARATOR '\\' -#endif - - fori (i, 0, 128) if (fn[i] == '/') fn[i] = DIR_SEPARATOR; - - if (bh_str_starts_with(filename, "./")) { - if (relative_to[strlen(relative_to) - 1] != DIR_SEPARATOR) - bh_snprintf(path, 256, "%s%c%s", relative_to, DIR_SEPARATOR, fn); - else - bh_snprintf(path, 256, "%s%s", relative_to, fn); - - if (bh_file_exists(path)) return bh_path_get_full_name(path, global_scratch_allocator); - - return fn; - } - - bh_arr_each(const char *, folder, context.options->included_folders) { - if ((*folder)[strlen(*folder) - 1] != DIR_SEPARATOR) - bh_snprintf(path, 256, "%s%c%s", *folder, DIR_SEPARATOR, fn); - else - bh_snprintf(path, 256, "%s%s", *folder, fn); - - if (bh_file_exists(path)) return bh_path_get_full_name(path, global_scratch_allocator); - } - - return fn; - -#undef DIR_SEPARATOR -} - static void parse_source_file(bh_file_contents* file_contents) { // :Remove passing the allocators as parameters OnyxTokenizer tokenizer = onyx_tokenizer_create(context.token_alloc, file_contents); @@ -304,7 +252,7 @@ static void process_load_entity(Entity* ent) { char* parent_folder = bh_path_get_parent(parent_file, global_scratch_allocator); - char* filename = lookup_included_file(include->name, parent_folder); + char* filename = lookup_included_file(include->name, parent_folder, 1, 1); char* formatted_name = bh_strdup(global_heap_allocator, filename); process_source_file(formatted_name, include->token->pos); diff --git a/src/onyxparser.c b/src/onyxparser.c index c24ff4e8..0b7195c6 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -483,7 +483,7 @@ static AstTyped* parse_factor(OnyxParser* parser) { if (parse_possible_directive(parser, "file_contents")) { AstFileContents* fc = make_node(AstFileContents, Ast_Kind_File_Contents); fc->token = parser->prev - 1; - fc->filename = expect_token(parser, Token_Type_Literal_String); + fc->filename_token = expect_token(parser, Token_Type_Literal_String); fc->type = type_make_slice(parser->allocator, &basic_types[Basic_Kind_U8]); ENTITY_SUBMIT(fc); diff --git a/src/onyxutils.c b/src/onyxutils.c index 49a10a9f..64a44ff1 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -1452,3 +1452,54 @@ i32 string_process_escape_seqs(char* dest, char* src, i32 len) { return total_len; } + +char* lookup_included_file(char* filename, char* relative_to, b32 add_onyx_suffix, b32 search_included_folders) { + assert(relative_to != NULL); + + static char path[256]; + fori (i, 0, 256) path[i] = 0; + + static char fn[128]; + fori (i, 0, 128) fn[i] = 0; + + if (!bh_str_ends_with(filename, ".onyx") && add_onyx_suffix) { + bh_snprintf(fn, 128, "%s.onyx", filename); + } else { + bh_snprintf(fn, 128, "%s", filename); + } + +#if defined(_BH_LINUX) + #define DIR_SEPARATOR '/' +#elif defined(_BH_WINDOWS) + #define DIR_SEPARATOR '\\' +#endif + + fori (i, 0, 128) if (fn[i] == '/') fn[i] = DIR_SEPARATOR; + + if (bh_str_starts_with(filename, "./")) { + if (relative_to[strlen(relative_to) - 1] != DIR_SEPARATOR) + bh_snprintf(path, 256, "%s%c%s", relative_to, DIR_SEPARATOR, fn + 2); + else + bh_snprintf(path, 256, "%s%s", relative_to, fn + 2); + + if (bh_file_exists(path)) return bh_path_get_full_name(path, global_scratch_allocator); + + return fn; + } + + if (search_included_folders) { + bh_arr_each(const char *, folder, context.options->included_folders) { + if ((*folder)[strlen(*folder) - 1] != DIR_SEPARATOR) + bh_snprintf(path, 256, "%s%c%s", *folder, DIR_SEPARATOR, fn); + else + bh_snprintf(path, 256, "%s%s", *folder, fn); + + if (bh_file_exists(path)) return bh_path_get_full_name(path, global_scratch_allocator); + } + } + + return fn; + +#undef DIR_SEPARATOR +} + diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 43b21cb1..851c7444 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -3081,26 +3081,40 @@ static void emit_memory_reservation(OnyxWasmModule* mod, AstMemRes* memres) { } static void emit_file_contents(OnyxWasmModule* mod, AstFileContents* fc) { - token_toggle_end(fc->filename); + token_toggle_end(fc->filename_token); - if (bh_table_has(StrLitInfo, mod->loaded_file_info, fc->filename->text)) { - StrLitInfo info = bh_table_get(StrLitInfo, mod->loaded_file_info, fc->filename->text); + // INVESTIGATE: I think that filename should always be NULL when this function starts because + // a file contents entity is only processed once and therefore should only go through this step + // once. But somehow filename isn't NULL occasionally so I have to check for that... + // - brendanfh 2021/05/23 + if (fc->filename == NULL) { + const char* parent_file = fc->token->pos.filename; + if (parent_file == NULL) parent_file = "."; + + char* parent_folder = bh_path_get_parent(parent_file, global_scratch_allocator); + + char* temp_fn = bh_alloc_array(global_scratch_allocator, char, fc->filename_token->length); + i32 temp_fn_len = string_process_escape_seqs(temp_fn, fc->filename_token->text, fc->filename_token->length); + char* filename = lookup_included_file(temp_fn, parent_folder, 0, 0); + fc->filename = bh_strdup(global_heap_allocator, filename); + } + + token_toggle_end(fc->filename_token); + + if (bh_table_has(StrLitInfo, mod->loaded_file_info, fc->filename)) { + StrLitInfo info = bh_table_get(StrLitInfo, mod->loaded_file_info, fc->filename); fc->addr = info.addr; fc->size = info.len; - - token_toggle_end(fc->filename); return; } u32 offset = mod->next_datum_offset; bh_align(offset, 16); - if (!bh_file_exists(fc->filename->text)) { - onyx_report_error(fc->filename->pos, + if (!bh_file_exists(fc->filename)) { + onyx_report_error(fc->filename_token->pos, "Unable to open file for reading, '%s'.", - fc->filename->text); - - token_toggle_end(fc->filename); + fc->filename); return; } @@ -3108,14 +3122,14 @@ static void emit_file_contents(OnyxWasmModule* mod, AstFileContents* fc) { // if the filename is prefixed with a './' or '.\\' then it should be relative to the // file in which is was inclded. The loaded file info above should probably use the full // file path in order to avoid duplicates. - bh_file_contents contents = bh_file_read_contents(global_heap_allocator, fc->filename->text); + bh_file_contents contents = bh_file_read_contents(global_heap_allocator, fc->filename); 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); - bh_table_put(StrLitInfo, mod->loaded_file_info, fc->filename->text, ((StrLitInfo) { + bh_table_put(StrLitInfo, mod->loaded_file_info, fc->filename, ((StrLitInfo) { .addr = offset, .len = length - 1, })); @@ -3132,8 +3146,6 @@ static void emit_file_contents(OnyxWasmModule* mod, AstFileContents* fc) { bh_arr_push(mod->data, datum); mod->next_datum_offset = offset + length; - - token_toggle_end(fc->filename); } OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) {