commit 7c54bc436fdb3050a031a335afcb1dd0e9cf3b18 from: Benjamin Stürz date: Wed Jul 31 09:09:36 2024 UTC add expr 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; + } +} + +