From e5eeded02a4abe2729e675203437c79d9ee71a7a Mon Sep 17 00:00:00 2001 From: David Phillips Date: Sun, 14 Apr 2019 19:27:09 +1200 Subject: emit_error -> emit, factor keywords out --- lex.c | 37 ++++++++++++++++--------------------- util.c | 20 +++++++++++++++++++- util.h | 26 ++++++++++++++------------ 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 #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); -- cgit v1.1