Commit Diff


commit - 25724ab6eacd8fbd40a60cad41920e8d56af27a6
commit + 7c54bc436fdb3050a031a335afcb1dd0e9cf3b18
blob - c22c130e9304ebbc5923980b54a497b522baa3e4
blob + 4628ff93e7f7753e161d942776e0131e286338e3
--- lex.l
+++ lex.l
@@ -11,31 +11,35 @@ void yyerror (const char *, ...);
 %option noyywrap
 
 IDENT		[a-zA-Z_][a-zA-Z0-9_]*
-INT		0|[1-9][0-9]*
 
 %%
 
-[ \t\r\n\f]+	;
-[:;,{}\[\]]	return *yytext;
+[ \t\r\n\f]+		;
+[:;,(){}\[\]+*/-]	return *yytext;
 
-struct		return STRUCT;
-union		return UNION;
-if		return IF;
-i8		return I8;
-i16		return I16;
-i32		return I32;
-i64		return I64;
-u8		return U8;
-u16		return U16;
-u32		return U32;
-u64		return U64;
+sizeof			return SIZEOF;
+struct			return STRUCT;
+union			return UNION;
+const			return CONST;
+if			return IF;
+i8			return I8;
+i16			return I16;
+i32			return I32;
+i64			return I64;
+u8			return U8;
+u16			return U16;
+u32			return U32;
+u64			return U64;
 
-==		return EQ;
+==			return EQ;
 
-{IDENT}		yylval.s = strdup (yytext); return IDENT;
-{INT}		yylval.i = atoi (yytext); return INT;
+{IDENT}			yylval.s = strdup (yytext); return IDENT;
+[1-9][0-9]*		yylval.i = strtol (yytext, NULL, 10); return INT;
+0[xX][0-9a-fA-F]+	yylval.i = strtol (yytext + 2, NULL, 16); return INT;
+0[bB][01]+		yylval.i = strtol (yytext + 2, NULL, 2); return INT;
+0[0-7]*			yylval.i = strtol (yytext, NULL, 8); return INT;
 
-.		yyerror ("invalid input: '%c'", *yytext);
+.			yyerror ("invalid input: '%c'", *yytext);
 
 %%
 
blob - 3bf7f55332f92d2e9c896eae8ba728032009a799
blob + 7036f7a1d62e2683fafdb50f85224289e2a6156b
--- parse.y
+++ parse.y
@@ -7,7 +7,7 @@ void yyerror (const char *, ...);
 %}
 
 %token IDENT, INT
-%token STRUCT, UNION, IF, EQ
+%token SIZEOF, STRUCT, UNION, CONST, IF, EQ
 %token I8, I16, I32, I64, U8, U16, U32, U64
 
 %union {
@@ -55,7 +55,7 @@ type		: I8					{ type_simple (&$$, T_I8); }
 		| U16					{ type_simple (&$$, T_U16); }
 		| U32					{ type_simple (&$$, T_U32); }
 		| U64					{ type_simple (&$$, T_U64); }
-		| '[' type ';' INT ']'			{ type_array (&$$, $2.ty, $4.i); }
+		| '[' 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); }
@@ -75,6 +75,28 @@ value		: IDENT					{ val_name (&$$, $1.s); }
 cond		: IDENT EQ value			{ cond_cmp (&$$, $1.s, $3.val); }
       		;
 
+expr		: add					{ $$ = $1; }
+      		;
+
+add		: add '+' mult				{ $$.i = $1.i + $3.i; }
+     		| add '-' mult				{ $$.i = $1.i - $3.i; }
+		| mult					{ $$ = $1; }
+		;
+
+mult		: mult '*' unary			{ $$.i = $1.i * $3.i; }
+      		| mult '/' unary			{ $$.i = $1.i / $3.i; }
+		| unary					{ $$ = $1; }
+		;
+
+unary		: '-' unary				{ $$.i = -$2.i; }
+       		| atom					{ $$ = $1; }
+		;
+
+atom		: INT					{ $$.i = $1.i; }
+      		| SIZEOF '(' type ')'			{ $$.i = sizeof_type ($3.ty); }
+      		| '(' expr ')'				{ $$ = $2; }
+		;
+
 %%
 
 #define new(T) ((T *)malloc (sizeof (T)))
@@ -196,3 +218,42 @@ void type_union (YYSTYPE *y, YYSTYPE *i)
 	y->ty->type = T_UNION;
 	y->ty->un = list_fin (i);
 }
+
+int sizeof_type (const struct type *ty)
+{
+	int x = 0;
+
+	switch (ty->type) {
+	case T_I8:
+	case T_U8:
+		return 1;
+	case T_I16:
+	case T_U16:
+		return 2;
+	case T_I32:
+	case T_U32:
+		return 4;
+	case T_I64:
+	case T_U64:
+		return 8;
+	case T_ARRAY:
+		return ty->len * sizeof_type (ty->inner);
+	case T_NAME:
+		yyerror ("sizeof (name) is not supported");
+		return -1;
+	case T_STRUCT:
+		for (struct item **it = ty->st->items; *it != NULL; ++it) {
+			x += sizeof_type ((*it)->type);
+		}
+		return x;
+	case T_UNION:
+		for (struct uitem **ui = ty->un; *ui != NULL; ++ui) {
+			int z = sizeof_type ((*ui)->type);
+			if (z > x)
+				z = x;
+		}
+		return x;
+	}
+}
+
+