harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit cc718c1d026a2f8e3d0980e16de9210f3682dea8
parent b12b2d604300464d407df43b8df2391de51886c6
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Fri, 20 Nov 2020 11:03:29 -0500

Subsume runes and strings into T_LITERAL

Diffstat:
Minclude/lex.h | 12++++--------
Minclude/types.h | 5++++-
Msrc/lex.c | 55+++++++++++++++++++++++++------------------------------
Msrc/parse.c | 52++++++++++++++++++++++++++--------------------------
Msrc/types.c | 4++++
5 files changed, 63 insertions(+), 65 deletions(-)

diff --git a/include/lex.h b/include/lex.h @@ -106,8 +106,6 @@ enum lexical_token { // Tokens with additional information T_LITERAL, T_NAME, - T_RUNE, - T_STRING, // Magic tokens T_EOF, @@ -120,19 +118,17 @@ enum lexical_token { struct token { enum lexical_token token; + enum type_storage storage; union { - struct { - uintmax_t u; - intmax_t s; - double f; - enum type_storage storage; - } literal; + double _float; char *name; uint32_t rune; + intmax_t _signed; struct { size_t len; char *value; } string; + uintmax_t _unsigned; }; }; diff --git a/include/types.h b/include/types.h @@ -2,7 +2,7 @@ #define HARE_TYPES_H enum type_storage { - /* Scalar types */ + // Scalar types TYPE_STORAGE_U8, TYPE_STORAGE_U16, TYPE_STORAGE_U32, @@ -12,11 +12,14 @@ enum type_storage { TYPE_STORAGE_I32, TYPE_STORAGE_I64, TYPE_STORAGE_INT, + TYPE_STORAGE_RUNE, TYPE_STORAGE_UINT, TYPE_STORAGE_UINTPTR, TYPE_STORAGE_SIZE, TYPE_STORAGE_F32, TYPE_STORAGE_F64, + // Aggregate types + TYPE_STORAGE_STRING, }; const char *type_storage_unparse(enum type_storage storage); diff --git a/src/lex.c b/src/lex.c @@ -285,12 +285,12 @@ lex_literal(struct lexer *lexer, struct token *out) finalize: out->token = T_LITERAL; if (isfloat) { - out->literal.storage = TYPE_STORAGE_F64; + out->storage = TYPE_STORAGE_F64; } else { - out->literal.storage = TYPE_STORAGE_INT; + out->storage = TYPE_STORAGE_INT; } if (suff) { - const char *isuffs[] = { + const char *suffs[] = { [TYPE_STORAGE_U8] = "u8", [TYPE_STORAGE_U16] = "u16", [TYPE_STORAGE_U32] = "u32", @@ -306,26 +306,12 @@ finalize: [TYPE_STORAGE_F32] = "f32", [TYPE_STORAGE_F64] = "f64", }; - - const char *fsuffs[] = { - [TYPE_STORAGE_F32] = "f32", - [TYPE_STORAGE_F64] = "f64", - }; bool isvalid = false; for (enum type_storage i = 0; - i < sizeof(isuffs) / sizeof(isuffs[0]); ++i) { - if (isuffs[i] && strcmp(suff, isuffs[i]) == 0) { - isvalid = true; - out->literal.storage = i; - break; - } - } - for (enum type_storage i = 0; - i < sizeof(fsuffs) / sizeof(fsuffs[0]); ++i) { - if (fsuffs[i] && strcmp(suff, fsuffs[i]) == 0) { + i < sizeof(suffs) / sizeof(suffs[0]); ++i) { + if (suffs[i] && strcmp(suff, suffs[i]) == 0) { isvalid = true; - out->literal.storage = i; - isfloat = true; + out->storage = i; break; } } @@ -348,16 +334,16 @@ finalize: } errno = 0; - switch (out->literal.storage) { + switch (out->storage) { case TYPE_STORAGE_U8: case TYPE_STORAGE_U16: case TYPE_STORAGE_U32: case TYPE_STORAGE_UINT: case TYPE_STORAGE_U64: case TYPE_STORAGE_SIZE: - out->literal.u = strtoumax(lexer->buf, NULL, strlen(base)); + out->_unsigned = strtoumax(lexer->buf, NULL, strlen(base)); for (uintmax_t i = 0; i < exponent; i++) { - out->literal.u *= 10; + out->_unsigned *= 10; } break; case TYPE_STORAGE_I8: @@ -365,14 +351,14 @@ finalize: case TYPE_STORAGE_I32: case TYPE_STORAGE_INT: case TYPE_STORAGE_I64: - out->literal.s = strtoimax(lexer->buf, NULL, strlen(base)); + out->_signed = strtoimax(lexer->buf, NULL, strlen(base)); for (uintmax_t i = 0; i < exponent; i++) { - out->literal.s *= 10; + out->_signed *= 10; } break; case TYPE_STORAGE_F32: case TYPE_STORAGE_F64: - out->literal.f = strtod(lexer->buf, NULL); + out->_float = strtod(lexer->buf, NULL); break; default: assert(0); @@ -457,7 +443,8 @@ lex_string(struct lexer *lexer, struct token *out) case '"':; char *buf = malloc(lexer->buflen); memcpy(buf, lexer->buf, lexer->buflen); - out->token = T_STRING; + out->token = T_LITERAL; + out->storage = TYPE_STORAGE_STRING; out->string.len = lexer->buflen; out->string.value = buf; consume(lexer, -1); @@ -483,7 +470,8 @@ lex_string(struct lexer *lexer, struct token *out) } c = next(lexer, false); assert(c == '\''); - out->token = T_RUNE; + out->token = T_LITERAL; + out->storage = TYPE_STORAGE_RUNE; return c; default: assert(0); // Invariant @@ -801,13 +789,20 @@ token_finish(struct token *tok) case T_NAME: free(tok->name); break; - case T_STRING: - free(tok->string.value); + case T_LITERAL: + switch (tok->storage) { + case TYPE_STORAGE_STRING: + free(tok->string.value); + break; + default: + break; + } break; default: break; } tok->token = 0; + tok->storage = 0; } const char * diff --git a/src/parse.c b/src/parse.c @@ -20,43 +20,43 @@ parse(struct lexer *lexer, struct identifier *ns, struct ast_unit *unit) fprintf(stderr, "'%s'\n", tok.name); break; case T_LITERAL: - switch (tok.literal.storage) { - case TYPE_STORAGE_U8: - case TYPE_STORAGE_U16: - case TYPE_STORAGE_U32: - case TYPE_STORAGE_UINT: - case TYPE_STORAGE_U64: - case TYPE_STORAGE_SIZE: - fprintf(stderr, "(%ju: %s)\n", tok.literal.u, - type_storage_unparse(tok.literal.storage)); + switch (tok.storage) { + case TYPE_STORAGE_F32: + case TYPE_STORAGE_F64: + fprintf(stderr, "(%lf: %s)\n", tok._float, + type_storage_unparse(tok.storage)); break; case TYPE_STORAGE_I8: case TYPE_STORAGE_I16: case TYPE_STORAGE_I32: - case TYPE_STORAGE_INT: case TYPE_STORAGE_I64: - fprintf(stderr, "(%jd: %s)\n", tok.literal.s, - type_storage_unparse(tok.literal.storage)); + case TYPE_STORAGE_INT: + fprintf(stderr, "(%jd: %s)\n", tok._signed, + type_storage_unparse(tok.storage)); break; - case TYPE_STORAGE_F32: - case TYPE_STORAGE_F64: - fprintf(stderr, "(%lf: %s)\n", tok.literal.f, - type_storage_unparse(tok.literal.storage)); + case TYPE_STORAGE_RUNE: + putc('\'', stderr); + utf8_fputch(stderr, tok.rune); + putc('\'', stderr); + putc('\n', stderr); + break; + case TYPE_STORAGE_STRING: + fprintf(stderr, "\"%*s\"\n", (int)tok.string.len, + tok.string.value); + break; + case TYPE_STORAGE_SIZE: + case TYPE_STORAGE_U8: + case TYPE_STORAGE_U16: + case TYPE_STORAGE_U32: + case TYPE_STORAGE_U64: + case TYPE_STORAGE_UINT: + fprintf(stderr, "(%ju: %s)\n", tok._unsigned, + type_storage_unparse(tok.storage)); break; default: assert(0); } break; - case T_RUNE: - putc('\'', stderr); - utf8_fputch(stderr, tok.rune); - putc('\'', stderr); - putc('\n', stderr); - break; - case T_STRING: - fprintf(stderr, "\"%*s\"\n", (int)tok.string.len, - tok.string.value); - break; case T_ERROR: fprintf(stderr, "ERROR\n"); break; diff --git a/src/types.c b/src/types.c @@ -23,6 +23,8 @@ type_storage_unparse(enum type_storage storage) return "i64"; case TYPE_STORAGE_INT: return "int"; + case TYPE_STORAGE_RUNE: + return "rune"; case TYPE_STORAGE_UINT: return "uint"; case TYPE_STORAGE_UINTPTR: @@ -33,6 +35,8 @@ type_storage_unparse(enum type_storage storage) return "f32"; case TYPE_STORAGE_F64: return "f64"; + case TYPE_STORAGE_STRING: + return "str"; default: assert(0); }