strongly connected components
[ccc.git] / ast.c
diff --git a/ast.c b/ast.c
index 72af738..bb8a541 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -36,20 +36,23 @@ struct vardecl *vardecl(struct type *type, char *ident, struct expr *expr)
        res->expr = expr;
        return res;
 }
-
-struct decl *decl_fun(char *ident, struct list *args, struct list *atypes,
+struct fundecl *fundecl(char *ident, struct list *args, struct list *atypes,
        struct type *rtype, struct list *body)
+{
+       struct fundecl *res = safe_malloc(sizeof(struct fundecl));
+       res->ident = ident;
+       res->args = (char **)list_to_array(args, &res->nargs, true);
+       res->atypes = (struct type **)list_to_array(atypes, &res->natypes, true);
+       res->rtype = rtype;
+       res->body = (struct stmt **)list_to_array(body, &res->nbody, true);
+       return res;
+}
+
+struct decl *decl_fun(struct fundecl *fundecl)
 {
        struct decl *res = safe_malloc(sizeof(struct decl));
        res->type = dfundecl;
-       res->data.dfun.ident = ident;
-       res->data.dfun.args = (char **)
-               list_to_array(args, &res->data.dfun.nargs, true);
-       res->data.dfun.atypes = (struct type **)
-               list_to_array(atypes, &res->data.dfun.natypes, true);
-       res->data.dfun.rtype = rtype;
-       res->data.dfun.body = (struct stmt **)
-               list_to_array(body, &res->data.dfun.nbody, true);
+       res->data.dfun = fundecl;
        return res;
 }
 
@@ -305,39 +308,46 @@ void vardecl_print(struct vardecl *decl, int indent, FILE *out)
        safe_fprintf(out, ";\n");
 }
 
+void fundecl_print(struct fundecl *decl, FILE *out)
+{
+       safe_fprintf(out, "%s (", decl->ident);
+       for (int i = 0; i<decl->nargs; i++) {
+               safe_fprintf(out, "%s", decl->args[i]);
+               if (i < decl->nargs - 1)
+                       safe_fprintf(out, ", ");
+       }
+       safe_fprintf(out, ")");
+       if (decl->rtype != NULL) {
+               safe_fprintf(out, " :: ");
+               for (int i = 0; i<decl->natypes; i++) {
+                       type_print(decl->atypes[i], out);
+                       safe_fprintf(out, " ");
+               }
+               safe_fprintf(out, "-> ");
+               type_print(decl->rtype, out);
+       }
+       safe_fprintf(out, " {\n");
+       for (int i = 0; i<decl->nbody; i++)
+               stmt_print(decl->body[i], 1, out);
+       safe_fprintf(out, "}\n");
+}
+
 void decl_print(struct decl *decl, FILE *out)
 {
        if (decl == NULL)
                return;
        switch(decl->type) {
        case dfundecl:
-               safe_fprintf(out, "%s (", decl->data.dfun.ident);
-               for (int i = 0; i<decl->data.dfun.nargs; i++) {
-                       safe_fprintf(out, "%s", decl->data.dfun.args[i]);
-                       if (i < decl->data.dfun.nargs - 1)
-                               safe_fprintf(out, ", ");
-               }
-               safe_fprintf(out, ")");
-               if (decl->data.dfun.rtype != NULL) {
-                       safe_fprintf(out, " :: ");
-                       for (int i = 0; i<decl->data.dfun.natypes; i++) {
-                               type_print(decl->data.dfun.atypes[i], out);
-                               safe_fprintf(out, " ");
-                       }
-                       safe_fprintf(out, "-> ");
-                       type_print(decl->data.dfun.rtype, out);
-               }
-               safe_fprintf(out, " {\n");
-               for (int i = 0; i<decl->data.dfun.nbody; i++)
-                       stmt_print(decl->data.dfun.body[i], 1, out);
-               safe_fprintf(out, "}\n");
+               fundecl_print(decl->data.dfun, out);
                break;
        case dvardecl:
                vardecl_print(decl->data.dvar, 0, out);
                break;
-       case dcomponent:
-               for (int i = 0; i<decl->data.dcomponent.ndecls; i++)
-                       decl_print(decl, out);
+       case dcomp:
+               fprintf(out, "//<<<comp\n");
+               for (int i = 0; i<decl->data.dcomp.ndecls; i++)
+                       fundecl_print(decl->data.dcomp.decls[i], out);
+               fprintf(out, "//>>>comp\n");
                break;
        default:
                die("Unsupported decl node\n");
@@ -515,28 +525,34 @@ void vardecl_free(struct vardecl *decl)
        free(decl);
 }
 
+void fundecl_free(struct fundecl *decl)
+{
+       free(decl->ident);
+       for (int i = 0; i<decl->nargs; i++)
+               free(decl->args[i]);
+       free(decl->args);
+       for (int i = 0; i<decl->natypes; i++)
+               type_free(decl->atypes[i]);
+       free(decl->atypes);
+       type_free(decl->rtype);
+       for (int i = 0; i<decl->nbody; i++)
+               stmt_free(decl->body[i]);
+       free(decl->body);
+       free(decl);
+}
+
 void decl_free(struct decl *decl)
 {
        if (decl == NULL)
                return;
        switch(decl->type) {
-       case dcomponent:
-               for (int i = 0; i<decl->data.dcomponent.ndecls; i++)
-                       decl_free(decl->data.dcomponent.decls[i]);
-               free(decl->data.dcomponent.decls);
+       case dcomp:
+               for (int i = 0; i<decl->data.dcomp.ndecls; i++)
+                       fundecl_free(decl->data.dcomp.decls[i]);
+               free(decl->data.dcomp.decls);
                break;
        case dfundecl:
-               free(decl->data.dfun.ident);
-               for (int i = 0; i<decl->data.dfun.nargs; i++)
-                       free(decl->data.dfun.args[i]);
-               free(decl->data.dfun.args);
-               for (int i = 0; i<decl->data.dfun.natypes; i++)
-                       type_free(decl->data.dfun.atypes[i]);
-               free(decl->data.dfun.atypes);
-               type_free(decl->data.dfun.rtype);
-               for (int i = 0; i<decl->data.dfun.nbody; i++)
-                       stmt_free(decl->data.dfun.body[i]);
-               free(decl->data.dfun.body);
+               fundecl_free(decl->data.dfun);
                break;
        case dvardecl:
                vardecl_free(decl->data.dvar);