From 00d99b082162e287d481577915be73d5bf1dc483 Mon Sep 17 00:00:00 2001 From: katherine Date: Thu, 30 May 2019 04:05:29 -0700 Subject: add enum defined types --- src/gen.c | 21 ++++++++-- src/parse.c | 137 +++++++++++++++++++++++++++++++++++++++++++----------------- src/parse.h | 8 +++- src/tok.c | 9 ++-- src/tok.h | 1 + 5 files changed, 130 insertions(+), 46 deletions(-) diff --git a/src/gen.c b/src/gen.c index b35ed62..e427b7c 100644 --- a/src/gen.c +++ b/src/gen.c @@ -67,15 +67,27 @@ void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar) pr.suffix, pr.suffix ); - /* structs */ + /* types */ HASH_ITER(hh, pr.deftypes, dcur, dtmp) { if (!dcur->is_used) continue; - fprintf(f, "struct confconf_type_%s_%s {\n", + fprintf(f, "%s confconf_type_%s_%s {\n", + (dcur->type == PARSE_DEFTYPE_ENUM ? "enum" : + (dcur->type == PARSE_DEFTYPE_UNION ? + "union" : "struct") + ), dcur->name, pr.suffix); for (i = 0; i < dcur->member_list_len; i++) { + if (dcur->type == PARSE_DEFTYPE_ENUM) { + fprintf(f, " CONFCONF_TYPE_%s_%s_%s,\n", + dcur->name, + dcur->member_name_list[i], + pr.suffix); + continue; + } + switch (dcur->member_type_list[i]) { case PARSE_TYPE_BOOL: fprintf(f, " bool "); @@ -160,7 +172,10 @@ void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar) HASH_ITER(hh, pr.deftypes, dcur, dtmp) { if (dcur->is_used && dcur->is_in_hash) { fprintf(f, " %s confconf_type_%s_%s type_%s;\n", - (dcur->is_union ? "union" : "struct"), + (dcur->type == PARSE_DEFTYPE_ENUM ? "enum" : + (dcur->type == PARSE_DEFTYPE_UNION ? + "union" : "struct") + ), dcur->name, pr.suffix, dcur->name); } } diff --git a/src/parse.c b/src/parse.c index a70f28d..6ec3ade 100644 --- a/src/parse.c +++ b/src/parse.c @@ -18,10 +18,12 @@ static const char *curfname; ERR(__VA_ARGS__); \ } while (0) -#define ERR_END(t) \ +#define ERR_END(t, m) \ do { \ - if ((t).type == TOK_END) \ - ERR_AT((t).line, (t).col, "unexpected end of file"); \ + if ((t).type == TOK_END) { \ + ERR_AT((t).line, (t).col, "unexpected end of file (expected %s)", \ + (m) ); \ + } \ } while (0) #define WARN_AT(l, c, ...) \ @@ -50,7 +52,7 @@ static enum parse_type_e sub_parse_type(void) t = tok_get(); } - ERR_END(t); + ERR_END(t, "type"); if (t.type != TOK_ID) { if (type >= PARSE_TYPE_HASH_BOOL) @@ -102,7 +104,8 @@ static enum parse_type_e sub_parse_type(void) return type + PARSE_TYPE_DEFTYPE; } -static void sub_parse_deftype(size_t line, size_t col, bool is_union) +static void sub_parse_deftype(size_t line, size_t col, + enum parse_deftype_e dtype) { struct tok_s t; enum parse_type_e type; @@ -111,7 +114,7 @@ static void sub_parse_deftype(size_t line, size_t col, bool is_union) .line = line, .col = col, .is_used = false, - .is_union = is_union, + .type = dtype, .is_in_array = false, .is_in_hash = false, .member_list_len = 0, @@ -119,13 +122,24 @@ static void sub_parse_deftype(size_t line, size_t col, bool is_union) unsigned i, j; t = tok_get(); - ERR_END(t); + ERR_END(t, + (dt.type == PARSE_DEFTYPE_UNION ? "union name" : + (dt.type == PARSE_DEFTYPE_STRUCT ? + "struct name" : "enum name" + ) + ) + ); if (t.type != TOK_ID) { - ERR_AT(t.line, t.col, "unexpected token `%s` (expected %s name)", - t.val, (dt.is_union ? "union" : "struct")); + ERR_AT(t.line, t.col, "unexpected token `%s` (expected %s name)", + t.val, + (dt.type == PARSE_DEFTYPE_UNION ? "union" + : (dt.type == PARSE_DEFTYPE_STRUCT ? "struct" : "enum") + ) + ); } if ( + dt.type != PARSE_DEFTYPE_ENUM && ( !strcmp(t.val, "hash") || !strcmp(t.val, "array") || !strcmp(t.val, "bool") || !strcmp(t.val, "string") || !strcmp(t.val, "id") || @@ -135,6 +149,7 @@ static void sub_parse_deftype(size_t line, size_t col, bool is_union) !strcmp(t.val, "uintll") || !strcmp(t.val, "float") || !strcmp(t.val, "double") || !strcmp(t.val, "doublell") + ) ) { ERR_AT(dt.line, dt.col, "defined type conflicts with builtin type `%s`", t.val); @@ -150,49 +165,86 @@ static void sub_parse_deftype(size_t line, size_t col, bool is_union) strcpy(dt.name, t.val); t = tok_get(); - ERR_END(t); + ERR_END(t, "`{`"); if (t.type != TOK_LBRACE) ERR_AT(t.line, t.col, "unexpected token `%s` (expected `{`)", t.val); while (true) { if (dt.member_list_len == PARSE_DEFTYPE_MAX_LEN) { - ERR_AT(dt.line, dt.col, "%s %s has too many members", - (dt.is_union ? "union" : "struct"), dt.name); + ERR_AT(dt.line, dt.col, "%s %s has too many %s", + (dt.type == PARSE_DEFTYPE_ENUM ? "enum" : + (dt.type == PARSE_DEFTYPE_UNION ? + "union" : "struct") + ), + dt.name, + (dt.type == PARSE_DEFTYPE_ENUM ? "ids" : "members") + ); } t = tok_get(); if (t.type == TOK_RBRACE) { if (dt.member_list_len < 2) { - ERR_AT(dt.line, dt.col, "%s `%s` must specify at fewest two members", - (dt.is_union ? "union" : "struct"), dt.name); + ERR_AT(dt.line, dt.col, "%s `%s` must specify at fewest two %s", + (dt.type == PARSE_DEFTYPE_ENUM ? "enum" : + (dt.type == PARSE_DEFTYPE_UNION ? + "union" : "struct") + ), + dt.name, + (dt.type == PARSE_DEFTYPE_ENUM ? "ids" : "members") + ); } break; } - tok_unget(t); + if (dt.type != PARSE_DEFTYPE_ENUM) { + tok_unget(t); - type = sub_parse_type(); + ERR_END(t, "type or `}`"); - if (type >= PARSE_TYPE_ARRAY_BOOL) { - ERR_AT(t.line, t.col, "defined types may not contain arrays or hashes"); - } + type = sub_parse_type(); + + if (type >= PARSE_TYPE_ARRAY_BOOL) { + ERR_AT(t.line, t.col, + "defined types may not contain arrays or hashes"); + } + /* */ + + if (type == PARSE_TYPE_DEFTYPE) { + t = tok_get(); + ERR_AT(t.line, t.col, + "defined types may not contain other defined types"); + } - if (type == PARSE_TYPE_DEFTYPE) { t = tok_get(); - ERR_AT(t.line, t.col, "defined types may not contain other defined types"); } - t = tok_get(); - ERR_END(t); + ERR_END(t, (dt.type == PARSE_DEFTYPE_ENUM ? "id or `}`" + : "member name")); + if (t.type != TOK_ID) { if (t.type == TOK_RBRACE || t.type == TOK_COMMA) { - ERR_AT(t.line, t.col, "missing member name in %s `%s'", - (dt.is_union ? "union" : "struct"), dt.name); + ERR_AT(t.line, t.col, "missing %s in %s `%s'", + (dt.type == PARSE_DEFTYPE_ENUM ? "id" : "member name"), + (dt.type == PARSE_DEFTYPE_ENUM ? "enum" : + (dt.type == PARSE_DEFTYPE_UNION ? + "union" : "struct" + ) + ), + dt.name + ); } - ERR_AT(t.line, t.col, "bad %s member name `%s`", - (dt.is_union ? "union" : "struct"), t.val); + ERR_AT(t.line, t.col, "bad %s `%s` in %s %s", + (dt.type == PARSE_DEFTYPE_ENUM ? "id" : "member name"), + t.val, + (dt.type == PARSE_DEFTYPE_ENUM ? "enum" : + (dt.type == PARSE_DEFTYPE_UNION ? + "union" : "struct" + ) + ), + dt.name + ); } strcpy(dt.member_name_list[dt.member_list_len], t.val); @@ -207,9 +259,16 @@ static void sub_parse_deftype(size_t line, size_t col, bool is_union) for (i = 0; i < dt.member_list_len; i++) { for (j = i + 1; j < dt.member_list_len; j++) { if (!strcmp(dt.member_name_list[i], dt.member_name_list[j]) ) { - ERR_AT(dt.line, dt.col, "%s `%s` contains multiple members named %s", - (dt.is_union ? "union" : "struct"), dt.name, - dt.member_name_list[i]); + ERR_AT(dt.line, dt.col, + "%s `%s` contains multiple %s named `%s`", + (dt.type == PARSE_DEFTYPE_ENUM ? "enum" : + (dt.type == PARSE_DEFTYPE_UNION ? + "union" : "struct") + ), + dt.name, + (dt.type == PARSE_DEFTYPE_ENUM ? "ids" : "members"), + dt.member_name_list[i] + ); } } @@ -227,24 +286,26 @@ static bool sub_parse_op(void) switch (t.type) { case TOK_OP_STRUCT: - sub_parse_deftype(t.line, t.col, false); + sub_parse_deftype(t.line, t.col, PARSE_DEFTYPE_STRUCT); return true; - case TOK_OP_UNION: - sub_parse_deftype(t.line, t.col, true); + sub_parse_deftype(t.line, t.col, PARSE_DEFTYPE_UNION); + return true; + case TOK_OP_ENUM: + sub_parse_deftype(t.line, t.col, PARSE_DEFTYPE_ENUM); return true; case TOK_OP_SUFFIX: if (r.suffix_seen) { WARN_AT(t.line, t.col, - "function-suffix redefined (previous value was `%s`)", + "naming suffix redefined (previous value was `%s`)", r.suffix); } t = tok_get(); - ERR_END(t); + ERR_END(t, "naming suffix"); if (t.type != TOK_ID) - ERR_AT(t.line, t.col, "invalid function-suffix `%s`", t.val); + ERR_AT(t.line, t.col, "invalid naming suffix `%s`", t.val); strcpy(r.suffix, t.val); @@ -278,7 +339,7 @@ static bool sub_parse_rule(void) v.col = t.col; t = tok_get(); - ERR_END(t); + ERR_END(t, "variable name"); if (t.type != TOK_ID) { ERR_AT(t.line, t.col, "unexpected token `%s`, (expected variable name)", t.val); @@ -294,7 +355,7 @@ static bool sub_parse_rule(void) strcpy(v.name, t.val); t = tok_get(); - ERR_END(t); + ERR_END(t, "`=`"); if (t.type != TOK_EQUAL) ERR_AT(t.line, t.col, "unexpected token `%s`, (expected `=`)", t.val); diff --git a/src/parse.h b/src/parse.h index 89cf4fc..754462f 100644 --- a/src/parse.h +++ b/src/parse.h @@ -55,12 +55,18 @@ enum parse_type_e { PARSE_TYPE_HASH_DEFTYPE = 38, }; +enum parse_deftype_e { + PARSE_DEFTYPE_STRUCT, + PARSE_DEFTYPE_UNION, + PARSE_DEFTYPE_ENUM, +}; + struct parse_deftype_s { char name[TOK_MAX_LEN]; + enum parse_deftype_e type; size_t line; size_t col; bool is_used; - bool is_union; bool is_in_array; bool is_in_hash; unsigned member_list_len; diff --git a/src/tok.c b/src/tok.c index 177507a..c80d397 100644 --- a/src/tok.c +++ b/src/tok.c @@ -70,9 +70,10 @@ static void sub_match_op(void) enum tok_type_e type; char name[(32 < TOK_MAX_LEN ? 32 : TOK_MAX_LEN)]; } ops[] = { - { true, TOK_OP_SUFFIX, ".suffix" }, - { true, TOK_OP_STRUCT, ".struct" }, - { true, TOK_OP_UNION, ".union" }, + { true, TOK_OP_SUFFIX, ".suffix" }, + { true, TOK_OP_STRUCT, ".struct" }, + { true, TOK_OP_UNION, ".union" }, + { true, TOK_OP_ENUM, ".enum" }, }; unsigned i, j; bool again; @@ -95,7 +96,7 @@ static void sub_match_op(void) val[vlen] = c; vlen++; - for (j = 0; j < 3; j++) { + for (j = 0; j < 4; j++) { if (!ops[j].possible) continue; diff --git a/src/tok.h b/src/tok.h index 7558508..488c5ad 100644 --- a/src/tok.h +++ b/src/tok.h @@ -16,6 +16,7 @@ enum tok_type_e { TOK_OP_SUFFIX, TOK_OP_STRUCT, TOK_OP_UNION, + TOK_OP_ENUM, TOK_UINT, TOK_ID, TOK_UNKNWN, -- cgit v1.2.3