diff options
| author | katherine <k@airen-no-jikken.icu> | 2019-05-30 04:05:29 -0700 | 
|---|---|---|
| committer | katherine <k@airen-no-jikken.icu> | 2019-05-30 04:05:29 -0700 | 
| commit | 00d99b082162e287d481577915be73d5bf1dc483 (patch) | |
| tree | 9d5fa7e28b6d9dcf959a6d3884bc62a6b3d9d9d5 | |
| parent | 58e3054794cde4148267d81c80cc3109fbd19298 (diff) | |
| download | confconf-00d99b082162e287d481577915be73d5bf1dc483.tar.gz | |
add enum defined types
| -rw-r--r-- | src/gen.c | 21 | ||||
| -rw-r--r-- | src/parse.c | 137 | ||||
| -rw-r--r-- | src/parse.h | 8 | ||||
| -rw-r--r-- | src/tok.c | 9 | ||||
| -rw-r--r-- | src/tok.h | 1 | 
5 files changed, 130 insertions, 46 deletions
| @@ -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; @@ -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; @@ -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, | 
