~mcf/cproc

88aa3b6891678669548f01a0f87c36a993694320 — Michael Forney 1 year, 7 months ago 652fde3
Improve token descriptions in errors
3 files changed, 36 insertions(+), 5 deletions(-)

M cc.h
M pp.c
M token.c
M cc.h => cc.h +1 -1
@@ 376,8 376,8 @@ struct init {
extern struct token tok;

void tokprint(const struct token *);
void tokdesc(char *, size_t, enum tokenkind, const char *);
_Noreturn void error(const struct location *, const char *, ...);
struct token;

/* scan */


M pp.c => pp.c +6 -3
@@ 124,10 124,13 @@ peek(int kind)
char *
expect(int kind, const char *msg)
{
	char *lit;
	char *lit, want[64], got[64];

	if (tok.kind != kind)
		error(&tok.loc, "expected %d %s, saw %d", kind, msg, tok.kind);
	if (tok.kind != kind) {
		tokdesc(want, sizeof(want), kind, NULL);
		tokdesc(got, sizeof(got), tok.kind, tok.lit);
		error(&tok.loc, "expected %s %s, saw %s", want, msg, got);
	}
	lit = tok.lit;
	next();


M token.c => token.c +29 -1
@@ 1,4 1,6 @@
#include <assert.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>


@@ 7,7 9,7 @@

struct token tok;

static char *tokstr[] = {
static const char *tokstr[] = {
	/* keyword */
	[TAUTO] = "auto",
	[TBREAK] = "break",


@@ 130,6 132,32 @@ tokprint(const struct token *t)
	fputs(str, stdout);
}

void
tokdesc(char *buf, size_t len, enum tokenkind kind, const char *lit)
{
	const char *class;
	bool quote;

	switch (kind) {
	case TIDENT:     class = "identifier"; quote = true;  break;
	case TNUMBER:    class = "number";     quote = true;  break;
	case TCHARCONST: class = "character";  quote = false; break;
	case TSTRINGLIT: class = "string";     quote = false; break;
	case TNEWLINE:   class = "newline";    quote = true;  break;
	default:
		class = NULL;
		lit = kind < LEN(tokstr) ? tokstr[kind] : NULL;
	}
	if (class && lit)
		snprintf(buf, len, quote ? "%s '%s'" : "%s %s", class, lit);
	else if (class)
		snprintf(buf, len, "%s", class);
	else if (lit)
		snprintf(buf, len, "'%s'", lit);
	else
		snprintf(buf, len, "<unknown>");
}

_Noreturn void error(const struct location *loc, const char *fmt, ...)
{
	va_list ap;