work on type inference some more
[ccc.git] / sem / hm / gamma.c
diff --git a/sem/hm/gamma.c b/sem/hm/gamma.c
new file mode 100644 (file)
index 0000000..9a97c27
--- /dev/null
@@ -0,0 +1,62 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "../hm.h"
+
+struct gamma *gamma_init()
+{
+       struct gamma *gamma = safe_malloc(sizeof(struct gamma));
+       gamma->fresh = 0;
+       gamma->nschemes = 0;
+       gamma->vars = NULL;
+       gamma->schemes = NULL;
+       return gamma;
+}
+
+void gamma_insert(struct gamma *gamma, char *ident, struct scheme *scheme)
+{
+       gamma->nschemes++;
+       gamma->vars = realloc(gamma->vars, gamma->nschemes*sizeof(char *));
+       gamma->schemes = realloc(gamma->schemes,
+               gamma->nschemes*sizeof(struct scheme *));
+       gamma->vars[gamma->nschemes-1] = safe_strdup(ident);
+       gamma->schemes[gamma->nschemes-1] = scheme;
+}
+
+struct scheme *gamma_lookup(struct gamma *gamma, char *ident)
+{
+       for (int i = 0; i<gamma->nschemes; i++)
+               if (strcmp(ident, gamma->vars[i]) == 0)
+                       return gamma->schemes[i];
+       return NULL;
+}
+
+struct type *gamma_fresh(struct gamma *gamma)
+{
+       char buf[10] = {0};
+       sprintf(buf, "%d", gamma->fresh++);
+       return type_var(safe_strdup(buf));
+}
+
+void gamma_print(struct gamma *gamma, FILE *out)
+{
+       fprintf(out, "{");
+       for (int i = 0; i<gamma->nschemes; i++) {
+               fprintf(out, "%s=", gamma->vars[i]);
+               scheme_print(gamma->schemes[i], out);
+               if (i + 1 < gamma->nschemes)
+                       fprintf(out, ", ");
+       }
+       fprintf(out, "}");
+}
+
+void gamma_free(struct gamma *gamma)
+{
+       for (int i = 0; i<gamma->nschemes; i++) {
+               free(gamma->vars[i]);
+               scheme_free(gamma->schemes[i]);
+       }
+       free(gamma->vars);
+       free(gamma->schemes);
+       free(gamma);
+}