commit a3884752fe0ed1480d2598d0a64e392ec63752a0 from: Benjamin Stürz date: Tue Nov 19 21:00:08 2024 UTC cc1: initial parsing of statements commit - ade78a5f9f5e649c90b9bb8e5918160917006f44 commit + a3884752fe0ed1480d2598d0a64e392ec63752a0 blob - 0db286cf173161bf9362647488bc470501f3bfff blob + 98d806e4a17ac8e5eb6474d197054837888b50ef --- cc/cc1/cc1.h +++ cc/cc1/cc1.h @@ -106,6 +106,21 @@ struct expr { }; }; +enum stmt_type { + ST_NULL, + ST_EXPR, + ST_LABEL, +}; + +struct stmt { + enum stmt_type type; + + union { + struct expr *ex; + char ident[IDENT_LEN + 1]; + }; +}; + struct ident_list { struct ident_list *next; char ident[IDENT_LEN + 1]; @@ -153,6 +168,7 @@ struct function { struct dtype *dt; char ident[IDENT_LEN + 1]; struct symbol *ahead, *vhead; + struct stmt **body; }; extern struct scope gscope, fscope; blob - e90576b48966c8706baea746ace9933b8a6093d0 blob + b2e78d9a6918ed04ddf2726764cbd96430e3f972 --- cc/cc1/gen.c +++ cc/cc1/gen.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "cc1.h" int reg; @@ -124,10 +125,26 @@ struct expr *e; return r; } +gen_stmt (st) +struct stmt *st; +{ + switch (st->type) { + case ST_NULL: + puts ("\t# ;"); + break; + case ST_EXPR: + case ST_LABEL: + errx (1, "TODO: gen_stmt()"); + break; + } + return 0; +} + gen_fn (fn) struct function *fn; { struct symbol *sym; + struct stmt **st; int r, ch; for (sym = fn->ahead; sym != NULL; sym = sym->xnext) @@ -194,6 +211,10 @@ struct function *fn; // TODO: define static variables + for (st = fn->body; *st != NULL; ++st) { + gen_stmt (*st); + } + printf ("}\n\n"); return 0; blob - ef383a1ff5f3b978173811ca2c69adfd5ab7bf26 blob + 3dd3f14de96292b938a521ffe2640fb793d20be1 --- cc/cc1/parse.y +++ cc/cc1/parse.y @@ -16,12 +16,17 @@ struct decl_init *di; struct decls_list *dd; struct expr *ex; + struct stmt *st; int i; struct { struct decls_list *dd; - // stmts + struct stmt **st; } fb; + struct list { + void **ptr; + size_t cap, len; + } lst; }; %token INTEGER @@ -47,10 +52,12 @@ %type initializer %type init_decl decl_list %type expression +%type statement %type ident_list %type
decls_list decls_list_opt %type fbody %type function +%type stmts %% @@ -59,17 +66,21 @@ file : file declaration { declare (&$2); } | ; -function : decl_specs declarator decls_list fbody { fn (&$$, &$1, &$2, $3, $4.dd); } - | declarator decls_list fbody { fn (&$$, NULL, &$1, $2, $3.dd); } +function : decl_specs declarator decls_list fbody { fn (&$$, &$1, &$2, $3, $4.dd, $4.st); } + | declarator decls_list fbody { fn (&$$, NULL, &$1, $2, $3.dd, $3.st); } ; ident_list : ident_list ',' IDENT { $$ = il_append ($1, lval.ident); } | IDENT { $$ = il_append (NULL, lval.ident); } ; -fbody : '{' decls_list_opt '}' { $$.dd = $2; } +fbody : '{' decls_list_opt stmts '}' { $$.dd = $2; $$.st = lst_fin (&$3); } ; +stmts : stmts statement { $$ = $1; lst_append (&$$, $2); } + | { lst_new (&$$); } + ; + decls_list_opt : decls_list { $$ = $1; } | { $$ = NULL; } ; @@ -130,6 +141,11 @@ declarator1 : IDENT { $$.type = DL_IDENT; cpident ( initializer : '=' expression { $$.type = IN_EX; $$.ex = $2; } ; +statement : expression ';' { $$ = new (struct stmt); $$->type = ST_EXPR; $$->ex = $1; } + | IDENT ':' { $$ = new (struct stmt); $$->type = ST_LABEL; cpident ($$->ident, lval.ident); } + | ';' { $$ = new (struct stmt); $$->type = ST_NULL; } + ; + expression : INTEGER { $$ = new (struct expr); $$->type = EX_INT; $$->i = lval.i; } ; @@ -138,6 +154,35 @@ expression : INTEGER { $$ = new (struct expr); $$->t static struct dtype default_int = { DT_INT }; +lst_new (lst) +struct list *lst; +{ + lst->len = 0; + lst->cap = 2; + lst->ptr = calloc (lst->cap + 1, sizeof (void *)); + return 0; +} + +lst_append (lst, x) +struct list *lst; +void *x; +{ + if (lst->len == lst->cap) { + lst->cap *= 2; + lst->ptr = reallocarray (lst->ptr, lst->cap + 1, sizeof (void *)); + } + lst->ptr[lst->len++] = x; + return 0; +} + +void * +lst_fin (lst) +struct list *lst; +{ + lst->ptr[lst->len] = NULL; + return lst->ptr; +} + struct ident_list * il_append (head, ident) struct ident_list *head; @@ -326,11 +371,12 @@ char *ident; return NULL; } -fn (fn, ds, dl, args, vars) +fn (fn, ds, dl, args, vars, stmts) struct function *fn; struct decl_spec *ds; struct declarator *dl; struct decls_list *args, *vars; +struct stmt **stmts; { struct symbol *sym, *atail, *vtail; struct decl_init *di; @@ -365,6 +411,7 @@ struct decls_list *args, *vars; fscope.typedefs = fscope.vars = NULL; fn->ahead = atail = NULL; fn->vhead = vtail = NULL; + fn->body = stmts; // declare arguments as implicit int for (il = dl->def.il; il != NULL; il = il->next) { blob - 77857a6ca4c97baeedd323a052bc4ce7b8109c14 blob + 773a67f29a0d5739a1993b2612d86c7fdb18ea39 --- cc/cc1/test.c +++ cc/cc1/test.c @@ -20,6 +20,8 @@ main (argc, argv) char **argv; { int i = 0, j, k = 42; + + ;;; } extern h ();