aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-04-26 16:29:55 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-04-26 16:29:55 +0300
commitda9fe1e040b04cbe816c67fab7cb45d7db75107c (patch)
tree2cee6a2aadeb654272e0655a8800c407721e4f3c
parent9ec0e372e1720b8f0857ee6c99997f695ef9ea5d (diff)
downloadposthaste-da9fe1e040b04cbe816c67fab7cb45d7db75107c.tar.gz
posthaste-da9fe1e040b04cbe816c67fab7cb45d7db75107c.zip
restructure debugging a bit
-rw-r--r--src/check.c30
-rw-r--r--src/compile.c1
-rw-r--r--src/core.c4
-rw-r--r--src/debug.c83
-rw-r--r--src/execute.c1
-rw-r--r--src/lower.c1
-rw-r--r--src/scope.c22
7 files changed, 90 insertions, 52 deletions
diff --git a/src/check.c b/src/check.c
index cdac83e..880f71f 100644
--- a/src/check.c
+++ b/src/check.c
@@ -1,4 +1,5 @@
#include <posthaste/check.h>
+#include <posthaste/debug.h>
#define UNUSED(x) (void)x
@@ -100,7 +101,15 @@ static int analyze_func_def(struct state *state, struct scope *scope,
if (analyze_list(&func_state, func_scope, func_vars(f)))
return -1;
- return analyze(&func_state, func_scope, func_body(f));
+ if (analyze(&func_state, func_scope, func_body(f)))
+ return -1;
+
+ if (f->t == TYPE_AUTO) {
+ semantic_error(scope, f, "unable to determine return type");
+ return -1;
+ }
+
+ return 0;
}
static int analyze_proc_def(struct state *state, struct scope *scope,
@@ -133,6 +142,11 @@ static int analyze_proc_def(struct state *state, struct scope *scope,
return -1;
}
+ if (p->t == TYPE_AUTO) {
+ semantic_error(scope, p, "unable to determine return type");
+ return -1;
+ }
+
return 0;
}
@@ -467,7 +481,7 @@ static int analyze_dot(struct state *state, struct scope *scope, struct ast *d)
return -1;
if (base->t != TYPE_DATE) {
- semantic_error(scope, d, "expected %d, got %d",
+ semantic_error(scope, d, "expected %s, got %s",
type_str(TYPE_DATE), type_str(base->t));
return -1;
}
@@ -566,13 +580,18 @@ static int analyze_proc_call(struct state *state, struct scope *scope,
return -1;
}
+ if (exists->t == TYPE_AUTO) {
+ semantic_error(scope, c, "proc call before deduction of auto");
+ return -1;
+ }
+
struct ast *args = proc_call_args(c);
if (analyze_list(state, scope, args))
return -1;
struct ast *formal = proc_formals(exists);
if (ast_list_len(formal) != ast_list_len(args)) {
- semantic_error(scope, c, "expected %s args, got %s",
+ semantic_error(scope, c, "expected %zd args, got %zd",
ast_list_len(formal), ast_list_len(args));
return -1;
}
@@ -605,6 +624,11 @@ static int analyze_func_call(struct state *state, struct scope *scope,
return -1;
}
+ if (exists->t == TYPE_AUTO) {
+ semantic_error(scope, c, "func call before deduction of auto");
+ return -1;
+ }
+
struct ast *args = func_call_args(c);
if (analyze_list(state, scope, args))
return -1;
diff --git a/src/compile.c b/src/compile.c
index 9bbdbf4..a45a4a6 100644
--- a/src/compile.c
+++ b/src/compile.c
@@ -1,4 +1,5 @@
#include <math.h>
+#include <stdio.h>
#include <sys/mman.h>
#include <posthaste/compile.h>
diff --git a/src/core.c b/src/core.c
index 44aa130..bd8c359 100644
--- a/src/core.c
+++ b/src/core.c
@@ -19,7 +19,7 @@ static char *read_file(const char *fname, FILE *f)
long s = ftell(f);
if (s == LONG_MAX) {
/** @todo should probably do this via fstat or something */
- error("%s might be a directory", fname);
+ fprintf(stderr, "%s might be a directory", fname);
return NULL;
}
@@ -44,7 +44,7 @@ int run(const char *fname)
FILE *f = fopen(fname, "rb");
if (!f) {
- error("failed opening %s: %s\n", fname, strerror(errno));
+ fprintf(stderr, "failed opening %s: %s\n", fname, strerror(errno));
return -1;
}
diff --git a/src/debug.c b/src/debug.c
index c146719..0f0e0fe 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -3,16 +3,7 @@
#include <posthaste/debug.h>
-/**
- * Find position in file buffer where line number \p no
- * starts. Lines are assumed to be one-indexed, with
- * \p no = \c 0 and \p no = \c 1 both considered the first line.
- *
- * @param buf Buffer to look in.
- * @param no Line number whose start to look for.
- * @return Pointer to location in buffer where line number \p no
- * starts.
- */
+/* find the start of line number no in buffer buf */
static const char *find_lineno(const char *buf, size_t no)
{
if (no == 0 || no == 1)
@@ -32,37 +23,79 @@ static const char *find_lineno(const char *buf, size_t no)
return buf;
}
-void vsrc_issue(struct src_issue issue, const char *msg, va_list args)
+static void print_bar(int lineno_len)
{
- const char *line_start = find_lineno(issue.buf, issue.loc.first_line);
- const char *line_end = strchr(line_start, '\n');
- if (!line_end)
- line_end = strchr(line_start, 0);
+ fprintf(stderr, "%*s", lineno_len + 4, "| ");
+}
+
+static void vsrc_multi_line(struct src_issue issue, const char *line_start, int lineno_len)
+{
+ /* just dump lines as they are, adding bars to the left */
+ size_t line = issue.loc.first_line;
+ for (size_t i = 0;; ++i) {
+ char c = line_start[i];
+ if (c == 0) {
+ fputc('\n', stderr);
+ break;
+ }
+
+ fputc(c, stderr);
+
+
+ if (c == '\n') {
+ if (++line > issue.loc.last_line)
+ break;
+
+ print_bar(lineno_len);
+ }
+ }
+}
- int line_len = line_end - line_start;
+void vsrc_issue(struct src_issue issue, const char *msg, va_list args)
+{
+ /* with color support we could start coloring the actual error region at
+ * issue.loc.first_column on issue.loc.first_line, but messing with
+ * xterm color codes is a bit cumbersome so for now just stick to
+ * monochrome */
- fprintf(stderr, "%s:%i:%i: ", issue.fname,
+ fprintf(stderr, "%s:%i:%i: ",
+ issue.fname,
issue.loc.first_line,
issue.loc.first_col);
vfprintf(stderr, msg, args);
fputc('\n', stderr);
+ /* figure out how many spaces line number takes up */
int lineno_len = snprintf(NULL, 0, "%i", issue.loc.first_line);
- fputc(' ', stderr);
- fprintf(stderr, "%i | ", issue.loc.first_line);
+ fprintf(stderr, " %i | ", issue.loc.first_line);
+
+ const char *line_start = find_lineno(issue.buf, issue.loc.first_line);
+ if (issue.loc.first_line != issue.loc.last_line) {
+ /* multiline location requires slightly different handling */
+ return vsrc_multi_line(issue, line_start, lineno_len);
+ }
- fprintf(stderr, "%.*s\n", line_len, line_start);
+ /* print the offending line */
+ for (size_t i = 0;; ++i) {
+ char c = line_start[i];
+ if (c == 0 || c == '\n')
+ break;
- for (int i = 0; i < lineno_len + 2; ++i)
- fputc(' ', stderr);
+ fputc(c, stderr);
+ }
+ fputc('\n', stderr);
- fprintf(stderr, "| ");
+ /* the rest is just to print a little squiggly line to highlight exact location */
+ print_bar(lineno_len);
- for (int i = 0; i < issue.loc.first_col - 1; ++i)
+ /* print tabs on tabs, otherwise spaces to make start of squiggle line
+ * up with start of offending location */
+ for (size_t i = 0; i < issue.loc.first_col - 1; ++i)
fputc(line_start[i] == '\t' ? '\t' : ' ', stderr);
- for (int i = issue.loc.first_col; i < issue.loc.last_col; ++i) {
+ /* highlight the offending location */
+ for (size_t i = issue.loc.first_col; i < issue.loc.last_col; ++i) {
if (i == issue.loc.first_col)
fputc('^', stderr);
else
diff --git a/src/execute.c b/src/execute.c
index bd9cd6b..d5e180e 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -1,4 +1,5 @@
#include <math.h>
+#include <stdio.h>
#include <posthaste/execute.h>
#include <posthaste/lower.h>
diff --git a/src/lower.c b/src/lower.c
index beb89c5..4b57a90 100644
--- a/src/lower.c
+++ b/src/lower.c
@@ -1,3 +1,4 @@
+#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
diff --git a/src/scope.c b/src/scope.c
index 290dfd6..d2521c8 100644
--- a/src/scope.c
+++ b/src/scope.c
@@ -5,16 +5,6 @@
#include <posthaste/debug.h>
#include <posthaste/vec.h>
-struct scope {
- size_t id;
- struct scope *parent;
-
- const char *fname;
- const char *buf;
-
- struct vec visible;
-};
-
struct vec scopes = {0};
struct scope *create_scope()
@@ -139,15 +129,3 @@ void destroy_scopes()
vec_destroy(&scopes);
}
-
-void semantic_error(struct scope *scope, struct ast *n, const char *msg, ...)
-{
- va_list args;
- va_start(args, msg);
- struct src_issue issue;
- issue.loc = n->loc;
- issue.fname = scope->fname;
- issue.buf = scope->buf;
- vsrc_issue(issue, msg, args);
- va_end(args);
-}