diff options
Diffstat (limited to 'src/debug.c')
-rw-r--r-- | src/debug.c | 91 |
1 files changed, 83 insertions, 8 deletions
diff --git a/src/debug.c b/src/debug.c index f47a022..f823442 100644 --- a/src/debug.c +++ b/src/debug.c @@ -15,6 +15,7 @@ #include <stdarg.h> #include <fwd/debug.h> +#include <fwd/scope.h> /** * Get string representation of issue_level. @@ -120,7 +121,7 @@ void src_issue(struct src_issue issue, const char *err_msg, ...) va_end(args); } -void semantic_error(struct file_ctx fctx, struct ast *node, +void semantic_error(struct scope *scope, struct ast *node, const char *fmt, ...) { va_list args; @@ -128,12 +129,86 @@ void semantic_error(struct file_ctx fctx, struct ast *node, struct src_issue issue; issue.level = SRC_ERROR; issue.loc = node->loc; - issue.fctx = fctx; + issue.fctx = scope->fctx; _issue(issue, fmt, args); va_end(args); } -void loc_error(struct file_ctx fctx, struct src_loc loc, +void type_mismatch(struct scope *scope, struct ast *node, + struct type *l, struct type *r) +{ + const char *ls = type_str(l); + const char *rs = type_str(r); + semantic_error(scope, node, "type mismatch: %s vs %s\n", ls, rs); + free((void *)ls); + free((void *)rs); +} + +static void _type_str(FILE *f, struct type *t); + +static void _type_list_str(FILE *f, struct type *types) +{ + _type_str(f, types); + + foreach_type(type, types->n) { + fprintf(f, ", "); + _type_str(f, type); + } +} + +static void _type_str(FILE *f, struct type *type) +{ + if (!type) + return; + + switch (type->k) { + case TYPE_VOID: + fprintf(f, "void"); + break; + + case TYPE_PTR: + fprintf(f, "*"); + break; + + case TYPE_REF: + fprintf(f, "&"); + break; + + case TYPE_ID: + fprintf(f, "%s", type->id); + break; + + case TYPE_CALLABLE: + fprintf(f, "("); + _type_list_str(f, type->t0); + fprintf(f, ")"); + break; + + case TYPE_CONSTRUCT: + fprintf(f, "%s![", type->id); + _type_list_str(f, type->t0); + fprintf(f, "]"); + break; + } +} + +const char *type_str(struct type *t) +{ + if (!t) + return strdup("NULL"); + + char *buf = NULL; size_t size = 0; + FILE *memstream = open_memstream(&buf, &size); + if (!memstream) + return NULL; + + _type_str(memstream, t); + + fclose(memstream); + return buf; +} + +void loc_error(struct scope *scope, struct src_loc loc, const char *fmt, ...) { va_list args; @@ -141,12 +216,12 @@ void loc_error(struct file_ctx fctx, struct src_loc loc, struct src_issue issue; issue.level = SRC_ERROR; issue.loc = loc; - issue.fctx = fctx; + issue.fctx = scope->fctx; _issue(issue, fmt, args); va_end(args); } -void semantic_warn(struct file_ctx fctx, struct ast *node, const char *fmt, +void semantic_warn(struct scope *scope, struct ast *node, const char *fmt, ...) { va_list args; @@ -154,12 +229,12 @@ void semantic_warn(struct file_ctx fctx, struct ast *node, const char *fmt, struct src_issue issue; issue.level = SRC_WARN; issue.loc = node->loc; - issue.fctx = fctx; + issue.fctx = scope->fctx; _issue(issue, fmt, args); va_end(args); } -void semantic_info(struct file_ctx fctx, struct ast *node, const char *fmt, +void semantic_info(struct scope *scope, struct ast *node, const char *fmt, ...) { va_list args; @@ -167,7 +242,7 @@ void semantic_info(struct file_ctx fctx, struct ast *node, const char *fmt, struct src_issue issue; issue.level = SRC_INFO; issue.loc = node->loc; - issue.fctx = fctx; + issue.fctx = scope->fctx; _issue(issue, fmt, args); va_end(args); } |