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;
// 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);
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;
}
}
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;
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
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);
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);
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);
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
+}
+
}
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;
}
// 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,
}));
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) {