#include "util.h"
#include "ast.h"
+#include "type.h"
+#include "list.h"
#include "parse.h"
const char *binop_str[] = {
const char *fieldspec_str[] = {
[fst] = "fst", [snd] = "snd", [hd] = "hd", [tl] = "tl"};
const char *unop_str[] = { [inverse] = "!", [negate] = "-", };
-static const char *basictype_str[] = {
- [btbool] = "Bool", [btchar] = "Char", [btint] = "Int",
- [btvoid] = "Void",
-};
struct ast *ast(struct list *decls)
{
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;
}
return res;
}
-struct type *type_basic(enum basictype type)
-{
- struct type *res = safe_malloc(sizeof(struct type));
- res->type = tbasic;
- res->data.tbasic = type;
- return res;
-}
-
-struct type *type_list(struct type *type)
-{
- struct type *res = safe_malloc(sizeof(struct type));
- res->type = tlist;
- res->data.tlist = type;
- return res;
-}
-
-struct type *type_tuple(struct type *l, struct type *r)
-{
- struct type *res = safe_malloc(sizeof(struct type));
- res->type = ttuple;
- res->data.ttuple.l = l;
- res->data.ttuple.r = r;
- return res;
-}
-
-struct type *type_var(char *ident)
-{
- struct type *res = safe_malloc(sizeof(struct type));
- if (strcmp(ident, "Int") == 0) {
- res->type = tbasic;
- res->data.tbasic = btint;
- free(ident);
- } else if (strcmp(ident, "Char") == 0) {
- res->type = tbasic;
- res->data.tbasic = btchar;
- free(ident);
- } else if (strcmp(ident, "Bool") == 0) {
- res->type = tbasic;
- res->data.tbasic = btbool;
- free(ident);
- } else if (strcmp(ident, "Void") == 0) {
- res->type = tbasic;
- res->data.tbasic = btvoid;
- free(ident);
- } else {
- res->type = tvar;
- res->data.tvar = ident;
- }
- return res;
-}
-
void ast_print(struct ast *ast, FILE *out)
{
if (ast == NULL)
return;
for (int i = 0; i<ast->ndecls; i++)
- decl_print(ast->decls[i], 0, out);
+ decl_print(ast->decls[i], out);
}
void vardecl_print(struct vardecl *decl, int indent, FILE *out)
safe_fprintf(out, ";\n");
}
-void decl_print(struct decl *decl, int indent, FILE *out)
+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:
- pindent(indent, out);
- 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], indent+1, out);
- pindent(indent, out);
- safe_fprintf(out, "}\n");
+ fundecl_print(decl->data.dfun, out);
break;
case dvardecl:
- vardecl_print(decl->data.dvar, indent, out);
+ vardecl_print(decl->data.dvar, 0, out);
+ break;
+ 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");
}
}
-void type_print(struct type *type, FILE *out)
-{
- if (type == NULL)
- return;
- switch (type->type) {
- case tbasic:
- safe_fprintf(out, "%s", basictype_str[type->data.tbasic]);
- break;
- case tlist:
- safe_fprintf(out, "[");
- type_print(type->data.tlist, out);
- safe_fprintf(out, "]");
- break;
- case ttuple:
- safe_fprintf(out, "(");
- type_print(type->data.ttuple.l, out);
- safe_fprintf(out, ",");
- type_print(type->data.ttuple.r, out);
- safe_fprintf(out, ")");
- break;
- case tvar:
- safe_fprintf(out, "%s", type->data.tvar);
- break;
- default:
- die("Unsupported type node\n");
- }
-}
-
void ast_free(struct ast *ast)
{
if (ast == NULL)
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 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);
}
free(expr);
}
-
-void type_free(struct type *type)
-{
- if (type == NULL)
- return;
- switch (type->type) {
- case tbasic:
- break;
- case tlist:
- type_free(type->data.tlist);
- break;
- case ttuple:
- type_free(type->data.ttuple.l);
- type_free(type->data.ttuple.r);
- break;
- case tvar:
- free(type->data.tvar);
- break;
- default:
- die("Unsupported type node\n");
- }
- free(type);
-}