Commit Diff


commit - 7c54bc436fdb3050a031a335afcb1dd0e9cf3b18
commit + abd55be479e44d41048b64aabe7204a1f771038d
blob - 7036f7a1d62e2683fafdb50f85224289e2a6156b
blob + 6efb98c26c284de343ce321cead165a15b5c25ea
--- parse.y
+++ parse.y
@@ -4,12 +4,28 @@
 
 int yylex (void);
 void yyerror (const char *, ...);
-%}
 
-%token IDENT, INT
-%token SIZEOF, STRUCT, UNION, CONST, IF, EQ
-%token I8, I16, I32, I64, U8, U16, U32, U64
+static struct list file;
 
+struct list list_new (void);
+struct list list_new_with (void *);
+struct list list_push (struct list, void *);
+struct item *item (char *, struct type *);
+struct uitem *uitem (char *, struct type *, struct cond *);
+struct cond *cond_cmp (char *, struct value *);
+struct structure *structure (char *, struct list);
+struct type *type_simple (enum type_type);
+struct type *type_name (char *);
+struct type *type_int (int);
+struct type *type_struct (struct structure *);
+struct type *type_union (struct list);
+struct type *type_array (struct type *, size_t);
+struct value *val_name (char *);
+struct value *val_int (int);
+
+int sizeof_type (const struct type *);
+%}
+
 %union {
 	struct structure *st;
 	struct value *val;
@@ -20,80 +36,100 @@ void yyerror (const char *, ...);
 	char *s;
 	int i;
 
-	struct {
+	struct list {
 		void **ptr;
 		size_t len, cap;
 	} list;
 };
 
+%token <s> IDENT
+%token <i> INT
+%token SIZEOF STRUCT UNION CONST IF EQ
+%token I8 I16 I32 I64 U8 U16 U32 U64
+
+%type <list> file items uitems 
+%type <val> value
+%type <ty> type
+%type <st> struct
+%type <it> item
+%type <ui> uitem
+%type <co> cond
+%type <s> ident
+
+%type <i> expr add mult unary atom
+
 %%
 
-file		: file struct ';'			{ list_push (&$$, &$1, $2.st); }
-      		| struct ';'				{ list_new_with (&$$, $1.st); }
+top		: file					{ file = $1; }
+     		;
+
+
+file		: file struct ';'			{ $$ = list_push ($1, $2); }
+      		| struct ';'				{ $$ = list_new_with ($1); }
 		;
 
-struct		: STRUCT ident '{' items comma '}' 	{ structure (&$$, $2.s, &$4); }
+struct		: STRUCT ident '{' items comma '}' 	{ $$ = structure ($2, $4); }
 		;
 
-ident		: IDENT					{ $$.s = $1.s; }
-       		|					{ $$.s = NULL; }
+ident		: IDENT					{ $$ = $1; }
+       		|					{ $$ = NULL; }
 		;
 
 comma		: ',' | ;
 
-items		: items ',' item			{ list_push (&$$, &$1, $3.it); }
-       		| item					{ list_new_with (&$$, $1.it); }
+items		: items ',' item			{ $$ = list_push ($1, $3); }
+       		| item					{ $$ = list_new_with ($1); }
 
-item		: IDENT ':' type			{ item (&$$, $1.s, $3.ty); }
+item		: IDENT ':' type			{ $$ = item ($1, $3); }
       		;
 
-type		: I8					{ type_simple (&$$, T_I8); }
-		| I16					{ type_simple (&$$, T_I16); }
-		| I32					{ type_simple (&$$, T_I32); }
-		| I64					{ type_simple (&$$, T_I64); }
-		| U8					{ type_simple (&$$, T_U8); }
-		| U16					{ type_simple (&$$, T_U16); }
-		| U32					{ type_simple (&$$, T_U32); }
-		| U64					{ type_simple (&$$, T_U64); }
-		| '[' type ';' expr ']'			{ type_array (&$$, $2.ty, $4.i); }
-		| STRUCT IDENT				{ type_name (&$$, $2.s); }
-		| struct				{ type_struct (&$$, $1.st); }
-		| UNION '{' uitems comma '}'		{ type_union (&$$, &$3); }
+type		: I8					{ $$ = type_simple (T_I8); }
+		| I16					{ $$ = type_simple (T_I16); }
+		| I32					{ $$ = type_simple (T_I32); }
+		| I64					{ $$ = type_simple (T_I64); }
+		| U8					{ $$ = type_simple (T_U8); }
+		| U16					{ $$ = type_simple (T_U16); }
+		| U32					{ $$ = type_simple (T_U32); }
+		| U64					{ $$ = type_simple (T_U64); }
+		| '[' type ';' expr ']'			{ $$ = type_array ($2, $4); }
+		| STRUCT IDENT				{ $$ = type_name ($2); }
+		| struct				{ $$ = type_struct ($1); }
+		| UNION '{' uitems comma '}'		{ $$ = type_union ($3); }
 		;
 
-uitems		: uitems ',' uitem			{ list_push (&$$, &$1, $3.ui); }
-		| uitem					{ list_new_with (&$$, $1.ui); }
+uitems		: uitems ',' uitem			{ $$ = list_push ($1, $3); }
+		| uitem					{ $$ = list_new_with ($1); }
 		;
 
-uitem		: IDENT ':' type IF cond		{ uitem (&$$, $1.s, $3.ty, $5.co); }
+uitem		: IDENT ':' type IF cond		{ $$ = uitem ($1, $3, $5); }
        		;
 
-value		: IDENT					{ val_name (&$$, $1.s); }
-       		| INT					{ val_int (&$$, $1.i); }
+value		: IDENT					{ $$ = val_name ($1); }
+       		| INT					{ $$ = val_int ($1); }
 		;
 
-cond		: IDENT EQ value			{ cond_cmp (&$$, $1.s, $3.val); }
+cond		: IDENT EQ value			{ $$ = cond_cmp ($1, $3); }
       		;
 
 expr		: add					{ $$ = $1; }
       		;
 
-add		: add '+' mult				{ $$.i = $1.i + $3.i; }
-     		| add '-' mult				{ $$.i = $1.i - $3.i; }
+add		: add '+' mult				{ $$ = $1 + $3; }
+     		| add '-' mult				{ $$ = $1 - $3; }
 		| mult					{ $$ = $1; }
 		;
 
-mult		: mult '*' unary			{ $$.i = $1.i * $3.i; }
-      		| mult '/' unary			{ $$.i = $1.i / $3.i; }
+mult		: mult '*' unary			{ $$ = $1 * $3; }
+      		| mult '/' unary			{ $$ = $1 / $3; }
 		| unary					{ $$ = $1; }
 		;
 
-unary		: '-' unary				{ $$.i = -$2.i; }
+unary		: '-' unary				{ $$ = -$2; }
        		| atom					{ $$ = $1; }
 		;
 
-atom		: INT					{ $$.i = $1.i; }
-      		| SIZEOF '(' type ')'			{ $$.i = sizeof_type ($3.ty); }
+atom		: INT					{ $$ = $1; }
+      		| SIZEOF '(' type ')'			{ $$ = sizeof_type ($3); }
       		| '(' expr ')'				{ $$ = $2; }
 		;
 
@@ -101,124 +137,130 @@ atom		: INT					{ $$.i = $1.i; }
 
 #define new(T) ((T *)malloc (sizeof (T)))
 
-void type_simple (YYSTYPE *y, enum type_type type)
+struct list list_new (void)
 {
-	y->ty = new (struct type);
-	y->ty->type = type;
+	struct list l;
+	l.len = 0;
+	l.cap = 10;
+	l.ptr = calloc (l.cap + 1, sizeof (void *));
+	return l;
 }
 
-void type_array (YYSTYPE *y, struct type *inner, size_t len)
+struct list list_new_with (void *e)
 {
-	y->ty = new (struct type);
-	y->ty->type = T_ARRAY;
-	y->ty->inner = inner;
-	y->ty->len = len;
+	struct list l = list_new ();
+	l.len = 1;
+	l.ptr[0] = e;
+	return l;
 }
 
-void type_name (YYSTYPE *y, char *s)
+struct list list_push (struct list l, void *e)
 {
-	y->ty = new (struct type);
-	y->ty->type = T_NAME;
-	y->ty->name = s;
+	if (l.len == l.cap) {
+		l.cap *= 2;
+		l.ptr = reallocarray (l.ptr, l.cap + 1, sizeof (void *));
+	}
+
+	l.ptr[l.len++] = e;
+	return l;
 }
 
-void type_struct (YYSTYPE *y, struct structure *st)
+void *list_fin (struct list l)
 {
-	y->ty = new (struct type);
-	y->ty->type = T_STRUCT;
-	y->ty->st = st;
+	l.ptr[l.len] = NULL;
+	return l.ptr;
 }
 
-void item (YYSTYPE *y, char *name, struct type *type)
+struct type *type_simple (enum type_type type)
 {
-	y->it = new (struct item);
-	y->it->name = name;
-	y->it->type = type;
+	struct type *ty = new (struct type);
+	ty->type = type;
+	return ty;
 }
 
-void list_new (YYSTYPE *y)
+struct type *type_array (struct type *inner, size_t len)
 {
-	y->list.len = 0;
-	y->list.cap = 10;
-	y->list.ptr = calloc (y->list.cap + 1, sizeof (void *));
+	struct type *ty = new (struct type);
+	ty->type = T_ARRAY;
+	ty->inner = inner;
+	ty->len = len;
+	return ty;
 }
 
-void list_new_with (YYSTYPE *y, void *e)
+struct type *type_name (char *s)
 {
-	list_new (y);
-	y->list.len = 1;
-	y->list.ptr[0] = e;
+	struct type *ty = new (struct type);
+	ty->type = T_NAME;
+	ty->name = s;
+	return ty;
 }
 
-void list_push (YYSTYPE *y, YYSTYPE *o, void *e)
+struct type *type_struct (struct structure *st)
 {
-	*y = *o;
-	if (y->list.len == y->list.cap) {
-		y->list.cap *= 2;
-		y->list.ptr = reallocarray (y->list.ptr, y->list.cap + 1, sizeof (void *));
-	}
-
-	y->list.ptr[y->list.len++] = e;
+	struct type *ty = new (struct type);
+	ty->type = T_STRUCT;
+	ty->st = st;
+	return ty;
 }
 
-void *list_fin (YYSTYPE *y)
+struct type *type_union (struct list items)
 {
-	y->list.ptr[y->list.len] = NULL;
-	return y->list.ptr;
+	struct type *ty = new (struct type);
+	ty->type = T_UNION;
+	ty->un = list_fin (items);
+	return ty;
 }
 
-void structure (YYSTYPE *y, char *name, YYSTYPE *items)
+struct item *item (char *name, struct type *type)
 {
-	y->st = new (struct structure);
-	y->st->name = name;
-	y->st->items = list_fin (items);
+	struct item *it = new (struct item);
+	it->name = name;
+	it->type = type;
+	return it;
 }
 
-struct structure **parse (void)
+struct structure *structure (char *name, struct list items)
 {
-	if (yyparse () != 0)
-		return NULL;
-
-	return list_fin (&yyval);
+	struct structure *st = new (struct structure);
+	st->name = name;
+	st->items = list_fin (items);
+	return st;
 }
 
-void val_name (YYSTYPE *y, char *name)
+struct value *val_name (char *name)
 {
-	y->val = new (struct value);
-	y->val->type = V_NAME;
-	y->val->s = name;
+	struct value *val = new (struct value);
+	val->type = V_NAME;
+	val->s = name;
+	return val;
 }
 
-void val_int (YYSTYPE *y, int i)
+struct value *val_int (int i)
 {
-	y->val = new (struct value);
-	y->val->type = V_INT;
-	y->val->i = i;
+	struct value *val = new (struct value);
+	val->type = V_INT;
+	val->i = i;
+	return val;
 }
 
-void cond_cmp (YYSTYPE *y, char *l, struct value *r)
+struct cond *cond_cmp (char *l, struct value *r)
 {
-	y->co = new (struct cond);
-	y->co->type = C_EQ;
-	y->co->cmp.left = l;
-	y->co->cmp.right = r;
+	struct cond *co = new (struct cond);
+	co->type = C_EQ;
+	co->cmp.left = l;
+	co->cmp.right = r;
+	return co;
 }
 
-void uitem (YYSTYPE *y, char *name, struct type *type, struct cond *co)
+struct uitem *uitem (char *name, struct type *type, struct cond *co)
 {
-	y->ui = new (struct uitem);
-	y->ui->name = name;
-	y->ui->type = type;
-	y->ui->cond = co;
+	struct uitem *ui = new (struct uitem);
+	ui->name = name;
+	ui->type = type;
+	ui->cond = co;
+	return ui;
 }
 
-void type_union (YYSTYPE *y, YYSTYPE *i)
-{
-	y->ty = new (struct type);
-	y->ty->type = T_UNION;
-	y->ty->un = list_fin (i);
-}
-
 int sizeof_type (const struct type *ty)
 {
 	int x = 0;
@@ -253,7 +295,16 @@ int sizeof_type (const struct type *ty)
 				z = x;
 		}
 		return x;
+	default:
+		abort ();
 	}
 }
 
+struct structure **parse (void)
+{
+	if (yyparse () != 0)
+		return NULL;
 
+	return list_fin (file);
+}
+