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:
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);
}