commit - 25724ab6eacd8fbd40a60cad41920e8d56af27a6
commit + 7c54bc436fdb3050a031a335afcb1dd0e9cf3b18
blob - c22c130e9304ebbc5923980b54a497b522baa3e4
blob + 4628ff93e7f7753e161d942776e0131e286338e3
--- lex.l
+++ lex.l
%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
%}
%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 {
| 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); }
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)))
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;
+ }
+}
+
+