summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Phillips <david@sighup.nz>2018-08-01 02:04:47 +1200
committerDavid Phillips <david@sighup.nz>2018-08-01 02:04:47 +1200
commit957d77141f56714e9f4551c8d49e6658ff778ce7 (patch)
treeb4d0207a06f12de12c1172312b6ee5de54c79a6f
parenta2e204aea97e7f844a5303f956c893579a89623e (diff)
downloadhence-957d77141f56714e9f4551c8d49e6658ff778ce7.tar.xz
Add line area/span indication to error messages
-rw-r--r--Makefile2
-rw-r--r--common.h4
-rw-r--r--lexer.c3
-rw-r--r--lexer.h1
-rw-r--r--parser.c42
-rw-r--r--parser.h2
-rw-r--r--simulator.c19
7 files changed, 64 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index bdfcc72..5ba9cc6 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ CFLAGS += -std=c99 -D_XOPEN_SOURCE=500 -D_POSIX_C_SOURCE=200809L -Wall -Wextra
all: simulator
-simulator: simulator.o gate.o logic.o lexer.o parser.o
+simulator: simulator.o common.o gate.o logic.o lexer.o parser.o
.PHONY: test
test: all
diff --git a/common.h b/common.h
index e5c0ab4..5a6977d 100644
--- a/common.h
+++ b/common.h
@@ -1,6 +1,10 @@
#ifndef COMMON_H
#define COMMON_H
+#include <stdio.h>
+#include <stddef.h>
+
+void indicate_file_area(FILE *fd, size_t line, size_t column, size_t span);
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
diff --git a/lexer.c b/lexer.c
index 40dfd67..a8b7716 100644
--- a/lexer.c
+++ b/lexer.c
@@ -138,6 +138,7 @@ lex_alphanum(void) {
t.value[i] = '\0';
column_number += i;
+ t.span = i;
if (i == 0) {
emit_error("Expected alphanumeric, got '%c'\n", buf[i]);
@@ -163,6 +164,7 @@ lex_eol(void) {
t.type = TOK_EOL;
t.loc = get_current_loc();
+ t.span = 1;
expect('\n');
@@ -175,6 +177,7 @@ lex_colon(void) {
t.type = TOK_COLON;
t.loc = get_current_loc();
+ t.span = 1;
expect(':');
diff --git a/lexer.h b/lexer.h
index 542dd2c..2e27ffa 100644
--- a/lexer.h
+++ b/lexer.h
@@ -25,6 +25,7 @@ struct token {
enum TOKEN_TYPE type;
struct location loc;
char value[MAX_IDENT_LENGTH];
+ size_t span;
struct token *next;
};
diff --git a/parser.c b/parser.c
index c577105..987f26d 100644
--- a/parser.c
+++ b/parser.c
@@ -10,6 +10,7 @@
#include "gate.h"
+static FILE* fd;
static struct token *cursor;
#ifdef emit_error
@@ -18,7 +19,8 @@ static struct token *cursor;
#endif /* ifdef emit_error */
#define emit_error(...) fprintf(stderr, "Error (%zd,%zd): ", cursor->loc.line, cursor->loc.column);\
- fprintf(stderr, __VA_ARGS__)
+ fprintf(stderr, __VA_ARGS__);\
+ indicate_file_area(fd, cursor->loc.line, cursor->loc.column, cursor->span)
//static struct op_lookup uop_handlers[] = {
@@ -54,10 +56,44 @@ expect(enum TOKEN_TYPE e) {
return 0;
}
+static void
+kerchunk() {
+ cursor = cursor->next;
+}
int
-parse(struct token *t) {
+parse(FILE *f, struct token *t) {
+ char *token_desc = "(internal error)";
+ fd = f;
cursor = t;
- expect(TOK_MODULE);
+
+ if (expect(TOK_MODULE)) {
+ return 1;
+ }
+ kerchunk();
+
+ if (expect(TOK_IDENT)) {
+ return 1;
+ }
+ emit_error("Debug: module is named %s\n", cursor->value);
+ kerchunk();
+
+ if (expect(TOK_EOL)) {
+ return 1;
+ }
+ kerchunk();
+
+ while (cursor) {
+ switch(cursor->type) {
+ case TOK_EOL:
+ kerchunk();
+ break;
+ /* FIXME implement everything */
+ default:
+ token_desc = get_token_description(cursor->type);
+ emit_error("Unexpected %s\n", token_desc);
+ return 1;
+ }
+ }
return 0;
}
diff --git a/parser.h b/parser.h
index cf5c3b0..1446650 100644
--- a/parser.h
+++ b/parser.h
@@ -1 +1 @@
-int parse(struct token *);
+int parse(FILE*, struct token *);
diff --git a/simulator.c b/simulator.c
index 4f99c4f..bbea893 100644
--- a/simulator.c
+++ b/simulator.c
@@ -7,13 +7,24 @@
#include "parser.h"
int main(int argc, char **argv) {
- (void)argc;
- (void)argv;
+ FILE *fd = NULL;
+
+ if (argc != 2) {
+ fprintf(stderr, "Syntax: %s file.hence\n", argv[0]);
+ return 1;
+ }
// gate_init();
- struct token *tok = lex_file(stdin);
- int p = parse(tok);
+ fd = fopen(argv[1], "r");
+
+ if (!fd) {
+ perror("fopen");
+ return 1;
+ }
+
+ struct token *tok = lex_file(fd);
+ int p = parse(fd, tok);
// gate_set_input("a", LOGIC_LOW);
// gate_set_input("b", LOGIC_LOW);