log-e-sappho/src/spho/tp.c

255 lines
4.6 KiB
C

#include <sys/queue.h>
#include <stdlib.h>
#include "spho/ctx.h"
#include "spho/scope.h"
#include "spho/tp.h"
const struct tp_konst_data tp_konst_true = { TP_KONST_KEY_TRUE, "True" };
const struct tp_konst_data tp_konst_false = { TP_KONST_KEY_FALSE, "False" };
//struct spho_tp *
//spho_tp_create_disj(struct spho_ctx *, struct spho_tp *, struct spho_tp *,
// struct spho_tp *)
//{
//
//}
static struct spho_tp *
spho_tp_alloc(struct spho_scope *sc)
{
struct spho_tp_alloc *tp_alloc;
if ((tp_alloc = calloc(1, sizeof(*tp_alloc))) == NULL) {
SPHO_SC_ERR(sc, SPHO_ERR_SYS);
return (NULL);
}
((struct spho_tp *)tp_alloc)->sc = sc;
TAILQ_INSERT_TAIL(&sc->tps, tp_alloc, allocs);
return ((struct spho_tp *)tp_alloc);
}
static void
spho_tp_free(struct spho_tp *tp)
{
struct spho_scope *sc;
struct spho_tp_alloc *tp_alloc;
sc = tp->sc;
tp_alloc = (struct spho_tp_alloc *)tp;
TAILQ_REMOVE(&sc->tps, tp_alloc, allocs);
free(tp_alloc);
}
struct spho_tp *
spho_tp_create_conj(struct spho_scope *sc, struct spho_tp *ltp,
struct spho_tp *rtp)
{
struct spho_tp *tp;
if ((tp = spho_tp_alloc(sc)) == NULL)
return (NULL);
tp->form = SPHO_TP_FORM_CONJ;
tp->d.binop.left = ltp;
tp->d.binop.right = rtp;
return (tp);
}
struct spho_tp *
spho_tp_create_disj(struct spho_scope *sc, struct spho_tp *ltp,
struct spho_tp *rtp)
{
struct spho_tp *tp;
if ((tp = spho_tp_alloc(sc)) == NULL)
return (NULL);
tp->form = SPHO_TP_FORM_DISJ;
tp->d.binop.left = ltp;
tp->d.binop.right = rtp;
return (tp);
}
struct spho_tp *
spho_tp_create_impl(struct spho_scope *sc, struct spho_tp *ltp,
struct spho_tp *rtp)
{
struct spho_tp *tp;
if ((tp = spho_tp_alloc(sc)) == NULL)
return (NULL);
tp->form = SPHO_TP_FORM_IMPL;
tp->d.binop.left = ltp;
tp->d.binop.right = rtp;
return (tp);
}
struct spho_tp *
spho_tp_create_arrow(struct spho_scope *sc, struct spho_tp *ltp,
struct spho_tp *rtp)
{
struct spho_tp *tp;
if ((tp = spho_tp_alloc(sc)) == NULL)
return (NULL);
tp->form = SPHO_TP_FORM_ARROW;
tp->d.binop.left = ltp;
tp->d.binop.right = rtp;
return (tp);
}
struct spho_tp *
spho_tp_create_box(struct spho_scope *sc, struct spho_tp *inner)
{
struct spho_tp *tp;
if ((tp = spho_tp_alloc(sc)) == NULL)
return (NULL);
tp->form = SPHO_TP_FORM_BOX;
tp->d.unop.operand = inner;
return (tp);
}
struct spho_tp *
spho_tp_create_forall(struct spho_scope *sc, struct spho_nom *nom,
struct spho_tp *tp)
{
struct spho_tp *ret;
if ((ret = spho_tp_alloc(sc)) == NULL)
return (NULL);
ret->form = SPHO_TP_FORM_FORALL;
ret->d.bind.nom = nom;
ret->d.bind.bound = tp;
return (ret);
}
struct spho_tp *
spho_tp_create_true(struct spho_scope *sc)
{
struct spho_tp *ret;
if ((ret = spho_tp_alloc(sc)) == NULL)
return (NULL);
ret->form = SPHO_TP_FORM_TRUE;
ret->d.konst = tp_konst_true;
return (ret);
}
struct spho_tp *
spho_tp_create_false(struct spho_scope *sc)
{
struct spho_tp *ret;
if ((ret = spho_tp_alloc(sc)) == NULL)
return (NULL);
ret->form = SPHO_TP_FORM_FALSE;
ret->d.konst = tp_konst_false;
return (ret);
}
struct spho_tp *
spho_tp_create_name(struct spho_scope *sc, struct spho_nom *nom)
{
struct spho_tp *ret;
if ((ret = spho_tp_alloc(sc)) == NULL)
return (NULL);
ret->form = SPHO_TP_FORM_NOM;
ret->d.nom.nom = nom;
return (ret);
}
struct spho_tp *
spho_tp_create_appl(struct spho_scope *sc, struct spho_nom *nom,
struct spho_tp_l *args)
{
struct spho_tp *ret;
if ((ret = spho_tp_alloc(sc)) == NULL)
return (NULL);
ret->form = SPHO_TP_FORM_APPL;
ret->d.appl.nom = nom;
ret->d.appl.args = args;
return (ret);
}
struct spho_tp *
spho_tp_create_member(struct spho_scope *sc, struct spho_nom *nom,
struct spho_tp *tp)
{
struct spho_tp *ret;
if ((ret = spho_tp_alloc(sc)) == NULL)
return (NULL);
ret->form = SPHO_TP_FORM_MEMBER;
ret->d.bind.nom = nom;
ret->d.bind.bound = tp;
return (ret);
}
/* Free type structure. External data (like nom) are freed elsewhere. */
void
spho_tp_destroy(struct spho_tp *tp)
{
struct spho_tp *arg;
switch (tp->form) {
case SPHO_TP_FORM_TRUE:
case SPHO_TP_FORM_FALSE:
case SPHO_TP_FORM_NOM:
break;
case SPHO_TP_FORM_CONJ:
case SPHO_TP_FORM_DISJ:
case SPHO_TP_FORM_IMPL:
case SPHO_TP_FORM_ARROW:
spho_tp_destroy(tp->d.binop.left);
spho_tp_destroy(tp->d.binop.right);
break;
case SPHO_TP_FORM_BOX:
spho_tp_destroy(tp->d.unop.operand);
break;
case SPHO_TP_FORM_FORALL:
case SPHO_TP_FORM_MEMBER:
spho_tp_destroy(tp->d.bind.bound);
break;
case SPHO_TP_FORM_APPL:
STAILQ_FOREACH(arg, tp->d.appl.args, entries) {
spho_tp_destroy(arg);
}
free(tp->d.appl.args);
break;
default:
SPHO_ASSERT(0);
break;
}
spho_tp_free(tp);
}