From: Brendan Hansen Date: Thu, 3 Sep 2020 15:38:12 +0000 (-0500) Subject: added ability to output a tag file X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=234fd065b88e21bc7a65a4bf55fa3f9de7a9372d;p=onyx.git added ability to output a tag file --- diff --git a/core/js/webgl.js b/core/js/webgl.js index 16b971e2..1199e896 100644 --- a/core/js/webgl.js +++ b/core/js/webgl.js @@ -11,6 +11,7 @@ WebGl_Wasm = { this.renderbuffers = []; this.textures = []; this.uniformlocs = []; + this.vertexArrays = []; this.canvas = document.getElementById(canvasname); if (this.canvas == null) return 0; @@ -34,6 +35,8 @@ WebGl_Wasm = { bindFramebuffer(target, framebuffer) { this.gl.bindFramebuffer(target, this.framebuffers[framebuffer]); }, bindRenderbuffer(target, renderbuffer) { this.gl.bindRenderbuffer(target, this.renderbuffers[renderbuffer]); }, bindTexture(target, texture) { this.gl.bindTexture(target, this.textures[texture]); }, + bindVertexArray(vertexArray) { this.gl.bindVertexArray(this.vertexArrays[vertexArray]); }, + blendColor(red, green, blue, alpha) { this.gl.blendColor(red, green, blue, alpha); }, blendEquation(mode) { this.gl.blendEquation(mode); }, blendEquationSeparate(modeRGB, modeAlpha) { this.gl.blendEquationSeparate(modeRGB, modeAlpha); }, @@ -118,6 +121,13 @@ WebGl_Wasm = { this.textures.push(texture); return this.textures.length - 1; }, + createVertexArray() { + const vao = this.gl.createVertexArray(); + if (vao == null) return -1; + + this.vertexArrays.push(vao); + return this.vertexArrays.length - 1; + }, cullFace(mode) { this.gl.cullFace(mode); }, deleteBuffer(buffer) { this.gl.deleteBuffer(this.buffers[buffer]); }, deleteFramebuffer(framebuffer) { this.gl.deleteFramebuffer(this.framebuffers[framebuffer]); }, @@ -125,6 +135,7 @@ WebGl_Wasm = { deleteRenderbuffer(renderbuffer) { this.gl.deleteRenderbuffer(this.renderbuffers[renderbuffer]); }, deleteShader(shader) { this.gl.deleteShader(this.shaders[shader]); }, deleteTexture(texture) { this.gl.deleteTexture(this.textures[texture]); }, + deleteVertexArray(vertexArray) { this.gl.deleteVertexArray(this.vertexArrays[vertexArray]); }, depthFunc(func) { this.gl.depthFunc(func); }, depthMask(flag) { this.gl.depthMask(flag); }, depthRange(znear, zfar) { this.gl.depthRange(znear, zfar); }, @@ -132,7 +143,9 @@ WebGl_Wasm = { disable(cap) { this.gl.disable(cap); }, disableVertexAttribArray(index) { this.gl.disableVertexAttribArray(index); }, drawArrays(mode, first, count) { this.gl.drawArrays(mode, first, count); }, + drawArraysInstanced(mode, first, count, instanceCount) { this.gl.drawArraysInstanced(mode, first, count, instanceCount); }, drawElements(mode, count, type, offset) { this.gl.drawElements(mode, count, type, offset); }, + drawElementsInstanced(mode, count, type, offset, instanceCount) { this.gl.drawElementsInstanced(mode, count, type, offset, instanceCount); }, enable(cap) { this.gl.enable(cap); }, enableVertexAttribArray(index) { this.gl.enableVertexAttribArray(index); }, finish() { this.gl.finish(); }, @@ -261,6 +274,7 @@ WebGl_Wasm = { vertexAttrib3f(idx, x, y, z) { this.gl.vertexAttrib3f(idx, x, y, z); }, vertexAttrib4f(idx, x, y, z, w) { this.gl.vertexAttrib4f(idx, x, y, z, w); }, vertexAttribPointer(idx, size, type, normalized, stride, offset) { this.gl.vertexAttribPointer(idx, size, type, normalized, stride, offset); }, + vertexAttribDivisor(idx, divisor) { this.gl.vertexAttribDivisor(idx, divisor); }, viewport(x, y, width, height) { this.gl.viewport(x, y, width, height); }, }; diff --git a/core/js/webgl.onyx b/core/js/webgl.onyx index d738253c..a4d2afea 100644 --- a/core/js/webgl.onyx +++ b/core/js/webgl.onyx @@ -1,6 +1,6 @@ package gl // To be used with the corresponding gl.js - +// There are many things that are missing but this suffices for me. // ClearBufferMask @@ -708,6 +708,7 @@ GLRenderbuffer :: #type i32 GLTexture :: #type i32 GLBuffer :: #type i32 GLUniformLocation :: #type i32 +GLVertexArrayObject :: #type i32 GLActiveInfo :: struct { size : GLint; @@ -728,6 +729,7 @@ bindBuffer :: proc (target: GLenum, buffer: GLBuffer) #forei bindFramebuffer :: proc (target: GLenum, framebuffer: GLFramebuffer) #foreign "gl" "bindFramebuffer" --- bindRenderbuffer :: proc (target: GLenum, renderbuffer: GLRenderbuffer) #foreign "gl" "bindRenderbuffer" --- bindTexture :: proc (target: GLenum, texture: GLTexture) #foreign "gl" "bindTexture" --- +bindVertexArray :: proc (vertexArray: GLVertexArrayObject) #foreign "gl" "bindVertexArray" --- blendColor :: proc (red: GLclampf, green: GLclampf, blue: GLclampf, alpha: GLclampf) #foreign "gl" "blendColor" --- blendEquation :: proc (mode: GLenum) #foreign "gl" "blendEquation" --- blendEquationSeparate :: proc (modeRGB: GLenum, modeAlpha: GLenum) #foreign "gl" "blendEquationSeparate" --- @@ -737,7 +739,7 @@ blitFramebuffer :: proc (sx0: GLint, sy0: GLint, sx1: GLint, sy1: bufferDataWithData :: proc (target: GLenum, buffer: Buffer, usage: GLenum) #foreign "gl" "bufferDataWithData" --- bufferDataNoData :: proc (target: GLenum, size: GLsizeiptr, usage: GLenum) #foreign "gl" "bufferDataNoData" --- bufferData :: proc #overloaded { bufferDataWithData, bufferDataNoData } -bufferSubData :: proc (target: GLenum, offset: GLintptr, data: string) #foreign "gl" "bufferSubData" --- +bufferSubData :: proc (target: GLenum, offset: GLsizei, data: Buffer) #foreign "gl" "bufferSubData" --- checkFrameBufferStatus :: proc (target: GLenum) -> GLenum #foreign "gl" "checkFrameBufferStatus" --- clear :: proc (mask: GLbitfield) #foreign "gl" "clear" --- clearColor :: proc (red: GLclampf, green: GLclampf, blue: GLclampf, alpha: GLclampf) #foreign "gl" "clearColor" --- @@ -756,6 +758,7 @@ createProgram :: proc -> GLProgram #foreign "gl" "createProgram createRenderbuffer :: proc -> GLRenderbuffer #foreign "gl" "createRenderbuffer" --- createShader :: proc (type: GLenum) -> GLShader #foreign "gl" "createShader" --- createTexture :: proc -> GLTexture #foreign "gl" "createTexture" --- +createVertexArray :: proc -> GLVertexArrayObject #foreign "gl" "createVertexArray" --- cullFace :: proc (mode: GLenum) #foreign "gl" "cullFace" --- deleteBuffer :: proc (buffer: GLBuffer) #foreign "gl" "deleteBuffer" --- deleteFramebuffer :: proc (framebuffer: GLFramebuffer) #foreign "gl" "deleteFramebuffer" --- @@ -763,6 +766,7 @@ deleteProgram :: proc (program: GLProgram) #foreign "gl" "delet deleteRenderbuffer :: proc (renderbuffer: GLRenderbuffer) #foreign "gl" "deleteRenderbuffer" --- deleteShader :: proc (shader: GLShader) #foreign "gl" "deleteShader" --- deleteTexture :: proc (texture: GLTexture) #foreign "gl" "deleteTexture" --- +deleteVertexArray :: proc (vertexArray: GLVertexArrayObject) #foreign "gl" "deleteVertexArray" --- depthFunc :: proc (func: GLenum) #foreign "gl" "depthFunc" --- depthMask :: proc (flag: GLboolean) #foreign "gl" "depthMask" --- depthRange :: proc (zNear: GLclampf, zFar: GLclampf) #foreign "gl" "depthRange" --- @@ -770,7 +774,9 @@ detachShader :: proc (program: GLProgram, shader: GLShader) #f disable :: proc (cap: GLenum) #foreign "gl" "disable" --- disableVertexAttribArray :: proc (index: GLuint) #foreign "gl" "disableVertexAttribArray" --- drawArrays :: proc (mode: GLenum, first: GLint, count: GLsizei) #foreign "gl" "drawArrays" --- +drawArraysInstanced :: proc (mode: GLenum, first: GLint, count: GLsizei, instanceCount: GLsizei) #foreign "gl" "drawArraysInstanced" --- drawElements :: proc (mode: GLenum, count: GLsizei, type: GLenum, offset: GLint) #foreign "gl" "drawElements" --- +drawElementsInstanced :: proc (mode: GLenum, count: GLsizei, type: GLenum, offset: GLint, instanceCount: GLsizei) #foreign "gl" "drawElementsInstanced" --- enable :: proc (cap: GLenum) #foreign "gl" "enable" --- enableVertexAttribArray :: proc (index: GLuint) #foreign "gl" "enableVertexAttribArray" --- finish :: proc #foreign "gl" "finish" --- @@ -838,4 +844,5 @@ vertexAttrib2f :: proc (idx: GLuint, x: GLfloat, y: GLfloat) #fo vertexAttrib3f :: proc (idx: GLuint, x: GLfloat, y: GLfloat, z: GLfloat) #foreign "gl" "vertexAttrib3f" --- vertexAttrib4f :: proc (idx: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat) #foreign "gl" "vertexAttrib4f" --- vertexAttribPointer :: proc (idx: GLuint, size: GLint, type: GLenum, normalized: GLboolean, stride: GLsizei, offset: GLint) #foreign "gl" "vertexAttribPointer" --- +vertexAttribDivisor :: proc (idx: GLuint, divisor: GLuint) #foreign "gl" "vertexAttribDivisor" --- viewport :: proc (x: GLint, y: GLint, width: GLsizei, height: GLsizei) #foreign "gl" "viewport" --- diff --git a/core/stdio.onyx b/core/stdio.onyx index a0f0794b..3d2fc0f5 100644 --- a/core/stdio.onyx +++ b/core/stdio.onyx @@ -39,6 +39,8 @@ print_array :: proc (arr: $T, sep := " ") { } print_buffer_flush :: proc { + if print_buffer.len == 0 do return; + ^print_buffer |> string_builder_to_string() |> system.output_string(); diff --git a/core/string.onyx b/core/string.onyx index 3804ea35..9dac85d4 100644 --- a/core/string.onyx +++ b/core/string.onyx @@ -26,9 +26,6 @@ string_length :: proc #overloaded { }, } -#private -string_length_string :: proc (s: string) -> u32 do return s.count; - string_concat :: proc (s1: string, s2: string) -> string { len1 :: string_length(s1); len2 :: string_length(s2); diff --git a/docs/cli b/docs/cli new file mode 100644 index 00000000..e372cc09 --- /dev/null +++ b/docs/cli @@ -0,0 +1,21 @@ +Thoughts about the CLI for Onyx +------------------------------- + +Right now, unless a specific argument is recognized, it is treated as a file to add to the compilation. +This has worked well, but as the amount of functionality that is being added to the compiler is increasing, +the need for a better CLI system is imminent. + +Here are all the things the compiler should be able to do: + * Compile a file or a set of files + * Validate a file or set of files + - Everything done in compilations + - No outputting to final WASM file + * Generate documentation for a compilation + - In Human, Tags, or Html format + * Print a help menu + + + + $ onyx compile progs/poly_test.onyx -I other_folder + + $ onyx doc progs/poly_test.onyx --format tag diff --git a/docs/plan b/docs/plan index 60b058bf..ba6b114e 100644 --- a/docs/plan +++ b/docs/plan @@ -174,7 +174,7 @@ HOW: X All members specified means names not required X Named member initialization X Default values on structs so they don't have to be named - + [X] #union on structs [X] #align on structs @@ -201,7 +201,7 @@ HOW: [X] Add slices - Arrays without a size - - Converted to a struct that looks like: + - Converted to a struct that looks like: []T :: struct { data : ^T; count : u32; @@ -226,8 +226,17 @@ HOW: [X] #file and #line directives - string and u32 respectively that represent the current file and line number where the directive is + [X] Generate a tags file + - This looks very simple + - I think all the infrastructure is there for this + [ ] data structure based iteration + [ ] baked parameters + - Compile time known parameters + - Removes the argument from the list and replaces the function with the + baked function + [ ] Put type info in data section so it is runtime accessible - type name - size diff --git a/include/onyxdoc.h b/include/onyxdoc.h index b3b3ba73..b5ec16d7 100644 --- a/include/onyxdoc.h +++ b/include/onyxdoc.h @@ -4,8 +4,15 @@ #include "bh.h" #include "onyxastnodes.h" +typedef enum DocFormat { + Doc_Format_Human, + Doc_Format_Tags, + Doc_Format_Html, +} DocFormat; + typedef struct DocEntry { OnyxFilePos pos; + char* sym; // Unused by doc generator char* def; char* additional; } DocEntry; @@ -20,10 +27,12 @@ typedef struct DocPackage { typedef struct OnyxDocumentation { bh_arena doc_arena; + DocFormat format; + bh_arr(DocPackage) package_docs; } OnyxDocumentation; OnyxDocumentation onyx_docs_generate(ProgramInfo* prog); -void onyx_docs_write(OnyxDocumentation* doc); +void onyx_docs_emit(OnyxDocumentation* doc); -#endif \ No newline at end of file +#endif diff --git a/onyx b/onyx index a21c5056..bfe7d9cd 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/poly_test.onyx b/progs/poly_test.onyx index 69f65488..b4a68d62 100644 --- a/progs/poly_test.onyx +++ b/progs/poly_test.onyx @@ -119,7 +119,7 @@ main :: proc (args: [] cstring) { print(ptrmap_has(^map, ^s.a[20])); print("\n"); } - + main2 :: proc (args: [] cstring) { print(cast(u32) __heap_start, 16); @@ -223,4 +223,4 @@ cmp_vec3 :: proc (v1: Vec3, v2: Vec3) -> i32 { if v1.x != v2.x do return v1.x - v2.x; if v1.y != v2.y do return v1.y - v2.y; return v1.z - v2.z; -} \ No newline at end of file +} diff --git a/src/onyx.c b/src/onyx.c index b1628aa6..59b6acf3 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -334,6 +334,16 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char* bh_file_contents fc = bh_file_read_contents(compiler_state->token_alloc, &file); bh_file_close(&file); + // POTENTIAL BUG: If there are too many files and too many collisions in the table, + // there is a chance that the inner arrays of the table will be repositioned. That + // would completely break the pointer taken here, which would break all references + // to file contents anywhere else in the program. + // + // A good solution would be to not use a table and just use a array of char* and + // ensure that the filename is not in that list. + // - brendanfh 2020/09/03 + + // NOTE: Need to reget the value out of the table so token references work bh_table_put(bh_file_contents, compiler_state->loaded_files, (char *) filename, fc); fc = bh_table_get(bh_file_contents, compiler_state->loaded_files, (char *) filename); @@ -394,7 +404,8 @@ static i32 onyx_compile(CompilerState* compiler_state) { if (compiler_state->options->action == ONYX_COMPILE_ACTION_DOCUMENT) { OnyxDocumentation docs = onyx_docs_generate(&compiler_state->prog_info); - onyx_docs_write(&docs); + docs.format = Doc_Format_Tags; + onyx_docs_emit(&docs); return ONYX_COMPILER_PROGRESS_SUCCESS; } diff --git a/src/onyxdoc.c b/src/onyxdoc.c index 918f6e8c..fbe7515d 100644 --- a/src/onyxdoc.c +++ b/src/onyxdoc.c @@ -12,7 +12,7 @@ static i32 cmp_doc_entry(const void * a, const void * b) { static i32 cmp_doc_package(const void * a, const void * b) { DocPackage* d1 = (DocPackage *) a; DocPackage* d2 = (DocPackage *) b; - + return strncmp(d1->name, d2->name, 1024); } @@ -79,7 +79,8 @@ static char* node_to_doc_def(const char* sym, AstNode *node, bh_allocator a) { case Ast_Kind_Basic_Type: case Ast_Kind_Array_Type: case Ast_Kind_Type_Alias: - case Ast_Kind_Slice_Type: { + case Ast_Kind_Slice_Type: + case Ast_Kind_DynArr_Type: { strncat(buf, type_get_name(type_build_from_ast(global_heap_allocator, (AstType *) node)), 1023); break; } @@ -105,6 +106,7 @@ static DocPackage doc_package_create(Package* p, bh_allocator a) { DocEntry de; de.pos = value->token->pos; de.def = node_to_doc_def(key, value, a); + de.sym = (char *) key; de.additional = NULL; bh_arr_push(dp.public_entries, de); @@ -114,6 +116,7 @@ static DocPackage doc_package_create(Package* p, bh_allocator a) { DocEntry de; de.pos = value->token->pos; de.def = node_to_doc_def(key, value, a); + de.sym = (char *) key; de.additional = NULL; bh_arr_push(dp.private_entries, de); @@ -144,7 +147,7 @@ OnyxDocumentation onyx_docs_generate(ProgramInfo* prog) { return doc; } -void onyx_docs_write(OnyxDocumentation* doc) { +static void onyx_docs_emit_human(OnyxDocumentation* doc) { // NOTE: Disabling fancy line printing until I can make it better #if 0 bh_arr_each(DocPackage, dp, doc->package_docs) { @@ -214,3 +217,66 @@ void onyx_docs_write(OnyxDocumentation* doc) { } #endif } + + +static i32 sort_tags(const void* a, const void* b) { + DocEntry *da = *((DocEntry **) a); + DocEntry *db = *((DocEntry **) b); + + return strcmp(da->sym, db->sym); +} + +static void onyx_docs_emit_tags(OnyxDocumentation* doc) { + bh_file tags_file; + if (bh_file_create(&tags_file, "./tags") != BH_FILE_ERROR_NONE) { + bh_printf("Cannot create 'tags'.\n"); + return; + } + + bh_fprintf(&tags_file, "!_TAG_FILE_FORMAT\t2\n"); + bh_fprintf(&tags_file, "!_TAG_FILE_SORTED\t1\n"); + bh_fprintf(&tags_file, "!_TAG_OUTPUT_FILESEP\tslash\n"); + bh_fprintf(&tags_file, "!_TAG_OUTPUT_MODE\tu-ctags\n"); + bh_fprintf(&tags_file, "!_TAG_PROGRAM_AUTHOR\tOnyx Compiler\n"); + bh_fprintf(&tags_file, "!_TAG_PROGRAM_NAME\tOnyx Compiler\n"); + bh_fprintf(&tags_file, "!_TAG_PROGRAM_URL\thttps://github.com/brendanfh/onyx\n"); + bh_fprintf(&tags_file, "!_TAG_PROGRAM_VERSION\t0.0.1\n"); + + bh_arr(DocEntry *) tags = NULL; + bh_arr_new(global_heap_allocator, tags, 256); + + bh_arr_each(DocPackage, dp, doc->package_docs) { + bh_arr_each(DocEntry, de, dp->public_entries) bh_arr_push(tags, de); + bh_arr_each(DocEntry, de, dp->private_entries) bh_arr_push(tags, de); + } + + qsort(tags, bh_arr_length(tags), sizeof(DocEntry *), sort_tags); + + bh_arr_each(DocEntry *, tag, tags) { + if ((*tag)->pos.filename == NULL) continue; + + i32 line_len = 0; + char *c = (*tag)->pos.line_start; + while (*c++ != '\n') line_len++; + + bh_fprintf(&tags_file, "%s\t%s\t/^%b$/\n", + (*tag)->sym, (*tag)->pos.filename, + (*tag)->pos.line_start, line_len); + } + + bh_file_close(&tags_file); +} + +static void onyx_docs_emit_html(OnyxDocumentation* doc) { + bh_printf("HTML documentation output not supported yet.\n"); + return; +} + +void onyx_docs_emit(OnyxDocumentation* doc) { + switch (doc->format) { + case Doc_Format_Human: onyx_docs_emit_human(doc); break; + case Doc_Format_Tags: onyx_docs_emit_tags(doc); break; + case Doc_Format_Html: onyx_docs_emit_html(doc); break; + } +} + diff --git a/src/onyxerrors.c b/src/onyxerrors.c index 5e9879d0..ed8bc702 100644 --- a/src/onyxerrors.c +++ b/src/onyxerrors.c @@ -50,6 +50,13 @@ static void print_detailed_message(OnyxError* err, bh_file_contents* fc) { } void onyx_errors_print() { + // NOTE: If the format of the error messages is ever changed, + // update onyx_compile.vim and onyx.sublime-build to match + // the new format. This was editor error highlighting is still + // supported. + // + // - brendanfh 2020/09/03 + bh_arr_each(OnyxError, err, errors.errors) { if (err->pos.filename) { bh_file_contents* fc = &bh_table_get(bh_file_contents, *errors.file_contents, (char *) err->pos.filename);