recursive lockstep example
This commit is contained in:
parent
26d0d3158f
commit
e036fa16f8
15 changed files with 536 additions and 133 deletions
|
@ -13,6 +13,11 @@ static int msph_tree_sphophi_decor_nom_lookup(struct spho_scope *,
|
|||
struct msph_tree *);
|
||||
static int msph_tree_sphophi_decor_tp(struct spho_scope *,
|
||||
struct msph_tree *);
|
||||
static int msph_tree_sphophi_bind_static_tp_name(struct spho_scope *,
|
||||
struct msph_tree *);
|
||||
|
||||
static int msph_tree_sphophi_get_scope(struct msph_tree *, struct
|
||||
spho_scope **);
|
||||
|
||||
/* foreach_pre: top down foreach */
|
||||
static int msph_sphophi_foreach_pre(msph_tree_sphophi_f,
|
||||
|
@ -135,6 +140,13 @@ msph_sphophi_tp(struct msph_tree_root *root)
|
|||
return (msph_sphophi_foreach_post(msph_tree_sphophi_decor_tp, root));
|
||||
}
|
||||
|
||||
int
|
||||
msph_sphophi_bind_static_tp_names(struct msph_tree_root *root)
|
||||
{
|
||||
return (msph_sphophi_foreach_pre(msph_tree_sphophi_bind_static_tp_name,
|
||||
root));
|
||||
}
|
||||
|
||||
int msph_sphophi(struct msph_tree_root *root)
|
||||
{
|
||||
int ret;
|
||||
|
@ -147,16 +159,18 @@ int msph_sphophi(struct msph_tree_root *root)
|
|||
return (ret);
|
||||
if ((ret = msph_sphophi_tp(root)) != 0)
|
||||
return (ret);
|
||||
if ((ret = msph_sphophi_bind_static_tp_names(root)) != 0)
|
||||
return (ret);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
#define IS_BINDING(tree) (((tree)->type == MSPH_TREE_TPDEF) || \
|
||||
((tree)->type == MSPH_TREE_NOMINDECL) || \
|
||||
((tree)->type == MSPH_TREE_MEMBDECL) || \
|
||||
((tree)->type == MSPH_TREE_FORALL))
|
||||
#define IS_TPEXPR(tree) (((tree)->type & MSPH_TREE_TPEXPR))
|
||||
#define IS_BINDING(tree) ((tree)->type == MSPH_TREE_TPDEF || \
|
||||
(tree)->type == MSPH_TREE_NOMINDECL || \
|
||||
(tree)->type == MSPH_TREE_MEMBDECL || \
|
||||
(tree)->type == MSPH_TREE_FORALL)
|
||||
#define IS_TPEXPR(tree) ((tree)->type & MSPH_TREE_TPEXPR)
|
||||
|
||||
static int
|
||||
msph_tree_sphophi_decor_scope(struct spho_scope *sc, struct msph_tree *tree)
|
||||
|
@ -214,11 +228,8 @@ msph_tree_sphophi_decor_nom_lookup(struct spho_scope *sc,
|
|||
if (tree->parent->type != MSPH_TREE_NAME)
|
||||
break;
|
||||
ident = (struct msph_tree_ident *)tree;
|
||||
if ((ret = spho_scope_nom_lookup(sc, ident->str,
|
||||
sizeof(ident->str), &ident->dec.nom)) != 0)
|
||||
break;
|
||||
if (ident->dec.nom == NULL)
|
||||
ret = -1;
|
||||
ret = spho_scope_nom_lookup_str_strict(sc, ident->str,
|
||||
sizeof(ident->str), &ident->dec.nom);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -265,31 +276,31 @@ msph_tree_sphophi_decor_tp(struct spho_scope *sc, struct msph_tree *tree)
|
|||
switch (tree->type) {
|
||||
case MSPH_TREE_CONJ:
|
||||
conj = (struct msph_tree_conj *)tree;
|
||||
if ((TP(&conj->htpe) = spho_tp_create_conj(sc, TP(conj->ltp),
|
||||
if ((tpexpr->dec.tp = spho_tp_create_conj(sc, TP(conj->ltp),
|
||||
TP(conj->rtp))) == NULL)
|
||||
goto cleanup;
|
||||
break;
|
||||
case MSPH_TREE_DISJ:
|
||||
disj = (struct msph_tree_disj *)tree;
|
||||
if ((TP(&disj->htpe) = spho_tp_create_conj(sc, TP(disj->ltp),
|
||||
if ((tpexpr->dec.tp = spho_tp_create_conj(sc, TP(disj->ltp),
|
||||
TP(disj->rtp))) == NULL)
|
||||
goto cleanup;
|
||||
break;
|
||||
case MSPH_TREE_IMPL:
|
||||
impl = (struct msph_tree_impl *)tree;
|
||||
if ((TP(&impl->htpe) = spho_tp_create_conj(sc, TP(impl->ltp),
|
||||
if ((tpexpr->dec.tp = spho_tp_create_conj(sc, TP(impl->ltp),
|
||||
TP(impl->rtp))) == NULL)
|
||||
goto cleanup;
|
||||
break;
|
||||
case MSPH_TREE_ARROW:
|
||||
arrow = (struct msph_tree_arrow *)tree;
|
||||
if ((TP(&arrow->htpe) = spho_tp_create_conj(sc, TP(arrow->ltp),
|
||||
if ((tpexpr->dec.tp = spho_tp_create_conj(sc, TP(arrow->ltp),
|
||||
TP(arrow->rtp))) == NULL)
|
||||
goto cleanup;
|
||||
break;
|
||||
case MSPH_TREE_NAME:
|
||||
name = (struct msph_tree_name *)tree;
|
||||
if ((TP(&name->htpe) = spho_tp_create_name(sc, NOM(name->id)))
|
||||
if ((tpexpr->dec.tp = spho_tp_create_name(sc, NOM(name->id)))
|
||||
== NULL)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
@ -303,34 +314,34 @@ msph_tree_sphophi_decor_tp(struct spho_scope *sc, struct msph_tree *tree)
|
|||
STAILQ_FOREACH(tpexpr_i, &appl->head, entries) {
|
||||
STAILQ_INSERT_TAIL(tps, tpexpr_i->dec.tp, entries);
|
||||
}
|
||||
if ((TP(&appl->htpe) = spho_tp_create_appl(sc, NOM(appl->id),
|
||||
if ((tpexpr->dec.tp = spho_tp_create_appl(sc, NOM(appl->id),
|
||||
tps)) == NULL)
|
||||
goto cleanup;
|
||||
tps = NULL;
|
||||
break;
|
||||
case MSPH_TREE_TRUE:
|
||||
if ((TP(tpexpr) = spho_tp_create_true(sc)) == NULL)
|
||||
if ((tpexpr->dec.tp = spho_tp_create_true(sc)) == NULL)
|
||||
goto cleanup;
|
||||
break;
|
||||
case MSPH_TREE_FALSE:
|
||||
if ((TP(tpexpr) = spho_tp_create_false(sc)) == NULL)
|
||||
if ((tpexpr->dec.tp = spho_tp_create_false(sc)) == NULL)
|
||||
goto cleanup;
|
||||
break;
|
||||
case MSPH_TREE_FORALL:
|
||||
forall = (struct msph_tree_forall *)tree;
|
||||
if ((TP(&forall->htpe) = spho_tp_create_forall(sc,
|
||||
if ((tpexpr->dec.tp = spho_tp_create_forall(sc,
|
||||
NOM(forall->id), TP(forall->inner))) == NULL)
|
||||
goto cleanup;
|
||||
break;
|
||||
case MSPH_TREE_BOX:
|
||||
box = (struct msph_tree_box *)tree;
|
||||
if ((TP(&box->htpe) = spho_tp_create_box(sc, TP(box->inner)))
|
||||
if ((tpexpr->dec.tp = spho_tp_create_box(sc, TP(box->inner)))
|
||||
== NULL)
|
||||
goto cleanup;
|
||||
break;
|
||||
case MSPH_TREE_PAREN:
|
||||
paren = (struct msph_tree_paren *)tree;
|
||||
if ((TP(&paren->htpe) = TP(paren->inner)) == NULL)
|
||||
if ((tpexpr->dec.tp = TP(paren->inner)) == NULL)
|
||||
goto cleanup;
|
||||
break;
|
||||
case MSPH_TREE_TRAIT:
|
||||
|
@ -352,7 +363,7 @@ msph_tree_sphophi_decor_tp(struct spho_scope *sc, struct msph_tree *tree)
|
|||
== NULL)
|
||||
goto cleanup;
|
||||
}
|
||||
trait->htpe.dec.tp = tp;
|
||||
tpexpr->dec.tp = tp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -369,6 +380,71 @@ cleanup:
|
|||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
msph_tree_sphophi_bind_static_tp_name(struct spho_scope *sc,
|
||||
struct msph_tree *tree)
|
||||
{
|
||||
int ret;
|
||||
struct spho_scope *sub_sc;
|
||||
struct msph_tree_tpdef *tpdef;
|
||||
struct msph_tree_nomindecl *nomdecl;
|
||||
|
||||
ret = 0;
|
||||
|
||||
if (MSPH_TREE_SCOPE(tree->type) &&
|
||||
MSPH_TREE_STATIC_BIND(tree->type)) {
|
||||
if ((ret = msph_tree_sphophi_get_scope(tree, &sub_sc)) == -1)
|
||||
goto ret;
|
||||
if ((ret = spho_scope_tp_bind_init(sub_sc)) == -1)
|
||||
goto ret;
|
||||
}
|
||||
|
||||
switch (tree->type) {
|
||||
case MSPH_TREE_TPDEF:
|
||||
tpdef = (struct msph_tree_tpdef *)tree;
|
||||
|
||||
ret = spho_scope_tp_bind_nom(sc, tpdef->id->dec.nom,
|
||||
tpdef->tp->dec.tp);
|
||||
break;
|
||||
case MSPH_TREE_NOMINDECL:
|
||||
nomdecl = (struct msph_tree_nomindecl *)tree;
|
||||
|
||||
ret = spho_scope_tp_bind_nom(sc, nomdecl->id->dec.nom,
|
||||
nomdecl->tp->dec.tp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ret:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
msph_tree_sphophi_get_scope(struct msph_tree *tree, struct spho_scope **out)
|
||||
{
|
||||
SPHO_PRECOND(MSPH_TREE_SCOPE(tree->type));
|
||||
|
||||
*out = NULL;
|
||||
switch (tree->type) {
|
||||
case MSPH_TREE_ROOT:
|
||||
*out = spho_scope_global(
|
||||
((struct msph_tree_root *)tree)->ctx->spho);
|
||||
break;
|
||||
case MSPH_TREE_UNIT:
|
||||
*out = ((struct msph_tree_unit *)tree)->dec.sc;
|
||||
break;
|
||||
case MSPH_TREE_TRAIT:
|
||||
*out = ((struct msph_tree_trait *)tree)->dec.sc;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SPHO_POSTCOND(*out != NULL);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* foreach pre: top down foreach node */
|
||||
static int
|
||||
msph_sphophi_foreach_pre(msph_tree_sphophi_f f, struct msph_tree_root *root)
|
||||
|
|
|
@ -1180,6 +1180,8 @@ struct msph_tree_dir *
|
|||
tree_parse_nomindecl(struct tree_parse *p, struct msph_tree *parent)
|
||||
{
|
||||
int res;
|
||||
struct msph_tree_ident *id;
|
||||
struct msph_tree_name *name;
|
||||
struct msph_tree_nomindecl *nomd;
|
||||
|
||||
EXPECT_CURR_TOKEN(p, TOK_KW_NOMINAL, MSPH_TREE_NOMINDECL,
|
||||
|
@ -1193,11 +1195,28 @@ tree_parse_nomindecl(struct tree_parse *p, struct msph_tree *parent)
|
|||
T(nomd)->parent = parent;
|
||||
TXT(nomd)->pos = CURR_TOKEN(p)->pos;
|
||||
nomd->id = NULL;
|
||||
nomd->tp = NULL;
|
||||
|
||||
EXPECT_READ_NEXT(res, p, MSPH_TREE_NOMINDECL, goto err);
|
||||
if ((nomd->id = tree_parse_ident(p, T(nomd))) == NULL)
|
||||
if ((id = tree_parse_ident(p, T(nomd))) == NULL)
|
||||
goto err;
|
||||
|
||||
/* name tpexpr to match tree shape of tpdef. This is not represented in
|
||||
* msph language grammar. */
|
||||
if ((name = malloc(sizeof(*name))) == NULL) {
|
||||
MSPH_ERR(CTX(p), MSPH_ERR_SYS);
|
||||
goto err;
|
||||
}
|
||||
T(name)->type = MSPH_TREE_NAME;
|
||||
T(name)->parent = T(nomd);
|
||||
|
||||
TXT(name)->pos = TXT(nomd->id)->pos;
|
||||
TP_DECOR_INIT(&name->htpe.dec);
|
||||
name->id = id;
|
||||
|
||||
nomd->id = id;
|
||||
nomd->tp = (struct msph_tree_tpexpr *)name;
|
||||
|
||||
return ((struct msph_tree_dir *)nomd);
|
||||
err:
|
||||
free_the_tree(T(nomd));
|
||||
|
|
|
@ -4,37 +4,74 @@
|
|||
#include "spho/bind.h"
|
||||
|
||||
struct spho_bind *
|
||||
spho_bind_create(struct spho_ctx *ctx, struct spho_bind *parent)
|
||||
spho_bind_create(struct spho_ctx *ctx, struct spho_bind_scope *binder,
|
||||
struct spho_bind *parent)
|
||||
{
|
||||
struct spho_bind *bind;
|
||||
|
||||
SPHO_PRECOND(ctx != NULL);
|
||||
SPHO_PRECOND(binder != NULL);
|
||||
|
||||
if ((bind = malloc(sizeof(*bind))) == NULL) {
|
||||
SPHO_ERR(ctx, SPHO_ERR_SYS);
|
||||
SPHO_ERR(binder->sc->ctx, SPHO_ERR_SYS);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
STAILQ_INIT(&bind->head);
|
||||
bind->ctx = ctx;
|
||||
bind->binder = binder;
|
||||
bind->parent = parent;
|
||||
|
||||
return (bind);
|
||||
}
|
||||
|
||||
int
|
||||
spho_bind_add(struct spho_bind *bind, struct spho_nom *nom, struct spho_tp *tp)
|
||||
spho_bind_lkp(int, struct spho_bind *bind, struct spho_nom *nom,
|
||||
union spho_bound **out)
|
||||
{
|
||||
struct spho_binding *b;
|
||||
|
||||
if ((b = malloc(sizeof(*b))) == NULL) {
|
||||
SPHO_ERR(bind->ctx, SPHO_ERR_SYS);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
b->nom = nom;
|
||||
b->tp = tp;
|
||||
|
||||
STAILQ_INSERT_TAIL(&bind->head, b, entries);
|
||||
|
||||
return (0);
|
||||
// TODO
|
||||
return (-1);
|
||||
}
|
||||
|
||||
void
|
||||
spho_bind_destroy(struct spho_bind *bind)
|
||||
{
|
||||
free(bind);
|
||||
}
|
||||
|
||||
|
||||
struct spho_bind_scope *
|
||||
spho_bind_scope_create(struct spho_scope *sc)
|
||||
{
|
||||
size_t sz;
|
||||
struct spho_binding *bds;
|
||||
struct spho_bind_scope *ret;
|
||||
|
||||
SPHO_PRECOND(sc != NULL);
|
||||
|
||||
if ((ret = malloc(sizeof(*ret))) == NULL) {
|
||||
SPHO_ERR(sc->ctx, SPHO_ERR_SYS);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((bds = calloc(sz, sizeof(*bds))) == NULL) {
|
||||
SPHO_ERR(sc->ctx, SPHO_ERR_SYS);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret->sc = sc;
|
||||
ret->cap_bds = sz;
|
||||
ret->n_bds = 0;
|
||||
ret->bds = bds;
|
||||
|
||||
err:
|
||||
free(ret);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
spho_binder_add_tp(struct spho_bind_scope *bdr, struct spho_nom *nom,
|
||||
struct spho_tp *tp)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -3,14 +3,16 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "spho/spho.h"
|
||||
#include "spho/ctx.h"
|
||||
#include "spho/scope.h"
|
||||
#include "spho/util.h"
|
||||
#include "spho/bind.h"
|
||||
|
||||
static void spho_nom_term(struct spho_nom *);
|
||||
|
||||
static int spho_scope_nom_get_norec(struct spho_scope *, const char *, size_t ,
|
||||
struct spho_nom **);
|
||||
static int scope_nom_lookup_str_loc(struct spho_scope *, const char *,
|
||||
size_t, struct spho_nom **);
|
||||
static int scope_nom_in_loc(struct spho_scope *, struct spho_nom *);
|
||||
|
||||
int
|
||||
spho_scope_init(struct spho_scope *sc, struct spho_ctx *ctx,
|
||||
|
@ -23,7 +25,7 @@ spho_scope_init(struct spho_scope *sc, struct spho_ctx *ctx,
|
|||
SLIST_INIT(&sc->noms);
|
||||
TAILQ_INIT(&sc->tps);
|
||||
|
||||
sc->bind = NULL;
|
||||
sc->stat_bind = NULL;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -36,6 +38,10 @@ spho_scope_term(struct spho_scope *sc)
|
|||
SPHO_UTIL_SLIST_DESTROY(&sc->noms, spho_nom, next, spho_nom_term);
|
||||
|
||||
sc->parent = NULL;
|
||||
|
||||
if (sc->stat_bind == NULL)
|
||||
spho_bind_scope_destroy(sc->stat_bind);
|
||||
sc->stat_bind = NULL;
|
||||
}
|
||||
|
||||
struct spho_scope *
|
||||
|
@ -69,7 +75,7 @@ spho_scope_create(struct spho_scope *sc)
|
|||
|
||||
|
||||
static void
|
||||
spho_nom_term(struct spho_nom *nom)
|
||||
spho_nom_term(__attribute__((unused)) struct spho_nom *nom)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -98,7 +104,7 @@ spho_scope_nom_add(struct spho_scope *sc, const char *nomstr, size_t sz)
|
|||
|
||||
nom = NULL;
|
||||
|
||||
if (spho_scope_nom_get_norec(sc, nomstr, sz, &nom) == -1)
|
||||
if (scope_nom_lookup_str_loc(sc, nomstr, sz, &nom) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (nom != NULL) {
|
||||
|
@ -139,7 +145,7 @@ err:
|
|||
|
||||
|
||||
int
|
||||
spho_scope_nom_get(struct spho_scope *sc, const char *nomstr, size_t sz,
|
||||
spho_scope_nom_lookup_str(struct spho_scope *sc, const char *nomstr, size_t sz,
|
||||
struct spho_nom **out)
|
||||
{
|
||||
struct spho_nom *nom;
|
||||
|
@ -166,12 +172,10 @@ spho_scope_nom_get(struct spho_scope *sc, const char *nomstr, size_t sz,
|
|||
}
|
||||
|
||||
int
|
||||
spho_scope_nom_lookup(struct spho_scope *sc, const char *nomstr, size_t sz,
|
||||
struct spho_nom **out)
|
||||
spho_scope_nom_lookup_str_strict(struct spho_scope *sc, const char *nomstr,
|
||||
size_t sz, struct spho_nom **out)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (spho_scope_nom_get(sc, nomstr, sz, out) == -1)
|
||||
if (spho_scope_nom_lookup_str(sc, nomstr, sz, out) == -1)
|
||||
return (-1);
|
||||
|
||||
if (*out == NULL) {
|
||||
|
@ -181,9 +185,33 @@ spho_scope_nom_lookup(struct spho_scope *sc, const char *nomstr, size_t sz,
|
|||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
spho_scope_static_bind_init(struct spho_scope *sc)
|
||||
{
|
||||
if ((sc->stat_bind = spho_bind_scope_create(sc))
|
||||
== NULL) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
spho_scope_static_bind_add_tp(struct spho_scope *sc, struct spho_nom *nom,
|
||||
struct spho_tp *tp)
|
||||
{
|
||||
if (! scope_nom_in_loc(sc, nom)) {
|
||||
SPHO_ERR(sc->ctx, SPHO_ERR_NOM_NOTINSCOPE);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (spho_bind_scope_add_tp(sc->stat_bind, nom, tp));
|
||||
}
|
||||
|
||||
static int
|
||||
spho_scope_nom_get_norec(struct spho_scope *sc, const char *nomstr, size_t sz,
|
||||
struct spho_nom **out)
|
||||
scope_nom_lookup_str_loc(struct spho_scope *sc, const char *nomstr,
|
||||
size_t sz, struct spho_nom **out)
|
||||
{
|
||||
struct spho_nom *nom;
|
||||
|
||||
|
@ -204,3 +232,16 @@ spho_scope_nom_get_norec(struct spho_scope *sc, const char *nomstr, size_t sz,
|
|||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
scope_nom_in_loc(struct spho_scope *sc, struct spho_nom *nom)
|
||||
{
|
||||
struct spho_nom *sc_nom;
|
||||
|
||||
SLIST_FOREACH(sc_nom, &sc->noms, next) {
|
||||
if (sc_nom == nom)
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -128,8 +128,8 @@ spho_tp_create_forall(struct spho_scope *sc, struct spho_nom *nom,
|
|||
return (NULL);
|
||||
|
||||
ret->kind = SPHO_TP_FORM_FORALL;
|
||||
ret->d.bind.nom = nom;
|
||||
ret->d.bind.bound = tp;
|
||||
ret->d.fa.nom = nom;
|
||||
ret->d.fa.tp = tp;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
@ -202,12 +202,28 @@ spho_tp_create_member(struct spho_scope *sc, struct spho_nom *nom,
|
|||
return (NULL);
|
||||
|
||||
ret->kind = SPHO_TP_FORM_MEMBER;
|
||||
ret->d.bind.nom = nom;
|
||||
ret->d.bind.bound = tp;
|
||||
ret->d.memb.nom = nom;
|
||||
ret->d.memb.tp = tp;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
struct spho_tp *
|
||||
spho_tp_create_nominal(struct spho_scope *sc, struct spho_nom *nom)
|
||||
{
|
||||
struct spho_tp *ret;
|
||||
|
||||
if ((ret = spho_tp_alloc(sc)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
ret->kind = SPHO_TP_FORM_NOMINAL;
|
||||
ret->d.nom.nom = nom;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Free type structure. External data (like nom) are freed elsewhere. */
|
||||
void
|
||||
spho_tp_destroy(struct spho_tp *tp)
|
||||
|
@ -230,8 +246,10 @@ spho_tp_destroy(struct spho_tp *tp)
|
|||
spho_tp_destroy(tp->d.unop.operand);
|
||||
break;
|
||||
case SPHO_TP_FORM_FORALL:
|
||||
spho_tp_destroy(tp->d.fa.tp);
|
||||
break;
|
||||
case SPHO_TP_FORM_MEMBER:
|
||||
spho_tp_destroy(tp->d.bind.bound);
|
||||
spho_tp_destroy(tp->d.memb.tp);
|
||||
break;
|
||||
case SPHO_TP_FORM_APPL:
|
||||
STAILQ_FOREACH(arg, tp->d.appl.args, entries) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue