diff options
-rw-r--r-- | allocator.c | 14 | ||||
-rw-r--r-- | cgen.c | 132 | ||||
-rw-r--r-- | copy.c | 14 | ||||
-rw-r--r-- | data_structures.c | 16 | ||||
-rw-r--r-- | development.md | 3 | ||||
-rw-r--r-- | err.c | 22 | ||||
-rw-r--r-- | eval.c | 82 | ||||
-rw-r--r-- | foreign64.c | 12 | ||||
-rw-r--r-- | foreign_avcall.c | 16 | ||||
-rw-r--r-- | foreign_msvc32.c | 12 | ||||
-rw-r--r-- | identifiers.c | 30 | ||||
-rw-r--r-- | infer.c | 10 | ||||
-rw-r--r-- | instance_table.c | 22 | ||||
-rw-r--r-- | main.c | 16 | ||||
-rw-r--r-- | misc.c | 2 | ||||
-rw-r--r-- | parse.c | 268 | ||||
-rw-r--r-- | test.toc | 8 | ||||
-rw-r--r-- | toc.c | 26 | ||||
-rw-r--r-- | tokenizer.c | 80 | ||||
-rw-r--r-- | types.c | 427 | ||||
-rw-r--r-- | types.h | 252 |
21 files changed, 728 insertions, 736 deletions
diff --git a/allocator.c b/allocator.c index 59dc350..677bf75 100644 --- a/allocator.c +++ b/allocator.c @@ -22,9 +22,9 @@ For more information, please refer to <http://unlicense.org/> */ #ifdef TOC_DEBUG -//#define NO_ALLOCATOR 1 /* useful for debugging; valgrind checks writing past the end of a malloc, but that won't work with an allocator */ +//#define NO_ALLOCATOR 1 // useful for debugging; valgrind checks writing past the end of a malloc, but that won't work with an allocator #endif -/* number of bytes a page hold, not including the header */ +// number of bytes a page hold, not including the header #define PAGE_BYTES (16384 - sizeof(Page)) #define PAGE_MAX_ALIGNS (PAGE_BYTES / sizeof(MaxAlign)) @@ -41,14 +41,14 @@ static void *allocr_malloc(Allocator *a, size_t bytes) { return NULL; if (a == NULL) return err_malloc(bytes); - /* position in this page to return */ + // position in this page to return size_t pos = PAGE_MAX_ALIGNS; if (a->last) pos = a->last->used; size_t max_aligns = (bytes + sizeof(MaxAlign) - 1) / sizeof(MaxAlign); if (pos + max_aligns > PAGE_MAX_ALIGNS) { - /* make a new page for this data */ + // make a new page for this data Page *page = err_malloc(sizeof *page + (bytes > PAGE_BYTES ? bytes : PAGE_BYTES)); page->next = NULL; page->used = max_aligns; @@ -71,7 +71,7 @@ static void *allocr_calloc(Allocator *a, size_t n, size_t sz) { #endif if (n == 0 || sz == 0) return NULL; if (a == NULL) return err_calloc(n, sz); - /* @OPTIM: use calloc */ + // @OPTIM: use calloc size_t bytes = n * sz; void *data = allocr_malloc(a, bytes); memset(data, 0, bytes); @@ -85,11 +85,11 @@ static void allocr_free(Allocator *a, void *data, size_t size) { if (a == NULL) { free(data); } - /* @OPTIM */ + // @OPTIM (void)size; } -/* @OPTIM */ +// @OPTIM static void *allocr_realloc(Allocator *a, void *data, size_t old_size, size_t new_size) { #if NO_ALLOCATOR a = NULL; @@ -17,7 +17,7 @@ static void cgen_create(CGenerator *g, FILE *out, Identifiers *ids, Allocator *a static void cgen_stmt(CGenerator *g, Statement *s); enum { - CGEN_BLOCK_NOBRACES = 0x01 /* should it use braces? */ + CGEN_BLOCK_NOBRACES = 0x01 // should it use braces? }; static void cgen_block(CGenerator *g, Block *b, uint16_t flags); static void cgen_expr_pre(CGenerator *g, Expression *e); @@ -29,20 +29,20 @@ static void cgen_type_pre(CGenerator *g, Type *t); static void cgen_type_post(CGenerator *g, Type *t); static void cgen_decl(CGenerator *g, Declaration *d); static void cgen_ret(CGenerator *g, Block *returning_from, Expression *ret_expr); -/* yes, these do need to take pointers, and furthermore they must be the same pointer (because of slices) */ +// yes, these do need to take pointers, and furthermore they must be the same pointer (because of slices) static void cgen_val(CGenerator *g, Value *v, Type *t); static void cgen_val_pre(CGenerator *g, Value *v, Type *t); static void cgen_val_ptr(CGenerator *g, void *v, Type *t); static inline FILE *cgen_writing_to(CGenerator *g) { - return g->outc; /* for now */ + return g->outc; // for now } static inline void *cgen_malloc(CGenerator *g, size_t sz) { return allocr_malloc(g->allocr, sz); } -/* indent iff needed */ +// indent iff needed static inline void cgen_indent(CGenerator *g) { if (g->will_indent) { for (unsigned i = 0; i < g->indent_lvl; ++i) @@ -80,7 +80,7 @@ static inline void cgen_lbl(CGenerator *g, IdentID lbl) { cgen_write(g, "lbl%lu_", (unsigned long)lbl); } -/* used for fields */ +// used for fields static inline void cgen_ident_simple(CGenerator *g, Identifier i) { cgen_indent(g); fprint_ident_reduced_charset(cgen_writing_to(g), i); @@ -91,7 +91,7 @@ static void cgen_ident(CGenerator *g, Identifier i) { cgen_write(g, "%s", i->nms->c.prefix); } if (i == g->main_ident && ident_scope(i) == NULL) { - /* don't conflict with C's main! */ + // don't conflict with C's main! cgen_write(g, "main_"); } else { cgen_ident_simple(g, i); @@ -100,7 +100,7 @@ static void cgen_ident(CGenerator *g, Identifier i) { #define CGEN_IDENT_ID_STR_SIZE 32 -/* buffer should be at least CGEN_IDENT_ID_STR_SIZE bytes */ +// buffer should be at least CGEN_IDENT_ID_STR_SIZE bytes static inline void cgen_ident_id_to_str(char *buffer, IdentID id) { snprintf(buffer, CGEN_IDENT_ID_STR_SIZE, "a%lu_", (unsigned long)id); } @@ -118,9 +118,9 @@ static inline void cgen_char(CGenerator *g, char c) { if (isprint(c) && c != '"') cgen_write(g, "%c", c); else - cgen_write(g, "\\%03o", c); /* can't use hex escape sequences, because they can be more than 2 characters "\xbafoo" is '\xbaf', 'o', 'o' */ + cgen_write(g, "\\%03o", c); // can't use hex escape sequences, because they can be more than 2 characters "\xbafoo" is '\xbaf', 'o', 'o' } -/* should this declaration be a direct function declaration C? (as opposed to using a function pointer or not being a function) */ +// should this declaration be a direct function declaration C? (as opposed to using a function pointer or not being a function) static bool cgen_fn_is_direct(CGenerator *g, Declaration *d) { return (!g->block || g->block->kind == BLOCK_NMS) && (d->flags & DECL_IS_CONST) && (d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1; } @@ -207,7 +207,7 @@ static void cgen_type_pre(CGenerator *g, Type *t) { case TYPE_TUPLE: case TYPE_EXPR: case TYPE_UNKNOWN: - /* We should never try to generate this type */ + // We should never try to generate this type assert(0); break; } @@ -335,7 +335,7 @@ static inline void cgen_fn_name(CGenerator *g, FnExpr *f) { } } -/* should we generate this function? (or is it just meant for compile time) */ +// should we generate this function? (or is it just meant for compile time) static bool cgen_should_gen_fn(FnExpr *f) { if (f->flags & FN_EXPR_FOREIGN) return true; @@ -359,7 +359,7 @@ static void cgen_val_ptr_pre(CGenerator *g, void *v, Type *t) { } cgen_write(g, "static "); cgen_type_pre(g, t->slice); - cgen_write(g, "(d%p_[])", v); /* @TODO: improve this somehow? */ + cgen_write(g, "(d%p_[])", v); // @TODO: improve this somehow? cgen_type_post(g, t->slice); cgen_write(g, " = "); if (type_is_builtin(t->slice, BUILTIN_CHAR)) { @@ -395,7 +395,7 @@ static void cgen_val_ptr_pre(CGenerator *g, void *v, Type *t) { } } -/* generate a value from a pointer */ +// generate a value from a pointer static void cgen_val_ptr(CGenerator *g, void *v, Type *t) { assert(t->flags & TYPE_IS_RESOLVED); switch (t->kind) { @@ -429,7 +429,7 @@ static void cgen_val_ptr(CGenerator *g, void *v, Type *t) { cgen_fn_name(g, *(FnExpr **)v); break; case TYPE_PTR: - /* this can happen; as i'm writing this it's only for null */ + // this can happen; as i'm writing this it's only for null cgen_write(g, "(("); cgen_type_pre(g, t); cgen_type_post(g, t); @@ -468,12 +468,12 @@ static void cgen_val_pre(CGenerator *g, Value *v, Type *t) { cgen_val_ptr_pre(g, val_get_ptr(v, t), t); } -/* generates a value fit for use as an initializer */ +// generates a value fit for use as an initializer static void cgen_val(CGenerator *g, Value *v, Type *t) { cgen_val_ptr(g, val_get_ptr(v, t), t); } -/* can the value generated by cgen_val for this type be used directly (as opposed to being stored in a variable)? */ +// can the value generated by cgen_val for this type be used directly (as opposed to being stored in a variable)? static inline bool cgen_is_type_simple(Type *t) { return t->kind == TYPE_BUILTIN || t->kind == TYPE_FN; } @@ -513,7 +513,7 @@ static void cgen_fn_params(CGenerator *g, FnExpr *f) { } if (out_param) { if (f->ret_type.kind == TYPE_TUPLE) { - /* multiple return variables */ + // multiple return variables for (size_t i = 0; i < arr_len(f->ret_type.tuple); ++i) { Type *x = &f->ret_type.tuple[i]; if (any_params || i > 0) @@ -539,7 +539,7 @@ static void cgen_fn_params(CGenerator *g, FnExpr *f) { static inline void cgen_arg_pre(CGenerator *g, Expression *arg) { cgen_expr_pre(g, arg); if (arg->type.kind == TYPE_ARR) { - /* create copy of array */ + // create copy of array IdentID copy = ++g->ident_counter; cgen_type_pre(g, &arg->type); char s[CGEN_IDENT_ID_STR_SIZE]; @@ -561,7 +561,7 @@ static inline void cgen_arg(CGenerator *g, Expression *arg) { } } -/* unless f has const/semi-const args, which_are_const can be set to 0 */ +// unless f has const/semi-const args, which_are_const can be set to 0 static void cgen_fn_header(CGenerator *g, FnExpr *f) { assert(!(f->flags & FN_EXPR_FOREIGN)); @@ -588,14 +588,14 @@ static inline void cgen_deferred_from_block(CGenerator *g, Block *from) { } } -/* generates deferred statements in g->block, g->block->parent, ..., to) */ +// generates deferred statements in g->block, g->block->parent, ..., to) static inline void cgen_deferred_up_to(CGenerator *g, Block *to) { for (Block *b = g->block; b; b = b == to ? NULL : b->parent) { cgen_deferred_from_block(g, b); } } -/* same as cgen_deferred_up_to but doesn't generate to->deferred */ +// same as cgen_deferred_up_to but doesn't generate to->deferred static inline void cgen_deferred_up_to_not_including(CGenerator *g, Block *to) { for (Block *b = g->block; b != to; b = b->parent) cgen_deferred_from_block(g, b); @@ -676,14 +676,14 @@ static void cgen_set(CGenerator *g, Expression *set_expr, const char *set_str, E } } -/* one of exprs, idents, and prefix should be NULL. does NOT call cgen_expr_pre for to/exprs */ +// one of exprs, idents, and prefix should be NULL. does NOT call cgen_expr_pre for to/exprs static void cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, const char *prefix, Expression *to) { switch (to->kind) { case EXPR_VAL: - assert(0); /* never needed at the moment */ + assert(0); // never needed at the moment break; case EXPR_TUPLE: - /* e.g. a, b = 3, 5; */ + // e.g. a, b = 3, 5; if (exprs) { for (size_t i = 0; i < arr_len(to->tuple); ++i) { cgen_expr_pre(g, &exprs[i]); @@ -727,7 +727,7 @@ static void cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, } } - /* e.g. a, b = fn_which_returns_tuple(); */ + // e.g. a, b = fn_which_returns_tuple(); arr_foreach(to->call.arg_exprs, Expression, arg) { if (!constness || !arg_is_const(arg, constness[i])) { cgen_arg_pre(g, arg); @@ -749,7 +749,7 @@ static void cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, } ++i; } - /* out params */ + // out params IdentID *u = underscore_ids; for (i = 0; i < nout_params; ++i) { if (any_args || i > 0) @@ -770,7 +770,7 @@ static void cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, arr_clear(underscore_ids); cgen_writeln(g, "); "); } break; - /* things which can never be tuples */ + // things which can never be tuples case EXPR_SLICE: case EXPR_IDENT: case EXPR_LITERAL_INT: @@ -815,11 +815,11 @@ static void cgen_expr_pre(CGenerator *g, Expression *e) { if (!constness || !arg_is_const(arg, constness[i])) { cgen_arg_pre(g, arg); } - if (i < nparams-1) /* necessary for varargs */ + if (i < nparams-1) // necessary for varargs ++i; } if (e->type.kind == TYPE_TUPLE) { - /* we actually don't ever need this; it's handled individually elsewhere */ + // we actually don't ever need this; it's handled individually elsewhere } else if (cgen_uses_ptr(&e->type)) { IdentID id = e->cgen.id = ++g->ident_counter; cgen_type_pre(g, &e->type); @@ -910,7 +910,7 @@ static void cgen_expr_pre(CGenerator *g, Expression *e) { cgen_nl(g); } break; case EXPR_VAL: - /* @TODO: don't make a variable for this if it's not needed */ + // @TODO: don't make a variable for this if it's not needed if (type_is_compileonly(&e->type)) break; if (!cgen_is_type_simple(&e->type)) { @@ -970,7 +970,7 @@ static void cgen_expr(CGenerator *g, Expression *e) { case EXPR_LITERAL_INT: cgen_write(g, U64_FMT, e->intl); if (e->intl > I64_MAX) - cgen_write(g, "U"); /* prevent GCC warnings */ + cgen_write(g, "U"); // prevent GCC warnings break; case EXPR_LITERAL_STR: { char *p = e->strl.str; @@ -989,7 +989,7 @@ static void cgen_expr(CGenerator *g, Expression *e) { case EXPR_IDENT: { bool handled = false; if (e->type.kind == TYPE_FN) { - /* generate the right function name, because it might be anonymous */ + // generate the right function name, because it might be anonymous Identifier i = e->ident; Declaration *d = i->decl; if (d->flags & DECL_IS_CONST) { @@ -1105,7 +1105,7 @@ static void cgen_expr(CGenerator *g, Expression *e) { cgen_ident_simple(g, e->binary.field->name); cgen_write(g, ")"); } else if (struct_type->kind == TYPE_SLICE) { - /* access slice data */ + // access slice data cgen_expr(g, lhs); bool is_ptr = lhs->type.kind == TYPE_PTR; cgen_write(g, is_ptr ? "->" :"."); @@ -1124,7 +1124,7 @@ static void cgen_expr(CGenerator *g, Expression *e) { cgen_expr(g, rhs); cgen_write(g, "))"); } else if (op == BINARY_SET_ADD || op == BINARY_SET_SUB) { - /* lhs could have side effects so we can't just do lhs = (char *)lhs + rhs */ + // lhs could have side effects so we can't just do lhs = (char *)lhs + rhs cgen_write(g, "{"); cgen_write(g, "void **t_ = &"); cgen_expr(g, lhs); @@ -1179,7 +1179,7 @@ static void cgen_expr(CGenerator *g, Expression *e) { } break; case EXPR_CALL: if (e->type.kind == TYPE_TUPLE) { - /* the only situation in which this could happen is if the return value doesn't matter */ + // the only situation in which this could happen is if the return value doesn't matter } else if (cgen_uses_ptr(&e->type)) { cgen_ident_id(g, e->cgen.id); } else { @@ -1225,7 +1225,7 @@ static void cgen_expr(CGenerator *g, Expression *e) { case BUILTIN_PLATFORM: cgen_write(g, "platform__"); break; - case BUILTIN_DEBUG: /* substituted for its value */ + case BUILTIN_DEBUG: // substituted for its value assert(0); break; } @@ -1234,7 +1234,7 @@ static void cgen_expr(CGenerator *g, Expression *e) { Type *from = &e->cast.expr->type; Type *to = &e->cast.type; if (to->kind == TYPE_ARR) { - /* can't cast to array type */ + // can't cast to array type cgen_expr(g, e->cast.expr); } else { CType *ctype = &e->cast.ctype; @@ -1248,7 +1248,7 @@ static void cgen_expr(CGenerator *g, Expression *e) { cgen_write(g, ")("); cgen_expr(g, e->cast.expr); cgen_write(g, ")"); - if (from->kind == TYPE_SLICE /* casting from a slice to a non-slice */ + if (from->kind == TYPE_SLICE // casting from a slice to a non-slice && to->kind != TYPE_SLICE) cgen_write(g, ".data"); cgen_write(g, ")"); @@ -1343,7 +1343,7 @@ from just f. */ static void cgen_fn(CGenerator *g, FnExpr *f) { if (f->flags & FN_EXPR_FOREIGN) - return; /* handled by cgen_fn_decl */ + return; // handled by cgen_fn_decl if (!cgen_should_gen_fn(f)) return; FnExpr *prev_fn = g->fn; @@ -1396,7 +1396,7 @@ static void cgen_fn(CGenerator *g, FnExpr *f) { } } - /* retdecls need to be after compile time arguments to allow fn(x::int) y := x */ + // retdecls need to be after compile time arguments to allow fn(x::int) y := x arr_foreach(f->ret_decls, Declaration, d) { cgen_decl(g, d); } @@ -1404,7 +1404,7 @@ static void cgen_fn(CGenerator *g, FnExpr *f) { cgen_block(g, body, CGEN_BLOCK_NOBRACES); cgen_deferred_from_block(g, body); arr_clear(body->deferred); - if (f->ret_decls) cgen_ret(g, NULL, NULL); /* for example, if function is fn() x: int, we need to generate return x; at the end */ + if (f->ret_decls) cgen_ret(g, NULL, NULL); // for example, if function is fn() x: int, we need to generate return x; at the end cgen_writeln(g, "}"); g->block = prev_block; g->fn = prev_fn; @@ -1414,12 +1414,12 @@ static void cgen_fn(CGenerator *g, FnExpr *f) { static void cgen_decl(CGenerator *g, Declaration *d) { if (!g->block || (g->block->kind == BLOCK_NMS)) - return; /* already dealt with */ + return; // already dealt with int has_expr = d->flags & DECL_HAS_EXPR; if (cgen_fn_is_direct(g, d)) - return; /* dealt with in the loop that defines all the functions in cgen_file */ + return; // dealt with in the loop that defines all the functions in cgen_file if (d->flags & DECL_FOUND_VAL) { - /* declarations where we use a value */ + // declarations where we use a value for (int idx = 0, nidents = (int)arr_len(d->idents); idx < nidents; ++idx) { Identifier i = d->idents[idx]; if (ident_eq_str(i, "_")) continue; @@ -1448,7 +1448,7 @@ static void cgen_decl(CGenerator *g, Declaration *d) { cgen_nl(g); } } else { - /* declarations where we use an expression */ + // declarations where we use an expression int nidents = (int)arr_len(d->idents); for (int idx = 0; idx < nidents; ++idx) { Identifier i = d->idents[idx]; @@ -1473,7 +1473,7 @@ static void cgen_decl(CGenerator *g, Declaration *d) { } else { if (expr->kind != EXPR_VAL) cgen_expr_pre(g, expr); if (nidents > 1) { - /* set expr__ first to make sure side effects don't happen twice */ + // set expr__ first to make sure side effects don't happen twice cgen_write(g, "{"); cgen_nl(g); cgen_type_pre(g, &d->type); @@ -1498,9 +1498,9 @@ static void cgen_decl(CGenerator *g, Declaration *d) { cgen_expr(g, expr); cgen_write(g, ";"); } else { - /* set it directly */ + // set it directly if (expr->kind == EXPR_VAL) { - /* don't use a temp variable */ + // don't use a temp variable cgen_ident(g, ident); cgen_write(g, " = "); cgen_val(g, &expr->val, &expr->type); @@ -1521,7 +1521,7 @@ static void cgen_decl(CGenerator *g, Declaration *d) { } } -/* pass NULL as returning_from if you don't want to run any deferred things */ +// pass NULL as returning_from if you don't want to run any deferred things static void cgen_ret(CGenerator *g, Block *returning_from, Expression *ret_expr) { FnExpr *f = g->fn; if (ret_expr) { @@ -1533,7 +1533,7 @@ static void cgen_ret(CGenerator *g, Block *returning_from, Expression *ret_expr) cgen_set(g, NULL, "*ret__", ret_expr, NULL); } } else { - /* set ret_ to ret_expr */ + // set ret_ to ret_expr cgen_type_pre(g, &ret_expr->type); cgen_write(g, " ret_"); cgen_type_post(g, &ret_expr->type); @@ -1600,7 +1600,7 @@ static void cgen_ret(CGenerator *g, Block *returning_from, Expression *ret_expr) static void cgen_stmt(CGenerator *g, Statement *s) { #ifdef CGEN_EMIT_LINE_NUMBER_COMMENTS - /* @TODO: add compiler option for this */ + // @TODO: add compiler option for this cgen_write(g, "/* %s:%d */", s->where.ctx->filename, s->where.line); #endif switch (s->kind) { @@ -1678,7 +1678,7 @@ static void cgen_stmt(CGenerator *g, Statement *s) { Type *fo_type = &header_decl->type; assert(fo_type->kind == TYPE_TUPLE && arr_len(fo_type->tuple) == 2); Type *val_type = &fo_type->tuple[0]; - assert(type_is_builtin(&fo_type->tuple[1], BUILTIN_I64)); /* index type is always int */ + assert(type_is_builtin(&fo_type->tuple[1], BUILTIN_I64)); // index type is always int bool has_val = !ident_eq_str(val_ident, "_"); bool has_index = !ident_eq_str(index_ident, "_"); @@ -1695,7 +1695,7 @@ static void cgen_stmt(CGenerator *g, Statement *s) { cgen_write(g, "{"); if (is_range) { if (fo->range.to) { - /* pre generate to */ + // pre generate to cgen_type_pre(g, val_type); cgen_write(g, " to_"); cgen_type_post(g, val_type); @@ -1704,7 +1704,7 @@ static void cgen_stmt(CGenerator *g, Statement *s) { cgen_write(g, "; "); } - /* set value to from */ + // set value to from if (has_val) { cgen_type_pre(g, val_type); cgen_write(g, " "); @@ -1731,7 +1731,7 @@ static void cgen_stmt(CGenerator *g, Statement *s) { of_type = of_type->ptr; } - /* pre-generate of */ + // pre-generate of switch (of_type->kind) { case TYPE_SLICE: cgen_type_pre(g, of_type); @@ -1778,7 +1778,7 @@ static void cgen_stmt(CGenerator *g, Statement *s) { } } cgen_write(g, "; "); - if (fo->range.to) { /* if finite */ + if (fo->range.to) { // if finite if (has_val) cgen_ident(g, val_ident); else @@ -1873,7 +1873,7 @@ static void cgen_stmt(CGenerator *g, Statement *s) { static void cgen_fn_decl(CGenerator *g, FnExpr *f) { if (f->flags & FN_EXPR_FOREIGN) { Type *t = &f->foreign.type; - /* foreign function declaration */ + // foreign function declaration cgen_write(g, "extern "); Type *fn_types = t->fn->types; const char *foreign_name = f->foreign.name; @@ -1943,9 +1943,9 @@ static void cgen_fn_decl(CGenerator *g, FnExpr *f) { static void cgen_global_decl(CGenerator *g, Declaration *d) { if (cgen_fn_is_direct(g, d)) { - /* handled by cgen_fn_decl */ + // handled by cgen_fn_decl } else { - /* global variables */ + // global variables for (int i = 0, n_idents = (int)arr_len(d->idents); i < n_idents; ++i) { Identifier ident = d->idents[i]; Type *type = decl_type_at_index(d, i); @@ -1982,7 +1982,7 @@ static void cgen_file(CGenerator *g, ParsedFile *f, Typer *tr) { g->fn = NULL; g->file = f; #ifdef TOC_DEBUG - /* if in debug mode, don't buffer output C file */ + // if in debug mode, don't buffer output C file setbuf(cgen_writing_to(g), NULL); #endif cgen_write(g, @@ -2002,7 +2002,7 @@ static void cgen_file(CGenerator *g, ParsedFile *f, Typer *tr) { "typedef struct { void *data; i64 len; } slice_;\n" "#define false ((bool)0)\n" "#define true ((bool)1)\n" - "#ifdef __linux__\n" /* see also toc.c */ + "#ifdef __linux__\n" // see also toc.c "#define platform__ " stringify(PLATFORM_LINUX) "\n" "#elif defined _WIN32\n" "#define platform__ " stringify(PLATFORM_WINDOWS) "\n" @@ -2019,7 +2019,7 @@ static void cgen_file(CGenerator *g, ParsedFile *f, Typer *tr) { "#endif\n" "static slice_ mkslice_(void *data, i64 len) { slice_ ret; ret.data = data; ret.len = len; return ret; }\n"); cgen_write(g, "/* types */\n"); - /* struct declarations */ + // struct declarations arr_foreach(tr->all_structs, StructDefPtr, sdefp) { StructDef *sdef = *sdefp; cgen_write(g, "struct "); @@ -2031,7 +2031,7 @@ static void cgen_file(CGenerator *g, ParsedFile *f, Typer *tr) { cgen_nl(g); } - /* struct definitions */ + // struct definitions arr_foreach(tr->all_structs, StructDefPtr, sdefp) { StructDef *sdef = *sdefp; cgen_write(g, "struct "); @@ -2053,7 +2053,7 @@ static void cgen_file(CGenerator *g, ParsedFile *f, Typer *tr) { } cgen_write(g, "/* declarations */\n"); - /* function declarations */ + // function declarations arr_foreach(tr->all_fns, FnWithCtx, fn_ctx) { g->nms = fn_ctx->nms; g->block = fn_ctx->block; @@ -2064,7 +2064,7 @@ static void cgen_file(CGenerator *g, ParsedFile *f, Typer *tr) { cgen_fn_decl(g, fn); } - /* global (non-function) declarations */ + // global (non-function) declarations arr_foreach(tr->all_globals, DeclWithCtx, dctx) { g->nms = dctx->nms; g->block = dctx->block; @@ -2072,7 +2072,7 @@ static void cgen_file(CGenerator *g, ParsedFile *f, Typer *tr) { } cgen_write(g, "/* code */\n"); - /* function definitions */ + // function definitions arr_foreach(tr->all_fns, FnWithCtx, fn_ctx) { g->nms = fn_ctx->nms; g->block = fn_ctx->block; @@ -47,13 +47,13 @@ static void copy_val(Allocator *a, Value *out, Value in, Type *t) { out->varargs = NULL; arr_set_lena(out->varargs, n, a); for (size_t i = 0; i < n; ++i) { - Copier c = copier_create(a, NULL); /* since the type is resolved, it doesn't matter that the block is wrong */ + Copier c = copier_create(a, NULL); // since the type is resolved, it doesn't matter that the block is wrong out->varargs[i].type = copy_type_(&c, in.varargs[i].type); out->varargs[i].val = in.varargs[i].val; } break; } - /* fallthrough */ + // fallthrough case TYPE_FN: case TYPE_PTR: case TYPE_SLICE: @@ -122,7 +122,7 @@ static void copy_struct(Copier *c, StructDef *out, StructDef *in) { c->block = prev; } -/* works on unresolved and resolved types (for inference) */ +// works on unresolved and resolved types (for inference) static void copy_type(Copier *c, Type *out, Type *in) { *out = *in; switch (in->kind) { @@ -172,7 +172,7 @@ static void copy_type(Copier *c, Type *out, Type *in) { break; case TYPE_STRUCT: { if (in->flags & TYPE_IS_RESOLVED) { - /* we don't actually need to make a copy of the struct here */ + // we don't actually need to make a copy of the struct here } else { /* it's okay to copy the struct definition here, because before resolving, @@ -237,7 +237,7 @@ static inline void copier_ident_translate(Copier *c, Identifier *i) { *i = ident_translate_forced(*i, &c->block->idents); } -/* in must be untyped! */ +// in must be untyped! static void copy_expr(Copier *c, Expression *out, Expression *in) { Allocator *a = c->allocr; *out = *in; /* NOTE : if in the future you are removing this, make sure in->type is still copied for EXPR_VAL, @@ -431,12 +431,12 @@ static void copy_stmt(Copier *c, Statement *out, Statement *in) { copy_block(c, out->block = copier_malloc(c, sizeof *out->block), in->block, 0); break; case STMT_INLINE_BLOCK: - assert(0); /* only exists after typing */ + assert(0); // only exists after typing break; } } -/* COPY_BLOCK_DONT_CREATE_IDENTS is for copy_fn_expr, etc. */ +// COPY_BLOCK_DONT_CREATE_IDENTS is for copy_fn_expr, etc. static void copy_block(Copier *c, Block *out, Block *in, U8 flags) { assert(!(in->flags & BLOCK_FINDING_TYPES)); out->flags = in->flags; diff --git a/data_structures.c b/data_structures.c index af89aa4..bc7b48b 100644 --- a/data_structures.c +++ b/data_structures.c @@ -73,7 +73,7 @@ static WarnUnusedResult void *arr_resva_(void *arr, size_t n, size_t item_sz, Al } -/* accommodate one more element if necessary */ +// accommodate one more element if necessary static WarnUnusedResult void *arr_grow(void *arr, size_t item_sz) { ArrHeader *hdr; if (arr == NULL) { @@ -131,7 +131,7 @@ static WarnUnusedResult void *arr_set_len_(void *arr, size_t n, size_t item_sz) arr = arr_resv_(arr, n, item_sz); } arr_hdr(arr)->len = (U32)n; - /* @OPTIM: shrink */ + // @OPTIM: shrink return arr; } static WarnUnusedResult void *arr_set_lena_(void *arr, size_t n, size_t item_sz, Allocator *a) { @@ -173,7 +173,7 @@ static void *arr_end_(void *arr, size_t item_sz) { } } -/* @OPTIM: shrink array */ +// @OPTIM: shrink array static WarnUnusedResult void *arr_remove_last_(void *arr) { assert(arr_hdr(arr)->len); if (--arr_hdr(arr)->len == 0) { @@ -232,7 +232,7 @@ You shouldn't rely on this, though, e.g. by doing #define arr_cleara(arr, allocr) arr = arr_cleara_((arr), sizeof *(arr), (allocr)) #define arr_last(arr) arr[arr_len(arr)-1] #define arr_last_ptr(arr) arr_last_((arr), sizeof *(arr)) -/* one past last, or NULL if empty */ +// one past last, or NULL if empty #define arr_end(arr) arr_end_((arr), sizeof *(arr)) #define arr_foreach(arr, type, var) for (type *var = (arr), *var##_foreach_end = arr_end(arr); var != var##_foreach_end; ++var) #define arr_foreach_reversed(arr, type, var) for (type *var = arr_last_ptr(arr), *var##_foreach_last = arr; var; var = var == var##_foreach_last ? NULL : (var-1)) @@ -241,7 +241,7 @@ You shouldn't rely on this, though, e.g. by doing #define arr_copya(out, in, allocr) do { assert(sizeof *(in) == sizeof *(out)); out = arr_copya_((out), (in), sizeof *(out), (allocr)); } while(0) #if RUN_TESTS -/* @TODO(eventually): more extensive test? */ +// @TODO(eventually): more extensive test? static void arr_test(void) { int *foos = NULL; for (int i = 0; i < 10; ++i) { @@ -259,7 +259,7 @@ static void arr_test(void) { } #endif -/* string hash table. entries are zero initialized (toc stuff depends on this!) */ +// string hash table. entries are zero initialized (toc stuff depends on this!) static U64 str_hash(const char *s, size_t len) { U32 x = 0xabcdef01; @@ -335,7 +335,7 @@ static StrHashTableSlot *str_hash_table_insert_(StrHashTable *t, const char *str return *slot; } -/* use this if you don't need the slot */ +// use this if you don't need the slot static inline void *str_hash_table_insert(StrHashTable *t, const char *str, size_t len) { return str_hash_table_insert_(t, str, len)->data; } @@ -352,7 +352,7 @@ static StrHashTableSlot *str_hash_table_insert_anonymous_(StrHashTable *t) { return *slot; } -/* use this if you don't need the slot */ +// use this if you don't need the slot static inline void *str_hash_table_insert_anonymous(StrHashTable *t) { return str_hash_table_insert_anonymous_(t)->data; } diff --git a/development.md b/development.md index 6795987..65c1bae 100644 --- a/development.md +++ b/development.md @@ -12,7 +12,8 @@ start. toc's memory management works using an allocator which never frees anything. This is because most of toc's data is kept around until the end of the program anyways. Use the allocator for "permanent" allocations, and err\_malloc/err\_calloc/err\_realloc for temporary -allocations (to avoid having it take up space for a long time). +allocations (to avoid having it take up space for a long time). Make sure you never pass +a size of 0 to those functions. Memory leaks can happen if the compilation fails at any point, but they should not happen if the compilation succeeds. Usually if there's an error @@ -32,11 +32,11 @@ static void print_pos_highlight(FILE *out, ErrCtx *ctx, File *file, U32 start_po char *line_start = start; char *end = str + end_pos; - /* go back to last newline / 0 byte */ + // go back to last newline / 0 byte while (*line_start != '\0' && *line_start != '\n') --line_start; if (line_start < start) ++line_start; - /* skip space at start of line */ + // skip space at start of line while (isspace(*line_start) && line_start < end) ++line_start; @@ -48,21 +48,21 @@ static void print_pos_highlight(FILE *out, ErrCtx *ctx, File *file, U32 start_po if (!line_start[0]) fprintf(out, "<end of file>"); else { - /* write up to start of error */ + // write up to start of error fwrite(line_start, 1, (size_t)(start - line_start), out); if (ctx->color_enabled) fprintf(out, TEXT_INDICATOR_START); if (line_end < end) { - /* write error part (only go to end of line) */ + // write error part (only go to end of line) fwrite(start, 1, (size_t)(line_end - start), out); if (ctx->color_enabled) fprintf(out, TEXT_INDICATOR_END); } else { - /* write error part */ + // write error part fwrite(start, 1, (size_t)(end - start), out); if (ctx->color_enabled) fprintf(out, TEXT_INDICATOR_END); - /* write rest of line */ + // write rest of line fwrite(end, 1, (size_t)(line_end - end), out); } } @@ -86,14 +86,14 @@ static void print_location_highlight(FILE *out, Location where) { assert(where.end >= where.start); File *f = where.file; ErrCtx *ctx = f->ctx; - if (where.start == 0 && where.end == 0) { fprintf(out, "\n"); return; } /* null location */ + if (where.start == 0 && where.end == 0) { fprintf(out, "\n"); return; } // null location Token *first = &f->tokens[where.start]; Token *last = &f->tokens[where.end-1]; print_pos_highlight(out, ctx, f, first->pos.start, last->pos.end); } -/* for debugging */ +// for debugging static void fprint_location(FILE *out, Location location) { File *f = location.file; if (location.start == 0 && location.end == 0) { @@ -188,7 +188,7 @@ static void err_print_footer_(Location where, bool show_ctx_stack) { } } -/* Write nicely-formatted errors to the error file */ +// Write nicely-formatted errors to the error file static void err_vprint(Location where, const char *fmt, va_list args) { ErrCtx *ctx = where.file->ctx; @@ -243,10 +243,10 @@ static void warn_print_( ErrCtx *ctx = where.file->ctx; if (!ctx->enabled) return; if (where.file) { - /* check if there's a #no_warn directive */ + // check if there's a #no_warn directive U32 *no_warn_lines = where.file->no_warn_lines; if (bsearch_u32(no_warn_lines, arr_len(no_warn_lines), where.file->tokens[where.start].pos.line)) { - /* yes there is */ + // yes there is return; } } @@ -142,7 +142,7 @@ static void u64_to_val(Value *v, BuiltinType v_type, U64 x) { } } -/* rerturns a pointer to the underlying data of v, e.g. an I64 * if t is the builtin BUILTIN_I64 */ +// rerturns a pointer to the underlying data of v, e.g. an I64 * if t is the builtin BUILTIN_I64 static void *val_get_ptr(Value *v, Type *t) { assert(t->flags & TYPE_IS_RESOLVED); switch (t->kind) { @@ -212,7 +212,7 @@ static void fprint_val_ptr(FILE *f, void *p, Type *t) { fprintf(f, ")"); } break; case TYPE_ARR: { - fprintf(f, "["); /* @TODO: change? when array initializers are added */ + fprintf(f, "["); // @TODO: change? when array initializers are added size_t n = (size_t)t->arr->n; if (n > 5) n = 5; for (size_t i = 0; i < n; ++i) { @@ -228,7 +228,7 @@ static void fprint_val_ptr(FILE *f, void *p, Type *t) { fprintf(f, "<pointer: %p>", *(void **)p); break; case TYPE_SLICE: { - fprintf(f, "["); /* @TODO: change? when slice initializers are added */ + fprintf(f, "["); // @TODO: change? when slice initializers are added Slice slice = *(Slice *)p; I64 n = slice.len; if (n > 5) n = 5; @@ -242,7 +242,7 @@ static void fprint_val_ptr(FILE *f, void *p, Type *t) { fprintf(f, "]"); } break; case TYPE_STRUCT: - fprintf(f, "["); /* @TODO: change? when struct initializers are added */ + fprintf(f, "["); // @TODO: change? when struct initializers are added arr_foreach(t->struc->fields, Field, fi) { if (fi != t->struc->fields) fprintf(f, ", "); @@ -372,7 +372,7 @@ static void val_builtin_cast(Value vin, BuiltinType from, Value *vout, BuiltinTy case BUILTIN_CHAR: switch (to) { builtin_casts_to_int(charv); - case BUILTIN_CHAR: /* handled at top of func */ + case BUILTIN_CHAR: // handled at top of func case BUILTIN_F32: case BUILTIN_F64: case BUILTIN_BOOL: @@ -508,13 +508,13 @@ static void val_cast(Value vin, Type *from, Value *vout, Type *to) { } } -/* type is the underlying type, not the pointer type. */ +// type is the underlying type, not the pointer type. static void eval_deref(Value *v, void *ptr, Type *type) { assert(type->flags & TYPE_IS_RESOLVED); switch (type->kind) { case TYPE_PTR: v->ptr = *(void **)ptr; break; - case TYPE_ARR: v->arr = ptr; break; /* when we have a pointer to an array, it points directly to the data in that array. */ - case TYPE_STRUCT: v->struc = ptr; break; /* same for structs */ + case TYPE_ARR: v->arr = ptr; break; // when we have a pointer to an array, it points directly to the data in that array. + case TYPE_STRUCT: v->struc = ptr; break; // same for structs case TYPE_FN: v->fn = *(FnExpr **)ptr; break; case TYPE_TUPLE: v->tuple = *(Value **)ptr; break; case TYPE_BUILTIN: @@ -550,7 +550,7 @@ static void eval_deref(Value *v, void *ptr, Type *type) { break; } } -/* inverse of eval_deref */ +// inverse of eval_deref static void eval_deref_set(void *set, Value *to, Type *type) { assert(type->flags & TYPE_IS_RESOLVED); switch (type->kind) { @@ -604,7 +604,7 @@ static Status eval_val_ptr_at_index(Location where, Value *arr, U64 i, Type *arr switch (arr_type->kind) { case TYPE_ARR: { U64 arr_sz = (U64)arr_type->arr->n; - if (i > arr_sz) { /* this is INTENTIONALLY > and not >=, because it's okay to have a pointer to one past the end of an array */ + if (i > arr_sz) { // this is INTENTIONALLY > and not >=, because it's okay to have a pointer to one past the end of an array err_print(where, "Array out of bounds (index = %lu, array size = %lu)\n", (unsigned long)i, (unsigned long)arr_sz); return false; } @@ -614,7 +614,7 @@ static Status eval_val_ptr_at_index(Location where, Value *arr, U64 i, Type *arr case TYPE_SLICE: { Slice slice = *(Slice *)arr_ptr; U64 slice_sz = (U64)slice.len; - if (i > slice_sz) { /* see above for why it's not >= */ + if (i > slice_sz) { // see above for why it's not >= err_print(where, "Slice out of bounds (index = %lu, slice size = %lu)\n", (unsigned long)i, (unsigned long)slice_sz); return false; } @@ -638,7 +638,7 @@ static Status eval_val_ptr_at_index(Location where, Value *arr, U64 i, Type *arr break; } } - /* fallthrough */ + // fallthrough default: assert(0); break; } return true; @@ -671,7 +671,7 @@ static Value *ident_val(Evaluator *ev, Identifier i, Location where) { assert(decl); int idx = decl_ident_index(decl, i); if (decl->type.kind == TYPE_UNKNOWN && ev->typer->gctx->err_ctx->have_errored) - return NULL; /* silently fail (something went wrong when we typed this decl) */ + return NULL; // silently fail (something went wrong when we typed this decl) if (decl->flags & DECL_IS_PARAM) { if (decl->val_stack) { Value *valp = arr_last(decl->val_stack); @@ -681,14 +681,14 @@ static Value *ident_val(Evaluator *ev, Identifier i, Location where) { return valp; } else { if (!(decl->flags & DECL_FOUND_VAL)) { - /* trying to access parameter, e.g. fn(y: int) { x ::= y; } */ + // trying to access parameter, e.g. fn(y: int) { x ::= y; } char *s = ident_to_str(i); err_print(where, "You can't access non-constant parameter %s at compile time.", s); info_print(decl->where, "%s was declared here.", s); free(s); return NULL; } - /* struct parameter */ + // struct parameter if (arr_len(decl->idents) > 1) return &decl->val.tuple[idx]; else @@ -708,7 +708,7 @@ static Value *ident_val(Evaluator *ev, Identifier i, Location where) { err_print(where, "You can't access non-constant variable %s at compile time.", s); info_print(decl->where, "%s was declared here.", s); free(s); - return NULL; /* uh oh... this is a runtime-only variable */ + return NULL; // uh oh... this is a runtime-only variable } } @@ -755,11 +755,11 @@ static Status eval_ptr_to_struct_field(Evaluator *ev, Expression *dot_expr, void return false; } if (str_eq_cstr(member, "data")) { - /* access struct data */ + // access struct data *p = &((Slice *)ptr)->data; } else { assert(str_eq_cstr(member, "len")); - /* access struct length */ + // access struct length *p = &((Slice *)ptr)->len; } } @@ -831,10 +831,10 @@ static Status eval_set(Evaluator *ev, Expression *set, Value *to) { case BINARY_AT_INDEX: { void *ptr; Type *type; - /* get pointer to x[i] */ + // get pointer to x[i] if (!eval_expr_ptr_at_index(ev, set, &ptr, &type)) return false; - /* set it to to */ + // set it to to eval_deref_set(ptr, to, type); } break; case BINARY_DOT: { @@ -859,9 +859,9 @@ static Status eval_set(Evaluator *ev, Expression *set, Value *to) { return true; } -/* @TODO(eventually): this could probably be made better */ +// @TODO(eventually): this could probably be made better static void eval_numerical_bin_op(Value lhs, Type *lhs_type, BinaryOp op, Value rhs, Type *rhs_type, Value *out, Type *out_type) { - /* WARNING: macros ahead */ + // WARNING: macros ahead #define eval_unary_op_nums_only(op) \ switch (builtin) { \ @@ -1034,7 +1034,7 @@ static Status eval_ident(Evaluator *ev, Identifier ident, Value *v, Location whe #if 0 Typer *tr = ev->typer; Block *prev_block = tr->block; - /* make sure we're in the right block for typing the declaration */ + // make sure we're in the right block for typing the declaration tr->block = ident->idents->scope; bool success = types_decl(ev->typer, d); tr->block = prev_block; @@ -1057,7 +1057,7 @@ static void evalr_add_val_on_stack(Evaluator *ev, Value v, Type *t) { arr_add(ev->to_free, ptr); } -/* remove and free the last value in d->val_stack. if free_val_ptr is false, the last value's contents will be freed, but not its pointer. */ +// remove and free the last value in d->val_stack. if free_val_ptr is false, the last value's contents will be freed, but not its pointer. static void decl_remove_val(Declaration *d, bool free_val_ptr) { Type *t = &d->type; Value *dval = arr_last(d->val_stack); @@ -1103,7 +1103,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { Expression *o = e->unary.of; if (type_is_builtin(&o->type, BUILTIN_TYPE)) { if (!eval_expr(ev, e->unary.of, &of)) return false; - /* "address" of type (pointer to type) */ + // "address" of type (pointer to type) v->type = evalr_malloc(ev, sizeof *v->type); v->type->flags = TYPE_IS_RESOLVED; v->type->kind = TYPE_PTR; @@ -1277,7 +1277,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { } size_t nargs = arr_len(e->call.arg_exprs); if (fn->flags & FN_EXPR_FOREIGN) { - /* evaluate foreign function */ + // evaluate foreign function Value *args = err_malloc(nargs * sizeof *args); for (size_t i = 0; i < nargs; ++i) { if (!eval_expr(ev, &e->call.arg_exprs[i], &args[i])) @@ -1292,7 +1292,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { } Type *ret_type = &fn->ret_type; - /* set parameter values */ + // set parameter values Declaration *params = fn->params, *ret_decls = fn->ret_decls; Expression *arg = e->call.arg_exprs; size_t pbytes = arr_len(params) * sizeof(Value); @@ -1304,12 +1304,12 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { #endif Value *pval = &pvals[0]; arr_foreach(params, Declaration, p) { - /* give each parameter its value */ + // give each parameter its value int idx = 0; bool multiple_idents = arr_len(p->idents) > 1; if (type_is_builtin(&p->type, BUILTIN_VARARGS)) { Expression *args_end = e->call.arg_exprs + nargs; - /* set varargs */ + // set varargs pval->varargs = NULL; for (; arg != args_end; ++arg) { VarArg *varg = arr_add_ptr(pval->varargs); @@ -1342,7 +1342,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { { Value *dval = dvals; arr_foreach(ret_decls, Declaration, d) { - /* give each return declaration its value */ + // give each return declaration its value int idx = 0; Value ret_decl_val; DeclFlags has_expr = d->flags & DECL_HAS_EXPR; @@ -1364,7 +1364,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { ++idx; } if (is_tuple && has_expr) - free(ret_decl_val.tuple); /* we extracted the individual elements of this */ + free(ret_decl_val.tuple); // we extracted the individual elements of this arr_add(d->val_stack, dval); ++dval; } @@ -1374,7 +1374,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { return false; } if (ret_decls) { - /* extract return value from return declarations */ + // extract return value from return declarations size_t nret_decls = 0; arr_foreach(ret_decls, Declaration, d) { nret_decls += arr_len(d->idents); @@ -1409,13 +1409,13 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { ev->returning = NULL; } - /* remove parameter values */ + // remove parameter values arr_foreach(params, Declaration, p) decl_remove_val(p, false); #if !ALLOCA_AVAILABLE free(pvals); #endif - /* remove ret decl values */ + // remove ret decl values arr_foreach(ret_decls, Declaration, d) decl_remove_val(d, false); #if !ALLOCA_AVAILABLE @@ -1448,7 +1448,7 @@ static Status eval_expr(Evaluator *ev, Expression *e, Value *v) { } else { to = n; } - /* @TODO: is this the best check? (Go also checks if from > to) */ + // @TODO: is this the best check? (Go also checks if from > to) if (to > n) { err_print(e->where, "Slice index out of bounds (to = %lu, length = %lu).", (unsigned long)to, (unsigned long)n); return false; @@ -1588,7 +1588,7 @@ static Status eval_stmt(Evaluator *ev, Statement *stmt) { } if (!eval_expr(ev, i->cond, &cond)) return false; if (val_truthiness(cond, &i->cond->type)) { - /* condition is true */ + // condition is true if (!eval_block(ev, &i->body)) return false; break; } @@ -1630,7 +1630,7 @@ static Status eval_stmt(Evaluator *ev, Statement *stmt) { Declaration *header = &fo->header; Value *for_valp = err_malloc(sizeof *for_valp); arr_add(header->val_stack, for_valp); - /* make a tuple */ + // make a tuple Value for_val_tuple[2]; for_valp->tuple = for_val_tuple; Value *value_val = &for_val_tuple[0]; @@ -1662,7 +1662,7 @@ static Status eval_stmt(Evaluator *ev, Statement *stmt) { } while (1) { if (fo->range.to) { - /* check if loop has ended */ + // check if loop has ended Value lhs = x; Value rhs = to; Type boolt = {0}; @@ -1774,11 +1774,11 @@ static Status eval_block(Evaluator *ev, Block *b) { } } { - /* deal with deferred stmts */ - /* these could overwrite ev->returning, ev->ret_val, so we should save them */ + // deal with deferred stmts + // these could overwrite ev->returning, ev->ret_val, so we should save them Block *return_block = ev->returning; Value return_val = ev->ret_val; - ev->returning = NULL; /* if we didn't set this, the deferred stmts would immediately return */ + ev->returning = NULL; // if we didn't set this, the deferred stmts would immediately return arr_foreach(b->deferred, StatementPtr, stmtp) { Statement *stmt = *stmtp; if (!eval_stmt(ev, stmt)) { diff --git a/foreign64.c b/foreign64.c index 5aaf574..d7a8a37 100644 --- a/foreign64.c +++ b/foreign64.c @@ -48,7 +48,7 @@ static inline double foreign_calld(FnPtr fn, U64 *args, I64 nargs, bool *is_floa } #endif -/* disable strict aliasing warnings */ +// disable strict aliasing warnings #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-aliasing" @@ -80,7 +80,7 @@ static Status val_to_word(Value v, Type *t, Location where, U64 *w) { *w = (U64)v.ptr; break; default: unsupported: { - /* @TODO(eventually) */ + // @TODO(eventually) char *s = type_to_str(t); err_print(where, "#foreign functions can't take arguments of type %s at compile time on Windows.", s); free(s); @@ -94,7 +94,7 @@ static Status val_to_word(Value v, Type *t, Location where, U64 *w) { #endif static Status foreign_call(ForeignFnManager *ffmgr, FnExpr *fn, Type *ret_type, Type *arg_types, size_t arg_types_stride, Value *args, size_t nargs, Location call_where, Value *ret) { - possibly_static_assert(sizeof(double) == 8); /* if either of these assertions fails, you'll need to use libffcall */ + possibly_static_assert(sizeof(double) == 8); // if either of these assertions fails, you'll need to use libffcall possibly_static_assert(sizeof(float) == 4); #if 0 @@ -106,7 +106,7 @@ static Status foreign_call(ForeignFnManager *ffmgr, FnExpr *fn, Type *ret_type, FnPtr fn_ptr = foreign_get_fn_ptr(ffmgr, fn, call_where); if (!fn_ptr) return false; - /* @OPTIM: use alloca/_malloca if available */ + // @OPTIM: use alloca/_malloca if available U64 *words = err_malloc(nargs * sizeof *words); bool *is_float = err_malloc(nargs); U64 *word = words; @@ -122,7 +122,7 @@ static Status foreign_call(ForeignFnManager *ffmgr, FnExpr *fn, Type *ret_type, type += arg_types_stride; ++word; } - int kind = 0; /* 0=>integer, 1=>f32, 2=>f64 */ + int kind = 0; // 0=>integer, 1=>f32, 2=>f64 switch (ret_type->kind) { case TYPE_BUILTIN: switch (ret_type->builtin) { @@ -153,7 +153,7 @@ static Status foreign_call(ForeignFnManager *ffmgr, FnExpr *fn, Type *ret_type, default: unsupported: { char *s = type_to_str(ret_type); - /* @TODO(eventually) */ + // @TODO(eventually) err_print(call_where, "You can't call functions which return type %s at compile time on Windows.", s); free(s); return false; diff --git a/foreign_avcall.c b/foreign_avcall.c index 3d2ba45..3996709 100644 --- a/foreign_avcall.c +++ b/foreign_avcall.c @@ -3,14 +3,14 @@ This file is part of toc. toc is distributed under version 3 of the GNU General Public License, without any warranty whatsoever. You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>. */ -/* WARNING: In this file, you will find crazy macros and dubious usage of avcall. Beware! */ +// WARNING: In this file, you will find crazy macros and dubious usage of avcall. Beware! #if CHAR_BIT != 8 #error "Compile-time foreign functions can only be used on systems where CHAR_BIT is 8." #endif -/* avcall has some sign conversion problems on BSD */ -/* (the macros it defines cause problems too, which is why this is ignored for so long) */ +// avcall has some sign conversion problems on BSD +// (the macros it defines cause problems too, which is why this is ignored for so long) #ifdef __clang__ #pragma clang diagnostic push @@ -135,7 +135,7 @@ static Status arg_list_start(av_alist *arg_list, FnPtr fn, Value *return_val, Ty toc_av_start(18446744073709551615)(*arg_list, fn, &return_val->u64); break; case BUILTIN_BOOL: - /* bool is probably just unsigned char.... hopefully... */ + // bool is probably just unsigned char.... hopefully... av_start_uchar(*arg_list, fn, &return_val->u8); break; case BUILTIN_CHAR: @@ -166,7 +166,7 @@ static Status arg_list_start(av_alist *arg_list, FnPtr fn, Value *return_val, Ty StructDef *struc = return_type->struc; return_val->struc = err_calloc(1, struct_size); bool splittable; - /* hopefully this is right! */ + // hopefully this is right! if (struct_size <= sizeof(long)) { splittable = true; } else if (struct_size > 2*sizeof(long)) { @@ -174,7 +174,7 @@ static Status arg_list_start(av_alist *arg_list, FnPtr fn, Value *return_val, Ty } else if (arr_len(struc->fields) > 4) { splittable = false; } else { - /* NOTE: this warning is not because splittable is being computed incorrectly! it doesn't handle it right with *either* splittable = 0 or splittable = 1 */ + // NOTE: this warning is not because splittable is being computed incorrectly! it doesn't handle it right with *either* splittable = 0 or splittable = 1 warn_print(where, "Dynamically calling function which returns a struct. avcall seems to not handle structs of size ~2*sizeof(long) correctly."); splittable = true; size_t word_size = sizeof(__avword); @@ -185,7 +185,7 @@ static Status arg_list_start(av_alist *arg_list, FnPtr fn, Value *return_val, Ty } } } - /* getting warning on Debian stretch about splittable being set but not used */ + // getting warning on Debian stretch about splittable being set but not used _av_start_struct(*arg_list, fn, struct_size, splittable, return_val->struc); (void)splittable; } break; case TYPE_SLICE: @@ -202,7 +202,7 @@ static Status arg_list_add(av_alist *arg_list, Value val, Type *type, Location w switch (type->kind) { case TYPE_TUPLE: case TYPE_UNKNOWN: - case TYPE_ARR: { /* @TODO: maybe just pass pointer for arr? */ + case TYPE_ARR: { // @TODO: maybe just pass pointer for arr? char *s = type_to_str(type); err_print(where, "Cannot pass type %s to foreign function.", s); free(s); diff --git a/foreign_msvc32.c b/foreign_msvc32.c index 3afbe20..da98f2d 100644 --- a/foreign_msvc32.c +++ b/foreign_msvc32.c @@ -13,7 +13,7 @@ typedef size_t Word; #error "What's going on? The 32-bit Windows file was included, but size_t isn't 32 bits!" #endif -/* f64s take 2 words */ +// f64s take 2 words static Status val_to_words(Value v, Type *t, Location where, Word *w) { switch (t->kind) { case TYPE_BUILTIN: @@ -45,7 +45,7 @@ static Status val_to_words(Value v, Type *t, Location where, Word *w) { *w = (Word)v.ptr; break; default: unsupported: { - /* @TODO(eventually) */ + // @TODO(eventually) char *s = type_to_str(t); err_print(where, "#foreign functions can't take arguments of type %s at compile time on Windows.", s); free(s); @@ -66,7 +66,7 @@ a lot more functions to support different combinations of integer and floating-p registers) */ -/* call function with 0 arguments, returning some sort of integer (or pointer) */ +// call function with 0 arguments, returning some sort of integer (or pointer) static U64 msvc_call0i(FnPtr fn, Word *w) { (void)w; return ((U64(*)(void))fn)(); @@ -116,7 +116,7 @@ static U64 (*const msvc_calli[11])(FnPtr fn, Word *w) = { }; -/* call function with 0 arguments, returning a float or double */ +// call function with 0 arguments, returning a float or double static double msvc_call0f(FnPtr fn, Word *w) { (void)w; return ((double(*)(void))fn)(); @@ -215,7 +215,7 @@ static Status foreign_call(ForeignFnManager *ffmgr, FnExpr *fn, Type *ret_type, default: unsupported: { char *s = type_to_str(ret_type); - /* @TODO(eventually) */ + // @TODO(eventually) err_print(call_where, "You can't call functions which return type %s at compile time on Windows.", s); free(s); return false; @@ -226,7 +226,7 @@ static Status foreign_call(ForeignFnManager *ffmgr, FnExpr *fn, Type *ret_type, double d = msvc_callf[nwords](fn_ptr, words); assert(ret_type->kind == TYPE_BUILTIN); if (ret_type->builtin == BUILTIN_F32) { - ret->f32 = (F32)d; /* turns out functions just always return doubles */ + ret->f32 = (F32)d; // turns out functions just always return doubles } else { assert(ret_type->builtin == BUILTIN_F64); ret->f64 = d; diff --git a/identifiers.c b/identifiers.c index 3232811..5df85c0 100644 --- a/identifiers.c +++ b/identifiers.c @@ -4,7 +4,7 @@ You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>. */ -/* can this character be used in an identifier? */ +// can this character be used in an identifier? static int is_ident(int c) { if (c >= 'a' && c <= 'z') return 1; @@ -14,22 +14,22 @@ static int is_ident(int c) { return 1; if (c == '_') return 1; #if CHAR_MIN < 0 - if (c < 0) /* on systems where char = signed char, UTF-8 characters are probably < 0? */ + if (c < 0) // on systems where char = signed char, UTF-8 characters are probably < 0? return 1; #endif - if (c > 127) /* UTF-8 */ + if (c > 127) // UTF-8 return 1; return 0; } -/* Initialize Identifiers. */ +// Initialize Identifiers. static void idents_create(Identifiers *ids, Allocator *allocr, Block *scope) { str_hash_table_create(&ids->table, sizeof(IdentSlot) - sizeof(StrHashTableSlot), allocr); ids->rseed = 0x27182818; ids->scope = scope; } -/* advances s until a non-identifier character is reached, then returns the number of characters advanced */ +// advances s until a non-identifier character is reached, then returns the number of characters advanced static size_t ident_str_len_advance(char **s) { char *original = *s; while (is_ident(**s)) { @@ -42,7 +42,7 @@ static size_t ident_str_len(char *s) { return ident_str_len_advance(&s); } -/* are these strings equal, up to the first non-ident character? */ +// are these strings equal, up to the first non-ident character? static bool ident_str_eq_str(const char *s, const char *t) { while (is_ident(*s) && is_ident(*t)) { if (*s != *t) return false; @@ -67,9 +67,9 @@ static inline Identifier ident_insert_with_len(Identifiers *ids, char *s, size_t return slot; } -/* moves s to the char after the identifier */ -/* inserts if does not exist. reads until non-ident char is found. */ -/* advances past identifier */ +// moves s to the char after the identifier +// inserts if does not exist. reads until non-ident char is found. +// advances past identifier static inline Identifier ident_insert(Identifiers *ids, char **s) { char *original = *s; size_t len = ident_str_len_advance(s); @@ -78,7 +78,7 @@ static inline Identifier ident_insert(Identifiers *ids, char **s) { static char *ident_to_str(Identifier i) { char *str = err_malloc(i->len + 1); - /* for some reason, GCC thinks that i->len is -1 when this is called from type_to_str_ (in release mode) */ + // for some reason, GCC thinks that i->len is -1 when this is called from type_to_str_ (in release mode) gcc_no_bounds_warnings_start memcpy(str, i->str, i->len); @@ -111,7 +111,7 @@ static void print_ident(Identifier id) { printf("\n"); } -/* reduced charset = a-z, A-Z, 0-9, _ */ +// reduced charset = a-z, A-Z, 0-9, _ static void fprint_ident_reduced_charset(FILE *out, Identifier id) { assert(id); for (const char *s = id->str; is_ident(*s); ++s) { @@ -155,13 +155,13 @@ static inline Identifier ident_get_with_len(Identifiers *ids, char *s, size_t le return (Identifier)str_hash_table_get_(&ids->table, s, len); } -/* NULL = no such identifier. returns identifier "foo" for both "foo\0" and "foo+92384324..." */ +// NULL = no such identifier. returns identifier "foo" for both "foo\0" and "foo+92384324..." static inline Identifier ident_get(Identifiers *ids, char *s) { size_t len = ident_str_len(s); return ident_get_with_len(ids, s, len); } -/* translate and insert if not already there */ +// translate and insert if not already there static inline Identifier ident_translate_forced(Identifier i, Identifiers *to_idents) { char *p = i->str; Identifier translated = ident_insert(to_idents, &p); @@ -169,12 +169,12 @@ static inline Identifier ident_translate_forced(Identifier i, Identifiers *to_id return translated; } -/* translate but don't add it if it's not there */ +// translate but don't add it if it's not there static inline Identifier ident_translate(Identifier i, Identifiers *to_idents) { return ident_get(to_idents, i->str); } -/* returns true if i and j are equal, even if they're not in the same table */ +// returns true if i and j are equal, even if they're not in the same table static inline bool ident_eq(Identifier i, Identifier j) { return i->len == j->len && memcmp(i->str, j->str, i->len) == 0; } @@ -20,7 +20,7 @@ static bool infer_from_expr(Typer *tr, Expression *match, Value to, Type *to_typ assert(to_type->flags & TYPE_IS_RESOLVED); switch (match->kind) { case EXPR_IDENT: - /* an identifier! maybe it's one of idents... */ + // an identifier! maybe it's one of idents... arr_foreach(idents, Identifier, ident) { if (ident_eq_string(*ident, match->ident_str)) { long idx = (long)(ident - idents); @@ -34,7 +34,7 @@ static bool infer_from_expr(Typer *tr, Expression *match, Value to, Type *to_typ if (!types_expr(tr, match->call.fn)) return false; if (type_is_builtin(&match->call.fn->type, BUILTIN_TYPE)) { - /* it's a parameterized struct */ + // it's a parameterized struct if (!type_is_builtin(to_type, BUILTIN_TYPE) || to.type->kind != TYPE_STRUCT) { err_print(to_where, "Wrong argument type. Expected this to be a struct, but it's not."); info_print(match->where, "Parameter was declared here."); @@ -65,7 +65,7 @@ static bool infer_from_expr(Typer *tr, Expression *match, Value to, Type *to_typ } free(order); } - /* don't try to match other kinds of function calls. it's impossible to get any information out of it. */ + // don't try to match other kinds of function calls. it's impossible to get any information out of it. } break; default: break; } @@ -88,7 +88,7 @@ static bool infer_from_type(Typer *tr, Type *match, Type *to, Identifier *idents switch (match->kind) { case TYPE_UNKNOWN: case TYPE_BUILTIN: - break; /* nothing we can do here */ + break; // nothing we can do here case TYPE_TUPLE: { if (arr_len(match->tuple) != arr_len(to->tuple)) return true; Type *b = to->tuple; @@ -138,7 +138,7 @@ static bool infer_from_type(Typer *tr, Type *match, Type *to, Identifier *idents construct_resolved_builtin_type(&n_type, BUILTIN_I64); Value val; val.i64 = (I64)to->arr->n; - /* try to match match's n expr to to's value */ + // try to match match's n expr to to's value if (!infer_from_expr(tr, match->arr->n_expr, val, &n_type, where, idents, vals, types)) return false; if (!infer_from_type(tr, match->arr->of, to->arr->of, idents, vals, types, where)) diff --git a/instance_table.c b/instance_table.c index 0f1004e..3a7c87e 100644 --- a/instance_table.c +++ b/instance_table.c @@ -10,7 +10,7 @@ are designed) */ -/* NOTE: any time you see 0x then 16 hexadecimal digits, that's probably a random number for hashing */ +// NOTE: any time you see 0x then 16 hexadecimal digits, that's probably a random number for hashing /* hash tables are initialized by setting them to {0}, e.g. @@ -22,7 +22,7 @@ static bool val_eq(Value u, Value v, Type *t); static bool type_eq_exact(Type *t1, Type *t2); static U64 f32_hash(F32 f) { - /* @OPTIM */ + // @OPTIM U64 hash = 0; if (f < 0) { hash = 0x9a6db29edcba8af4; @@ -34,7 +34,7 @@ static U64 f32_hash(F32 f) { ++exponent; f /= 10; if (f == last) { - /* +/- infinity probably */ + // +/- infinity probably hash ^= 0x78bf61a81e80b9f2; return hash; } @@ -48,7 +48,7 @@ static U64 f32_hash(F32 f) { } static U64 f64_hash(F64 f) { - /* @OPTIM */ + // @OPTIM U64 hash = 0; if (f < 0) { hash = 0x9a6db29edcba8af4; @@ -60,7 +60,7 @@ static U64 f64_hash(F64 f) { ++exponent; f /= 10; if (f == last) { - /* +/- infinity probably */ + // +/- infinity probably hash ^= 0x78bf61a81e80b9f2; return hash; } @@ -118,7 +118,7 @@ static U64 type_hash(Type *t) { assert(0); return 0; } -/* Note that for these value hashing functions, values of different types may collide */ +// Note that for these value hashing functions, values of different types may collide static U64 val_ptr_hash(void *v, Type *t) { assert(t->flags & TYPE_IS_RESOLVED); switch (t->kind) { @@ -304,7 +304,7 @@ static bool val_eq(Value u, Value v, Type *t) { and set already_exists accordingly make sure v's data remains valid */ -/* @OPTIM: store instances in a block array (remember that the pointers need to stay valid!) */ +// @OPTIM: store instances in a block array (remember that the pointers need to stay valid!) static Instance *instance_table_adda(Allocator *a, HashTable *h, Value v, Type *t, bool *already_exists) { if (h->n * 2 >= h->cap) { @@ -314,9 +314,9 @@ static Instance *instance_table_adda(Allocator *a, HashTable *h, Value v, Type * Instance **old_data = h->data; bool *old_occupied = h->occupied; for (U64 i = 0; i < h->cap; ++i) { - /* re-hash */ + // re-hash if (old_occupied[i]) { - /* @OPTIM: keep hashes around */ + // @OPTIM: keep hashes around U64 index = val_hash(old_data[i]->val, t) % new_cap; while (new_occupied[index]) { ++index; @@ -347,7 +347,7 @@ static Instance *instance_table_adda(Allocator *a, HashTable *h, Value v, Type * index -= h->cap; } if (already_exists) { - /* create, because it doesn't exist */ + // create, because it doesn't exist *already_exists = false; data[index] = allocr_malloc(a, sizeof *data[index]); data[index]->val = v; @@ -360,7 +360,7 @@ static Instance *instance_table_adda(Allocator *a, HashTable *h, Value v, Type * #if 0 -/* only call if you're not using an allocator */ +// only call if you're not using an allocator static void hash_table_free(HashTable *h) { free(h->data); free(h->occupied); @@ -4,9 +4,9 @@ You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>. */ -/* see development.md for development information */ +/* +see development.md for development information -/* @TODO: if we do #include "foo.toc", bar; and foo.toc fails, bar should be declared as TYPE_UNKNOWN (right now it's undeclared) fix #foreign not at global scope - right now the cgen'd definition doesn't use the proper type @@ -96,7 +96,7 @@ static void signal_handler(int num) { static void *addrs[300]; int naddrs = (int)(sizeof addrs / sizeof *addrs); naddrs = backtrace(addrs, naddrs); - /* char **syms = backtrace_symbols(addrs, naddrs); */ + // char **syms = backtrace_symbols(addrs, naddrs); char command[2048] = "addr2line -p -f -a -e "; strcat(command, program_name); strcat(command, " "); @@ -105,7 +105,7 @@ static void signal_handler(int num) { snprintf(command + strlen(command), sizeof command - strlen(command), "%p ", addrs[i]); } system(command); - /* free(syms); */ + // free(syms); signal(SIGABRT, SIG_DFL); abort(); } @@ -164,13 +164,13 @@ int main(int argc, char **argv) { bool default_color_enabled; #if UNISTD_AVAILABLE #if defined _POSIX_VERSION && _POSIX_VERSION >= 200112L - /* isatty available */ - default_color_enabled = (bool)isatty(2); /* is /dev/stderr a tty? */ + // isatty available + default_color_enabled = (bool)isatty(2); // is /dev/stderr a tty? #else - default_color_enabled = false; /* old posix version */ + default_color_enabled = false; // old posix version #endif #else - default_color_enabled = false; /* probably windows */ + default_color_enabled = false; // probably windows #endif err_ctx.color_enabled = default_color_enabled; @@ -81,7 +81,7 @@ static inline U32 rand_u32(U32 seed) { #define plural_suffix(x) ((x) == 1 ? "" : "s") static const char *indefinite_article(const char *s) { - /* usually, words starting with "u" use "a" - "a unique thing", "a u64" */ + // usually, words starting with "u" use "a" - "a unique thing", "a u64" if (*s == 'a' || *s == 'e' || *s == 'i' || *s == 'o') return "an"; return "a"; @@ -11,7 +11,7 @@ enum { PARSE_DECL_ALLOW_INFER = 0x0004, PARSE_DECL_ALLOW_EXPORT = 0x0008, PARSE_DECL_DONT_SET_IDECLS = 0x0010, - PARSE_DECL_IGNORE_EXPR = 0x0020, /* NOTE: if you pass this to parse_decl, you must set d->where.end */ + PARSE_DECL_IGNORE_EXPR = 0x0020, // NOTE: if you pass this to parse_decl, you must set d->where.end DECL_CAN_END_WITH_SEMICOLON = 0x0100, DECL_CAN_END_WITH_RPAREN = 0x0200, DECL_CAN_END_WITH_LBRACE = 0x0400, @@ -159,7 +159,7 @@ static inline void mklocation(Location *l, File *f, Token *start, Token *end) { l->end = (U32)(end - f->tokens); } -/* returns -1 on failure */ +// returns -1 on failure static int kw_to_builtin_type(Keyword kw) { switch (kw) { case KW_I8: return BUILTIN_I8; @@ -179,7 +179,7 @@ static int kw_to_builtin_type(Keyword kw) { case KW_TYPE: return BUILTIN_TYPE; case KW_VOID: return BUILTIN_VOID; case KW_NAMESPACE: return BUILTIN_NMS; - /* don't allow .. => varargs because it's not a normal type */ + // don't allow .. => varargs because it's not a normal type default: return -1; } return -1; @@ -208,7 +208,7 @@ static Keyword builtin_type_to_kw(BuiltinType t) { return KW_COUNT; } -/* returns the number of characters written, not including the null character */ +// returns the number of characters written, not including the null character static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) { bool resolved = (t->flags & TYPE_IS_RESOLVED) != 0; switch (t->kind) { @@ -262,7 +262,7 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) { if (def->params) { written += str_copy(buffer + written, bufsize - written, "("); arr_foreach(def->params, Declaration, param) { - /* @TODO: val to str */ + // @TODO: val to str if (param != def->params) written += str_copy(buffer + written, bufsize - written, ", "); written += str_copy(buffer + written, bufsize - written, "<argument>"); @@ -306,21 +306,21 @@ static size_t type_to_str_(Type *t, char *buffer, size_t bufsize) { return written; } case TYPE_EXPR: - /* @TODO: improve this... we're gonna need expr_to_str ): */ + // @TODO: improve this... we're gonna need expr_to_str ): return str_copy(buffer, bufsize, "<type expression>"); } assert(0); return 0; } -/* return value should be freed by caller */ +// return value should be freed by caller static char *type_to_str(Type *t) { char *ret = err_malloc(256); type_to_str_(t, ret, 256); return ret; } -/* defaults start to wherever we are now */ +// defaults start to wherever we are now static inline Location parser_mk_loc(Parser *p) { Location loc = {0}; loc.file = p->file; @@ -367,19 +367,19 @@ static inline void *parser_calloc(Parser *p, size_t n, size_t bytes) { return allocr_calloc(p->allocr, n, bytes); } -/* allocate a new expression. */ +// allocate a new expression. static inline Expression *parser_new_expr(Parser *p) { return parser_malloc(p, sizeof(Expression)); } typedef enum { - EXPR_CAN_END_WITH_COMMA = 0x01, /* a comma could end the expression */ + EXPR_CAN_END_WITH_COMMA = 0x01, // a comma could end the expression EXPR_CAN_END_WITH_LBRACE = 0x02, EXPR_CAN_END_WITH_COLON = 0x04, EXPR_CAN_END_WITH_DOTDOT = 0x08, EXPR_CAN_END_WITH_EQ = 0x10, EXPR_CAN_END_WITH_WHERE = 0x20 - /* note that parse_type uses -1 for this */ + // note that parse_type uses -1 for this } ExprEndFlags; static Token *expr_find_end(Parser *p, ExprEndFlags flags) { @@ -420,7 +420,7 @@ static Token *expr_find_end(Parser *p, ExprEndFlags flags) { case KW_RBRACE: --brace_level; if (paren_level == 0 && brace_level == 0 && square_level == 0) { - return token + 1; /* token afer } is end */ + return token + 1; // token afer } is end } if (brace_level < 0) return token; @@ -448,31 +448,31 @@ static Token *expr_find_end(Parser *p, ExprEndFlags flags) { } if (token->kind == TOKEN_EOF) { if (brace_level > 0) { - tokr_err(t, "Opening brace { was never closed."); /* @TODO: Find out where this is */ + tokr_err(t, "Opening brace { was never closed."); // @TODO: Find out where this is } else if (paren_level > 0) { tokr_err(t, "Opening parenthesis ( was never closed."); } else if (square_level > 0) { tokr_err(t, "Opening square bracket [ was never closed."); } else { tokr_err(t, "Could not find end of expression (did you forget a semicolon?)."); - /* @TODO: ? improve err message */ + // @TODO: ? improve err message } - t->token = token; /* don't try to continue */ + t->token = token; // don't try to continue return NULL; } ++token; } } -/* parses, e.g. "(3, 5, foo)" */ +// parses, e.g. "(3, 5, foo)" static Status parse_args(Parser *p, Argument **args) { Tokenizer *t = p->tokr; Token *start = t->token; assert(token_is_kw(start, KW_LPAREN)); *args = NULL; - ++t->token; /* move past ( */ + ++t->token; // move past ( if (!token_is_kw(t->token, KW_RPAREN)) { - /* non-empty arg list */ + // non-empty arg list while (1) { if (t->token->kind == TOKEN_EOF) { tokr_err(t, "Expected argument list to continue."); @@ -481,7 +481,7 @@ static Status parse_args(Parser *p, Argument **args) { } Argument *arg = parser_arr_add_ptr(p, *args); arg->where = parser_mk_loc(p); - /* named arguments */ + // named arguments if (t->token->kind == TOKEN_IDENT && token_is_kw(t->token + 1, KW_EQ)) { arg->name = t->token->ident; t->token += 2; @@ -496,15 +496,15 @@ static Status parse_args(Parser *p, Argument **args) { if (token_is_kw(t->token, KW_RPAREN)) break; assert(token_is_kw(t->token, KW_COMMA)); - ++t->token; /* move past , */ + ++t->token; // move past , } } - ++t->token; /* move past ) */ + ++t->token; // move past ) return true; } static void correct_ret_type(Parser *p, Type *ret_type) { if (ret_type->kind == TYPE_EXPR && ret_type->expr->kind == EXPR_TUPLE) { - /* it's returning a tuple! */ + // it's returning a tuple! Expression *tuple_members = ret_type->expr->tuple; size_t ntuple_members = arr_len(tuple_members); ret_type->kind = TYPE_TUPLE; @@ -519,7 +519,7 @@ static void correct_ret_type(Parser *p, Type *ret_type) { } } -/* where will be filled out with the location, if not NULL */ +// where will be filled out with the location, if not NULL static Status parse_type(Parser *p, Type *type, Location *where) { Tokenizer *t = p->tokr; if (where) { @@ -537,10 +537,10 @@ static Status parse_type(Parser *p, Type *type, Location *where) { break; } } - /* Not a builtin */ + // Not a builtin switch (t->token->kw) { case KW_FN: { - /* function type */ + // function type type->kind = TYPE_FN; FnType *fn = type->fn = parser_calloc(p, 1, sizeof *type->fn); ++t->token; @@ -548,7 +548,7 @@ static Status parse_type(Parser *p, Type *type, Location *where) { tokr_err(t, "Expected ( to follow fn."); return false; } - parser_arr_add_ptr(p, fn->types); /* add return type */ + parser_arr_add_ptr(p, fn->types); // add return type ++t->token; if (!token_is_kw(t->token, KW_RPAREN)) { while (1) { @@ -561,12 +561,12 @@ static Status parse_type(Parser *p, Type *type, Location *where) { tokr_err(t, "Expected , to continue function type parameter list."); return false; } - ++t->token; /* move past , */ + ++t->token; // move past , } } - ++t->token; /* move past ) */ + ++t->token; // move past ) Type *ret_type = fn->types; - /* if there's a symbol that isn't [, (, or &, that can't be the start of a type */ + // if there's a symbol that isn't [, (, or &, that can't be the start of a type if ((t->token->kind == TOKEN_KW && t->token->kw <= KW_LAST_SYMBOL && t->token->kw != KW_LSQUARE @@ -584,15 +584,15 @@ static Status parse_type(Parser *p, Type *type, Location *where) { break; } case KW_LSQUARE: { - /* array/slice */ + // array/slice type->kind = TYPE_ARR; ArrType *arr = type->arr = parser_malloc(p, sizeof *type->arr); - ++t->token; /* move past [ */ + ++t->token; // move past [ if (token_is_kw(t->token, KW_RSQUARE)) { - /* slice */ + // slice type->kind = TYPE_SLICE; type->slice = parser_malloc(p, sizeof *type->slice); - ++t->token; /* move past ] */ + ++t->token; // move past ] Location slice_where; if (!parse_type(p, type->slice, &slice_where)) return false; break; @@ -600,37 +600,37 @@ static Status parse_type(Parser *p, Type *type, Location *where) { Token *end = expr_find_end(p, 0); arr->n_expr = parser_new_expr(p); if (!parse_expr(p, arr->n_expr, end)) return false; - t->token = end + 1; /* go past ] */ + t->token = end + 1; // go past ] arr->of = parser_malloc(p, sizeof *arr->of); Location of_where; if (!parse_type(p, arr->of, &of_where)) return false; } break; case KW_AMPERSAND: { - /* pointer */ + // pointer type->kind = TYPE_PTR; type->ptr = parser_malloc(p, sizeof *type->ptr); - ++t->token; /* move past & */ + ++t->token; // move past & Location ptr_where; if (!parse_type(p, type->ptr, &ptr_where)) return false; } break; case KW_ANDAND: { - /* pointer to pointer */ + // pointer to pointer type->kind = TYPE_PTR; Type *ptr = type->ptr = parser_malloc(p, sizeof *type->ptr); ptr->flags = 0; ptr->kind = TYPE_PTR; ptr->ptr = parser_malloc(p, sizeof *ptr->ptr); - ++t->token; /* move past && */ + ++t->token; // move past && Location ptrptr_where; if (!parse_type(p, ptr->ptr, &ptrptr_where)) return false; } break; case KW_STRUCT: { - /* struct */ + // struct type->kind = TYPE_STRUCT; StructDef *struc = type->struc = parser_malloc(p, sizeof *type->struc); struc->flags = 0; struc->name = NULL; - /* help cgen out */ + // help cgen out struc->c.id = 0; struc->params = NULL; struc->where = parser_mk_loc(p); @@ -659,7 +659,7 @@ static Status parse_type(Parser *p, Type *type, Location *where) { goto struct_fail; } if ((param->flags & DECL_ANNOTATES_TYPE) && type_is_builtin(¶m->type, BUILTIN_VARARGS)) { - /* @TODO(eventually) */ + // @TODO(eventually) err_print(param->where, "structs cannot have varargs parameters (yet)."); goto struct_fail; } @@ -684,7 +684,7 @@ static Status parse_type(Parser *p, Type *type, Location *where) { break; default: type_expr: { - /* TYPE_EXPR */ + // TYPE_EXPR Token *end = expr_find_end(p, (ExprEndFlags)-1 /* end as soon as possible */); if (parse_expr(p, type->expr = parser_new_expr(p), end)) { type->kind = TYPE_EXPR; @@ -714,13 +714,13 @@ static bool parser_is_definitely_type(Parser *p, Token **end) { case TOKEN_KW: switch (t->token->kw) { case KW_ANDAND: - /* &&int */ + // &&int return true; case KW_STRUCT: ret = true; if (end) { int level = 1; - t->token += 2; /* skip struct { */ + t->token += 2; // skip struct { while (t->token->kind != TOKEN_EOF) { if (t->token->kind == TOKEN_KW) switch (t->token->kw) { case KW_LBRACE: @@ -751,7 +751,7 @@ static bool parser_is_definitely_type(Parser *p, Token **end) { if (level == 0) { if (end) { ++t->token; - parser_is_definitely_type(p, &t->token); /* move to end of type */ + parser_is_definitely_type(p, &t->token); // move to end of type } goto end; } @@ -779,13 +779,13 @@ static bool parser_is_definitely_type(Parser *p, Token **end) { --paren_level; if (paren_level == 0) { ++t->token; - if (token_is_kw(t->token, KW_LBRACE)) goto end; /* void fn expr */ - if (is_decl(t)) /* has return declaration */ + if (token_is_kw(t->token, KW_LBRACE)) goto end; // void fn expr + if (is_decl(t)) // has return declaration goto end; if (t->token->kind == TOKEN_KW && (t->token->kw == KW_SEMICOLON || t->token->kw == KW_COMMA || t->token->kw == KW_RPAREN || t->token->kw == KW_LBRACE)) { - /* void fn type */ + // void fn type ret = true; goto end; } @@ -794,10 +794,10 @@ static bool parser_is_definitely_type(Parser *p, Token **end) { return false; } if (token_is_kw(t->token, KW_LBRACE)) { - /* non-void fn expr */ + // non-void fn expr goto end; } - /* it's a non-void function type */ + // it's a non-void function type ret = true; goto end; } @@ -810,7 +810,7 @@ static bool parser_is_definitely_type(Parser *p, Token **end) { case KW_DOTDOT: return true; case KW_AMPERSAND: - ++t->token; /* continue; see if next thing is definitely a type */ + ++t->token; // continue; see if next thing is definitely a type goto continu; default: { int x = kw_to_builtin_type(t->token->kw); @@ -854,14 +854,14 @@ static Status parse_block(Parser *p, Block *b, U8 flags) { } b->where = parser_mk_loc(p); #ifdef TOC_DEBUG - /* temporary, so we can still print the location of the block while we're parsing it. */ + // temporary, so we can still print the location of the block while we're parsing it. parser_set_end_to_token(p, &b->where, t->token + 1); #endif - ++t->token; /* move past { */ + ++t->token; // move past { b->stmts = NULL; bool ret = true; if (!token_is_kw(t->token, KW_RBRACE)) { - /* non-empty block */ + // non-empty block while (1) { Statement *stmt = parser_arr_add_ptr(p, b->stmts); bool was_a_statement; @@ -876,7 +876,7 @@ static Status parse_block(Parser *p, Block *b, U8 flags) { break; } if (t->token->kind == TOKEN_EOF) { - /* sometimes we skip to the end of the file to give up on parsing, so if there's already been an error, don't give this one. */ + // sometimes we skip to the end of the file to give up on parsing, so if there's already been an error, don't give this one. if (ret) { tokr_err(t, "Expected '}' to close function body."); ret = false; @@ -886,19 +886,19 @@ static Status parse_block(Parser *p, Block *b, U8 flags) { } } - ++t->token; /* move past } */ + ++t->token; // move past } parser_put_end(p, &b->where); end: p->block = prev_block; if (!ret) { - /* @TODO: better way of skipping to end of block */ + // @TODO: better way of skipping to end of block while (t->token->kind != TOKEN_EOF && !token_is_kw(t->token, KW_RBRACE)) ++t->token; } return ret; } -/* does NOT handle empty declaration lists */ +// does NOT handle empty declaration lists static Status parse_decl_list(Parser *p, Declaration **decls, U16 flags) { Tokenizer *t = p->tokr; bool ret = true; @@ -912,13 +912,13 @@ static Status parse_decl_list(Parser *p, Declaration **decls, U16 flags) { Declaration *decl = parser_arr_add_ptr(p, *decls); if (!parse_decl(p, decl, flags)) { ret = false; - /* skip to end of list */ + // skip to end of list while (t->token->kind != TOKEN_EOF && !ends_decl(t->token, flags)) ++t->token; break; } if (decl->flags & DECL_INFER) { - /* split this declaration */ + // split this declaration size_t nidents = arr_len(decl->idents); for (size_t i = 1; i < nidents; ++i) { Declaration *new_decl = parser_arr_add_ptr(p, *decls); @@ -930,7 +930,7 @@ static Status parse_decl_list(Parser *p, Declaration **decls, U16 flags) { parser_arr_set_len(p, decl->idents, 1); } } - /* correct ident decls because the pointers to declarations might have changed */ + // correct ident decls because the pointers to declarations might have changed arr_foreach(*decls, Declaration, decl) { arr_foreach(decl->idents, Identifier, ident) { (*ident)->decl = decl; @@ -944,7 +944,7 @@ static Status parse_fn_expr(Parser *p, FnExpr *f) { f->instance_id = 0; f->ret_decls = NULL; f->instances = NULL; - /* only called when token is fn */ + // only called when token is fn assert(token_is_kw(t->token, KW_FN)); ++t->token; if (!token_is_kw(t->token, KW_LPAREN)) { @@ -955,7 +955,7 @@ static Status parse_fn_expr(Parser *p, FnExpr *f) { f->params = NULL; bool success = true; Block *prev_block = p->block; - /* enter block so that parameters' scope will be the function body */ + // enter block so that parameters' scope will be the function body f->body.parent = p->block; p->block = &f->body; idents_create(&f->body.idents, p->allocr, &f->body); @@ -977,7 +977,7 @@ static Status parse_fn_expr(Parser *p, FnExpr *f) { } if (token_is_kw(t->token, KW_LBRACE)) { - /* void function */ + // void function f->ret_type.kind = TYPE_BUILTIN; f->ret_type.builtin = BUILTIN_VOID; f->ret_type.flags = 0; @@ -990,8 +990,8 @@ static Status parse_fn_expr(Parser *p, FnExpr *f) { success = false; goto ret; } } - --t->token; /* move back to { */ - /* just set return type to void. the actual return type will be set by types.c:type_of_fn */ + --t->token; // move back to { + // just set return type to void. the actual return type will be set by types.c:type_of_fn f->ret_type.kind = TYPE_BUILTIN; f->ret_type.builtin = BUILTIN_VOID; f->ret_type.flags = 0; @@ -1002,7 +1002,7 @@ static Status parse_fn_expr(Parser *p, FnExpr *f) { } correct_ret_type(p, &f->ret_type); } - p->block = prev_block; /* be nice to parse_block */ + p->block = prev_block; // be nice to parse_block if (!parse_block(p, &f->body, PARSE_BLOCK_DONT_CREATE_IDENTS)) success = false; ret: @@ -1015,7 +1015,7 @@ static void fprint_expr(FILE *out, Expression *e); #define NOT_AN_OP -1 -/* cast isn't really an operator since it operates on types, not exprs. */ +// cast isn't really an operator since it operates on types, not exprs. #define CAST_PRECEDENCE 2 #define DSIZEOF_PRECEDENCE 5 #define DALIGNOF_PRECEDENCE 5 @@ -1267,18 +1267,18 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { } { Token *before = t->token; - /* @OPTIM very few expressions are types */ + // @OPTIM very few expressions are types if (parser_is_definitely_type(p, NULL)) { - /* it's a type! */ + // it's a type! e->kind = EXPR_TYPE; if (!parse_type(p, e->typeval = parser_malloc(p, sizeof *e->typeval), NULL)) return false; if (t->token == end) goto success; - /* there's more stuff after */ + // there's more stuff after } t->token = before; if (end - t->token == 1) { - /* 1-token expression */ + // 1-token expression switch (t->token->kind) { case TOKEN_LITERAL_INT: e->kind = EXPR_LITERAL_INT; @@ -1339,7 +1339,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { Token *start = t->token; if (t->token->kind == TOKEN_KW) switch (t->token->kw) { case KW_FN: { - /* this is a function */ + // this is a function e->kind = EXPR_FN; Token *fn_start = t->token; if (!parse_fn_expr(p, e->fn = parser_calloc(p, 1, sizeof *e->fn))) @@ -1381,7 +1381,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { Type *fn_t = &fn->foreign.type; fn_t->kind = TYPE_FN; FnType *fn_type = fn_t->fn = parser_calloc(p, 1, sizeof *fn_type); - /* reserve space for return type (Type + CType) */ + // reserve space for return type (Type + CType) parser_arr_add_ptr(p, fn_type->types); parser_arr_add_ptr(p, fn->foreign.ctypes); @@ -1436,7 +1436,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { Type *ret_type = &fn_type->types[0]; CType *ret_ctype = &fn->foreign.ctypes[0]; if (t->token == end) { - /* void */ + // void ret_ctype->kind = CTYPE_NONE; ret_type->kind = TYPE_BUILTIN; ret_type->builtin = BUILTIN_VOID; @@ -1448,15 +1448,15 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { goto success; } - /* NOTE: the . operator is not handled here, but further down, in order to allow some_struct.fn_member() */ - Token *dot = NULL; /* this keeps track of it for later */ + // NOTE: the . operator is not handled here, but further down, in order to allow some_struct.fn_member() + Token *dot = NULL; // this keeps track of it for later - /* Find the lowest-precedence operator not in parentheses/braces/square brackets */ + // Find the lowest-precedence operator not in parentheses/braces/square brackets int paren_level = 0; int brace_level = 0; int square_level = 0; int lowest_precedence = NOT_AN_OP; - /* e.g. (5+3) */ + // e.g. (5+3) bool entirely_within_parentheses = token_is_kw(t->token, KW_LPAREN); Token *lowest_precedence_op = NULL; for (Token *token = t->token; token < end; ++token) { @@ -1554,40 +1554,40 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { } if (entirely_within_parentheses) { - ++t->token; /* move past opening ( */ + ++t->token; // move past opening ( if (token_is_kw(t->token, KW_RPAREN)) { - /* ()foo */ + // ()foo --t->token; tokr_err(t, "Stray () (maybe try wrapping the stuff before this in parentheses)"); return false; } - Token *new_end = end - 1; /* parse to ending ) */ + Token *new_end = end - 1; // parse to ending ) U32 start_idx = e->where.start; if (!parse_expr(p, e, new_end)) return false; - e->where.start = start_idx; /* make sure we keep e->where.start intact */ - ++t->token; /* move past closing ) */ + e->where.start = start_idx; // make sure we keep e->where.start intact + ++t->token; // move past closing ) goto success; } if (lowest_precedence != NOT_AN_OP) { - /* Check if this is a unary op not a binary one (e.g. +-3 => +(-3), not (+)-(3)). */ + // Check if this is a unary op not a binary one (e.g. +-3 => +(-3), not (+)-(3)). while (lowest_precedence_op != t->token && lowest_precedence_op[-1].kind == TOKEN_KW && op_precedence(lowest_precedence_op[-1].kw) != NOT_AN_OP) { --lowest_precedence_op; } if (lowest_precedence_op == t->token) { - /* Unary */ + // Unary UnaryOp op; bool is_unary = true; if (t->token->kind == TOKEN_KW) { switch (t->token->kw) { case KW_PLUS: - /* unary + is ignored entirely */ + // unary + is ignored entirely ++t->token; - /* re-parse this expression without + */ + // re-parse this expression without + return parse_expr(p, e, end); case KW_MINUS: op = UNARY_MINUS; @@ -1644,7 +1644,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { } if (lowest_precedence_op->kw == KW_AS) { - /* cast */ + // cast Expression *casted = parser_new_expr(p); e->kind = EXPR_CAST; e->cast.expr = casted; @@ -1652,7 +1652,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { return false; t->token = lowest_precedence_op + 1; if (token_is_direct(t->token, DIRECT_C)) { - /* cast to #C type */ + // cast to #C type if (!parse_c_type(p, &e->cast.ctype, &e->cast.type)) return false; } else { @@ -1672,7 +1672,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { if (!parse_expr(p, &lhs, lowest_precedence_op)) return false; t->token = lowest_precedence_op + 1; if (!parse_expr(p, &rhs, end)) return false; - /* create tuple expr out of lhs, rhs */ + // create tuple expr out of lhs, rhs e->kind = EXPR_TUPLE; e->tuple = NULL; if (lhs.kind == EXPR_TUPLE) { @@ -1768,15 +1768,15 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { } goto success; } else { - /* function calls, array accesses, etc. */ + // function calls, array accesses, etc. if (t->token->kind == TOKEN_DIRECT) { - /* it's a directive */ - Expression *single_arg = NULL; /* points to an expr if this is a directive with one expression argument */ + // it's a directive + Expression *single_arg = NULL; // points to an expr if this is a directive with one expression argument switch (t->token->direct) { case DIRECT_IF: - assert(0); /* handled above */ + assert(0); // handled above break; case DIRECT_C: e->kind = EXPR_C; @@ -1810,10 +1810,10 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { } } - /* try a function call or array access */ + // try a function call or array access Token *token = t->token; - /* currently unnecessary: paren_level = square_level = 0; */ + // currently unnecessary: paren_level = square_level = 0; /* can't call at start, e.g. in (fn() {})(), it is not the empty function "" being called with fn() {} as an argument @@ -1822,7 +1822,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { ++paren_level; ++token; } - /* which opening bracket starts the call/array access */ + // which opening bracket starts the call/array access Token *opening_bracket = NULL; Token *closing_bracket = NULL; for (; token < end; ++token) { @@ -1831,14 +1831,14 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { case KW_LPAREN: if (square_level == 0 && paren_level == 0 && brace_level == 0 && token != t->tokens - && token[-1].kind != TOKEN_DIRECT /* don't include directives */ - && !token_is_kw(&token[-1], KW_DOT)) /* or some_struct.("property") */ - opening_bracket = token; /* maybe this left parenthesis opens the function call */ + && token[-1].kind != TOKEN_DIRECT // don't include directives + && !token_is_kw(&token[-1], KW_DOT)) // or some_struct.("property") + opening_bracket = token; // maybe this left parenthesis opens the function call ++paren_level; break; case KW_LSQUARE: if (square_level == 0 && paren_level == 0 && brace_level == 0) - opening_bracket = token; /* (array access) */ + opening_bracket = token; // (array access) ++square_level; break; case KW_RPAREN: @@ -1875,10 +1875,10 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { if (opening_bracket && closing_bracket && closing_bracket + 1 == end /* make sure there's nothing after the closing bracket */) { switch (opening_bracket->kw) { case KW_LPAREN: { - /* it's a function call! */ + // it's a function call! e->kind = EXPR_CALL; e->call.fn = parser_new_expr(p); - if (!parse_expr(p, e->call.fn, opening_bracket)) { /* parse up to ( as function */ + if (!parse_expr(p, e->call.fn, opening_bracket)) { // parse up to ( as function return false; } t->token = opening_bracket; @@ -1888,14 +1888,14 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { } case KW_LSQUARE: { Expression *arr = parser_new_expr(p); - /* it's an array access or slice */ - /* parse array */ + // it's an array access or slice + // parse array if (!parse_expr(p, arr, opening_bracket)) return false; t->token = opening_bracket + 1; Token *iend = NULL; if (token_is_kw(t->token, KW_COLON)) { - /* slice */ + // slice goto expr_is_slice; } iend = expr_find_end(p, EXPR_CAN_END_WITH_COLON); @@ -1905,7 +1905,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { } switch (iend->kw) { case KW_RSQUARE: - /* array access */ + // array access e->kind = EXPR_BINARY_OP; e->binary.op = BINARY_AT_INDEX; e->binary.lhs = arr; @@ -1915,7 +1915,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { break; expr_is_slice: case KW_COLON: { - /* slice */ + // slice SliceExpr *s = &e->slice; e->kind = EXPR_SLICE; s->of = arr; @@ -1924,13 +1924,13 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { if (!parse_expr(p, s->from, iend)) return false; } else { - /* e.g. x[:5] */ + // e.g. x[:5] s->from = NULL; } assert(token_is_kw(t->token, KW_COLON)); ++t->token; if (token_is_kw(t->token, KW_RSQUARE)) { - /* e.g. x[5:] */ + // e.g. x[5:] s->to = NULL; } else { s->to = parser_new_expr(p); @@ -1947,7 +1947,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { err_print(token_location(p->file, iend), "Expected ] or : after index."); return false; } - ++t->token; /* move past ] */ + ++t->token; // move past ] goto success; } default: @@ -2008,7 +2008,7 @@ static inline bool ends_decl(Token *t, U16 flags) { static Status parse_decl(Parser *p, Declaration *d, U16 flags) { Tokenizer *t = p->tokr; d->where = parser_mk_loc(p); - parser_set_end_to_token(p, &d->where, t->token+1); /* set temporary end in case this fails and we need to know the location of this declaration */ + parser_set_end_to_token(p, &d->where, t->token+1); // set temporary end in case this fails and we need to know the location of this declaration d->idents = NULL; d->flags = 0; d->val_stack = NULL; @@ -2063,7 +2063,7 @@ static Status parse_decl(Parser *p, Declaration *d, U16 flags) { } if (token_is_kw(t->token, KW_SEMICOLON) || token_is_kw(t->token, KW_RPAREN)) { - /* e.g. foo :; */ + // e.g. foo :; tokr_err(t, "Cannot infer type without expression."); goto ret_false; } @@ -2122,7 +2122,7 @@ static Status parse_decl(Parser *p, Declaration *d, U16 flags) { if (token_is_kw(t->token, KW_EQ)) { ++t->token; if ((flags & PARSE_DECL_ALLOW_INFER) && ends_decl(t->token, flags)) { - /* inferred expression */ + // inferred expression d->flags |= DECL_INFER; if (!(d->flags & DECL_IS_CONST)) { tokr_err(t, "Inferred parameters must be constant."); @@ -2152,11 +2152,11 @@ static Status parse_decl(Parser *p, Declaration *d, U16 flags) { } Expression *e = &d->expr; if (!parse_expr(p, e, end)) { - t->token = end; /* move to ; */ + t->token = end; // move to ; goto ret_false; } if ((flags & DECL_CAN_END_WITH_SEMICOLON) && end > t->tokens && token_is_kw(end - 1, KW_RBRACE)) { - /* allow semicolon to be ommitted, e.g. f ::= fn() {} */ + // allow semicolon to be ommitted, e.g. f ::= fn() {} } else if (ends_decl(t->token, flags)) { ++t->token; } else { @@ -2174,7 +2174,7 @@ static Status parse_decl(Parser *p, Declaration *d, U16 flags) { if ((d->flags & DECL_IS_CONST) && !(d->flags & DECL_HAS_EXPR) && !(flags & PARSE_DECL_ALLOW_CONST_WITH_NO_EXPR)) { --t->token; - /* disallow constant without an expression, e.g. x :: int; */ + // disallow constant without an expression, e.g. x :: int; tokr_err(t, "You must have an expression at the end of this constant declaration."); goto ret_false; } @@ -2182,11 +2182,11 @@ static Status parse_decl(Parser *p, Declaration *d, U16 flags) { parser_put_end(p, &d->where); if (!token_is_kw(t->token, KW_SEMICOLON)) - --d->where.end; /* e.g., in fn(x: float), the param decl does not contain the ) */ + --d->where.end; // e.g., in fn(x: float), the param decl does not contain the ) return true; ret_false: - /* move past end of decl */ + // move past end of decl tokr_skip_semicolon(t); return false; } @@ -2194,11 +2194,11 @@ static Status parse_decl(Parser *p, Declaration *d, U16 flags) { static bool is_decl(Tokenizer *t) { Token *token = t->token; - /* you can only export declarations */ + // you can only export declarations if (token_is_direct(token, DIRECT_EXPORT)) return true; - /* use decls, e.g. use p: Point */ + // use decls, e.g. use p: Point if (token_is_kw(token, KW_USE)) ++token; @@ -2217,7 +2217,7 @@ static bool is_for_range_separator(Keyword kw) { return kw == KW_DOTDOT || kw == KW_DOTCOMMA || kw == KW_COMMADOT || kw == KW_COMMACOMMA; } -/* sets *was_a_statement to false if s was not filled, but the token was advanced */ +// sets *was_a_statement to false if s was not filled, but the token was advanced static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { Tokenizer *t = p->tokr; if (t->token->kind == TOKEN_EOF) { @@ -2239,7 +2239,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { ++t->token; break; case KW_LBRACE: - /* it's a block */ + // it's a block s->kind = STMT_BLOCK; if (!parse_block(p, s->block = parser_malloc(p, sizeof *s->block), 0)) return false; break; @@ -2249,14 +2249,14 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { Return *r = s->ret = parser_malloc(p, sizeof *r); r->flags = 0; if (token_is_kw(t->token, KW_SEMICOLON)) { - /* return with no expr */ + // return with no expr ++t->token; break; } r->flags |= RET_HAS_EXPR; Token *end = expr_find_end(p, 0); if (!end) { - while (t->token->kind != TOKEN_EOF) ++t->token; /* move to end of file */ + while (t->token->kind != TOKEN_EOF) ++t->token; // move to end of file return false; } if (!token_is_kw(end, KW_SEMICOLON)) { @@ -2352,7 +2352,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { next->cond = NULL; if (!parse_block(p, &next->body, 0)) return false; } else { - /* elif */ + // elif ++t->token; cond_end = expr_find_end(p, EXPR_CAN_END_WITH_LBRACE); if (!cond_end) { @@ -2388,7 +2388,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { } Expression *cond = parser_new_expr(p); w->cond = cond; - /* parse the body even if the condition fails */ + // parse the body even if the condition fails bool cond_success = parse_expr(p, cond, cond_end); t->token = cond_end; if (!parse_block(p, &w->body, 0)) return false; @@ -2427,7 +2427,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { fo->flags |= FOR_IS_RANGE; fo->range.from = first; if (token_is_kw(first_end, KW_COMMA)) { - /* step */ + // step ++t->token; fo->range.step = parser_new_expr(p); Token *step_end = expr_find_end(p, EXPR_CAN_END_WITH_LBRACE|EXPR_CAN_END_WITH_DOTDOT); @@ -2448,9 +2448,9 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { if (separator == KW_DOTDOT || separator == KW_COMMADOT) fo->flags |= FOR_INCLUDES_TO; } - ++t->token; /* move past .. */ + ++t->token; // move past .. if (token_is_kw(t->token, KW_LBRACE)) { - fo->range.to = NULL; /* infinite loop! */ + fo->range.to = NULL; // infinite loop! } else { fo->range.to = parser_new_expr(p); Token *to_end = expr_find_end(p, EXPR_CAN_END_WITH_LBRACE); @@ -2583,8 +2583,8 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { } bool valid = parse_expr(p, s->expr = parser_malloc(p, sizeof *s->expr), end); - /* go past end of expr regardless of whether successful or not */ - t->token = end + 1; /* skip ; */ + // go past end of expr regardless of whether successful or not + t->token = end + 1; // skip ; if (!valid) return false; } @@ -2622,7 +2622,7 @@ static Status parse_file(Parser *p, ParsedFile *f) { return ret; } -#define PARSE_PRINT_LOCATION(l) /* fprintf(out, "[%lu:%lu]", (unsigned long)(l).line, (unsigned long)(l).pos); */ +#define PARSE_PRINT_LOCATION(l) // fprintf(out, "[%lu:%lu]", (unsigned long)(l).line, (unsigned long)(l).pos); static void fprint_expr(FILE *out, Expression *e); static void fprint_stmt(FILE *out, Statement *s); @@ -1,10 +1,6 @@ #include "std/io.toc", io; main ::= fn() { - foo(12); + io.puts("Hello, world!"); } +main(); -use io; - -foo ::= fn(x :: int) { - puti(x); -} @@ -4,7 +4,7 @@ You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>. */ -/* Includes all of toc's files */ +// Includes all of toc's files #include <assert.h> #include <ctype.h> #include <stdio.h> @@ -44,27 +44,27 @@ #endif -/* use toc_alignof only for non-structs. it may be incorrect for pre-C(++)11. */ +// use toc_alignof only for non-structs. it may be incorrect for pre-C(++)11. #if (__STDC_VERSION__ >= 201112 || __cplusplus >= 201103L) && !defined __TINYC__ && !defined __OpenBSD__ && !defined __FreeBSD__ #include <stdalign.h> #define toc_alignof alignof #ifdef __GNUC__ -/* GCC supports non-string literals as the message for a static assertion */ +// GCC supports non-string literals as the message for a static assertion #define possibly_static_assert(cond) static_assert(cond, "Assertion " #cond " failed.") #else #define possibly_static_assert(cond) static_assert(cond, "Assertion failed") #endif -#else /* __STDC_VERSION >= 201112 ... */ +#else // __STDC_VERSION >= 201112 ... #define toc_alignof sizeof #define possibly_static_assert(cond) assert(cond) -#endif /* __STDC_VERSION >= 201112 ... */ +#endif // __STDC_VERSION >= 201112 ... -/* this is to prevent erroneous warnings from GCC (v. 8.3.0) with -O3 */ +// this is to prevent erroneous warnings from GCC (v. 8.3.0) with -O3 #if !defined(__clang__) && defined(__GNUC__) #define gcc_no_bounds_warnings_start _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wstringop-overflow\"") \ @@ -78,7 +78,7 @@ #include "types.h" -/* forward declarations for debugging */ +// forward declarations for debugging static void print_val(Value v, Type *t); static void print_token(Token *t); static void print_type(Type *t); @@ -88,7 +88,7 @@ static void print_stmt(Statement *s); static void print_block_location(Block *b); -/* misc */ +// misc #define join3(a,b) a##b #define join2(a,b) join3(a,b) #define join(a,b) join2(a,b) @@ -96,7 +96,7 @@ static void print_block_location(Block *b); #define stringify2(x) stringify3(x) #define stringify(x) stringify2(x) -#ifdef __linux__ /* see also cgen_file */ +#ifdef __linux__ // see also cgen_file #define platform__ PLATFORM_LINUX #elif defined _WIN32 #define platform__ PLATFORM_WINDOWS @@ -152,7 +152,7 @@ static void *err_realloc(void *prev, size_t new_size); #define err_calloc err_calloc_ #endif -/* utilities */ +// utilities #include "allocator.c" #include "misc.c" #include "data_structures.c" @@ -161,7 +161,7 @@ static size_t compiler_alignof(Type *t); static size_t compiler_sizeof(Type *t); #include "instance_table.c" -/* returns NULL on error */ +// returns NULL on error static char *read_file_contents(Allocator *a, const char *filename, Location where) { FILE *in = fopen(filename, "r"); @@ -170,8 +170,8 @@ static char *read_file_contents(Allocator *a, const char *filename, Location whe return NULL; } char *contents = allocr_malloc(a, 4096); - contents[0] = 0; /* put 0 byte at the start of the file. see err.c:err_print_location_text to find out why */ - contents[1] = 0; /* if fgets fails the first time */ + contents[0] = 0; // put 0 byte at the start of the file. see err.c:err_print_location_text to find out why + contents[1] = 0; // if fgets fails the first time long contents_cap = 4095; long contents_len = 1; while (fgets(contents + contents_len, (int)(contents_cap - contents_len), in)) { diff --git a/tokenizer.c b/tokenizer.c index d384da2..c26c692 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -6,8 +6,8 @@ static inline const char *kw_to_str(Keyword k) { return keywords[k]; } -/* Returns KW_COUNT if it's not a keyword */ -/* @OPTIM: don't use strncmp so much */ +// Returns KW_COUNT if it's not a keyword +// @OPTIM: don't use strncmp so much static Keyword tokenize_kw(char **s) { for (Keyword k = 0; k < KW_COUNT; k = k + 1) { size_t len = strlen(keywords[k]); @@ -29,7 +29,7 @@ static Keyword tokenize_kw(char **s) { -/* Returns DIRECT_COUNT if it's not a directive */ +// Returns DIRECT_COUNT if it's not a directive static Directive tokenize_direct(char **s) { for (Directive d = 0; d < DIRECT_COUNT; d = d + 1) { size_t len = strlen(directives[d]); @@ -110,7 +110,7 @@ static inline void tokr_nextchar(Tokenizer *t) { ++t->s; } -/* returns -1 if not a hex digit, otherwise 0-15 */ +// returns -1 if not a hex digit, otherwise 0-15 static inline int char_as_hex_digit(char c) { if (c >= '0' && c <= '9') return c - '0'; @@ -121,9 +121,9 @@ static inline int char_as_hex_digit(char c) { return -1; } -/* returns -1 if escape sequence is invalid */ +// returns -1 if escape sequence is invalid static int tokr_esc_seq(Tokenizer *t) { - /* @TODO: octal (\032)? */ + // @TODO: octal (\032)? switch (*t->s) { case '\'': tokr_nextchar(t); @@ -168,7 +168,7 @@ static void print_token_location(File *file, Token *t) { print_location(token_location(file, t)); } -/* for use during tokenization */ +// for use during tokenization static void tokenization_err_( #if ERR_SHOW_SOURCE_LOCATION const char *src_file, int src_line, @@ -203,7 +203,7 @@ static void tokenization_err_( #define tokenization_err tokenization_err_ #endif -/* for use after tokenization */ +// for use after tokenization static void tokr_err_( #if ERR_SHOW_SOURCE_LOCATION const char *src_file, int src_line, @@ -275,17 +275,17 @@ static Status tokenize_file(Tokenizer *t, File *file) { } if (*t->s == '/') { - /* maybe it's a comment */ + // maybe it's a comment int is_comment = 1; switch (t->s[1]) { - case '/': /* single line comment */ + case '/': // single line comment tokr_nextchar(t); while (*t->s && *t->s != '\n') ++t->s; - if (*t->s) tokr_nextchar(t); /* skip newline */ + if (*t->s) tokr_nextchar(t); // skip newline break; - case '*': { /* multi line comment */ + case '*': { // multi line comment tokr_nextchar(t); - int comment_level = 1; /* allow nested multi-line comments */ + int comment_level = 1; // allow nested multi-line comments while (1) { if (t->s[0] == '*' && t->s[1] == '/') { t->s += 2; @@ -314,13 +314,13 @@ static Status tokenize_file(Tokenizer *t, File *file) { } if (*t->s == '#') { - /* it's a directive */ + // it's a directive Token token; tokr_put_start_pos(t, &token); - ++t->s; /* move past # */ + ++t->s; // move past # Directive direct = tokenize_direct(&t->s); if (direct != DIRECT_COUNT) { - /* it's a directive */ + // it's a directive if (direct == DIRECT_NO_WARN) { arr_adda(file->no_warn_lines, t->line, t->allocr); } else { @@ -331,7 +331,7 @@ static Status tokenize_file(Tokenizer *t, File *file) { } continue; } - --t->s; /* go back to # */ + --t->s; // go back to # tokenization_err(t, "Unrecognized directive."); goto err; } @@ -341,7 +341,7 @@ static Status tokenize_file(Tokenizer *t, File *file) { tokr_put_start_pos(t, &token); Keyword kw = tokenize_kw(&t->s); if (kw != KW_COUNT) { - /* it's a keyword */ + // it's a keyword tokr_put_end_pos(t, &token); token.kind = TOKEN_KW; token.kw = kw; @@ -350,9 +350,9 @@ static Status tokenize_file(Tokenizer *t, File *file) { } } - /* check if it's a number */ + // check if it's a number if (isdigit(*t->s)) { - /* it's a numeric literal */ + // it's a numeric literal int base = 10; Floating decimal_pow10 = 0; Token *token = tokr_add(t); @@ -361,9 +361,9 @@ static Status tokenize_file(Tokenizer *t, File *file) { if (*t->s == '0') { tokr_nextchar(t); - /* octal/hexadecimal/binary (or zero) */ + // octal/hexadecimal/binary (or zero) char format = *t->s; - if (isdigit(format)) /* octal */ + if (isdigit(format)) // octal base = 8; else { switch (format) { @@ -380,7 +380,7 @@ static Status tokenize_file(Tokenizer *t, File *file) { tokr_nextchar(t); break; default: - /* it's 0/0.something etc. */ + // it's 0/0.something etc. break; } } @@ -388,7 +388,7 @@ static Status tokenize_file(Tokenizer *t, File *file) { while (1) { if (*t->s == '.') { if (!isdigit(t->s[1])) { - /* not a decimal point; end the number here (could be .. or .,) */ + // not a decimal point; end the number here (could be .. or .,) break; } if (token->kind == TOKEN_LITERAL_FLOAT) { @@ -412,10 +412,10 @@ static Status tokenize_file(Tokenizer *t, File *file) { U64 i = token->intl; token->floatl = (Floating)i; } - /* @TODO: check if exceeding maximum exponent */ + // @TODO: check if exceeding maximum exponent int exponent = 0; if (*t->s == '+') - tokr_nextchar(t); /* ignore + after e */ + tokr_nextchar(t); // ignore + after e int negative_exponent = 0; if (*t->s == '-') { @@ -426,7 +426,7 @@ static Status tokenize_file(Tokenizer *t, File *file) { exponent *= 10; exponent += *t->s - '0'; } - /* @OPTIM: Slow for very large exponents (unlikely to happen) */ + // @OPTIM: Slow for very large exponents (unlikely to happen) for (int i = 0; i < exponent; ++i) { if (negative_exponent) token->floatl /= 10; @@ -449,18 +449,18 @@ static Status tokenize_file(Tokenizer *t, File *file) { } if (digit < 0 || digit >= base) { if (isdigit(*t->s)) { - /* something like 0b011012 */ + // something like 0b011012 tokenization_err(t, "Digit %d cannot appear in a base %d number.", digit, base); goto err; } - /* end of numeric literal */ + // end of numeric literal break; } switch (token->kind) { case TOKEN_LITERAL_INT: if (token->intl > U64_MAX / (U64)base || token->intl * (U64)base > U64_MAX - (U64)digit) { - /* too big! */ + // too big! tokenization_err(t, "Number too big to fit in a numeric literal."); goto err; } @@ -480,12 +480,12 @@ static Status tokenize_file(Tokenizer *t, File *file) { } if (*t->s == '\'') { - /* it's a character literal! */ + // it's a character literal! Token *token = tokr_add(t); tokr_nextchar(t); char c; if (*t->s == '\\') { - /* escape sequence */ + // escape sequence tokr_nextchar(t); int e = tokr_esc_seq(t); if (e == -1) { @@ -509,16 +509,16 @@ static Status tokenize_file(Tokenizer *t, File *file) { } if (*t->s == '"') { - /* it's a string literal! */ + // it's a string literal! Token *token = tokr_add(t); tokr_nextchar(t); - size_t len = 0; /* counts \n as 2 chars */ + size_t len = 0; // counts \n as 2 chars size_t backslashes = 0; while (*t->s != '"' || backslashes % 2 == 1) { if (*t->s == '\\') { ++backslashes; } else if (*t->s == 0) { - /* return t to opening " */ + // return t to opening " tokr_get_start_pos(t, token); tokenization_err(t, "No matching \" found."); goto err; @@ -531,7 +531,7 @@ static Status tokenize_file(Tokenizer *t, File *file) { char *strlit = tokr_malloc(t, len + 1); char *strptr = strlit; tokr_get_start_pos(t, token); - tokr_nextchar(t); /* past opening " */ + tokr_nextchar(t); // past opening " while (*t->s != '"') { assert(*t->s); if (*t->s == '\\') { @@ -551,13 +551,13 @@ static Status tokenize_file(Tokenizer *t, File *file) { token->kind = TOKEN_LITERAL_STR; token->str.len = (size_t)(strptr - strlit); token->str.str = strlit; - tokr_nextchar(t); /* move past closing " */ + tokr_nextchar(t); // move past closing " tokr_put_end_pos(t, token); continue; } if (is_ident(*t->s)) { - /* it's an identifier */ + // it's an identifier Token *token = tokr_add(t); token->kind = TOKEN_IDENT; token->ident = t->s; @@ -577,7 +577,7 @@ static Status tokenize_file(Tokenizer *t, File *file) { return !has_err; } -/* skip to one token past the next semicolon not in braces (or the end of the file). */ +// skip to one token past the next semicolon not in braces (or the end of the file). static void tokr_skip_semicolon(Tokenizer *t) { int brace_level = 0; while (t->token->kind != TOKEN_EOF) { @@ -597,5 +597,5 @@ static void tokr_skip_semicolon(Tokenizer *t) { } static inline void tokr_skip_to_eof(Tokenizer *t) { - while (t->token->kind != TOKEN_EOF) ++t->token; /* move to end of file */ + while (t->token->kind != TOKEN_EOF) ++t->token; // move to end of file } @@ -52,12 +52,12 @@ static size_t compiler_sizeof_builtin(BuiltinType b) { case BUILTIN_U64: return sizeof(U64); case BUILTIN_F32: return sizeof(F32); case BUILTIN_F64: return sizeof(F64); - case BUILTIN_CHAR: return sizeof(char); /* = 1 */ + case BUILTIN_CHAR: return sizeof(char); // = 1 case BUILTIN_BOOL: return sizeof(bool); case BUILTIN_TYPE: return sizeof(Type *); case BUILTIN_NMS: return sizeof(Namespace *); case BUILTIN_VARARGS: return sizeof(VarArg *); - case BUILTIN_VOID: return 1; /* void ptr arithmetic */ + case BUILTIN_VOID: return 1; // void ptr arithmetic } assert(0); return 0; @@ -89,7 +89,7 @@ static inline char *get_struct_name(StructDef *s) { return s->name ? ident_to_str(s->name) : str_dup("anonymous struct"); } -/* adds fields of add to to */ +// adds fields of add to to static Status struct_add_used_struct(Typer *tr, StructDef *to, StructDef *add, Declaration *use_decl) { Location use_where = use_decl->where; if (!struct_resolve(tr, add)) @@ -104,20 +104,20 @@ static Status struct_add_used_struct(Typer *tr, StructDef *to, StructDef *add, D } arr_foreach(decl->idents, Identifier, ip) { Identifier i = *ip; - /* @OPTIM: only hash once */ + // @OPTIM: only hash once Identifier previously_existing = ident_translate(i, &to->body.idents); if (previously_existing) { - /* uh oh */ + // uh oh UsedFrom *uf = previously_existing->used_from; char *struct_name = get_struct_name(to); char *member_name = ident_to_str(previously_existing); if (uf) { - /* conflicting uses */ + // conflicting uses Declaration *first_use = uf->use_decl; err_print(first_use->where, "Conflicting used structs, while dealing with %s. %s was imported by this use statement...", struct_name, member_name); info_print(use_where, "... and also by this use statement."); } else { - /* declared a field, then used something which contains something of the same name */ + // declared a field, then used something which contains something of the same name Declaration *first_decl = previously_existing->decl; char *used_struct_name = get_struct_name(add); err_print(use_where, "used struct conflicts with field %s of %s (%s is also a member of %s).", member_name, struct_name, member_name, used_struct_name); @@ -138,7 +138,7 @@ static Status struct_add_used_struct(Typer *tr, StructDef *to, StructDef *add, D return true; } -/* create s->fields, also check to make sure the struct's statements are valid */ +// create s->fields, also check to make sure the struct's statements are valid static Status struct_add_stmts(Typer *tr, StructDef *s, Statement *stmts) { arr_foreach(stmts, Statement, stmt) { StatementKind kind = stmt->kind; @@ -182,14 +182,14 @@ static Status struct_add_stmts(Typer *tr, StructDef *s, Statement *stmts) { } } if (flags & DECL_USE) { - /* add everything in the used struct to the namespace */ + // add everything in the used struct to the namespace if (flags & DECL_IS_CONST) { - /* @TODO(eventually) */ + // @TODO(eventually) err_print(d->where, "You can't use constant stuff in a struct."); return false; } if (d->type.kind != TYPE_STRUCT) { - /* i don't think this can ever happen right now */ + // i don't think this can ever happen right now err_print(d->where, "You can only use structs inside a struct."); return false; } @@ -255,7 +255,7 @@ static size_t compiler_alignof(Type *t) { return 0; } -/* size of a type at compile time */ +// size of a type at compile time static size_t compiler_sizeof(Type *t) { Value v; assert(t->flags & TYPE_IS_RESOLVED); @@ -273,7 +273,7 @@ static size_t compiler_sizeof(Type *t) { case TYPE_SLICE: return sizeof v.slice; case TYPE_STRUCT: { - /* these two ifs are purely for struct_resolve, so that it can detect use of future structs in a non-pointery way */ + // these two ifs are purely for struct_resolve, so that it can detect use of future structs in a non-pointery way if (t->struc->flags & STRUCT_DEF_RESOLVING) return SIZE_MAX-1; if (!(t->struc->flags & STRUCT_DEF_RESOLVED)) @@ -291,11 +291,11 @@ static size_t compiler_sizeof(Type *t) { static Status struct_resolve(Typer *tr, StructDef *s) { if (s->flags & STRUCT_DEF_RESOLVING_FAILED) - return false; /* silently fail; do not try to resolve again, because there'll be duplicate errors */ + return false; // silently fail; do not try to resolve again, because there'll be duplicate errors if (!(s->flags & STRUCT_DEF_RESOLVED)) { s->flags |= STRUCT_DEF_RESOLVING; typer_arr_add(tr, tr->all_structs, s); - { /* resolving stuff */ + { // resolving stuff Block *body = &s->body; if (!types_block(tr, body)) goto fail; @@ -306,8 +306,8 @@ static Status struct_resolve(Typer *tr, StructDef *s) { struct_set_decl_field_ptrs(tr, s, stmts); s->instance_id = 0; } - /* find offsets and size */ - /* assume the align of a struct is the greatest align out of its children's */ + // find offsets and size + // assume the align of a struct is the greatest align out of its children's { size_t bytes = 0; size_t total_align = 1; @@ -324,14 +324,14 @@ static Status struct_resolve(Typer *tr, StructDef *s) { size_t falign = compiler_alignof(f->type); if (falign > total_align) total_align = falign; - /* align */ - bytes += ((falign - bytes) % falign + falign) % falign; /* = -bytes mod falign */ + // align + bytes += ((falign - bytes) % falign + falign) % falign; // = -bytes mod falign assert(bytes % falign == 0); f->offset = bytes; - /* add size */ + // add size bytes += size; } - bytes += ((total_align - bytes) % total_align + total_align) % total_align; /* = -bytes mod align */ + bytes += ((total_align - bytes) % total_align + total_align) % total_align; // = -bytes mod align s->size = bytes; s->align = total_align; } @@ -345,7 +345,7 @@ fail: } -/* are a and b EXACTLY equal (not counting flags)? */ +// are a and b EXACTLY equal (not counting flags)? static bool type_eq_exact(Type *a, Type *b) { assert(a->flags & TYPE_IS_RESOLVED); assert(b->flags & TYPE_IS_RESOLVED); @@ -400,7 +400,7 @@ static bool type_eq_exact(Type *a, Type *b) { return false; } -/* are a and b equal, allowing implicit conversions? */ +// are a and b equal, allowing implicit conversions? static bool type_eq_implicit(Type *a, Type *b) { assert(a->flags & TYPE_IS_RESOLVED); assert(b->flags & TYPE_IS_RESOLVED); @@ -424,14 +424,14 @@ static bool type_eq_implicit(Type *a, Type *b) { return type_builtin_is_numerical(b->builtin); } if (a->kind == TYPE_PTR) { - /* &void casts to &anything */ + // &void casts to &anything if (type_is_builtin(a->ptr, BUILTIN_VOID) || type_is_builtin(b->ptr, BUILTIN_VOID)) return true; } return type_eq_exact(a, b); } -/* which is the "overriding" type? i.e. which type should the other one convert to? */ +// which is the "overriding" type? i.e. which type should the other one convert to? static Type *overriding_type(Type *a, Type *b) { if (a->kind == TYPE_UNKNOWN) return b; if (b->kind == TYPE_UNKNOWN) return a; @@ -450,7 +450,7 @@ static Type *overriding_type(Type *a, Type *b) { if (a->kind == TYPE_PTR && type_is_builtin(a->ptr, BUILTIN_VOID)) return b; - /* doesn't matter */ + // doesn't matter return a; } @@ -459,7 +459,7 @@ prints an error and returns false if the given expression is not an l-value purpose is something like "take address of" */ static Status expr_must_lval(Expression *e, const char *purpose) { - /* NOTE: make sure you update eval when you change this */ + // NOTE: make sure you update eval when you change this assert(e->flags & EXPR_FOUND_TYPE); switch (e->kind) { case EXPR_IDENT: { @@ -496,14 +496,14 @@ static Status expr_must_lval(Expression *e, const char *purpose) { } return true; case BINARY_DOT: - if (e->type.kind == TYPE_PTR) return true; /* structure->member is always an lvalue */ + if (e->type.kind == TYPE_PTR) return true; // structure->member is always an lvalue return expr_must_lval(e->binary.lhs, purpose); default: break; } err_print(e->where, "Cannot %s operator %s.", purpose, binary_op_to_str(e->binary.op)); return false; case EXPR_TUPLE: - /* x, y is an lval, but 3, "hello" is not. */ + // x, y is an lval, but 3, "hello" is not. arr_foreach(e->tuple, Expression, x) { if (!expr_must_lval(x, purpose)) return false; @@ -519,7 +519,7 @@ static Status expr_must_lval(Expression *e, const char *purpose) { } -/* does this type have a Type or a Namespace in it? (e.g. [5]Type, &&Namespace) */ +// does this type have a Type or a Namespace in it? (e.g. [5]Type, &&Namespace) static bool type_is_compileonly(Type *t) { assert(t->flags & TYPE_IS_RESOLVED); switch (t->kind) { @@ -535,7 +535,7 @@ static bool type_is_compileonly(Type *t) { return type_is_compileonly(t->arr->of); case TYPE_FN: arr_foreach(t->fn->types, Type, sub) { - if (sub->flags & TYPE_IS_RESOLVED) /* for templates */ { + if (sub->flags & TYPE_IS_RESOLVED) { // for templates if (type_is_compileonly(sub)) return true; } else { @@ -549,14 +549,14 @@ static bool type_is_compileonly(Type *t) { return true; return false; case TYPE_STRUCT: - return false; /* structs can only have non-compileonly members */ + return false; // structs can only have non-compileonly members case TYPE_EXPR: break; } assert(0); return false; } -/* returns NULL if an error occured */ +// returns NULL if an error occured static char *eval_expr_as_cstr(Typer *tr, Expression *e, const char *what_is_this) { Value e_val; if (!types_expr(tr, e)) @@ -584,14 +584,14 @@ static char *slice_to_cstr(Slice s) { } enum { - /* is f an instance? (changes behaviour a bit) */ + // is f an instance? (changes behaviour a bit) TYPE_OF_FN_IS_INSTANCE = 0x01 }; static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { if (f->flags & FN_EXPR_FOREIGN) { - /* we've already mostly determined the type in parse_expr */ + // we've already mostly determined the type in parse_expr if (!type_resolve(tr, &f->foreign.type, f->where)) return false; *t = f->foreign.type; @@ -622,11 +622,11 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { bool has_varargs = last_param && (last_param->flags & DECL_ANNOTATES_TYPE) && type_is_builtin(&last_param->type, BUILTIN_VARARGS); if (has_varargs) f->flags |= FN_EXPR_HAS_VARARGS; - /* f has compile time params/varargs, but it's not an instance! */ + // f has compile time params/varargs, but it's not an instance! bool generic = !(flags & TYPE_OF_FN_IS_INSTANCE) && (fn_has_any_const_params(f) || has_varargs); size_t idx = 0; bool has_constant_params = false; - /* reserve space for return type */ + // reserve space for return type typer_arr_add_ptr(tr, t->fn->types); tr->fn = f; Block *prev_block = tr->block; @@ -661,7 +661,7 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { param->expr.kind = EXPR_VAL; param->expr.val = val; if (param->expr.type.flags & TYPE_IS_FLEXIBLE) { - /* cast to the annotated type, if one exists */ + // cast to the annotated type, if one exists if (param->flags & DECL_ANNOTATES_TYPE) { val_cast(param->expr.val, ¶m->expr.type, ¶m->expr.val, ¶m->type); param->expr.type = param->type; @@ -701,7 +701,7 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { } if (f->ret_decls && !generic && type_is_builtin(&f->ret_type, BUILTIN_VOID) /* haven't found return type yet */) { - /* find return type */ + // find return type arr_foreach(f->ret_decls, Declaration, d) { if (!types_decl(tr, d)) { @@ -761,7 +761,7 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { } ret: - /* cleanup */ + // cleanup tr->block = prev_block; if (entered_fn) { tr->fn = prev_fn; @@ -769,17 +769,17 @@ static Status type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) { return success; } -/* doesn't do any translation on ident or check if it's declared or anything, so make sure it's in the right scope */ +// doesn't do any translation on ident or check if it's declared or anything, so make sure it's in the right scope static Status type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { Declaration *d = i->decl; assert(d); if (!(d->flags & DECL_IS_CONST)) { - /* check for trying to capture a variable into a function */ + // check for trying to capture a variable into a function bool captured = false; Block *decl_scope = ident_scope(i); if (decl_scope && decl_scope->kind != BLOCK_NMS) { if (decl_scope->kind != BLOCK_NMS) { - /* go back through scopes */ + // go back through scopes for (Block *block = tr->block; block; block = block->parent) { if (block == decl_scope) break; if (block->kind == BLOCK_FN) { @@ -795,21 +795,21 @@ static Status type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { } } if ((d->flags & DECL_HAS_EXPR) && (d->expr.kind == EXPR_TYPE)) { - /* allow using a type before declaring it */ + // allow using a type before declaring it t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_TYPE; t->flags = TYPE_IS_RESOLVED; return true; } - /* are we inside this declaration? */ + // are we inside this declaration? arr_foreach(tr->in_decls, DeclarationPtr, in_decl) { if (d == *in_decl) { - /* d needn't have an expression, because it could be its type that refers to itself */ + // d needn't have an expression, because it could be its type that refers to itself if ((d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_FN) { - /* it's okay if a function references itself */ + // it's okay if a function references itself } else { - /* if we've complained about it before when we were figuring out the type, don't complain again */ + // if we've complained about it before when we were figuring out the type, don't complain again if (!(d->flags & DECL_ERRORED_ABOUT_SELF_REFERENCE)) { char *s = ident_to_str(i); err_print(where, "Use of identifier %s in its own declaration.", s); @@ -828,10 +828,10 @@ static Status type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { return true; } else { if ((d->flags & DECL_HAS_EXPR) && (d->expr.kind == EXPR_FN)) { - /* allow using a function before declaring it */ + // allow using a function before declaring it if (!type_of_fn(tr, d->expr.fn, &d->expr.type, 0)) return false; *t = d->expr.type; - t->flags |= TYPE_IS_RESOLVED; /* for function templates */ + t->flags |= TYPE_IS_RESOLVED; // for function templates return true; } else { if (d->flags & DECL_INFER) { @@ -869,13 +869,13 @@ static Status type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { return true; } -/* fixes the type (replaces [5+3]int with [8]int, etc.) */ +// fixes the type (replaces [5+3]int with [8]int, etc.) static Status type_resolve(Typer *tr, Type *t, Location where) { Evaluator *ev = tr->evalr; if (t->flags & TYPE_IS_RESOLVED) return true; switch (t->kind) { case TYPE_ARR: { - /* it's an array */ + // it's an array Value val; Expression *n_expr = t->arr->n_expr; if (!types_expr(tr, n_expr)) return false; @@ -938,9 +938,9 @@ static Status type_resolve(Typer *tr, Type *t, Location where) { if (!types_expr(tr, expr)) return false; if (expr->type.kind == TYPE_UNKNOWN && tr->gctx->err_ctx->have_errored) - return false; /* silently fail (e.g. if a function couldn't be typed) */ + return false; // silently fail (e.g. if a function couldn't be typed) if (!type_is_builtin(&expr->type, BUILTIN_TYPE)) { - /* ok maybe it's a tuple of types, which we'll convert to a TYPE_TUPLE */ + // ok maybe it's a tuple of types, which we'll convert to a TYPE_TUPLE bool is_tuple_of_types = false; if (expr->kind == EXPR_TUPLE) { Type *tuple = NULL; @@ -978,7 +978,7 @@ static Status type_resolve(Typer *tr, Type *t, Location where) { } } if (!(t->flags & TYPE_IS_RESOLVED)) { - /* this can happen with functions returning parameterized structs or pointers */ + // this can happen with functions returning parameterized structs or pointers if (!type_resolve(tr, t, where)) return false; } @@ -1165,11 +1165,11 @@ static bool arg_is_const(Expression *arg, Constness constness) { return false; } -/* does this statement no matter what result in a return? */ +// does this statement no matter what result in a return? static Status definitely_returns(Statement *s) { - if (s->kind == STMT_RET) return true; /* of course */ + if (s->kind == STMT_RET) return true; // of course if (s->kind == STMT_IF) { - /* if foo { return 5; } else { return 6; } */ + // if foo { return 5; } else { return 6; } bool has_else = false; for (If *i = s->if_; i; i = i->next_elif) { Statement *last_stmt = arr_last_ptr(i->body.stmts); @@ -1179,14 +1179,14 @@ static Status definitely_returns(Statement *s) { } return has_else; } else if (s->kind == STMT_BLOCK) { - /* { return 7; } */ + // { return 7; } Statement *last_stmt = arr_last_ptr(s->block->stmts); return definitely_returns(last_stmt); } return false; } -/* pass NULL for instance if this isn't an instance */ +// pass NULL for instance if this isn't an instance static Status types_fn(Typer *tr, FnExpr *f, Type *t, Instance *instance) { f->declaration_block = tr->block; if (f->flags & FN_EXPR_FOREIGN) { @@ -1203,7 +1203,7 @@ static Status types_fn(Typer *tr, FnExpr *f, Type *t, Instance *instance) { f = instance->fn; } else { if (t->fn->constness) - return true; /* don't type function body yet; we need to do that for every instance */ + return true; // don't type function body yet; we need to do that for every instance } { FnWithCtx fn_ctx = {f, tr->nms, tr->block}; @@ -1236,7 +1236,7 @@ static Status types_fn(Typer *tr, FnExpr *f, Type *t, Instance *instance) { return success; } -/* puts a dynamic array of the argument indices of the parameters into order. *order must be freed, even if function fails */ +// puts a dynamic array of the argument indices of the parameters into order. *order must be freed, even if function fails static Status call_arg_param_order(FnExpr *fn, Type *fn_type, Argument *args, Location where, I16 **orderp) { *orderp = NULL; assert(fn_type->flags & TYPE_IS_RESOLVED); @@ -1249,12 +1249,7 @@ static Status call_arg_param_order(FnExpr *fn, Type *fn_type, Argument *args, Lo } - I16 *order = *orderp = - /* thanks, gcc, for making me do this! (getting erroneous -Walloc-size-larger-than) */ -#if defined __GNUC__ && !defined __clang__ - nparams > PTRDIFF_MAX ? NULL : -#endif - err_malloc(nparams * sizeof *order); + I16 *order = *orderp = err_malloc(nparams * sizeof *order); for (size_t i = 0; i < nparams; ++i) order[i] = -1; @@ -1270,7 +1265,7 @@ static Status call_arg_param_order(FnExpr *fn, Type *fn_type, Argument *args, Lo return true; } - int p = 0; /* counter for sequential parameters */ + int p = 0; // counter for sequential parameters Declaration *param = fn->params; size_t ident_idx = 0; I16 arg_idx = -1; @@ -1280,7 +1275,7 @@ static Status call_arg_param_order(FnExpr *fn, Type *fn_type, Argument *args, Lo int param_idx = -1; Declaration *this_param; if (named) { - /* named argument */ + // named argument int index = 0; bool found = false; arr_foreach(fn->params, Declaration, pa) { @@ -1300,7 +1295,7 @@ static Status call_arg_param_order(FnExpr *fn, Type *fn_type, Argument *args, Lo } if (!found) { char *name_end = arg->name + ident_str_len(arg->name); - /* temporarily null-terminate string to print it out */ + // temporarily null-terminate string to print it out char before = *name_end; *name_end = 0; err_print(arg->where, "Argument '%s' does not appear in declaration of function.", arg->name); @@ -1310,7 +1305,7 @@ static Status call_arg_param_order(FnExpr *fn, Type *fn_type, Argument *args, Lo } param_idx = index; } else { - /* move past inferred parameters because they must be named */ + // move past inferred parameters because they must be named while (param < (Declaration *)arr_end(fn->params) && (param->flags & DECL_INFER)) { ++p; ++ident_idx; @@ -1344,7 +1339,7 @@ static Status call_arg_param_order(FnExpr *fn, Type *fn_type, Argument *args, Lo } if (!named) { - /* sequential order of parameters */ + // sequential order of parameters ++p; if (!type_is_builtin(¶m->type, BUILTIN_VARARGS)) { ++ident_idx; @@ -1397,7 +1392,7 @@ static Status parameterized_struct_arg_order(StructDef *struc, Argument *args, I } for (size_t i = 0; i < nparams; ++i) (*order)[i] = -1; - int p = 0; /* sequential parameter */ + int p = 0; // sequential parameter I16 argno = 0; arr_foreach(args, Argument, arg) { @@ -1485,7 +1480,7 @@ static void get_builtin_val_type(Allocator *a, BuiltinVal val, Type *t) { case BUILTIN_STDOUT: case BUILTIN_STDERR: case BUILTIN_STDIN: - /* use &u8 for FILE * */ + // use &u8 for FILE * t->kind = TYPE_PTR; t->ptr = allocr_calloc(a, 1, sizeof *t->ptr); t->ptr->flags = TYPE_IS_RESOLVED; @@ -1508,7 +1503,7 @@ static void get_builtin_val_type(Allocator *a, BuiltinVal val, Type *t) { } -/* gets a struct's constant or parameter, and puts it into e->val. */ +// gets a struct's constant or parameter, and puts it into e->val. static Status get_struct_constant(StructDef *struc, String ident, Expression *e) { if (struc->params && !(struc->params[0].flags & DECL_FOUND_VAL)) { err_print(e->where, "To access constants from a parameterized struct, you must supply its arguments."); @@ -1530,7 +1525,7 @@ static Status get_struct_constant(StructDef *struc, String ident, Expression *e) return false; } if (i->decl->flags & DECL_FOUND_VAL) { - /* replace with decl value */ + // replace with decl value int ident_idx = decl_ident_index(i->decl, i); e->kind = EXPR_VAL; e->flags = EXPR_FOUND_TYPE; @@ -1564,7 +1559,7 @@ static Status expr_must_usable(Typer *tr, Expression *e) { if (!(t->kind == TYPE_PTR && t->ptr->kind == TYPE_STRUCT)) { if (t->kind == TYPE_UNKNOWN) { if (tr->gctx->err_ctx->have_errored) { - /* silently fail; this could've been because of an earlier error */ + // silently fail; this could've been because of an earlier error return false; } } @@ -1579,7 +1574,7 @@ static Status expr_must_usable(Typer *tr, Expression *e) { static Status use_ident(Typer *tr, Identifier i, Type *t, Location where) { - /* add to uses */ + // add to uses Use **usep; if (tr->block) usep = typer_arr_add_ptr(tr, tr->block->uses); @@ -1599,7 +1594,7 @@ static Status use_ident(Typer *tr, Identifier i, Type *t, Location where) { static void typer_gen_nms_prefix(Typer *tr, Namespace *n) { assert(tr->nms != n); - /* create a C prefix for this namespace */ + // create a C prefix for this namespace const char *prev_prefix = ""; size_t prev_prefix_len = 0; if (tr->nms) { @@ -1626,14 +1621,14 @@ static void typer_gen_nms_prefix(Typer *tr, Namespace *n) { static Status types_expr(Typer *tr, Expression *e) { if (e->flags & EXPR_FOUND_TYPE) return true; - e->flags |= EXPR_FOUND_TYPE; /* even if failed, pretend we found the type */ + e->flags |= EXPR_FOUND_TYPE; // even if failed, pretend we found the type if (e->kind == EXPR_VAL) { - /* can exist, e.g. for null */ + // can exist, e.g. for null return true; } Type *t = &e->type; t->flags = TYPE_IS_RESOLVED; - t->kind = TYPE_UNKNOWN; /* default to unknown type (in the case of an error) */ + t->kind = TYPE_UNKNOWN; // default to unknown type (in the case of an error) switch (e->kind) { case EXPR_FN: { FnExpr *fn = e->fn; @@ -1642,7 +1637,7 @@ static Status types_expr(Typer *tr, Expression *e) { } if (!(fn->flags & FN_EXPR_FOREIGN) && (fn_has_any_const_params(fn) || fn_type_has_varargs(e->type.fn))) { fn->instances = typer_calloc(tr, 1, sizeof *fn->instances); - t->flags |= TYPE_IS_RESOLVED; /* pretend this type is resolved, even though its children aren't to fix some assertions */ + t->flags |= TYPE_IS_RESOLVED; // pretend this type is resolved, even though its children aren't to fix some assertions } else { if (!types_fn(tr, fn, &e->type, NULL)) { return false; @@ -1685,8 +1680,8 @@ static Status types_expr(Typer *tr, Expression *e) { } Identifier final_ident = NULL; bool undeclared = true; - while (1) { /* for each block we are inside... */ - /* @OPTIM: only hash once */ + while (1) { // for each block we are inside... + // @OPTIM: only hash once Identifier translated = ident_get_with_len(b ? &b->idents : tr->globals, i_str, i_len); if (translated) { #if 0 @@ -1712,10 +1707,10 @@ static Status types_expr(Typer *tr, Expression *e) { return 0; Namespace *nms = val.nms; Block *body = &nms->body; - /* look up identifier in namespace */ + // look up identifier in namespace translated_use = ident_get_with_len(&body->idents, i_str, i_len); } else { - /* it's a struct */ + // it's a struct was_a_struct = true; Type *struct_type = &used->type; if (struct_type->kind == TYPE_PTR) @@ -1734,11 +1729,11 @@ static Status types_expr(Typer *tr, Expression *e) { err_print(e->where, "Conflicting declarations for identifier %s.", s); char *also = ""; if (previous_use_which_uses_i) { - /* i was use'd twice */ + // i was use'd twice info_print(previous_use_which_uses_i->expr.where, "%s was imported by this use statement.", s); also = "also "; } else { - /* i was declared then used. */ + // i was declared then used. info_print(ident_decl_location(translated), "%s was declared here.", s); } free(s); @@ -1746,7 +1741,7 @@ static Status types_expr(Typer *tr, Expression *e) { return false; } if (was_a_struct) { - /* change to BINARY_DOT */ + // change to BINARY_DOT e->kind = EXPR_BINARY_OP; e->flags = 0; e->binary.op = BINARY_DOT; @@ -1757,7 +1752,7 @@ static Status types_expr(Typer *tr, Expression *e) { rhs->flags = 0; rhs->ident_str.str = i_str; rhs->ident_str.len = i_len; - /* re-type */ + // re-type if (!types_expr(tr, e)) return false; return true; @@ -1778,11 +1773,11 @@ static Status types_expr(Typer *tr, Expression *e) { return false; } if (b && b->kind == BLOCK_STRUCT) { - /* this is really necessary if you're trying to access a struct constant from inside a function in the same struct */ + // this is really necessary if you're trying to access a struct constant from inside a function in the same struct e->kind = EXPR_VAL; Declaration *decl = final_ident->decl; if (!(decl->flags & DECL_IS_CONST)) { - /* not sure if this can even happen right now, but might as well have this check here */ + // not sure if this can even happen right now, but might as well have this check here err_print(e->where, "Trying to access non-constant struct member from inside of it. This is not allowed."); return false; } @@ -1834,7 +1829,7 @@ static Status types_expr(Typer *tr, Expression *e) { return true; } if (type_is_builtin(&f->type, BUILTIN_TYPE)) { - /* maybe it's a parameterized type */ + // maybe it's a parameterized type } else if (f->type.kind != TYPE_FN) { char *type = type_to_str(&f->type); err_print(e->where, "Calling non-function (type %s).", type); @@ -1844,10 +1839,10 @@ static Status types_expr(Typer *tr, Expression *e) { bool fn_being_used_before_declared = false; if (expr_is_definitely_const(f) || type_is_builtin(&f->type, BUILTIN_TYPE) || has_varargs) { - /* evaluate the function when possible (this allows us to use named arguments, default arguments, etc.) */ + // evaluate the function when possible (this allows us to use named arguments, default arguments, etc.) Value val; if (f->kind == EXPR_IDENT) { - /* necessary for future functions, including future foreign functions */ + // necessary for future functions, including future foreign functions Declaration *d = f->ident->decl; if (!(d->flags & DECL_FOUND_TYPE)) { fn_being_used_before_declared = true; @@ -1859,7 +1854,7 @@ static Status types_expr(Typer *tr, Expression *e) { return false; fn_decl = val.fn; if (type_is_builtin(&f->type, BUILTIN_TYPE)) { - /* structs with arguments */ + // structs with arguments Type *base = val.type; if (base->kind != TYPE_STRUCT) { err_print(e->where, "Cannot pass arguments to non-struct type."); @@ -1873,8 +1868,8 @@ static Status types_expr(Typer *tr, Expression *e) { Copier cop = copier_create(tr->allocr, base->struc->body.parent); HashTable *table = &base->struc->instances; StructDef struc; - /* @OPTIM: don't copy the struct body unless necessary? */ - /* make a copy of the struct. this is the specific version of the struct which we are producing. */ + // @OPTIM: don't copy the struct body unless necessary? + // make a copy of the struct. this is the specific version of the struct which we are producing. copy_struct(&cop, &struc, base->struc); size_t nparams = 0; @@ -1884,23 +1879,23 @@ static Status types_expr(Typer *tr, Expression *e) { Value args_val = {0}; Type args_type = {0}; I16 *order; - /* get proper order of arguments (some of them might be named, etc.) */ + // get proper order of arguments (some of them might be named, etc.) if (!parameterized_struct_arg_order(&struc, c->args, &order, e->where)) { free(order); return false; } Type *arg_types = NULL; arr_set_len(arg_types, nparams); - /* needs to stay around because the instance table keeps a reference to it (if it hasn't already been added) */ + // needs to stay around because the instance table keeps a reference to it (if it hasn't already been added) Value *arg_vals = typer_malloc(tr, nparams * sizeof *arg_vals); ErrCtx *err_ctx = tr->gctx->err_ctx; size_t p = 0; - /* give the parameters their values */ + // give the parameters their values arr_foreach(struc.params, Declaration, param) { Value param_val = {0}; bool is_tuple = arr_len(param->idents) > 1; int ident_idx = 0; - /* temporarily add this instance to the stack, while we type the decl, in case you, e.g., pass t = float to struct(t::Type, u::t = "hello") */ + // temporarily add this instance to the stack, while we type the decl, in case you, e.g., pass t = float to struct(t::Type, u::t = "hello") arr_add(err_ctx->instance_stack, e->where); Block *prev = tr->block; typer_block_enter(tr, &struc.body); @@ -1946,13 +1941,13 @@ static Status types_expr(Typer *tr, Expression *e) { args_type.flags = TYPE_IS_RESOLVED; Instance *inst = instance_table_adda(tr->allocr, table, args_val, &args_type, &already_exists); if (!already_exists) { - /* this is a new parameterization of the struct */ + // this is a new parameterization of the struct inst->struc = struc; - /* make error messages show we are resolving this struct parameterization */ + // make error messages show we are resolving this struct parameterization arr_add(err_ctx->instance_stack, e->where); Block *prev_block = tr->block; tr->block = &inst->struc.body; - bool success = struct_resolve(tr, &inst->struc); /* resolve the struct (evaluate array sizes, etc.) */ + bool success = struct_resolve(tr, &inst->struc); // resolve the struct (evaluate array sizes, etc.) tr->block = prev_block; arr_remove_last(err_ctx->instance_stack); if (!success) return false; @@ -1961,7 +1956,7 @@ static Status types_expr(Typer *tr, Expression *e) { } - /* expression is actually a type */ + // expression is actually a type e->kind = EXPR_TYPE; e->typeval = typer_calloc(tr, 1, sizeof *e->typeval); e->typeval->kind = TYPE_STRUCT; @@ -1993,7 +1988,7 @@ static Status types_expr(Typer *tr, Expression *e) { size_t nvarargs = 0; if (has_varargs) { assert(fn_decl); - /* fn_decl could be foreign, so order could be NULL */ + // fn_decl could be foreign, so order could be NULL nvarargs = nargs - (order ? (size_t)order[nparams-1] : nparams-1); narg_exprs = nparams-1 + nvarargs; } else { @@ -2017,8 +2012,8 @@ static Status types_expr(Typer *tr, Expression *e) { arg_exprs[i].flags = param->expr.flags; arg_exprs[i].type = param->type; if (has_varargs || f->type.fn->constness) { - /* param->expr hasn't been typed or evaluated, because we passed type_of_fn a "generic" function */ - /* we actually need to make a copy of this, so that copy_fn_expr still works later */ + // param->expr hasn't been typed or evaluated, because we passed type_of_fn a "generic" function + // we actually need to make a copy of this, so that copy_fn_expr still works later Expression default_arg; Copier cop = copier_create(tr->allocr, &fn_decl->body); copy_expr(&cop, &default_arg, ¶m->expr); @@ -2030,7 +2025,7 @@ static Status types_expr(Typer *tr, Expression *e) { arg_exprs[i].val = param->expr.val; } } - /* else, it's inferred */ + // else, it's inferred } else { arg_exprs[i] = args[arg_idx].val; } @@ -2053,33 +2048,33 @@ static Status types_expr(Typer *tr, Expression *e) { } } if (has_varargs) { - /* deal with varargs (put them at the end of arg_exprs) */ + // deal with varargs (put them at the end of arg_exprs) int idx = order ? order[nparams-1] : (I16)nparams-1; assert(idx >= 0); Expression *arg_out = &arg_exprs[(int)nparams-1]; for (; idx < (int)nargs; ++idx) { Expression *arg = &args[idx].val; if (type_is_builtin(&arg->type, BUILTIN_VARARGS)) { - /* add each vararg separately */ + // add each vararg separately assert(arg->kind == EXPR_IDENT); Identifier ident = arg->ident; Declaration *decl = ident->decl; VarArg *varargs_here = decl->val.varargs; size_t nvarargs_here = arr_len(varargs_here); - /* not just += nvarargs-1 to handle nvarargs_here == 0 */ + // not just += nvarargs-1 to handle nvarargs_here == 0 narg_exprs += nvarargs_here; --narg_exprs; nvarargs += nvarargs_here; --nvarargs; - long arg_out_idx = (long)(arg_out - arg_exprs); /* save and restore arg_out to prevent realloc from causing problems */ - /* add more room (or if nvarargs_here == 0, remove room) for more varargs */ + long arg_out_idx = (long)(arg_out - arg_exprs); // save and restore arg_out to prevent realloc from causing problems + // add more room (or if nvarargs_here == 0, remove room) for more varargs arr_set_lena(arg_exprs, narg_exprs, tr->allocr); arg_out = arg_exprs + arg_out_idx; for (size_t i = 0; i < nvarargs_here; ++i) { VarArg *vararg = &varargs_here[i]; Expression *out = arg_out++; - /* construct varargs_here[i] */ + // construct varargs_here[i] out->flags = EXPR_FOUND_TYPE; out->type = *vararg->type; out->where = arg->where; @@ -2122,15 +2117,15 @@ static Status types_expr(Typer *tr, Expression *e) { return false; } FnExpr *fn = fn_decl; - /* create a copy of the function header (we will copy the body if this instance hasn't been generated yet) */ - /* fn is the instance, original_fn is not */ + // create a copy of the function header (we will copy the body if this instance hasn't been generated yet) + // fn is the instance, original_fn is not original_fn = fn; fn_copy = typer_malloc(tr, sizeof *fn_copy); Copier cop = copier_create(tr->allocr, fn->body.parent); copy_fn_expr(&cop, fn_copy, fn, COPY_FN_EXPR_DONT_COPY_BODY); if (has_varargs) { - /* set value of varargs param decl */ + // set value of varargs param decl VarArg *varargs = NULL; arr_set_lena(varargs, nvarargs, tr->allocr); Declaration *varargs_param = arr_last_ptr(fn_copy->params); @@ -2157,7 +2152,7 @@ static Status types_expr(Typer *tr, Expression *e) { if (fn_type->constness) { FnExpr *fn = fn_copy; - /* keep track of the declaration */ + // keep track of the declaration Declaration *param_decl = fn->params; size_t ident_idx = 0; size_t i = 0; @@ -2173,8 +2168,8 @@ static Status types_expr(Typer *tr, Expression *e) { arr_add(inferred_idents, *ident); } else if ((param->flags & DECL_ANNOTATES_TYPE) && !type_is_builtin(¶m->type, BUILTIN_VARARGS)) { - /* add to stuff infer can use */ - /* @OPTIM: don't do this if we're not inferring */ + // add to stuff infer can use + // @OPTIM: don't do this if we're not inferring arr_add(decl_types, ¶m->type); arr_add(arg_types, &arg_exprs[i].type); arr_add(arg_wheres, arg_exprs[i].where); @@ -2208,7 +2203,7 @@ static Status types_expr(Typer *tr, Expression *e) { ++decl; } - if (!tr->gctx->err_ctx->have_errored) { /* something could've gone wrong elsewhere causing a strange error message here. for example, one of the arguments could be TYPE_UNKNOWN, because its declaration had a typing error */ + if (!tr->gctx->err_ctx->have_errored) { // something could've gone wrong elsewhere causing a strange error message here. for example, one of the arguments could be TYPE_UNKNOWN, because its declaration had a typing error err_print(decl->where, "Could not infer value of declaration."); info_print(e->where, "While processing this call"); } @@ -2222,7 +2217,7 @@ static Status types_expr(Typer *tr, Expression *e) { if (param->flags & DECL_INFER) { Value *val = &inferred_vals[i]; Type *type = &inferred_types[i]; - /* if we have an inferred type argument, it shouldn't be flexible */ + // if we have an inferred type argument, it shouldn't be flexible if (type_is_builtin(type, BUILTIN_TYPE)) val->type->flags &= (TypeFlags)~(TypeFlags)TYPE_IS_FLEXIBLE; param->val = *val; @@ -2240,11 +2235,11 @@ static Status types_expr(Typer *tr, Expression *e) { arr_clear(arg_wheres); arr_clear(decl_types); - /* eval compile time arguments */ + // eval compile time arguments for (i = 0; i < nparams; ++i) { bool should_be_evald = arg_is_const(&arg_exprs[i], fn_type->constness[i]); if (i == nparams-1 && has_varargs) { - /* handled above */ + // handled above } else if (should_be_evald) { if (!order || order[i] != -1) { Expression *expr = &arg_exprs[i]; @@ -2255,7 +2250,7 @@ static Status types_expr(Typer *tr, Expression *e) { expr->kind = EXPR_VAL; expr->flags = EXPR_FOUND_TYPE; expr->val = arg_val; - param_decl->expr = *expr; /* this is so that an error occurs if the type of expr doesn't match param_decl->type (we can't check here because param_decl->type isn't resolved yet) */ + param_decl->expr = *expr; // this is so that an error occurs if the type of expr doesn't match param_decl->type (we can't check here because param_decl->type isn't resolved yet) param_decl->flags |= DECL_FOUND_VAL|DECL_HAS_EXPR; copy_val(tr->allocr, ¶m_decl->val, arg_val, type); if (!(param_decl->flags & DECL_ANNOTATES_TYPE)) { @@ -2271,12 +2266,12 @@ static Status types_expr(Typer *tr, Expression *e) { } } if (fn_type->constness || (has_varargs && !is_foreign)) { - /* type params, return declarations, etc */ + // type params, return declarations, etc if (!type_of_fn(tr, fn_copy, &f->type, TYPE_OF_FN_IS_INSTANCE)) return false; if (fn_type->constness) { - /* deal with default arguments */ + // deal with default arguments size_t i = 0; arr_foreach(fn_copy->params, Declaration, param) { arr_foreach(param->idents, Identifier, ident) { @@ -2288,7 +2283,7 @@ static Status types_expr(Typer *tr, Expression *e) { arg_exprs[i].val = param->val; } else { assert(param->flags & DECL_HAS_EXPR); - assert(param->expr.kind == EXPR_VAL); /* this was done by type_of_fn */ + assert(param->expr.kind == EXPR_VAL); // this was done by type_of_fn arg_exprs[i] = param->expr; copy_val(tr->allocr, &arg_exprs[i].val, param->expr.val, ¶m->expr.type); } @@ -2303,7 +2298,7 @@ static Status types_expr(Typer *tr, Expression *e) { } - /* check types of arguments */ + // check types of arguments for (size_t p = 0; p < nparams; ++p) { if (p != nparams-1 || !has_varargs) { Expression *arg = &arg_exprs[p]; @@ -2316,7 +2311,7 @@ static Status types_expr(Typer *tr, Expression *e) { return false; } if (got->flags & TYPE_IS_FLEXIBLE) { - /* "cast" */ + // "cast" *got = *expected; } } @@ -2328,7 +2323,7 @@ static Status types_expr(Typer *tr, Expression *e) { Type table_index_type = {0}; Value table_index = {0}; - /* NOTE: we need to keep table_index's memory around because instance_table_add keeps it to compare against. */ + // NOTE: we need to keep table_index's memory around because instance_table_add keeps it to compare against. table_index_type.flags = TYPE_IS_RESOLVED; table_index_type.kind = TYPE_TUPLE; table_index_type.tuple = NULL; @@ -2345,7 +2340,7 @@ static Status types_expr(Typer *tr, Expression *e) { bool is_vararg = has_varargs && i == nparams-1; Copier cop = copier_create(tr->allocr, tr->block); if (is_vararg) { - /* create one additional table index member for varargs */ + // create one additional table index member for varargs Value *varargs_val = typer_arr_add_ptr(tr, table_index.tuple); Type *varargs_type = typer_arr_add_ptr(tr, table_index_type.tuple); memset(varargs_type, 0, sizeof *varargs_type); @@ -2360,7 +2355,7 @@ static Status types_expr(Typer *tr, Expression *e) { if (is_const) { copy_val(tr->allocr, &varg->val, arg->val, varg->type); } else { - /* use zero value everywhere */ + // use zero value everywhere varg->val = val_zero(tr->allocr, varg->type); } } @@ -2389,11 +2384,11 @@ static Status types_expr(Typer *tr, Expression *e) { Copier cop = copier_create(tr->allocr, fn_copy->body.parent); copy_block(&cop, &fn_copy->body, &original_fn->body, COPY_BLOCK_DONT_CREATE_IDENTS); c->instance->fn = fn_copy; - /* fix parameter and return types (they were kind of problematic before, because we didn't know about the instance) */ - fn_copy->instance_id = 1+original_fn->instances->n; /* let's help cgen out and assign a non-zero ID to this */ - /* type this instance */ + // fix parameter and return types (they were kind of problematic before, because we didn't know about the instance) + fn_copy->instance_id = 1+original_fn->instances->n; // let's help cgen out and assign a non-zero ID to this + // type this instance - /* if anything happens, make sure we let the user know that this happened while generating a fn */ + // if anything happens, make sure we let the user know that this happened while generating a fn ErrCtx *err_ctx = e->where.file->ctx; arr_add(err_ctx->instance_stack, e->where); Block *prev_block = tr->block; @@ -2444,12 +2439,12 @@ static Status types_expr(Typer *tr, Expression *e) { get_builtin_val_type(tr->allocr, builtin, t); assert(t->flags & TYPE_IS_RESOLVED); switch (builtin) { - /* immediately evaluate (things which do not differ between compile time & run time) */ + // immediately evaluate (things which do not differ between compile time & run time) case BUILTIN_DEBUG: e->kind = EXPR_VAL; e->val = get_builtin_val(tr->gctx, builtin); break; - /* stuff that's different between compile & run time */ + // stuff that's different between compile & run time default: e->builtin.which.val = builtin; break; @@ -2479,7 +2474,7 @@ static Status types_expr(Typer *tr, Expression *e) { break; case UNARY_ADDRESS: if (type_is_builtin(of_type, BUILTIN_TYPE)) { - /* oh it's a type! */ + // oh it's a type! t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_TYPE; break; @@ -2488,7 +2483,7 @@ static Status types_expr(Typer *tr, Expression *e) { return false; } if (of_type->kind == TYPE_TUPLE) { - /* necessary because x, y (where x and y are variables) is an l-value */ + // necessary because x, y (where x and y are variables) is an l-value err_print(e->where, "Cannot take address of tuple."); return false; } @@ -2552,7 +2547,7 @@ static Status types_expr(Typer *tr, Expression *e) { } break; case UNARY_SIZEOF: case UNARY_ALIGNOF: { - /* eval of */ + // eval of if (!type_is_builtin(&of->type, BUILTIN_TYPE)) { char *s = e->unary.op == UNARY_SIZEOF ? "sizeof" : "alignof"; err_print(e->where, "Argument of %s must be a Type. Did you mean %s(typeof ...)?", s, s); @@ -2594,7 +2589,7 @@ static Status types_expr(Typer *tr, Expression *e) { if (!expr_must_lval(e->binary.lhs, "set value of")) { return false; } - /* fallthrough */ + // fallthrough case BINARY_ADD: case BINARY_SUB: case BINARY_MUL: @@ -2615,9 +2610,9 @@ static Status types_expr(Typer *tr, Expression *e) { if (o == BINARY_SET) { valid = type_eq_implicit(lhs_type, rhs_type); } else { - /* numerical binary ops */ + // numerical binary ops if (lhs_type->kind == TYPE_BUILTIN && type_eq_implicit(lhs_type, rhs_type)) { - /* int + int, etc. */ + // int + int, etc. valid = true; } if (o == BINARY_ADD || o == BINARY_SUB || o == BINARY_SET_ADD || o == BINARY_SET_SUB) { @@ -2646,11 +2641,11 @@ static Status types_expr(Typer *tr, Expression *e) { } if (o == BINARY_LT || o == BINARY_GT || o == BINARY_LE || o == BINARY_GE || o == BINARY_EQ || o == BINARY_NE) { - /* comparable types */ + // comparable types if (type_eq_implicit(lhs_type, rhs_type)) { switch (lhs_type->kind) { case TYPE_PTR: - case TYPE_BUILTIN: /* all builtins are comparable */ + case TYPE_BUILTIN: // all builtins are comparable valid = true; default: break; @@ -2661,7 +2656,7 @@ static Status types_expr(Typer *tr, Expression *e) { if (valid) { switch (o) { case BINARY_SET: - /* type of x = y is always void */ + // type of x = y is always void t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_VOID; break; @@ -2675,7 +2670,7 @@ static Status types_expr(Typer *tr, Expression *e) { t->builtin = BUILTIN_BOOL; break; default: { - if (t->kind == TYPE_UNKNOWN) { /* have not yet determined type */ + if (t->kind == TYPE_UNKNOWN) { // have not yet determined type *t = *overriding_type(lhs_type, rhs_type); if ((o == BINARY_MOD || o == BINARY_SET_MOD) && type_builtin_is_float(t->builtin)) { @@ -2701,7 +2696,7 @@ static Status types_expr(Typer *tr, Expression *e) { o == BINARY_SET_SUB || o == BINARY_SET_MUL || o == BINARY_SET_DIV) { - t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_VOID; /* actually, it's just void */ + t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_VOID; // actually, it's just void } break; @@ -2726,7 +2721,7 @@ static Status types_expr(Typer *tr, Expression *e) { } break; case BINARY_AT_INDEX: if (type_is_slicechar(rhs_type)) { - /* switch to BINARY_DOT (point["x"] => point.x) */ + // switch to BINARY_DOT (point["x"] => point.x) e->binary.op = BINARY_DOT; Value val; if (!eval_expr(tr->evalr, rhs, &val)) { @@ -2736,7 +2731,7 @@ static Status types_expr(Typer *tr, Expression *e) { rhs->flags = 0; rhs->ident_str.str = val.slice.data; rhs->ident_str.len = (size_t)val.slice.len; - /* re-type with new expression */ + // re-type with new expression e->flags = (ExprFlags)~(ExprFlags)EXPR_FOUND_TYPE; return types_expr(tr, e); } @@ -2762,7 +2757,7 @@ static Status types_expr(Typer *tr, Expression *e) { Value index_val; if (!eval_expr(tr->evalr, rhs, &index_val)) return false; - /* NOTE: rhs->type was checked above */ + // NOTE: rhs->type was checked above I64 i = val_to_i64(index_val, rhs->type.builtin); VarArg *varargs = decl->val.varargs; if (i < 0 || i >= (I64)arr_len(varargs)) { @@ -2771,12 +2766,12 @@ static Status types_expr(Typer *tr, Expression *e) { } VarArg *vararg = &varargs[i]; if (decl->flags & DECL_IS_CONST) { - /* replace with value */ + // replace with value e->kind = EXPR_VAL; e->type = *vararg->type; copy_val(tr->allocr, &e->val, vararg->val, &e->type); } else { - /* just use vararg's type */ + // just use vararg's type rhs->kind = EXPR_VAL; rhs->val.i64 = i; rhs->type.builtin = BUILTIN_I64; @@ -2784,7 +2779,7 @@ static Status types_expr(Typer *tr, Expression *e) { } break; } - /* fallthrough */ + // fallthrough default: { char *s = type_to_str(lhs_type); err_print(e->where, "Cannot subscript type %s", s); @@ -2805,7 +2800,7 @@ static Status types_expr(Typer *tr, Expression *e) { return false; } if (type_is_builtin(struct_type, BUILTIN_TYPE)) { - /* accessing struct constant/parameter with a Type */ + // accessing struct constant/parameter with a Type Value lval = {0}; if (!eval_expr(tr->evalr, lhs, &lval)) return false; @@ -2837,7 +2832,7 @@ static Status types_expr(Typer *tr, Expression *e) { } UsedFrom *uf = struct_ident->used_from; if (uf) { - /* foo.baz => (foo.bar).baz */ + // foo.baz => (foo.bar).baz Expression *old_lhs = lhs; lhs = e->binary.lhs = typer_malloc(tr, sizeof *lhs); lhs->where = old_lhs->where; @@ -2852,7 +2847,7 @@ static Status types_expr(Typer *tr, Expression *e) { assert(arr_len(uf->use_decl->idents) == 1); middle->ident_str = ident_to_string(uf->use_decl->idents[0]); e->flags &= (ExprFlags)~(ExprFlags)EXPR_FOUND_TYPE; - /* re-type now that we know where it's from */ + // re-type now that we know where it's from return types_expr(tr, e); } if (struct_ident && !(struct_ident->decl->flags & DECL_IS_CONST)) { @@ -2867,7 +2862,7 @@ static Status types_expr(Typer *tr, Expression *e) { break; } else if (struct_type->kind == TYPE_SLICE || struct_type->kind == TYPE_ARR || type_is_builtin(struct_type, BUILTIN_VARARGS)) { if (str_eq_cstr(rhs->ident_str, "data") && struct_type->kind == TYPE_SLICE) { - /* allow access of slice pointer */ + // allow access of slice pointer t->kind = TYPE_PTR; t->ptr = typer_calloc(tr, 1, sizeof *t->ptr); t->ptr->kind = TYPE_BUILTIN; @@ -2881,12 +2876,12 @@ static Status types_expr(Typer *tr, Expression *e) { free(s); return false; } - /* length of slice/arr is i64 */ + // length of slice/arr is i64 t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_I64; Expression *of = lhs; if (type_is_builtin(struct_type, BUILTIN_VARARGS)) { - /* replace with val */ + // replace with val assert(of->kind == EXPR_IDENT); Identifier ident = of->ident; Declaration *decl = ident->decl; @@ -2962,7 +2957,7 @@ static Status types_expr(Typer *tr, Expression *e) { case EXPR_TYPE: { Type *tval = e->typeval; if (tval->kind == TYPE_STRUCT && tval->struc->params) { - /* don't try to resolve this */ + // don't try to resolve this t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_TYPE; break; @@ -3009,7 +3004,7 @@ static Status types_block(Typer *tr, Block *b) { b->c.break_lbl = 0; b->c.cont_lbl = 0; - /* for and fn need to deal with their own useds, because you can use stuff in the header */ + // for and fn need to deal with their own useds, because you can use stuff in the header if (b->kind != BLOCK_FOR && b->kind != BLOCK_FN) b->uses = NULL; @@ -3020,7 +3015,7 @@ static Status types_block(Typer *tr, Block *b) { if (!types_stmt(tr, s)) { success = false; if (tr->had_include_err) { - /* stop immediately; prevent too many "undeclared identifier" errors */ + // stop immediately; prevent too many "undeclared identifier" errors break; } continue; @@ -3061,7 +3056,7 @@ static Status types_decl(Typer *tr, Declaration *d) { } typer_arr_add(tr, tr->in_decls, d); if (flags & DECL_ANNOTATES_TYPE) { - /* type supplied */ + // type supplied if (!type_resolve(tr, dtype, d->where)) { success = false; goto ret; @@ -3096,7 +3091,7 @@ static Status types_decl(Typer *tr, Declaration *d) { if (!type_eq_implicit(&e->type, dtype)) { char *decl_type = type_to_str(dtype), *expr_type = type_to_str(&e->type); - bool is_parameter = (flags & DECL_IS_PARAM) && (flags & DECL_FOUND_VAL); /* this can happen if the wrong type is passed to a template function */ + bool is_parameter = (flags & DECL_IS_PARAM) && (flags & DECL_FOUND_VAL); // this can happen if the wrong type is passed to a template function if (is_parameter) err_print(e->where, "Parameter type %s does not match argument type %s.", decl_type, expr_type); else @@ -3107,13 +3102,13 @@ static Status types_decl(Typer *tr, Declaration *d) { } } else { if (type_is_void(&e->type)) { - /* e.g. x := (fn(){})(); */ + // e.g. x := (fn(){})(); err_print(e->where, "Use of void value."); success = false; goto ret; } *dtype = e->type; - dtype->flags &= (TypeFlags)~(TypeFlags)TYPE_IS_FLEXIBLE; /* x := 5; => x is not flexible */ + dtype->flags &= (TypeFlags)~(TypeFlags)TYPE_IS_FLEXIBLE; // x := 5; => x is not flexible } bool need_value = (flags & DECL_IS_CONST) || !tr->block || tr->block->kind == BLOCK_NMS; if (need_value) { @@ -3133,7 +3128,7 @@ static Status types_decl(Typer *tr, Declaration *d) { Value *copy = typer_malloc(tr, sizeof *copy); if (n_idents > 1 && dtype->kind != TYPE_TUPLE) { - /* actually, make n_idents copies of the value, and put them in a tuple. */ + // actually, make n_idents copies of the value, and put them in a tuple. Value *tuple = copy->tuple = typer_malloc(tr, n_idents * sizeof *copy); for (size_t i = 0; i < n_idents; ++i) { copy_val(tr->allocr, &tuple[i], val, dtype); @@ -3146,9 +3141,9 @@ static Status types_decl(Typer *tr, Declaration *d) { } } } else if (!tr->block || tr->block->kind == BLOCK_NMS) { - /* give global variables without initializers a value stack */ + // give global variables without initializers a value stack Value *val = typer_malloc(tr, sizeof *val); - arr_adda(d->val_stack, val, tr->allocr); /* arr_adda because this will never be freed */ + arr_adda(d->val_stack, val, tr->allocr); // arr_adda because this will never be freed if (n_idents > 1 && dtype->kind != TYPE_TUPLE) { Value *tuple = val->tuple = typer_malloc(tr, n_idents * sizeof *tuple); for (size_t i = 0; i < n_idents; ++i) @@ -3177,7 +3172,7 @@ static Status types_decl(Typer *tr, Declaration *d) { } } if (dtype->kind == TYPE_UNKNOWN) { - if (!d->where.file->ctx->have_errored) /* don't do an error if we haven't already done one, because it might be because of that */ + if (!d->where.file->ctx->have_errored) // don't do an error if we haven't already done one, because it might be because of that err_print(d->where, "Can't determine type of declaration."); success = false; goto ret; @@ -3208,7 +3203,7 @@ static Status types_decl(Typer *tr, Declaration *d) { if (flags & DECL_HAS_EXPR) { Value *val = decl_val_at_index(d, i); if (val->type->kind == TYPE_STRUCT && val->type->struc->params) { - /* don't resolve it because it's not really complete */ + // don't resolve it because it's not really complete } else { if (!type_resolve(tr, val->type, d->where)) return false; } @@ -3221,7 +3216,7 @@ static Status types_decl(Typer *tr, Declaration *d) { goto ret; } } - /* make constness NULL, so that semi-constant parameters turn into non-constant arguments */ + // make constness NULL, so that semi-constant parameters turn into non-constant arguments t->fn->constness = NULL; } } @@ -3254,11 +3249,11 @@ static Status types_decl(Typer *tr, Declaration *d) { } ret: - /* pretend we found the type even if we didn't to prevent too many errors */ + // pretend we found the type even if we didn't to prevent too many errors flags |= DECL_FOUND_TYPE; d->flags = flags; if (!success) { - /* use unknown type if we didn't get the type */ + // use unknown type if we didn't get the type dtype->flags = TYPE_IS_RESOLVED; dtype->kind = TYPE_UNKNOWN; } @@ -3288,7 +3283,7 @@ static Status fix_ident_decls_inline_block(Typer *tr, Statement *stmts) { return true; } -/* introduce identifiers from stmts into current scope, setting their "nms" field to nms */ +// introduce identifiers from stmts into current scope, setting their "nms" field to nms static Status include_stmts_link_to_nms(Typer *tr, Namespace *nms, Statement *stmts) { Identifiers *idents = typer_get_idents(tr); arr_foreach(stmts, Statement, s) { @@ -3298,7 +3293,7 @@ static Status include_stmts_link_to_nms(Typer *tr, Namespace *nms, Statement *st } else if (s->kind == STMT_DECL) { Declaration *d = s->decl; arr_foreach(d->idents, Identifier, ident) { - /* @OPTIM: only hash once */ + // @OPTIM: only hash once Identifier preexisting = ident_translate(*ident, idents); if (preexisting && preexisting->decl != d) { char *istr = ident_to_str(preexisting); @@ -3341,7 +3336,7 @@ top: case STMT_FOR: { bool in_header = true; - Block *prev_block = tr->block; { /* additional block because c++ */ + Block *prev_block = tr->block; { // additional block because c++ For *fo = s->for_; Declaration *header = &fo->header; U32 is_range = fo->flags & FOR_IS_RANGE; @@ -3359,13 +3354,13 @@ top: if (nidents < 2) { annotated_index = false; assert(nidents == 1); - /* turn value := arr to value, _ := arr to simplify things */ + // turn value := arr to value, _ := arr to simplify things typer_arr_add(tr, header->idents, ident_insert_with_len(typer_get_idents(tr), "_", 1)); } } Type *fo_type_tuple = NULL; - /* fo_type is (val_type, index_type) */ + // fo_type is (val_type, index_type) arr_set_lena(fo_type_tuple, 2, tr->allocr); memset(fo_type_tuple, 0, 2*sizeof *fo_type_tuple); Type *val_type = &fo_type_tuple[0]; @@ -3482,7 +3477,7 @@ top: val_type->flags &= (TypeFlags)~(TypeFlags)TYPE_IS_FLEXIBLE; if (fo->range.step) { - /* we can't put this above because *val_type might have changed. */ + // we can't put this above because *val_type might have changed. Value *stepval = typer_malloc(tr, sizeof *fo->range.stepval); if (!eval_expr(tr->evalr, fo->range.step, stepval)) { info_print(fo->range.step->where, "Note that the step of a for loop must be a compile-time constant."); @@ -3512,17 +3507,17 @@ top: case TYPE_BUILTIN: switch (iter_type->builtin) { case BUILTIN_VARARGS: { - /* exit for body */ + // exit for body tr->block = prev_block; arr_remove_lasta(tr->in_decls, tr->allocr); - /* create one block, containing a block for each vararg */ - /* e.g. for x := varargs { total += x; } => { { x := varargs[0]; total += x; } { x := varargs[0]; total += x; } } */ + // create one block, containing a block for each vararg + // e.g. for x := varargs { total += x; } => { { x := varargs[0]; total += x; } { x := varargs[0]; total += x; } } assert(fo->of->kind == EXPR_IDENT); Identifier varargs_ident = fo->of->ident; Declaration *idecl = varargs_ident->decl; VarArg *varargs = idecl->val.varargs; size_t nvarargs = arr_len(varargs); - /* create surrounding block */ + // create surrounding block s->kind = STMT_BLOCK; Block *b = s->block = typer_calloc(tr, 1, sizeof *s->block); idents_create(&b->idents, tr->allocr, b); @@ -3541,7 +3536,7 @@ top: bool has_index = !ident_eq_str(index_ident, "_"); for (size_t i = 0; i < nvarargs; ++i, ++stmt) { - /* create sub-block #i */ + // create sub-block #i memset(stmt, 0, sizeof *stmt); stmt->kind = STMT_BLOCK; Block *sub = stmt->block = typer_calloc(tr, 1, sizeof *sub); @@ -3553,13 +3548,13 @@ top: arr_set_lena(sub->stmts, total_nstmts, tr->allocr); Copier copier = copier_create(tr->allocr, sub); if (has_val) { - /* @TODO(eventually): don't put a decl in each block, just put one at the start */ + // @TODO(eventually): don't put a decl in each block, just put one at the start Statement *decl_stmt = &sub->stmts[0]; decl_stmt->flags = 0; decl_stmt->kind = STMT_DECL; decl_stmt->where = s->where; - /* declare value */ + // declare value Declaration *decl = decl_stmt->decl = typer_calloc(tr, 1, sizeof *decl); decl->where = fo->of->where; Identifier ident = ident_translate_forced(val_ident, &sub->idents); @@ -3577,13 +3572,13 @@ top: index->where = fo->of->where; } if (has_index) { - /* @TODO(eventually): don't put a decl in each block, just put one at the start */ + // @TODO(eventually): don't put a decl in each block, just put one at the start Statement *decl_stmt = &sub->stmts[has_val]; decl_stmt->flags = 0; decl_stmt->kind = STMT_DECL; decl_stmt->where = s->where; - /* declare value */ + // declare value Declaration *decl = decl_stmt->decl = typer_calloc(tr, 1, sizeof *decl); decl->where = fo->of->where; Identifier ident = ident_translate_forced(index_ident, &sub->idents); @@ -3605,10 +3600,10 @@ top: } default: break; } - /* fallthrough */ + // fallthrough default: { if (fo->of->type.kind == TYPE_UNKNOWN && tr->gctx->err_ctx->have_errored) { - /* silently fail */ + // silently fail goto for_fail; } char *str = type_to_str(&fo->of->type); @@ -3670,7 +3665,7 @@ top: If *i = s->if_; If *curr = i; if (curr->flags & IF_STATIC) { - /* handle #if */ + // handle #if while (1) { Expression *cond = curr->cond; If *next = curr->next_elif; @@ -3706,8 +3701,8 @@ top: curr = next; } if (s->kind == STMT_IF) { - /* all conds were false */ - /* empty inline block */ + // all conds were false + // empty inline block s->kind = STMT_INLINE_BLOCK; s->inline_block = NULL; } @@ -3782,7 +3777,7 @@ top: err_print(s->where, "Returning type %s in function which returns %s.", got, expected); return false; } - /* e.g. return #C("3+6"); */ + // e.g. return #C("3+6"); if (r->expr.type.kind == TYPE_UNKNOWN) { r->expr.type = tr->fn->ret_type; } @@ -3801,7 +3796,7 @@ top: Namespace *prev_nms = tr->nms; Block *prev_block = tr->block; IncludedFile *inc_f = NULL; - Namespace *inc_nms = NULL; /* non-NULL if this is an include to nms */ + Namespace *inc_nms = NULL; // non-NULL if this is an include to nms bool success = true; if (inc->nms) { inc_nms = typer_calloc(tr, 1, sizeof *inc_nms); @@ -3813,7 +3808,7 @@ top: body->parent = tr->block; inc_nms->inc_file = inc_f; - /* turn #include "foo", bar into bar ::= nms { ... } */ + // turn #include "foo", bar into bar ::= nms { ... } s->kind = STMT_DECL; Declaration *d = s->decl = typer_calloc(tr, 1, sizeof *d); d->flags = DECL_FOUND_TYPE | DECL_HAS_EXPR | DECL_IS_CONST | DECL_FOUND_VAL; @@ -3822,10 +3817,10 @@ top: Identifier i = ident_insert(typer_get_idents(tr), &ident_str); if (i->decl) { Declaration *d2 = i->decl; - /* maybe they included it twice into one namespace */ + // maybe they included it twice into one namespace if ((d2->flags & DECL_HAS_EXPR) && (d2->expr.kind == EXPR_NMS) && (d2->expr.nms->inc_file == inc_f)) { - /* that's okay; get rid of this declaration */ + // that's okay; get rid of this declaration s->kind = STMT_INLINE_BLOCK; s->inline_block = NULL; break; @@ -3834,7 +3829,7 @@ top: err_print(s->where, "Redeclaration of identifier %s.", istr); info_print(ident_decl_location(i), "Previous declaration was here."); free(istr); - return false; /* NOT goto inc_fail; */ + return false; // NOT goto inc_fail; } } typer_arr_add(tr, d->idents, i); @@ -3849,7 +3844,7 @@ top: d->val.nms = inc_nms; d->where = d->expr.where = s->where; - /* go inside namespace and block (it'll help to be there later on) */ + // go inside namespace and block (it'll help to be there later on) tr->nms = inc_nms; typer_block_enter(tr, &inc_nms->body); } else { @@ -3864,13 +3859,13 @@ top: } inc_f = str_hash_table_get(&tr->included_files, filename, filename_len); if (inc_f) { - /* has already been included */ + // has already been included if (inc_f->flags & INC_FILE_INCLUDING) { err_print(s->where, "Circular #include detected. You can add #force to this #include to force it to be included."); success = false; goto nms_done; } - if (s->kind == STMT_INLINE_BLOCK) s->inline_block = NULL; /* nothing needed here */ - /* just set ident declarations */ + if (s->kind == STMT_INLINE_BLOCK) s->inline_block = NULL; // nothing needed here + // just set ident declarations if (!include_stmts_link_to_nms(tr, inc_f->main_nms, inc_f->stmts)) { success = false; goto nms_done; } @@ -3945,7 +3940,7 @@ top: } break; case STMT_BREAK: case STMT_CONT: { - /* make sure we are actually in a loop */ + // make sure we are actually in a loop Block *block; for (block = tr->block; block; block = block->parent) { if (block->kind == BLOCK_FOR || block->kind == BLOCK_WHILE) { @@ -3998,17 +3993,17 @@ top: typer_arr_add(tr, tr->uses, u); } break; case STMT_INLINE_BLOCK: - assert(0); /* only exists after typing */ + assert(0); // only exists after typing break; } success: s->flags |= STMT_TYPED; if (tr->block == NULL || tr->block->kind == BLOCK_NMS) { - /* evaluate statements at global scope */ + // evaluate statements at global scope switch (s->kind) { case STMT_DECL: case STMT_USE: - case STMT_INLINE_BLOCK: /* have already been evaluated */ + case STMT_INLINE_BLOCK: // have already been evaluated case STMT_MESSAGE: break; case STMT_EXPR: @@ -4053,7 +4048,7 @@ static Status types_file(Typer *tr, ParsedFile *f) { arr_foreach(f->stmts, Statement, s) { if (!types_stmt(tr, s)) { if (tr->had_include_err) { - /* stop immediately; prevent too many "undeclared identifier" errors */ + // stop immediately; prevent too many "undeclared identifier" errors return false; } ret = false; @@ -23,7 +23,7 @@ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to <http://unlicense.org/> */ -/* NOTE: make sure you edit copy.c and cgen_recurse_subexprs/types when you make a change to expression-related types or type-related types in this file! */ +// NOTE: make sure you edit copy.c and cgen_recurse_subexprs/types when you make a change to expression-related types or type-related types in this file! typedef double Floating; @@ -42,10 +42,10 @@ typedef unsigned long ulonglong; #define ULONGLONG_FMT "%lu" #endif -/* generic function pointer */ +// generic function pointer typedef void (*FnPtr)(void); -/* try to find the type with the strictest alignment */ +// try to find the type with the strictest alignment typedef union { double floating; void *ptr; @@ -96,7 +96,7 @@ typedef U8 bool; #define Status bool WarnUnusedResult -/* NOTE: if you change these, make sure you change hash_tables.c */ +// NOTE: if you change these, make sure you change hash_tables.c typedef float F32; typedef double F64; #define F32_MANT_DIG FLT_MANT_DIG @@ -107,19 +107,19 @@ typedef double F64; #define F32_FMT "%.10f" #define F64_FMT "%.18f" -typedef U32 IdentID; /* identifier ID for cgen (anonymous variables). */ +typedef U32 IdentID; // identifier ID for cgen (anonymous variables). typedef struct ErrCtx { bool enabled; bool color_enabled; bool have_errored; - struct Location *instance_stack; /* stack of locations which generate the instances we're dealing with */ + struct Location *instance_stack; // stack of locations which generate the instances we're dealing with } ErrCtx; typedef struct Page { struct Page *next; - size_t used; /* number MaxAligns used, not bytes */ + size_t used; // number MaxAligns used, not bytes MaxAlign data[]; } Page; @@ -128,7 +128,7 @@ typedef struct Allocator { Page *last; } Allocator; -/* initialize to 0 */ +// initialize to 0 typedef struct HashTable { void *data; bool *occupied; @@ -162,7 +162,7 @@ typedef union Value { Slice slice; struct Type *type; struct Namespace *nms; - struct VarArg *varargs; /* dynamic array */ + struct VarArg *varargs; // dynamic array } Value; typedef Value *ValuePtr; @@ -173,18 +173,18 @@ typedef struct VarArg { typedef struct { struct StructDef *struc; - struct Declaration *use_decl; /* field declaration which uses the identifier */ + struct Declaration *use_decl; // field declaration which uses the identifier } UsedFrom; typedef struct IdentSlot { char *str; size_t len; - /* where this identifier was declared */ - struct Declaration *decl; /* if NULL, a declaration hasn't been found for it yet */ + // where this identifier was declared + struct Declaration *decl; // if NULL, a declaration hasn't been found for it yet struct Identifiers *idents; union { - struct Namespace *nms; /* only exists after typing, and only for namespace-level declarations (i.e. not local variables inside namespaces) */ - UsedFrom *used_from; /* for stuff used inside structs -- NULL if this is actually in the struct body */ + struct Namespace *nms; // only exists after typing, and only for namespace-level declarations (i.e. not local variables inside namespaces) + UsedFrom *used_from; // for stuff used inside structs -- NULL if this is actually in the struct body }; } IdentSlot; @@ -201,7 +201,7 @@ typedef struct StrHashTable { Allocator *allocr; U32 rand_seed; size_t data_size; - size_t nentries; /* # of filled slots */ + size_t nentries; // # of filled slots } StrHashTable; typedef IdentSlot *Identifier; @@ -210,7 +210,7 @@ typedef IdentSlot *IdentSlotPtr; typedef struct Identifiers { StrHashTable table; U32 rseed; - struct Block *scope; /* NULL for file scope */ + struct Block *scope; // NULL for file scope } Identifiers; typedef enum { @@ -283,7 +283,7 @@ typedef enum { KW_COMMA, KW_DOT, KW_EQ, - KW_LAST_SYMBOL = KW_EQ, /* last one entirely consisting of symbols */ + KW_LAST_SYMBOL = KW_EQ, // last one entirely consisting of symbols KW_IF, KW_ELIF, KW_ELSE, @@ -347,8 +347,8 @@ typedef String StrLiteral; typedef struct { U32 line; - U32 start; /* index in file->contents */ - U32 end; /* exclusive */ + U32 start; // index in file->contents + U32 end; // exclusive } SourcePos; typedef struct Token { @@ -370,13 +370,13 @@ typedef struct { const char *filename; char *contents; Token *tokens; - U32 *no_warn_lines; /* in sorted order; right now we do a binary search */ + U32 *no_warn_lines; // in sorted order; right now we do a binary search } File; typedef struct Location { File *file; - U32 start; /* index of first token */ - U32 end; /* index of one past last token */ + U32 start; // index of first token + U32 end; // index of one past last token } Location; @@ -384,10 +384,10 @@ typedef struct Tokenizer { Allocator *allocr; Token *tokens; File *file; - char *s; /* string being parsed */ + char *s; // string being parsed ErrCtx *err_ctx; U32 line; - Token *token; /* token currently being processed */ + Token *token; // token currently being processed Identifiers *globals; } Tokenizer; @@ -400,7 +400,7 @@ typedef enum { TYPE_ARR, TYPE_PTR, TYPE_SLICE, - TYPE_EXPR, /* just use this expression as the type. this kind of type doesn't exist after resolving. */ + TYPE_EXPR, // just use this expression as the type. this kind of type doesn't exist after resolving. TYPE_STRUCT #define TYPE_COUNT (TYPE_STRUCT+1) } TypeKind; @@ -433,15 +433,15 @@ typedef U8 Constness; #define CONSTNESS_YES ((Constness)2) typedef struct FnType { - struct Type *types; /* dynamic array [0] = ret_type, [1:] = param_types */ - Constness *constness; /* [i] = constness of param #i. iff no parameters are constant, this is NULL. don't use it as a dynamic array, because it might not always be. */ + struct Type *types; // dynamic array [0] = ret_type, [1:] = param_types + Constness *constness; // [i] = constness of param #i. iff no parameters are constant, this is NULL. don't use it as a dynamic array, because it might not always be. } FnType; typedef struct { struct Type *of; union { - U64 n; /* after resolving */ - struct Expression *n_expr; /* before resolving */ + U64 n; // after resolving + struct Expression *n_expr; // before resolving }; } ArrType; @@ -460,18 +460,18 @@ typedef struct Type { ArrType *arr; struct Type *ptr; struct Type *slice; - struct StructDef *struc; /* multiple resolved types can refer to the same struct */ + struct StructDef *struc; // multiple resolved types can refer to the same struct struct Expression *expr; }; } Type; -/* field of a struct */ +// field of a struct typedef struct Field { Location where; Identifier name; Type *type; - size_t offset; /* offset during compile time */ + size_t offset; // offset during compile time } Field; @@ -490,19 +490,19 @@ typedef enum { typedef U8 BlockFlags; typedef struct Block { - /* NOTE: make sure you check copy.c when you add something to this */ + // NOTE: make sure you check copy.c when you add something to this BlockFlags flags; BlockKind kind; /* set during the parsing phase, but don't access while this specific block is being parsed, because sometimes it's set after parse_block */ struct { - IdentID break_lbl, cont_lbl; /* initially 0, set to non-zero values if needed (tr->lbl_counter); set during typing */ + IdentID break_lbl, cont_lbl; // initially 0, set to non-zero values if needed (tr->lbl_counter); set during typing } c; Location where; Identifiers idents; struct Statement *stmts; struct Block *parent; - struct Statement **deferred; /* deferred stuff from this block; used by both eval and cgen */ - struct Use **uses; /* use statements (for types.c) */ + struct Statement **deferred; // deferred stuff from this block; used by both eval and cgen + struct Use **uses; // use statements (for types.c) } Block; typedef Block *BlockPtr; @@ -515,7 +515,7 @@ enum { }; typedef U8 StructFlags; typedef struct StructDef { - /* these two only exist after resolving (before then, it's scope.stmts) */ + // these two only exist after resolving (before then, it's scope.stmts) Field *fields; Location where; /* @@ -527,15 +527,15 @@ typedef struct StructDef { union { HashTable instances; struct { - size_t size; /* size of this struct during compile time */ + size_t size; // size of this struct during compile time size_t align; - U64 instance_id; /* ID of instance */ + U64 instance_id; // ID of instance }; }; Identifier name; struct Declaration *params; struct { - /* if name is NULL, use this */ + // if name is NULL, use this IdentID id; } c; StructFlags flags; @@ -548,7 +548,7 @@ typedef enum { EXPR_LITERAL_STR, EXPR_LITERAL_BOOL, EXPR_LITERAL_CHAR, - EXPR_IDENT, /* variable or constant */ + EXPR_IDENT, // variable or constant EXPR_BINARY_OP, EXPR_UNARY_OP, EXPR_FN, @@ -570,10 +570,10 @@ typedef enum { typedef enum { UNARY_MINUS, - UNARY_ADDRESS, /* &x */ - UNARY_DEREF, /* *x */ - UNARY_NOT, /* !x */ - UNARY_TYPEOF, /* typeof x */ + UNARY_ADDRESS, // &x + UNARY_DEREF, // *x + UNARY_NOT, // !x + UNARY_TYPEOF, // typeof x UNARY_DSIZEOF, UNARY_DALIGNOF, UNARY_SIZEOF, @@ -581,13 +581,13 @@ typedef enum { } UnaryOp; typedef enum { - BINARY_SET, /* e.g. x = y */ + BINARY_SET, // e.g. x = y BINARY_ADD, BINARY_SUB, BINARY_MUL, BINARY_DIV, BINARY_MOD, - BINARY_SET_ADD, /* e.g. x += y */ + BINARY_SET_ADD, // e.g. x += y BINARY_SET_SUB, BINARY_SET_MUL, BINARY_SET_DIV, @@ -598,19 +598,19 @@ typedef enum { BINARY_LE, BINARY_EQ, BINARY_NE, - BINARY_AT_INDEX, /* e.g. x[i] */ + BINARY_AT_INDEX, // e.g. x[i] BINARY_DOT, - BINARY_AND, /* && */ - BINARY_OR /* || */ + BINARY_AND, // && + BINARY_OR // || } BinaryOp; typedef struct CallExpr { struct Expression *fn; union { - struct Argument *args; /* before typing */ - struct Expression *arg_exprs; /* after typing */ + struct Argument *args; // before typing + struct Expression *arg_exprs; // after typing }; - struct Instance *instance; /* NULL = ordinary function, no compile time args */ + struct Instance *instance; // NULL = ordinary function, no compile time args } CallExpr; @@ -628,7 +628,7 @@ typedef enum { CTYPE_UNSIGNED_INT = CTYPE_UNSIGNED|CTYPE_INT, CTYPE_UNSIGNED_LONG = CTYPE_UNSIGNED|CTYPE_LONG, CTYPE_UNSIGNED_LONGLONG = CTYPE_UNSIGNED|CTYPE_LONGLONG, - /* things that can't be unsigned */ + // things that can't be unsigned CTYPE_PTR = 0x10, CTYPE_FLOAT, CTYPE_DOUBLE, @@ -637,33 +637,33 @@ typedef enum { } CTypeKind; typedef struct { CTypeKind kind; - char *points_to; /* if kind == CTYPE_PTR, ident string of C type which it points to */ + char *points_to; // if kind == CTYPE_PTR, ident string of C type which it points to } CType; enum { FN_EXPR_FOREIGN = 0x01, - FN_EXPR_EXPORT = 0x02, /* set during typing */ + FN_EXPR_EXPORT = 0x02, // set during typing FN_EXPR_HAS_VARARGS = 0x04 }; typedef struct FnExpr { Location where; - Block *declaration_block; /* block wherein this function is declared */ - U64 instance_id; /* 0 if not an instance. needs to be available even for #foreign functions */ + Block *declaration_block; // block wherein this function is declared + U64 instance_id; // 0 if not an instance. needs to be available even for #foreign functions union { struct { - struct Declaration *params; /* declarations of the parameters to this function */ - struct Declaration *ret_decls; /* array of decls, if this has named return values. otherwise, NULL */ + struct Declaration *params; // declarations of the parameters to this function + struct Declaration *ret_decls; // array of decls, if this has named return values. otherwise, NULL Type ret_type; Block body; }; struct { - Type type; /* type of this function */ - CType *ctypes; /* ctypes[i] = CTYPE_NONE if this isn't a ctype, or the specified CType. don't use this as a dynamic array. */ + Type type; // type of this function + CType *ctypes; // ctypes[i] = CTYPE_NONE if this isn't a ctype, or the specified CType. don't use this as a dynamic array. const char *name; - /* name of foreign function and dynamic library file it comes from (dll/so) */ - struct Expression *name_expr; /* STILL VALID even after running type_of_fn, because sometimes we run type_of_fn multiple times on a function */ + // name of foreign function and dynamic library file it comes from (dll/so) + struct Expression *name_expr; // STILL VALID even after running type_of_fn, because sometimes we run type_of_fn multiple times on a function const char *lib; - struct Expression *lib_expr; /* see name_expr */ + struct Expression *lib_expr; // see name_expr FnPtr fn_ptr; } foreign; }; @@ -672,18 +672,18 @@ typedef struct FnExpr { if the ith semi-constant parameter is constant. */ struct { - /* if name = NULL, this is an anonymous function, and id will be the ID of the fn. */ + // if name = NULL, this is an anonymous function, and id will be the ID of the fn. Identifier name; IdentID id; } c; U8 flags; -} FnExpr; /* an expression such as fn(x: int) int { return 2 * x; } */ +} FnExpr; // an expression such as fn(x: int) int { return 2 * x; } typedef FnExpr *FnExprPtr; typedef struct Instance { - Value val; /* key into hash table */ + Value val; // key into hash table union { - FnExpr *fn; /* the typed function */ + FnExpr *fn; // the typed function StructDef struc; }; } Instance; @@ -696,13 +696,13 @@ typedef struct CastExpr { typedef struct NewExpr { Type type; - struct Expression *n; /* e.g. for new(int, 5) */ + struct Expression *n; // e.g. for new(int, 5) } NewExpr; typedef struct SliceExpr { - struct Expression *of; /* required */ - struct Expression *from; /* optional */ - struct Expression *to; /* optional */ + struct Expression *of; // required + struct Expression *from; // optional + struct Expression *to; // optional struct { IdentID id; } c; @@ -731,10 +731,10 @@ const char *const builtin_val_names[BUILTIN_VAL_COUNT] = typedef struct Namespace { Block body; - Identifier associated_ident; /* if this is foo ::= nms { ... }, then associated_ident is foo; can be NULL. used by cgen. only non-null if the namespace isn't in a non-namespace block */ - struct IncludedFile *inc_file; /* NULL if this is not generated from an include to nms */ + Identifier associated_ident; // if this is foo ::= nms { ... }, then associated_ident is foo; can be NULL. used by cgen. only non-null if the namespace isn't in a non-namespace block + struct IncludedFile *inc_file; // NULL if this is not generated from an include to nms struct { - char *prefix; /* generated during typing */ + char *prefix; // generated during typing } c; } Namespace; typedef Namespace *NamespacePtr; @@ -751,7 +751,7 @@ typedef struct Expression { ExprKind kind; ExprFlags flags; struct { - IdentID id; /* cgen ID used for this expression */ + IdentID id; // cgen ID used for this expression } cgen; union { Floating floatl; @@ -768,7 +768,7 @@ typedef struct Expression { struct Expression *lhs; union { struct Expression *rhs; - Field *field; /* for struct., after resolving */ + Field *field; // for struct., after resolving }; } binary; CallExpr call; @@ -781,8 +781,8 @@ typedef struct Expression { BuiltinVal val; } which; } builtin; - String ident_str; /* before typing */ - Identifier ident; /* after typing */ + String ident_str; // before typing + Identifier ident; // after typing NewExpr new; Namespace *nms; struct { @@ -792,7 +792,7 @@ typedef struct Expression { CastExpr cast; SliceExpr slice; Block *block; - struct Expression *tuple; /* dynamic array, even after typing */ + struct Expression *tuple; // dynamic array, even after typing Type *typeval; Value val; }; @@ -801,7 +801,7 @@ typedef struct Expression { typedef struct Argument { Location where; - char *name; /* NULL = no name */ + char *name; // NULL = no name Expression val; } Argument; @@ -811,12 +811,12 @@ enum { DECL_SEMI_CONST = 0x0004, DECL_HAS_EXPR = 0x0008, DECL_FOUND_TYPE = 0x0010, - DECL_ERRORED_ABOUT_SELF_REFERENCE = 0x0020, /* has there been an error about this decl referencing itself? */ + DECL_ERRORED_ABOUT_SELF_REFERENCE = 0x0020, // has there been an error about this decl referencing itself? DECL_FOUND_VAL = 0x0040, - DECL_INFER = 0x0080, /* infer the value (e.g. fn(t::Type=, x:t)) */ + DECL_INFER = 0x0080, // infer the value (e.g. fn(t::Type=, x:t)) DECL_EXPORT = 0x0100, DECL_IS_PARAM = 0x0200, - DECL_USE = 0x0400 /* e.g. use p: Point */ + DECL_USE = 0x0400 // e.g. use p: Point }; typedef U16 DeclFlags; @@ -828,20 +828,20 @@ typedef struct Declaration { DeclFlags flags; union { Expression expr; - Field *field; /* pointer to the field which the first identifier in this decl refers to */ + Field *field; // pointer to the field which the first identifier in this decl refers to struct { union { struct { - /* only exist before typing */ + // only exist before typing Expression *name; Expression *lib; }; - /* only set for non-functions */ + // only set for non-functions const char *name_str; }; } foreign; }; - Value val; /* only for constant decls, non-constant globals, and varargs. */ + Value val; // only for constant decls, non-constant globals, and varargs. /* for eval, for non-constant decls @@ -858,8 +858,8 @@ enum { typedef struct If { U8 flags; - Expression *cond; /* NULL = this is an else */ - struct If *next_elif; /* next elif/else of this statement */ + Expression *cond; // NULL = this is an else + struct If *next_elif; // next elif/else of this statement Block body; } If; @@ -880,11 +880,11 @@ typedef struct For { Block body; union { struct { - Expression *from; /* can't be null */ - Expression *to; /* can be null */ + Expression *from; // can't be null + Expression *to; // can be null union { - /* (either) can be null */ - Expression *step; /* before typing */ + // (either) can be null + Expression *step; // before typing Value *stepval; /* after typing. the type of this is header.type.tuple[0] (i.e. the value type for this for loop), NOTE: this might be different from the original ForExpr.step.type, because of implicit type conversions. */ }; @@ -898,12 +898,12 @@ enum { }; typedef struct Return { U8 flags; - Block *referring_to; /* eval uses this; it's the function body we're returning from */ + Block *referring_to; // eval uses this; it's the function body we're returning from Expression expr; } Return; enum { - INC_FILE_INCLUDING = 0x01, /* are we currently in the process of including this file (i.e. during typing)? */ + INC_FILE_INCLUDING = 0x01, // are we currently in the process of including this file (i.e. during typing)? INC_FILE_CGEND_SDECLS = 0x10, INC_FILE_CGEND_DECLS = 0x20, INC_FILE_CGEND_DEFS = 0x40, @@ -912,7 +912,7 @@ enum { typedef U8 IncFileFlags; typedef struct IncludedFile { IncFileFlags flags; - Namespace *main_nms; /* namespace of first inclusion */ + Namespace *main_nms; // namespace of first inclusion struct Statement *stmts; } IncludedFile; @@ -924,7 +924,7 @@ enum { typedef struct { U8 flags; Expression filename; - char *nms; /* NULL if this is just a plain old #include, otherwise string which can be used with ident_get */ + char *nms; // NULL if this is just a plain old #include, otherwise string which can be used with ident_get } Include; typedef enum { @@ -949,7 +949,7 @@ typedef enum { STMT_RET, STMT_BREAK, STMT_CONT, - STMT_INCLUDE, /* turns into STMT_INLINE_BLOCK after typing */ + STMT_INCLUDE, // turns into STMT_INLINE_BLOCK after typing STMT_MESSAGE, STMT_DEFER, STMT_USE, @@ -957,25 +957,25 @@ typedef enum { STMT_FOR, STMT_WHILE, STMT_BLOCK, - STMT_INLINE_BLOCK /* a group of statements acting as one statement, e.g. all the statements from a #include */ + STMT_INLINE_BLOCK // a group of statements acting as one statement, e.g. all the statements from a #include } StatementKind; enum { STMT_TYPED = 0x01, - STMT_IS_INIT = 0x02 /* is this an initialization statement? if so, during typing it will be added to gctx->inits (this can't be done at parsing because the statements array is changing) */ + STMT_IS_INIT = 0x02 // is this an initialization statement? if so, during typing it will be added to gctx->inits (this can't be done at parsing because the statements array is changing) }; typedef struct Statement { Location where; StatementKind kind; U8 flags; union { - Declaration *decl; /* we want the pointer to be fixed so that we can refer to it from an identifier */ + Declaration *decl; // we want the pointer to be fixed so that we can refer to it from an identifier Expression *expr; Return *ret; Include *inc; - Message *message; /* #error, #warn, #info */ - Block *referring_to; /* for break/continue; set during typing */ + Message *message; // #error, #warn, #info + Block *referring_to; // for break/continue; set during typing struct Statement *defer; - struct Statement *inline_block; /* statements in an inline block (dynamic array) */ + struct Statement *inline_block; // statements in an inline block (dynamic array) Use *use; If *if_; While *while_; @@ -1010,9 +1010,9 @@ typedef struct { these are in order of appearance (which is the order in which they are called) */ Initialization *inits; - StrHashTable included_files; /* maps to IncludedFile. */ - File *main_file; /* this is the file which the compiler is invoked on. needed for checking for circular includes. */ - StatementWithCtx *static_ifs; /* all the #ifs */ + StrHashTable included_files; // maps to IncludedFile. + File *main_file; // this is the file which the compiler is invoked on. needed for checking for circular includes. + StatementWithCtx *static_ifs; // all the #ifs ErrCtx *err_ctx; bool debug_build; } GlobalCtx; @@ -1022,23 +1022,23 @@ typedef struct Parser { Allocator *allocr; Identifiers *globals; File *file; - Block *block; /* which block are we in? NULL = file scope */ + Block *block; // which block are we in? NULL = file scope ParsedFile *parsed_file; GlobalCtx *gctx; } Parser; typedef struct { Allocator *allocr; - StrHashTable libs_loaded; /* of Library (NOTE: Library is defined in foreign_something.c) */ + StrHashTable libs_loaded; // of Library (NOTE: Library is defined in foreign_something.c) } ForeignFnManager; typedef struct Evaluator { Allocator *allocr; struct Typer *typer; - Block *returning; /* function body from which we are returning OR loop body in which we are continuing/breaking */ - bool is_break; /* is returning because of a break, as opposed to a continue? */ - void **to_free; /* array of pointers to free once block is exited */ - Declaration **decls_given_values; /* array of declarations whose last value in their val stacks should be removed when the block is exited */ + Block *returning; // function body from which we are returning OR loop body in which we are continuing/breaking + bool is_break; // is returning because of a break, as opposed to a continue? + void **to_free; // array of pointers to free once block is exited + Declaration **decls_given_values; // array of declarations whose last value in their val stacks should be removed when the block is exited Value ret_val; ForeignFnManager ffmgr; } Evaluator; @@ -1064,19 +1064,19 @@ typedef struct Typer { Allocator *allocr; Evaluator *evalr; Identifiers *globals; - Use **uses; /* global used things */ - Declaration **in_decls; /* array of declarations we are currently inside */ + Use **uses; // global used things + Declaration **in_decls; // array of declarations we are currently inside Block *block; - FnExpr *fn; /* the function we're currently parsing. */ + FnExpr *fn; // the function we're currently parsing. GlobalCtx *gctx; ParsedFile *parsed_file; Namespace *nms; - FnWithCtx *all_fns; /* does not include templates */ + FnWithCtx *all_fns; // does not include templates StructDef **all_structs; - DeclWithCtx *all_globals; /* includes stuff in namespaces, as long as it's not in a function */ + DeclWithCtx *all_globals; // includes stuff in namespaces, as long as it's not in a function IdentID lbl_counter; - unsigned long nms_counter; /* counter for namespace IDs */ - StrHashTable included_files; /* maps to IncludedFile */ + unsigned long nms_counter; // counter for namespace IDs + StrHashTable included_files; // maps to IncludedFile /* have we had an error because we couldn't find a file that was #include'd (so that we can stop compiling immediately) @@ -1088,14 +1088,14 @@ typedef struct CGenerator { Allocator *allocr; FILE *outc; IdentID ident_counter, lbl_counter; - U16 indent_lvl; /* how many levels of indentation? */ - bool will_indent; /* will the next thing be indented? */ + U16 indent_lvl; // how many levels of indentation? + bool will_indent; // will the next thing be indented? ParsedFile *file; Block *block; Namespace *nms; - FnExpr *fn; /* which function are we in? (NULL for none) - not used during decls */ + FnExpr *fn; // which function are we in? (NULL for none) - not used during decls Identifier main_ident; Identifiers *globals; - char **nms_prefixes; /* dynamic (null-terminated) array of namespace prefixes */ + char **nms_prefixes; // dynamic (null-terminated) array of namespace prefixes GlobalCtx *gctx; } CGenerator; |