summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Phillips <david@sighup.nz>2019-04-14 19:27:09 +1200
committerDavid Phillips <david@sighup.nz>2019-08-03 12:43:46 +1200
commite5eeded02a4abe2729e675203437c79d9ee71a7a (patch)
treec4d5ce737a70b89a0ec33e7a1524d899765dcb0f
parent36566268c9ead4a3d53730e66460a38a92820f3d (diff)
downloadtoy-cpu-assembler-e5eeded02a4abe2729e675203437c79d9ee71a7a.tar.xz
emit_error -> emit, factor keywords out
-rw-r--r--lex.c37
-rw-r--r--util.c20
-rw-r--r--util.h26
3 files changed, 49 insertions, 34 deletions
diff --git a/lex.c b/lex.c
index 6c32c97..47beb01 100644
--- a/lex.c
+++ b/lex.c
@@ -4,18 +4,10 @@
#include <ctype.h>
#include "lex.h"
+#include "util.h"
-#define emit_error(...) fprintf(stderr, "%s at (%zd,%zd): ", filename, 1 + line, 1 + column);\
- fprintf(stderr, __VA_ARGS__)
-
-static const char *keywords[] = {
- "declare",
- "byte",
- "bytes",
- "word",
- "words",
- "base",
-};
+#define emit(...) fprintf(stderr, "%s at (%zd,%zd): ", filename, 1 + line, 1 + column);\
+ fprintf(stderr, __VA_ARGS__)
static const char *filename = NULL;
static size_t line;
@@ -26,7 +18,7 @@ static char buffer[1024]; /* XXX limitation: sources must have lines < 1024 byte
static int expect(const char c) {
if (buffer[column] != c) {
- emit_error("Expected '%c', got '%c'\n", c, buffer[column]);
+ emit("Expected '%c', got '%c'\n", c, buffer[column]);
return 1;
}
column++;
@@ -141,7 +133,7 @@ static int lex_char_escaped(struct token *t) {
case '\\': t->i_val = '\\'; break;
case '\'': t->i_val = '\''; break;
default:
- emit_error("Unknown escape sequence '\\%c'\n", buffer[column]);
+ emit("Unknown escape sequence '\\%c'\n", buffer[column]);
break;
}
column++;
@@ -186,7 +178,7 @@ static int lex_num(struct token *t)
}
if (!isdigit(buffer[column])) {
- emit_error("Error: '%c' cannot start a numerical literal\n", buffer[column]);
+ emit("Error: '%c' cannot start a numerical literal\n", buffer[column]);
return 1;
}
@@ -199,7 +191,7 @@ static int lex_num(struct token *t)
span = strcspn(&buffer[column], " \n\t,");
if (span == 0) {
- emit_error("Error: malformed numerical literal\n");
+ emit("Error: malformed numerical literal\n");
return 1;
}
num_s = strndup(&buffer[column], span);
@@ -218,7 +210,7 @@ static int lex_num(struct token *t)
case 'b': base = 2; break;
default:
if (!isdigit(*suffix)) {
- emit_error("Error: '%c' is an invalid base suffix in numerical literal\n", *suffix);
+ emit("Error: '%c' is an invalid base suffix in numerical literal\n", *suffix);
free(num_s);
return 1;
}
@@ -231,7 +223,7 @@ static int lex_num(struct token *t)
value = strtol(num_s, &end, base);
if (*end != '\0') {
- emit_error("Error: malformed numerical literal\n", *end, base);
+ emit("Error: malformed numerical literal\n", *end, base);
free(num_s);
return 1;
}
@@ -250,7 +242,7 @@ static int lex_misc(struct token *t) {
int j = 0;
if (!isalpha(buffer[column])) {
- emit_error("Error: '%c' cannot start an identifier\n", buffer[column]);
+ emit("Error: '%c' cannot start an identifier\n", buffer[column]);
return 1;
}
@@ -268,9 +260,12 @@ static int lex_misc(struct token *t) {
if (!t->s_val)
return 1;
- for (j = 0; j < sizeof(keywords)/sizeof(*keywords); j++)
- if (strcmp(t->s_val, keywords[j]) == 0)
- t->type = TOKEN_KEYWORD;
+ if (get_keyword(t->s_val, NULL) == 0)
+ t->type = TOKEN_KEYWORD;
+
+// for (j = 0; j < sizeof(keywords)/sizeof(*keywords); j++)
+// if (strcmp(t->s_val, keywords[j]) == 0)
+// t->type = TOKEN_KEYWORD;
t->span = i - column;
column = i;
diff --git a/util.c b/util.c
index c9b0bc1..8d171a1 100644
--- a/util.c
+++ b/util.c
@@ -5,6 +5,22 @@
#include "lex.h"
/**
+ * Keywords
+ */
+static struct {
+ int look;
+ const char *str;
+} keywords[] = {
+ { .look = 0, .str = "declare" },
+ { .look = 0, .str = "byte" },
+ { .look = 0, .str = "bytes" },
+ { .look = 0, .str = "word" },
+ { .look = 0, .str = "words" },
+ { .look = 0, .str = "base" },
+ { .str = NULL },
+};
+
+/**
* Human-readable descriptions for tokens
*/
static struct {
@@ -117,7 +133,8 @@ int name(const char *x, type *res) { \
size_t i = 0; \
for (i = 0; lookup[i].str; i++) \
if (strcmp(lookup[i].str, x) == 0) { \
- *res = lookup[i].look; \
+ if (res) \
+ *res = lookup[i].look; \
return 0; \
} \
return 1; \
@@ -129,6 +146,7 @@ GENERATE_STR_LOOKUP_FUNC(get_asm_from_b, b_to_asm, enum JCOND);
GENERATE_STR_LOOKUP_FUNC(get_asm_from_reg, reg_to_asm, enum REG);
GENERATE_STR_LOOKUP_FUNC(get_token_description, token_to_desc, enum TOKEN_TYPE);
+GENERATE_NUM_LOOKUP_FUNC(get_keyword, keywords, int);
GENERATE_NUM_LOOKUP_FUNC(get_oper_from_asm, oper_to_asm, enum OPER);
GENERATE_NUM_LOOKUP_FUNC(get_j_from_asm, j_to_asm, enum JCOND);
GENERATE_NUM_LOOKUP_FUNC(get_b_from_asm, b_to_asm, enum JCOND);
diff --git a/util.h b/util.h
index 4225357..25128d8 100644
--- a/util.h
+++ b/util.h
@@ -1,24 +1,26 @@
#ifndef TOK_UTIL
#define TOK_UTIL
+#include "instruction.h"
#include "lex.h"
-#define GENERATE_PROTO_STR_LOOKUP_FUNC(name, lookup, type) \
-const char* name(type x);
+#define GENERATE_PROTO_STR_LOOKUP_FUNC(name, type) \
+const char* name(type);
-#define GENERATE_PROTO_NUM_LOOKUP_FUNC(name, lookup, type) \
+#define GENERATE_PROTO_NUM_LOOKUP_FUNC(name, type) \
int name(const char *x, type *res);
-GENERATE_PROTO_STR_LOOKUP_FUNC(get_asm_from_oper, oper_to_asm, enum OPER);
-GENERATE_PROTO_STR_LOOKUP_FUNC(get_asm_from_j, j_to_asm, enum JCOND);
-GENERATE_PROTO_STR_LOOKUP_FUNC(get_asm_from_b, b_to_asm, enum JCOND);
-GENERATE_PROTO_STR_LOOKUP_FUNC(get_asm_from_reg, reg_to_asm, enum REG);
-GENERATE_PROTO_STR_LOOKUP_FUNC(get_token_description, token_to_desc, enum TOKEN_TYPE);
+GENERATE_PROTO_STR_LOOKUP_FUNC(get_asm_from_oper, enum OPER);
+GENERATE_PROTO_STR_LOOKUP_FUNC(get_asm_from_j, enum JCOND);
+GENERATE_PROTO_STR_LOOKUP_FUNC(get_asm_from_b, enum JCOND);
+GENERATE_PROTO_STR_LOOKUP_FUNC(get_asm_from_reg, enum REG);
+GENERATE_PROTO_STR_LOOKUP_FUNC(get_token_description, enum TOKEN_TYPE);
-GENERATE_PROTO_NUM_LOOKUP_FUNC(get_oper_from_asm, oper_to_asm, enum OPER);
-GENERATE_PROTO_NUM_LOOKUP_FUNC(get_j_from_asm, j_to_asm, enum JCOND);
-GENERATE_PROTO_NUM_LOOKUP_FUNC(get_b_from_asm, b_to_asm, enum JCOND);
-GENERATE_PROTO_NUM_LOOKUP_FUNC(get_reg_from_asm, reg_to_asm, enum REG);
+GENERATE_PROTO_NUM_LOOKUP_FUNC(get_keyword, int);
+GENERATE_PROTO_NUM_LOOKUP_FUNC(get_oper_from_asm, enum OPER);
+GENERATE_PROTO_NUM_LOOKUP_FUNC(get_j_from_asm, enum JCOND);
+GENERATE_PROTO_NUM_LOOKUP_FUNC(get_b_from_asm, enum JCOND);
+GENERATE_PROTO_NUM_LOOKUP_FUNC(get_reg_from_asm, enum REG);
const char * get_token_description(enum TOKEN_TYPE t);
void indicate_file_area(FILE* fd, size_t line, size_t column, size_t span);