this.renderbuffers = [];
this.textures = [];
this.uniformlocs = [];
+ this.vertexArrays = [];
this.canvas = document.getElementById(canvasname);
if (this.canvas == null) return 0;
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); },
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]); },
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); },
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(); },
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); },
};
package gl
// To be used with the corresponding gl.js
-
+// There are many things that are missing but this suffices for me.
// ClearBufferMask
GLTexture :: #type i32
GLBuffer :: #type i32
GLUniformLocation :: #type i32
+GLVertexArrayObject :: #type i32
GLActiveInfo :: struct {
size : GLint;
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" ---
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" ---
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" ---
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" ---
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" ---
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" ---
}
print_buffer_flush :: proc {
+ if print_buffer.len == 0 do return;
+
^print_buffer
|> string_builder_to_string()
|> system.output_string();
},
}
-#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);
--- /dev/null
+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
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
[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;
[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
#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;
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
print(ptrmap_has(^map, ^s.a[20]));
print("\n");
}
-
+
main2 :: proc (args: [] cstring) {
print(cast(u32) __heap_start, 16);
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
+}
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);
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;
}
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);
}
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;
}
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);
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);
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) {
}
#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;
+ }
+}
+
}
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);