shithub: dfc

Download patch

ref: a4d5200c459b91d2f33c939e68f250a8543a6978
parent: 87988f39a68117c491f094e6879a5a74cb0e33ae
author: Jacob Moody <moody@posixcafe.org>
date: Tue Jul 25 14:45:15 EDT 2023

major cleanup

get rid of junk that is not actual C input.
handle enums.
add pragmas for control, for switching between big and little, and exiting early
delay printing byte functions until we need to

--- a/dfc.y
+++ b/dfc.y
@@ -16,15 +16,16 @@
 };
 
 int ordermode = Big;
+int donebyteprint = 0;
+int nextenumval = 0;
 
 enum{
 	TCmplx,
-	TNum,
 	TUchar,
 	TU16,
 	TU32,
 	TU64,
-	TVLA,
+	TEnum,
 };
 
 typedef struct Field Field;
@@ -34,13 +35,11 @@
 	char *name;
 	int type;
 	int val;
-	char *from;
 };
 
 struct Field{
 	char *name;
 	int len;
-	int count;
 	Sym sym;
 };
 
@@ -82,6 +81,21 @@
 }
 
 static int
+aligned2size(Sym *s)
+{
+	switch(s->type){
+	case TU16:
+		return 2;
+	case TU32:
+		return 4;
+	case TU64:
+		return 8;
+	default:
+		return 0;
+	}
+}
+
+static int
 aligned(Sym *s)
 {
 	switch(s->type){
@@ -98,6 +112,10 @@
 	int x, y;
 	int shift;
 
+	if(donebyteprint)
+	for(x = 2; x <= 8; x++)
+		print("#undef GET%d\n#undef PUT%d\n", x, x);
+
 	if(ordermode == Big)
 	for(x = 2; x <= 8; x++){
 		print("#define GET%d(p) ", x);
@@ -138,6 +156,7 @@
 		print("\n");
 	}
 	print("\n");
+	donebyteprint = 1;
 }
 
 static void
@@ -146,44 +165,29 @@
 	int i, j;
 	char buf[128];
 
-/*
-	print("typedef struct %s %s;\n", name, name);
-	print("struct %s{\n", name);
-	for(i = 0; i < ntobe; i++){
-		if(tobe[i].sym.type == TCmplx){
-			print("\t%s %s;\n", tobe[i].sym.name, tobe[i].name);
-			continue;
-		}
-		if(tobe[i].len == 0)
-			print("\tuchar *%s;\n", tobe[i].name);
-		else if(aligned(tobe[i].len))
-			print("\t%s %s;\n", size2type(tobe[i].len), tobe[i].name);
-		else
-			print("\tuchar %s[%d];\n", tobe[i].name, tobe[i].len);
-	}
-	print("};\n\n");
-*/
-
 	mklower(buf, buf + sizeof buf - 1, name);
 	print("long\nget%s(%s *ret, uchar *data)\n{\n\tlong n;\n\n\tn = 0;\n", buf, name);
 	for(i = 0; i < ntobe; i++){
-		switch(tobe[i].sym.type){
-		case TCmplx:
+		if(tobe[i].sym.type == TCmplx){
 			mklower(buf, buf + sizeof buf - 1, tobe[i].sym.name);
-			if(tobe[i].count == 1)
+			if(tobe[i].len == 1)
 				print("\tn += get%s(&ret->%s, data+n);\n", buf, tobe[i].name);
-			else for(j = 0; j < tobe[i].count; j++)
+			else for(j = 0; j < tobe[i].len; j++)
 				print("\tn += get%s(&ret->%s[%d], data+n);\n", buf, tobe[i].name, j);
 			continue;
-		case TVLA:
-			print("\tret->%s = data+n;\n", tobe[i].name);
-			print("\tn += ret->%s;\n", tobe[i].sym.from);
+		}
+		if(aligned(&tobe[i].sym)){
+			if(tobe[i].len == 1){
+				print("\tret->%s = GET%d(data+n);\n", tobe[i].name, aligned2size(&tobe[i].sym));
+				print("\tn += %d;\n", aligned2size(&tobe[i].sym));
+			} else for(j = 0; j < tobe[i].len; j++){
+				print("\tret->%s[%d] = GET%d(data+n);\n", tobe[i].name, j, aligned2size(&tobe[i].sym));
+				print("\tn += %d;\n", aligned2size(&tobe[i].sym));
+			}
 			continue;
 		}
 		if(tobe[i].len == 1)
 			print("\tret->%s = data[n];\n", tobe[i].name);
-		else if(aligned(&tobe[i].sym))
-			print("\tret->%s = GET%d(data+n);\n", tobe[i].name, tobe[i].len);
 		else
 			print("\tmemcpy(ret->%s, data+n, %d);\n", tobe[i].name, tobe[i].len);
 		print("\tn += %d;\n", tobe[i].len);
@@ -193,23 +197,26 @@
 	mklower(buf, buf + sizeof buf - 1, name);
 	print("long\nput%s(uchar *dst, %s *src)\n{\n\tlong n;\n\n\tn = 0;\n", buf, name);
 	for(i = 0; i < ntobe; i++){
-		switch(tobe[i].sym.type){
-		case TCmplx:
+		if(tobe[i].sym.type == TCmplx){
 			mklower(buf, buf + sizeof buf - 1, tobe[i].sym.name);
-			if(tobe[i].count == 1)
+			if(tobe[i].len == 1)
 				print("\tn += put%s(dst+n, &src->%s);\n", buf, tobe[i].name);
-			else for(j = 0; j < tobe[i].count; j++)
+			else for(j = 0; j < tobe[i].len; j++)
 				print("\tn += put%s(dst+n, &src->%s[%d]);\n", buf, tobe[i].name, j);
 			continue;
-		case TVLA:
-			print("\tmemmove(dst+n, src->%s, src->%s);\n", tobe[i].name, tobe[i].sym.from);
-			print("\tn += src->%s;\n", tobe[i].sym.from);
+		}
+		if(aligned(&tobe[i].sym)){
+			if(tobe[i].len == 1){
+				print("\tPUT%d(dst+n, src->%s);\n", aligned2size(&tobe[i].sym), tobe[i].name);
+				print("\tn += %d;\n", aligned2size(&tobe[i].sym));
+			} else for(j = 0; j < tobe[i].len; j++){
+				print("\tPUT%d(dst+n, src->%s[%d]);\n", aligned2size(&tobe[i].sym), tobe[i].name, j);
+				print("\tn += %d;\n", aligned2size(&tobe[i].sym));
+			}
 			continue;
 		}
 		if(tobe[i].len == 1)
 			print("\tdst[n] = src->%s;\n", tobe[i].name);
-		else if(aligned(&tobe[i].sym))
-			print("\tPUT%d(dst+n, src->%s);\n", tobe[i].len, tobe[i].name);
 		else
 			print("\tmemcpy(dst+n, src->%s, %d);\n", tobe[i].name, tobe[i].len);
 		print("\tn += %d;\n", tobe[i].len);
@@ -232,9 +239,9 @@
 
 %left '{' '}' '[' ']' ';' '=' '(' ')' '.'
 
-%token STRUCT TYPEDEF UCHAR U16 U32 U64
-%token <sval>	NAME NUM CHAR
-%token <ival>	VAR CMPLX
+%token STRUCT TYPEDEF ENUM UCHAR U16 U32 U64
+%token <sval>	NAME
+%token <ival>	NUM CMPLX
 
 %%
 
@@ -252,12 +259,8 @@
 num:
 	NUM
 	{
-		$$ = atoi($1);
+		$$ = $1;
 	}
-|	VAR
-	{
-		$$ = defs[$1].val;
-	}
 
 type:
 	UCHAR
@@ -293,6 +296,8 @@
 	TYPEDEF STRUCT name name sem
 |	STRUCT name '{' members '}' sem
 	{
+		if(!donebyteprint)
+			byteprint();
 		cprint($2);
 		defs[ndef].name = $2;
 		defs[ndef].type = TCmplx;
@@ -300,12 +305,9 @@
 		ntobe = 0;
 		ndef++;
 	}
-|	name '=' num sem
+|	ENUM '{' emembers '}' sem
 	{
-		defs[ndef].name = $1;
-		defs[ndef].type = TNum;
-		defs[ndef].val = $3;
-		ndef++;
+		nextenumval = 0;
 	}
 
 members:
@@ -316,8 +318,7 @@
 	type name sem
 	{
 		tobe[ntobe].name = $2;
-		tobe[ntobe].len = $1.val;
-		tobe[ntobe].count = 1;
+		tobe[ntobe].len = 1;
 		tobe[ntobe].sym = $1;
 		ntobe++;
 	}
@@ -325,20 +326,31 @@
 	{
 		tobe[ntobe].name = $2;
 		tobe[ntobe].len = $4;
-		tobe[ntobe].count = $4;
 		tobe[ntobe].sym = $1;
 		ntobe++;
 	}
-|	type name '[' '.' name ']' sem
-	{
 
-		tobe[ntobe].name = $2;
-		tobe[ntobe].len = 0;
-		$1.type = TVLA;
-		$1.from = $5;
-		tobe[ntobe].sym = $1;
-		ntobe++;
+emembers:
+	emembers emember
+|	emember
+
+emember:
+	name '=' num
+	{
+		defs[ndef].name = $1;
+		defs[ndef].type = TEnum;
+		defs[ndef].val = $3;
+		nextenumval = $3+1;
+		ndef++;
 	}
+|	name
+	{
+		defs[ndef].name = $1;
+		defs[ndef].type = TEnum;
+		defs[ndef].val = nextenumval;
+		nextenumval++;
+		ndef++;
+	}
 
 %%
 
@@ -372,11 +384,71 @@
 	exits(s);
 }
 
+void
+wordlex(char *dst, int n)
+{
+	int c;
+
+	while(--n > 0){
+		c = getch();
+		if((c >= Runeself)
+		|| (c == '_')
+		|| (c == ':')
+		|| isalnum(c)){
+			*dst++ = c;
+			continue;
+		}
+		ungetc();
+		break;
+	}
+	if(n <= 0)
+		yyerror("symbol buffer overrun");
+	*dst = '\0';
+}
+
 int
+praglex(void)
+{
+	char buf[200];
+	int i;
+	int newmode;
+	char *wordtab[] = {
+		"pragma",
+		"dfc",
+	};
+
+	for(i = 0; i < nelem(wordtab); i++){
+		wordlex(buf, sizeof buf - 1);
+		if(strcmp(buf, wordtab[i]) != 0)
+			return 0;
+		if(getch() != ' '){
+			ungetc();
+			return 0;
+		}
+	}
+
+	wordlex(buf, sizeof buf - 1);
+	if(strcmp(buf, "big") == 0)
+		newmode = Big;
+	else if(strcmp(buf, "little") == 0)
+		newmode = Little;
+	else if(strcmp(buf, "done") == 0){
+		goteof = 1;
+		return -1;
+	} else
+		return 0;
+
+	if(ordermode != newmode){
+		ordermode = newmode;
+		byteprint();
+	}
+	return 0;
+}
+
+int
 yylex(void)
 {
 	static char buf[200];
-	char *p;
 	int c;
 	int i;
 
@@ -388,6 +460,7 @@
 	case ' ':
 	case '\t':
 	case '\n':
+	case ',':
 		goto Loop;
 	case '/':
 		if(getch() != '*'){
@@ -404,6 +477,8 @@
 			goto Loop;
 		goto More;
 	case '#':
+		if(praglex() < 0)
+			return -1;
 		while((c = getch()) > 0)
 			if(c == '\n')
 				break;
@@ -415,27 +490,11 @@
 	case '{': case '}':
 	case '[': case ']':
 	case '(': case ')':
-	case '.':
 		return c;
 	}
 
 	ungetc();
-	p = buf;
-	for(;;){
-		c = getch();
-		if((c >= Runeself)
-		|| (c == '_')
-		|| (c == ':')
-		|| (c >= 'a' && c <= 'z')
-		|| (c >= 'A' && c <= 'Z')
-		|| (c >= '0' && c <= '9')){
-			*p++ = c;
-			continue;
-		}
-		ungetc();
-		break;
-	}
-	*p = '\0';
+	wordlex(buf, sizeof buf);
 
 	if(strcmp(buf, "struct") == 0)
 		return STRUCT;
@@ -449,16 +508,27 @@
 		return U32;
 	if(strcmp(buf, "u64int") == 0)
 		return U64;
+	if(strcmp(buf, "enum") == 0)
+		return ENUM;
 
 	for(i = 0; i < ndef; i++){
 		if(strcmp(buf, defs[i].name) != 0)
 			continue;
-		yylval.ival = i;
-		return defs[i].type == TNum ? VAR : CMPLX;
+		if(defs[i].type == TCmplx){
+			yylval.ival = i;
+			return CMPLX;
+		}
+		yylval.ival = defs[i].val;
+		return NUM;
 	}
 
+	if(isdigit(buf[0])){
+		yylval.ival = atoi(buf);
+		return NUM;
+	}
+
 	yylval.sval = strdup(buf);
-	return (buf[0] >= '0' && buf[0] <= '9') ? NUM : NAME;
+	return NAME;
 }
 
 void
@@ -487,7 +557,6 @@
 	bin = Bopen(argv[0], OREAD);
 	goteof = 0;
 	print("#include <u.h>\n#include <libc.h>\n#include \"%s\"\n\n", argv[0]);
-	byteprint();
 	while(!goteof)
 		yyparse();
 	Bterm(bin);