From a0d1d841829411133b3bea1cef835fd8f16b21fe Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Thu, 8 Dec 2022 23:55:57 -0600 Subject: [PATCH] added `--tag` command line argument for generating ctag file --- compiler/include/astnodes.h | 8 + compiler/include/doc.h | 2 + compiler/src/doc.c | 523 ++++++++++++++++++------------------ compiler/src/onyx.c | 26 +- compiler/src/parser.c | 2 +- compiler/src/symres.c | 2 + compiler/src/utils.c | 7 + core/container/iter.onyx | 32 +++ 8 files changed, 333 insertions(+), 269 deletions(-) diff --git a/compiler/include/astnodes.h b/compiler/include/astnodes.h index fbfa4acc..3ad01782 100644 --- a/compiler/include/astnodes.h +++ b/compiler/include/astnodes.h @@ -1589,6 +1589,8 @@ struct CompileOptions { b32 generate_foreign_info : 1; b32 no_std : 1; + b32 generate_tag_file : 1; + Runtime runtime; bh_arr(const char *) included_folders; @@ -1619,6 +1621,10 @@ struct Context { // NOTE: This is defined in onyxwasm.h struct OnyxWasmModule* wasm_module; + // NOTE: All definitions (bindings, injections, aliases) are + // present in this list when generating CTags. + bh_arr(AstNode *) tag_locations; + b32 cycle_almost_detected : 1; b32 cycle_detected : 1; }; @@ -1796,6 +1802,8 @@ Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySoluti b32 resolve_intrinsic_interface_constraint(AstConstraint *constraint); +void track_declaration_for_tags(AstNode *); + // NOTE: Useful inlined functions static inline b32 is_lval(AstNode* node) { node = strip_aliases(node); diff --git a/compiler/include/doc.h b/compiler/include/doc.h index 75d4bfc5..b34b1031 100644 --- a/compiler/include/doc.h +++ b/compiler/include/doc.h @@ -35,4 +35,6 @@ typedef struct OnyxDocumentation { OnyxDocumentation onyx_docs_generate(); void onyx_docs_emit(OnyxDocumentation* doc, const char* filename); +void onyx_docs_emit_tags(char *dest); + #endif diff --git a/compiler/src/doc.c b/compiler/src/doc.c index 2a8bbd44..fb716cb9 100644 --- a/compiler/src/doc.c +++ b/compiler/src/doc.c @@ -2,236 +2,23 @@ #include "utils.h" #include "types.h" -static i32 cmp_doc_entry(const void * a, const void * b) { - DocEntry* d1 = (DocEntry *) a; - DocEntry* d2 = (DocEntry *) b; - - return strncmp(d1->def, d2->def, 1024); -} - -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); -} - -static char* node_to_doc_def(const char* sym, AstNode *node, bh_allocator a) { - static char buf[1024]; - memset(buf, 0, 1023); - - strncat(buf, sym, 1023); - strncat(buf, " :: ", 1023); - - switch (node->kind) { - case Ast_Kind_Function: { - strncat(buf, "(", 1023); - - AstFunction *func = (AstFunction *) node; - bh_arr_each(AstParam, param, func->params) { - if (param != func->params) - strncat(buf, ", ", 1023); - - token_toggle_end(param->local->token); - strncat(buf, param->local->token->text, 1023); - token_toggle_end(param->local->token); - - strncat(buf, ": ", 1023); - - strncat(buf, type_get_name(param->local->type), 1023); - - if (param->default_value != NULL) { - strncat(buf, " = ", 1023); - } - } - - strncat(buf, ") -> ", 1023); - strncat(buf, type_get_name(func->type->Function.return_type), 1023); - - break; - } - - case Ast_Kind_Struct_Type: { - strncat(buf, "struct { ", 1023); - - AstStructType* st = (AstStructType *) node; - bh_arr_each(AstStructMember *, smem, st->members) { - - token_toggle_end((*smem)->token); - strncat(buf, (*smem)->token->text, 1023); - token_toggle_end((*smem)->token); - - strncat(buf, ": ", 1023); - - strncat(buf, type_get_name((*smem)->type), 1023); - - strncat(buf, "; ", 1023); - } - - strncat(buf, "}", 1023); - break; - } - - case Ast_Kind_Basic_Type: - case Ast_Kind_Array_Type: - case Ast_Kind_Type_Alias: - 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; - } - - default: { - strncat(buf, "", 1023); - } - } - - return bh_strdup(a, buf); -} - -static DocPackage doc_package_create(Package* p, bh_allocator a) { - DocPackage dp; - dp.name = p->name; - dp.public_entries = NULL; - dp.private_entries = NULL; - - bh_arr_new(global_heap_allocator, dp.public_entries, 16); - bh_arr_new(global_heap_allocator, dp.private_entries, 16); - - fori (i, 0, shlen(p->scope->symbols)) { - char *key = p->scope->symbols[i].key; - AstNode *value = p->scope->symbols[i].value; - - DocEntry de; - if (value->token) 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); - } - - fori (i, 0, shlen(p->private_scope->symbols)) { - char *key = p->scope->symbols[i].key; - AstNode *value = p->scope->symbols[i].value; - - DocEntry de; - if (value->token) 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); - } - - qsort(dp.public_entries, bh_arr_length(dp.public_entries), sizeof(DocEntry), cmp_doc_entry); - qsort(dp.private_entries, bh_arr_length(dp.private_entries), sizeof(DocEntry), cmp_doc_entry); - - return dp; -} - -OnyxDocumentation onyx_docs_generate() { - OnyxDocumentation doc; - - bh_arena_init(&doc.doc_arena, global_heap_allocator, 16 * 1024); - bh_allocator a = bh_arena_allocator(&doc.doc_arena); - - doc.package_docs = NULL; - bh_arr_new(global_heap_allocator, doc.package_docs, 16); - - fori (i, 0, shlen(context.packages)) { - DocPackage dp = doc_package_create(context.packages[i].value, a); - bh_arr_push(doc.package_docs, dp); - } - - qsort(doc.package_docs, bh_arr_length(doc.package_docs), sizeof(DocPackage), cmp_doc_package); - - return doc; -} - -static void onyx_docs_emit_human(OnyxDocumentation* doc, bh_file* file) { - // NOTE: Disabling fancy line printing until I can make it better - #if 0 - bh_arr_each(DocPackage, dp, doc->package_docs) { - bh_printf("Package '%s'\n", dp->name); - - if (bh_arr_length(dp->public_entries) > 0) { - bh_printf("\xe2\x94\x9c\xe2\x94\x80 Public symbols\n"); - bh_arr_each(DocEntry, de, dp->public_entries) { - bh_printf("\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80 %s\n", de->def); - - if (de->pos.filename != NULL) - bh_printf("\xe2\x94\x82 \xe2\x94\x82 at %s:%d,%d\n", de->pos.filename, de->pos.line, de->pos.column); - else - bh_printf("\xe2\x94\x82 \xe2\x94\x82 compiler built-in\n"); - - bh_printf("\xe2\x94\x82 \xe2\x94\x82\n"); - } - } - - if (bh_arr_length(dp->private_entries) > 0) { - bh_printf("\xe2\x94\x9c\xe2\x94\x80 Private symbols\n"); - bh_arr_each(DocEntry, de, dp->private_entries) { - bh_printf("\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80 %s\n", de->def); - if (de->pos.filename != NULL) - bh_printf("\xe2\x94\x82 \xe2\x94\x82 at %s:%d,%d\n", de->pos.filename, de->pos.line, de->pos.column); - else - bh_printf("\xe2\x94\x82 \xe2\x94\x82 compiler built-in\n"); - - bh_printf("\xe2\x94\x82 \xe2\x94\x82\n"); - } +static i32 sort_tags(const void* a, const void* b) { + AstNode *n1 = *(AstNode **) a; + AstNode *n2 = *(AstNode **) b; - bh_printf("\n"); - } + i32 diff; + if ((diff = strncmp(n1->token->text, n2->token->text, n2->token->length))) { + return diff; } - #else - bh_arr_each(DocPackage, dp, doc->package_docs) { - bh_fprintf(file, "Package '%s'\n", dp->name); - - if (bh_arr_length(dp->public_entries) > 0) { - bh_fprintf(file, " Public symbols\n"); - bh_arr_each(DocEntry, de, dp->public_entries) { - bh_fprintf(file, " %s\n", de->def); - - if (de->pos.filename != NULL) - bh_fprintf(file, " at %s:%d,%d\n", de->pos.filename, de->pos.line, de->pos.column); - else - bh_fprintf(file, " compiler built-in\n"); - - bh_fprintf(file, " \n"); - } - } - if (bh_arr_length(dp->private_entries) > 0) { - bh_fprintf(file, " Private symbols\n"); - bh_arr_each(DocEntry, de, dp->private_entries) { - bh_fprintf(file, " %s\n", de->def); - if (de->pos.filename != NULL) - bh_fprintf(file, " at %s:%d,%d\n", de->pos.filename, de->pos.line, de->pos.column); - else - bh_fprintf(file, " compiler built-in\n"); - - bh_fprintf(file, " \n"); - } - - bh_fprintf(file, "\n"); - } - } - #endif + return n1->token->length - n2->token->length; } -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) { +void onyx_docs_emit_tags(char *dest) { bh_file tags_file; - if (bh_file_create(&tags_file, "./tags") != BH_FILE_ERROR_NONE) { - bh_printf("Cannot create 'tags'.\n"); + if (bh_file_create(&tags_file, dest) != BH_FILE_ERROR_NONE) { + bh_printf("Cannot create '%s'.\n", dest); return; } @@ -241,52 +28,268 @@ static void onyx_docs_emit_tags(OnyxDocumentation* doc) { 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); - } + bh_fprintf(&tags_file, "!_TAG_PROGRAM_URL\thttps://github.com/onyx-lang/onyx\n"); + bh_fprintf(&tags_file, "!_TAG_PROGRAM_VERSION\t0.1.0\n"); - qsort(tags, bh_arr_length(tags), sizeof(DocEntry *), sort_tags); + qsort(context.tag_locations, bh_arr_length(context.tag_locations), sizeof(AstNode *), sort_tags); - bh_arr_each(DocEntry *, tag, tags) { - if ((*tag)->pos.filename == NULL) continue; + bh_arr_each(AstNode *, pnode, context.tag_locations) { + AstBinding *node = (AstBinding *) *pnode; + assert(node->kind == Ast_Kind_Binding); i32 line_len = 0; - char *c = (*tag)->pos.line_start; + char *c = node->token->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_fprintf(&tags_file, "%b\t%s\t/^%b$/\n", + node->token->text, node->token->length, + node->token->pos.filename, + node->token->pos.line_start, line_len); + } bh_file_close(&tags_file); } -static void onyx_docs_emit_html(OnyxDocumentation* doc, bh_file* file) { - bh_fprintf(file, "HTML documentation output not supported yet.\n"); - return; -} - -void onyx_docs_emit(OnyxDocumentation* doc, const char* filename) { - bh_file file; - if (bh_file_create(&file, filename) != BH_FILE_ERROR_NONE) { - bh_printf("ERROR: Failed to open file '%s' for writing documentation.\n", filename); - return; - } - - switch (doc->format) { - case Doc_Format_Human: onyx_docs_emit_human(doc, &file); break; - case Doc_Format_Html: onyx_docs_emit_html(doc, &file); break; - case Doc_Format_Tags: onyx_docs_emit_tags(doc); break; - } - - bh_file_close(&file); -} +// static i32 cmp_doc_entry(const void * a, const void * b) { +// DocEntry* d1 = (DocEntry *) a; +// DocEntry* d2 = (DocEntry *) b; +// +// return strncmp(d1->def, d2->def, 1024); +// } +// +// 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); +// } +// +// static char* node_to_doc_def(const char* sym, AstNode *node, bh_allocator a) { +// static char buf[1024]; +// memset(buf, 0, 1023); +// +// strncat(buf, sym, 1023); +// strncat(buf, " :: ", 1023); +// +// switch (node->kind) { +// case Ast_Kind_Function: { +// strncat(buf, "(", 1023); +// +// AstFunction *func = (AstFunction *) node; +// bh_arr_each(AstParam, param, func->params) { +// if (param != func->params) +// strncat(buf, ", ", 1023); +// +// token_toggle_end(param->local->token); +// strncat(buf, param->local->token->text, 1023); +// token_toggle_end(param->local->token); +// +// strncat(buf, ": ", 1023); +// +// strncat(buf, type_get_name(param->local->type), 1023); +// +// if (param->default_value != NULL) { +// strncat(buf, " = ", 1023); +// } +// } +// +// strncat(buf, ") -> ", 1023); +// strncat(buf, type_get_name(func->type->Function.return_type), 1023); +// +// break; +// } +// +// case Ast_Kind_Struct_Type: { +// strncat(buf, "struct { ", 1023); +// +// AstStructType* st = (AstStructType *) node; +// bh_arr_each(AstStructMember *, smem, st->members) { +// +// token_toggle_end((*smem)->token); +// strncat(buf, (*smem)->token->text, 1023); +// token_toggle_end((*smem)->token); +// +// strncat(buf, ": ", 1023); +// +// strncat(buf, type_get_name((*smem)->type), 1023); +// +// strncat(buf, "; ", 1023); +// } +// +// strncat(buf, "}", 1023); +// break; +// } +// +// case Ast_Kind_Basic_Type: +// case Ast_Kind_Array_Type: +// case Ast_Kind_Type_Alias: +// 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; +// } +// +// default: { +// strncat(buf, "", 1023); +// } +// } +// +// return bh_strdup(a, buf); +// } +// +// static DocPackage doc_package_create(Package* p, bh_allocator a) { +// DocPackage dp; +// dp.name = p->name; +// dp.public_entries = NULL; +// dp.private_entries = NULL; +// +// bh_arr_new(global_heap_allocator, dp.public_entries, 16); +// bh_arr_new(global_heap_allocator, dp.private_entries, 16); +// +// fori (i, 0, shlen(p->scope->symbols)) { +// char *key = p->scope->symbols[i].key; +// AstNode *value = p->scope->symbols[i].value; +// if (!key || !value) continue; +// +// DocEntry de; +// if (value->token) 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); +// } +// +// fori (i, 0, shlen(p->private_scope->symbols)) { +// char *key = p->scope->symbols[i].key; +// AstNode *value = p->scope->symbols[i].value; +// if (!key || !value) continue; +// +// DocEntry de; +// if (value->token) 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); +// } +// +// qsort(dp.public_entries, bh_arr_length(dp.public_entries), sizeof(DocEntry), cmp_doc_entry); +// qsort(dp.private_entries, bh_arr_length(dp.private_entries), sizeof(DocEntry), cmp_doc_entry); +// +// return dp; +// } +// +// OnyxDocumentation onyx_docs_generate() { +// OnyxDocumentation doc; +// +// bh_arena_init(&doc.doc_arena, global_heap_allocator, 16 * 1024); +// bh_allocator a = bh_arena_allocator(&doc.doc_arena); +// +// doc.package_docs = NULL; +// bh_arr_new(global_heap_allocator, doc.package_docs, 16); +// +// fori (i, 0, shlen(context.packages)) { +// DocPackage dp = doc_package_create(context.packages[i].value, a); +// bh_arr_push(doc.package_docs, dp); +// } +// +// qsort(doc.package_docs, bh_arr_length(doc.package_docs), sizeof(DocPackage), cmp_doc_package); +// +// return doc; +// } +// +// static void onyx_docs_emit_human(OnyxDocumentation* doc, bh_file* file) { +// // NOTE: Disabling fancy line printing until I can make it better +// #if 0 +// bh_arr_each(DocPackage, dp, doc->package_docs) { +// bh_printf("Package '%s'\n", dp->name); +// +// if (bh_arr_length(dp->public_entries) > 0) { +// bh_printf("\xe2\x94\x9c\xe2\x94\x80 Public symbols\n"); +// bh_arr_each(DocEntry, de, dp->public_entries) { +// bh_printf("\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80 %s\n", de->def); +// +// if (de->pos.filename != NULL) +// bh_printf("\xe2\x94\x82 \xe2\x94\x82 at %s:%d,%d\n", de->pos.filename, de->pos.line, de->pos.column); +// else +// bh_printf("\xe2\x94\x82 \xe2\x94\x82 compiler built-in\n"); +// +// bh_printf("\xe2\x94\x82 \xe2\x94\x82\n"); +// } +// } +// +// if (bh_arr_length(dp->private_entries) > 0) { +// bh_printf("\xe2\x94\x9c\xe2\x94\x80 Private symbols\n"); +// bh_arr_each(DocEntry, de, dp->private_entries) { +// bh_printf("\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80 %s\n", de->def); +// if (de->pos.filename != NULL) +// bh_printf("\xe2\x94\x82 \xe2\x94\x82 at %s:%d,%d\n", de->pos.filename, de->pos.line, de->pos.column); +// else +// bh_printf("\xe2\x94\x82 \xe2\x94\x82 compiler built-in\n"); +// +// bh_printf("\xe2\x94\x82 \xe2\x94\x82\n"); +// } +// +// bh_printf("\n"); +// } +// } +// #else +// bh_arr_each(DocPackage, dp, doc->package_docs) { +// bh_fprintf(file, "Package '%s'\n", dp->name); +// +// if (bh_arr_length(dp->public_entries) > 0) { +// bh_fprintf(file, " Public symbols\n"); +// bh_arr_each(DocEntry, de, dp->public_entries) { +// bh_fprintf(file, " %s\n", de->def); +// +// if (de->pos.filename != NULL) +// bh_fprintf(file, " at %s:%d,%d\n", de->pos.filename, de->pos.line, de->pos.column); +// else +// bh_fprintf(file, " compiler built-in\n"); +// +// bh_fprintf(file, " \n"); +// } +// } +// +// if (bh_arr_length(dp->private_entries) > 0) { +// bh_fprintf(file, " Private symbols\n"); +// bh_arr_each(DocEntry, de, dp->private_entries) { +// bh_fprintf(file, " %s\n", de->def); +// if (de->pos.filename != NULL) +// bh_fprintf(file, " at %s:%d,%d\n", de->pos.filename, de->pos.line, de->pos.column); +// else +// bh_fprintf(file, " compiler built-in\n"); +// +// bh_fprintf(file, " \n"); +// } +// +// bh_fprintf(file, "\n"); +// } +// } +// #endif +// } +// +// +// +// static void onyx_docs_emit_html(OnyxDocumentation* doc, bh_file* file) { +// bh_fprintf(file, "HTML documentation output not supported yet.\n"); +// return; +// } +// +// void onyx_docs_emit(OnyxDocumentation* doc, const char* filename) { +// bh_file file; +// if (bh_file_create(&file, filename) != BH_FILE_ERROR_NONE) { +// bh_printf("ERROR: Failed to open file '%s' for writing documentation.\n", filename); +// return; +// } +// +// switch (doc->format) { +// case Doc_Format_Human: onyx_docs_emit_human(doc, &file); break; +// case Doc_Format_Html: onyx_docs_emit_html(doc, &file); break; +// } +// +// bh_file_close(&file); +// } diff --git a/compiler/src/onyx.c b/compiler/src/onyx.c index d2b07193..82982019 100644 --- a/compiler/src/onyx.c +++ b/compiler/src/onyx.c @@ -50,7 +50,8 @@ static const char* docstring = "Onyx compiler version " VERSION "\n" "\t -VVV Very very verbose output (to be used by compiler developers).\n" "\t--wasm-mvp Use only WebAssembly MVP features.\n" "\t--multi-threaded Enables multi-threading for this compilation.\n" - "\t--doc \n" + "\t--tag Generates a C-Tag file.\n" + // "\t--doc \n" "\t--generate-foreign-info\n" "\n" "Developer flags:\n" @@ -87,6 +88,8 @@ static CompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *arg .passthrough_argument_count = 0, .passthrough_argument_data = NULL, + + .generate_tag_file = 0, }; bh_arr_new(alloc, options.files, 2); @@ -180,8 +183,11 @@ static CompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *arg options.runtime = Runtime_Wasi; } } - else if (!strcmp(argv[i], "--doc")) { - options.documentation_file = argv[++i]; + // else if (!strcmp(argv[i], "--doc")) { + // options.documentation_file = argv[++i]; + // } + else if (!strcmp(argv[i], "--tag")) { + options.generate_tag_file = 1; } else if (!strcmp(argv[i], "--debug")) { options.debug_enabled = 1; @@ -706,6 +712,10 @@ static i32 onyx_compile() { printf("\n"); } + if (context.options->generate_tag_file) { + onyx_docs_emit_tags("./tags"); + } + return ONYX_COMPILER_PROGRESS_SUCCESS; } @@ -767,11 +777,11 @@ static CompilerProgress onyx_flush_module() { bh_file_close(&output_file); - if (context.options->documentation_file != NULL) { - OnyxDocumentation docs = onyx_docs_generate(); - docs.format = Doc_Format_Tags; - onyx_docs_emit(&docs, context.options->documentation_file); - } + // if (context.options->documentation_file != NULL) { + // OnyxDocumentation docs = onyx_docs_generate(); + // docs.format = Doc_Format_Human; + // onyx_docs_emit(&docs, context.options->documentation_file); + // } return ONYX_COMPILER_PROGRESS_SUCCESS; } diff --git a/compiler/src/parser.c b/compiler/src/parser.c index cae57cdb..93f363ca 100644 --- a/compiler/src/parser.c +++ b/compiler/src/parser.c @@ -455,7 +455,7 @@ static AstTyped* parse_factor(OnyxParser* parser) { if (peek_token(0)->type == ',') { expect_token(parser, ','); - cast_node->expr = parse_factor(parser); + cast_node->expr = parse_expression(parser, 0); expect_token(parser, ')'); } else { diff --git a/compiler/src/symres.c b/compiler/src/symres.c index 4b93f276..341a1288 100644 --- a/compiler/src/symres.c +++ b/compiler/src/symres.c @@ -1710,6 +1710,8 @@ void symres_entity(Entity* ent) { switch (ent->type) { case Entity_Type_Binding: { symbol_introduce(curr_scope, ent->binding->token, ent->binding->node); + track_declaration_for_tags((AstNode *) ent->binding); + package_reinsert_use_packages(ent->package); next_state = Entity_State_Finalized; break; diff --git a/compiler/src/utils.c b/compiler/src/utils.c index 810c5cf2..53f0a122 100644 --- a/compiler/src/utils.c +++ b/compiler/src/utils.c @@ -1248,3 +1248,10 @@ char *find_closest_symbol_in_node(AstNode* node, char *sym) { return find_closest_symbol_in_scope(scope, sym, &dist); } + + +void track_declaration_for_tags(AstNode *node) { + if (context.options->generate_tag_file) { + bh_arr_push(context.tag_locations, node); + } +} \ No newline at end of file diff --git a/core/container/iter.onyx b/core/container/iter.onyx index d3e3fcab..ac993bd7 100644 --- a/core/container/iter.onyx +++ b/core/container/iter.onyx @@ -761,6 +761,38 @@ every :: (it: Iterator($T), cond: (T) -> bool) -> bool { return true; } +prod :: (x: $I1/Iterable, y: $I2/Iterable) => { + y_iter := as_iterator(y); + y_val, _ := take_one(y_iter); + + return generator( + ^.{ + x = x, + x_iter = as_iterator(x), + + y_iter = y_iter, + y_val = y_val + }, + + ctx => { + x_val, cont := take_one(ctx.x_iter); + if cont { + return .{ x=x_val, y=ctx.y_val }, true; + } + + ctx.y_val, cont = take_one(ctx.y_iter); + if !cont do return .{}, false; + + ctx.x_iter = as_iterator(ctx.x); + x_val, cont = take_one(ctx.x_iter); + if !cont do return .{}, false; + + return .{ x=x_val, y=ctx.y_val }, true; + } + ); +} + + to_array :: (it: Iterator($T), allocator := context.allocator) -> [..] T { arr := array.make(T, allocator=allocator); for v: it do array.push(^arr, v); -- 2.25.1