infix parsing and prebind fixes

This commit is contained in:
Ellen Arvidsson 2025-06-27 02:48:48 +02:00
parent 65066c493e
commit 33f38c03d6
14 changed files with 1555 additions and 1089 deletions

2
.gitignore vendored
View file

@ -52,6 +52,8 @@ Mkfile.old
dkms.conf
# vim
.swp
.swo
.*.swp
.*.swo

View file

@ -39,6 +39,8 @@
enum msph_tok_type {
TOK_INVAL = -1, // special: invalid, use to mark invalid toks
TOK_EOF = 0, // special: end-of-file
TOK_LBRACE, // {
TOK_RBRACE, // }
TOK_LBRAK, // [
@ -67,9 +69,10 @@ enum msph_tok_type {
TOK_CONST_FALSE, // False
TOK_IDENT, // identifiers
TOK_INVAL, // special: invalid, use to mark invalid toks
TOK_WSPACE, // special: whitespace
TOK_END // special: end of array/token stream
TOK_WSPACE, // whitespace
TOK_NOPE // special indicator: end of info array,
// start of parsing
};
#define MSPH_TAB_WIDTH 8

View file

@ -37,6 +37,8 @@ struct msph_decor {
#define MSPH_TREE_BOX 0x004a
#define MSPH_TREE_FORALL 0x004b
#define MSPH_TREE_PAREN 0x004c
#define MSPH_TREE_SUBT 0x004d
#define MSPH_TREE_IDENT 0x0100
#define MSPH_TREE_NAMEDECL 0x0101
@ -162,8 +164,7 @@ struct msph_tree_membdecl {
struct msph_tree_assert {
struct msph_tree_dir hd_dir;
struct msph_tree_tpexpr *ltp;
struct msph_tree_tpexpr *rtp;
struct msph_tree_tpexpr *tp;
};
struct msph_tree_namedecl {
@ -209,6 +210,7 @@ struct msph_tree_trait {
struct msph_tree_body *body;
};
/* XXX should probably merge all binary type ops into one */
struct msph_tree_conj {
struct msph_tree_tpexpr hd_tpe;
@ -230,6 +232,13 @@ struct msph_tree_impl {
struct msph_tree_tpexpr *rtp;
};
struct msph_tree_subt {
struct msph_tree_tpexpr hd_tpe;
struct msph_tree_tpexpr *ltp;
struct msph_tree_tpexpr *rtp;
};
struct msph_tree_arrow {
struct msph_tree_tpexpr hd_tpe;
@ -259,7 +268,11 @@ struct msph_tree_paren {
struct msph_tree_root *msph_tree_makeroot(struct msph_ctx *);
int msph_tree_parse(struct msph_token_stream *, struct msph_tree_root *);
#define MSPH_PARSE_PREFIX 1
#define MSPH_PARSE_INFIX 2
int msph_tree_parse(struct msph_token_stream *, struct msph_tree_root *,
int);
ssize_t msph_tree_fprint(FILE *, struct msph_tree *);

View file

@ -14,6 +14,8 @@ struct spho_ctx {
int err_info;
char errbuf[SPHO_ERR_BUF_LEN];
unsigned int nom_cnt;
#ifdef SPHO_DEBUG
char filebuf[SPHO_ERR_FILEBUF_LEN];
int errline;
@ -22,6 +24,7 @@ struct spho_ctx {
};
struct spho_ctx *spho_ctx_create(void);
void spho_ctx_init(struct spho_ctx *);
void spho_ctx_destroy(struct spho_ctx *);
const char *spho_ctx_strerror(struct spho_ctx *);

View file

@ -39,7 +39,7 @@
(ctx)->err = (e); \
(ctx)->err_info = (info); \
snprintf((ctx)->filebuf, sizeof((ctx)->filebuf), \
__FILE__); \
__FILE__ ":%s", __func__); \
(ctx)->errline = __LINE__; \
} while (0)

View file

@ -7,13 +7,22 @@
#define SPHO_NOM_LEN 128
/* name */
struct spho_nom {
char s[SPHO_NOM_LEN];
SLIST_ENTRY(spho_nom) next; // TODO change to allocs
union spho_ext_data {
void *ptr;
uint64_t n;
};
/* name */
struct spho_nom {
unsigned int id;
char s[SPHO_NOM_LEN];
union spho_ext_data ext_data;
SLIST_ENTRY(spho_nom) entries;
};
SLIST_HEAD(spho_nom_l, spho_nom);
#define TP_KONST_KEY_TRUE 0x43445 /* don't change!!!!! */
@ -76,6 +85,7 @@ struct spho_tp {
int kind;
union tp_data d;
union spho_ext_data ext_data;
STAILQ_ENTRY(spho_tp) entries;
};
@ -85,30 +95,20 @@ struct spho_tp_op {
struct spho_scope *op_sc;
struct spho_tp *op_tp;
union spho_ext_data ext_data;
};
STAILQ_HEAD(spho_tp_l, spho_tp);
struct spho_tp_ptr {
struct spho_tp *p;
STAILQ_ENTRY(spho_tp_ptr) entries;
};
STAILQ_HEAD(spho_tp_ptr_l, spho_tp_ptr);
struct spho_tp_alloc {
union {
struct spho_tp tp;
struct spho_tp_op tp_op;
} alloc;
TAILQ_ENTRY(spho_tp_alloc) allocs;
STAILQ_ENTRY(spho_tp_alloc) entries;
};
TAILQ_HEAD(spho_tp_alloc_l, spho_tp_alloc);
SLIST_HEAD(spho_scope_l, spho_scope);
/* defined in spho/bind.h */
struct spho_bind;
@ -116,33 +116,38 @@ struct spho_scope {
struct spho_ctx *ctx;
struct spho_scope *parent;
struct spho_scope_l subs;
size_t n_noms;
struct spho_nom_l noms;
struct spho_tp_alloc_l tps;
STAILQ_HEAD(
spho_scope_l,
spho_scope) subs;
STAILQ_HEAD(
spho_tp_alloc_l,
spho_tp_alloc) tps;
SLIST_HEAD(
spho_nom_l,
spho_nom) noms;
size_t nom_cnt;
struct spho_prebind *bind_loc;
union spho_ext_data ext_data;
SLIST_ENTRY(spho_scope) next;
STAILQ_ENTRY(spho_scope) entries;
};
#define SPHO_SC_ERR(sc, err) SPHO_ERR((sc)->ctx, (err))
int spho_scope_init(struct spho_scope *, struct spho_ctx *,
void spho_scope_init(struct spho_scope *, struct spho_ctx *,
struct spho_scope *);
void spho_scope_term(struct spho_scope *);
void spho_scope_cleanup(struct spho_scope *);
struct spho_scope *spho_scope_global(struct spho_ctx *);
struct spho_scope *spho_scope_create(struct spho_scope *);
struct spho_scope *spho_scope_create_subscope(struct spho_scope *);
void spho_scope_destroy(struct spho_scope *);
void spho_scope_free(struct spho_scope *);
struct spho_nom *spho_scope_nom_add(struct spho_scope *, const char *, size_t);
int spho_scope_nom_lookup_str(struct spho_scope *, const char *, size_t,
int spho_scope_nom_lookup(struct spho_scope *, const char *, size_t,
struct spho_nom **);
int spho_scope_nom_lookup_str_strict(struct spho_scope *, const char *,
int spho_scope_nom_lookup_strict(struct spho_scope *, const char *,
size_t, struct spho_nom **);
int spho_scope_prebind_init(struct spho_scope *);

View file

@ -9,21 +9,25 @@
struct msph_opts {
int tokenize_only;
int parser;
const char *in_path;
const char *out_path;
} run_opts = {
0,
MSPH_PARSE_INFIX,
NULL,
NULL
};
#define USAGE \
"msph: micro sappho\n" \
"\tUsage: msph [-t] [-o out_path] [in_path]\n" \
"\n" \
"\t-t - print tokenization\n" \
"\t-o - output path\n"
"msph: micro sappho\n" \
" Usage: msph [-t] [-o out_path] [-p i|p] [in_path]\n" \
"\n" \
" -t - print tokenization\n" \
" -o - output path\n" \
" -p i[nfix]|p[refix] - infix or prefix &, |, =>, -> parsing\n" \
" (default infix)\n"
void
print_usage(void)
@ -38,7 +42,7 @@ main(int argc, char *argv[])
{
int opt;
while ((opt = getopt(argc, argv, "hto:")) != -1) {
while ((opt = getopt(argc, argv, "hto:p:")) != -1) {
switch (opt) {
case 't':
run_opts.tokenize_only = 1;
@ -46,6 +50,19 @@ main(int argc, char *argv[])
case 'o':
run_opts.out_path = optarg;
break;
case 'p':
switch (optarg[0]) {
case 'p':
run_opts.parser = MSPH_PARSE_PREFIX;
break;
case 'i':
run_opts.parser = MSPH_PARSE_INFIX;
break;
default:
print_usage();
exit(EXIT_FAILURE);
}
break;
case 'h':
print_usage();
exit(EXIT_SUCCESS);
@ -122,7 +139,7 @@ run(struct msph_opts *opts)
goto err;
}
if (msph_tree_parse(s, root) == -1)
if (msph_tree_parse(s, root, opts->parser) == -1)
goto err;
printf("msph tree successfully parsed :)\n");

View file

@ -15,7 +15,7 @@ static int msph_tree_sphophi_decor_tpexpr_nom(struct spho_scope *,
struct msph_tree *);
static int msph_tree_sphophi_decor_tp(struct spho_scope *,
struct msph_tree *);
static int msph_tree_sphophi_tp_prebind(struct spho_scope *,
static int msph_tree_sphophi_prebind(struct spho_scope *,
struct msph_tree *);
/* is the tree a name binding? */
@ -65,6 +65,8 @@ static int msph_sphophi_foreach_pre_disj(msph_tree_sphophi_f,
struct spho_scope *, struct msph_tree_disj *);
static int msph_sphophi_foreach_pre_impl(msph_tree_sphophi_f,
struct spho_scope *, struct msph_tree_impl *);
static int msph_sphophi_foreach_pre_subt(msph_tree_sphophi_f,
struct spho_scope *, struct msph_tree_subt *);
static int msph_sphophi_foreach_pre_arrow(msph_tree_sphophi_f,
struct spho_scope *, struct msph_tree_arrow *);
static int msph_sphophi_foreach_pre_box(msph_tree_sphophi_f,
@ -109,6 +111,8 @@ static int msph_sphophi_foreach_post_disj(msph_tree_sphophi_f,
struct spho_scope *, struct msph_tree_disj *);
static int msph_sphophi_foreach_post_impl(msph_tree_sphophi_f,
struct spho_scope *, struct msph_tree_impl *);
static int msph_sphophi_foreach_post_subt(msph_tree_sphophi_f,
struct spho_scope *, struct msph_tree_subt *);
static int msph_sphophi_foreach_post_arrow(msph_tree_sphophi_f,
struct spho_scope *, struct msph_tree_arrow *);
static int msph_sphophi_foreach_post_box(msph_tree_sphophi_f,
@ -154,7 +158,7 @@ msph_sphophi_tp(struct msph_tree_root *root)
int
msph_sphophi_tp_prebind(struct msph_tree_root *root)
{
return (msph_sphophi_foreach_pre(msph_tree_sphophi_tp_prebind,
return (msph_sphophi_foreach_pre(msph_tree_sphophi_prebind,
root));
}
@ -191,25 +195,25 @@ msph_tree_sphophi_decor_scope(struct spho_scope *sc, struct msph_tree *tree)
case MSPH_TREE_UNIT:
case MSPH_TREE_TRAIT:
case MSPH_TREE_FORALL:
if ((SCOPE(tree) = spho_scope_create(sc)) == NULL)
ret = -1;
if ((SCOPE(tree) = spho_scope_create_subscope(sc)) == NULL)
return (-1);
ADD_FLAG(tree, MSPH_TREE_FLAG_SCOPE);
break;
case MSPH_TREE_TPDEF:
tpdef = (struct msph_tree_tpdef *)tree;
if (! STAILQ_EMPTY(&tpdef->params) &&
((SCOPE(tpdef) = spho_scope_create(sc)) == NULL)) {
ret = -1;
}
if (STAILQ_EMPTY(&tpdef->params))
break;
if (((SCOPE(tpdef) = spho_scope_create_subscope(sc)) == NULL))
return (-1);
ADD_FLAG(tree, MSPH_TREE_FLAG_SCOPE);
break;
case MSPH_TREE_IDENT:
if (! IS_BINDING(tree->parent))
break;
case MSPH_TREE_NAMEDECL:
SPHO_ASSERT(IS_BINDING(tree->parent));
ident = (struct msph_tree_ident *)tree;
if ((NOM(ident) = spho_scope_nom_add(sc, ident->str,
sizeof(ident->str))) == NULL)
ret = -1;
sizeof(ident->str))) == NULL) {
return (-1);
}
ADD_FLAG(tree, MSPH_TREE_FLAG_NOM);
break;
default:
@ -230,12 +234,14 @@ msph_tree_sphophi_decor_tpexpr_nom(struct spho_scope *sc,
switch (TREE_ID(tree)) {
case MSPH_TREE_IDENT:
if (! IS_TPEXPR(tree->parent))
break;
ident = (struct msph_tree_ident *)tree;
ret = spho_scope_nom_lookup_str_strict(sc, ident->str,
sizeof(ident->str), &NOM(ident));
SPHO_ASSERT(IS_TPEXPR(tree->parent));
ident = (struct msph_tree_ident *)tree;
if (spho_scope_nom_lookup_strict(sc, ident->str,
sizeof(ident->str), &NOM(ident)) == -1) {
return (-1);
}
ADD_FLAG(ident, MSPH_TREE_FLAG_NOM);
break;
default:
break;
@ -261,6 +267,7 @@ msph_tree_sphophi_decor_tp(struct spho_scope *sc, struct msph_tree *tree)
struct msph_tree_trait *trait;
struct msph_tree_dir *dir;
struct msph_tree_membdecl *membd;
struct msph_tree_subt *subt;
struct spho_tp_l *tps;
struct spho_tp *tp, *tp_memb;
@ -271,43 +278,59 @@ msph_tree_sphophi_decor_tp(struct spho_scope *sc, struct msph_tree *tree)
dir = NULL;
membd = NULL;
if (! (tree->type & MSPH_TREE_TPEXPR))
if (! IS_TPEXPR(tree))
return (0);
switch (TREE_ID(tree)) {
case MSPH_TREE_CONJ:
conj = (struct msph_tree_conj *)tree;
if ((TP(conj) = spho_tp_create_conj(sc, TP(conj->ltp),
TP(conj->rtp))) == NULL)
TP(conj->rtp))) == NULL) {
goto cleanup;
}
ADD_FLAG(conj, MSPH_TREE_FLAG_TP);
break;
case MSPH_TREE_DISJ:
disj = (struct msph_tree_disj *)tree;
if ((TP(disj) = spho_tp_create_conj(sc, TP(disj->ltp),
TP(disj->rtp))) == NULL)
TP(disj->rtp))) == NULL) {
goto cleanup;
}
ADD_FLAG(disj, MSPH_TREE_FLAG_TP);
break;
case MSPH_TREE_IMPL:
impl = (struct msph_tree_impl *)tree;
if ((TP(impl) = spho_tp_create_conj(sc, TP(impl->ltp),
TP(impl->rtp))) == NULL)
TP(impl->rtp))) == NULL) {
goto cleanup;
}
ADD_FLAG(impl, MSPH_TREE_FLAG_TP);
break;
case MSPH_TREE_SUBT:
/* a <: b == box(a => b) */
subt = (struct msph_tree_subt *)tree;
if ((tp = spho_tp_create_impl(sc, TP(subt->ltp),
TP(subt->rtp))) == NULL) {
goto cleanup;
}
if ((TP(subt) = spho_tp_create_box(sc, tp)) == NULL)
goto cleanup;
ADD_FLAG(subt, MSPH_TREE_FLAG_TP);
break;
case MSPH_TREE_ARROW:
arrow = (struct msph_tree_arrow *)tree;
if ((TP(arrow) = spho_tp_create_conj(sc, TP(arrow->ltp),
TP(arrow->rtp))) == NULL)
TP(arrow->rtp))) == NULL) {
goto cleanup;
}
ADD_FLAG(arrow, MSPH_TREE_FLAG_TP);
break;
case MSPH_TREE_TPNAME:
tpname = (struct msph_tree_tpname *)tree;
if ((TP(tpname) = spho_tp_create_name(sc, NOM(tpname->name)))
== NULL)
== NULL) {
goto cleanup;
}
ADD_FLAG(tpname, MSPH_TREE_FLAG_TP);
break;
case MSPH_TREE_TPAPPL:
@ -383,7 +406,7 @@ msph_tree_sphophi_decor_tp(struct spho_scope *sc, struct msph_tree *tree)
ADD_FLAG(trait, MSPH_TREE_FLAG_TP);
break;
default:
SPHO_ASSERT(0);
SPHO_RIP("impossible-default-reached");
break;
}
@ -397,7 +420,7 @@ cleanup:
}
static int
msph_tree_sphophi_tp_prebind(struct spho_scope *sc,
msph_tree_sphophi_prebind(struct spho_scope *sc,
struct msph_tree *tree)
{
int ret;
@ -444,6 +467,8 @@ msph_tree_sphophi_tp_prebind(struct spho_scope *sc,
}
}
break;
case MSPH_TREE_NOMINDECL:
break;
default:
break;
}
@ -628,9 +653,7 @@ msph_sphophi_foreach_pre_assert(msph_tree_sphophi_f f, struct spho_scope *sc,
if ((ret = f(sc, TREE(ass))) != 0)
return (ret);
if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, ass->ltp)) != 0)
return (ret);
if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, ass->rtp)) != 0)
if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, ass->tp)) != 0)
return (ret);
return (ret);
@ -680,6 +703,10 @@ msph_sphophi_foreach_pre_tpexpr(msph_tree_sphophi_f f, struct spho_scope *sc,
ret = msph_sphophi_foreach_pre_impl(f, sc,
(struct msph_tree_impl *)tpexpr);
break;
case MSPH_TREE_SUBT:
ret = msph_sphophi_foreach_pre_subt(f, sc,
(struct msph_tree_subt *)tpexpr);
break;
case MSPH_TREE_ARROW:
ret = msph_sphophi_foreach_pre_arrow(f, sc,
(struct msph_tree_arrow *)tpexpr);
@ -717,7 +744,7 @@ msph_sphophi_foreach_pre_tpexpr(msph_tree_sphophi_f f, struct spho_scope *sc,
(struct msph_tree_false *)tpexpr);
break;
default:
SPHO_RIP("default-reach");
SPHO_RIP("impossible-default-reached");
break;
}
@ -775,6 +802,23 @@ msph_sphophi_foreach_pre_impl(msph_tree_sphophi_f f, struct spho_scope *sc,
return (msph_sphophi_foreach_pre_tpexpr(f, sc, impl->rtp));
}
static int
msph_sphophi_foreach_pre_subt(msph_tree_sphophi_f f, struct spho_scope *sc,
struct msph_tree_subt *subt)
{
int ret;
SPHO_PRECOND(sc != NULL);
SPHO_PRECOND(subt != NULL);
if ((ret = f(sc, TREE(subt))) != 0)
return (ret);
if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, subt->ltp)) != 0)
return (ret);
return (msph_sphophi_foreach_pre_tpexpr(f, sc, subt->rtp));
}
static int
msph_sphophi_foreach_pre_arrow(msph_tree_sphophi_f f, struct spho_scope *sc,
struct msph_tree_arrow *arrow)
@ -1092,9 +1136,7 @@ msph_sphophi_foreach_post_assert(msph_tree_sphophi_f f, struct spho_scope *sc,
SPHO_PRECOND(sc != NULL);
SPHO_PRECOND(ass != NULL);
if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, ass->ltp)) != 0)
return (ret);
if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, ass->rtp)) != 0)
if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, ass->tp)) != 0)
return (ret);
return (f(sc, TREE(ass)));
@ -1144,6 +1186,10 @@ msph_sphophi_foreach_post_tpexpr(msph_tree_sphophi_f f, struct spho_scope *sc,
ret = msph_sphophi_foreach_post_impl(f, sc,
(struct msph_tree_impl *)tpexpr);
break;
case MSPH_TREE_SUBT:
ret = msph_sphophi_foreach_post_subt(f, sc,
(struct msph_tree_subt *)tpexpr);
break;
case MSPH_TREE_ARROW:
ret = msph_sphophi_foreach_post_arrow(f, sc,
(struct msph_tree_arrow *)tpexpr);
@ -1240,6 +1286,22 @@ msph_sphophi_foreach_post_impl(msph_tree_sphophi_f f, struct spho_scope *sc,
return (f(sc, TREE(impl)));
}
static int
msph_sphophi_foreach_post_subt(msph_tree_sphophi_f f, struct spho_scope *sc,
struct msph_tree_subt *subt)
{
int ret;
SPHO_PRECOND(sc != NULL);
SPHO_PRECOND(subt != NULL);
if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, subt->ltp)) != 0)
return (ret);
if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, subt->rtp)) != 0)
return (ret);
return (f(sc, TREE(subt)));
}
static int
msph_sphophi_foreach_post_arrow(msph_tree_sphophi_f f, struct spho_scope *sc,
struct msph_tree_arrow *arrow)

View file

@ -48,7 +48,7 @@ struct msph_matcher token_matchers[] = {
{ 0, 0, TOK_CONST_FALSE },
{ 0, 0, TOK_IDENT },
{ 0, 0, TOK_END }
{ 0, 0, TOK_NOPE }
};
struct msph_matcher wspace = { 0, 0, TOK_WSPACE };
@ -86,7 +86,7 @@ struct msph_token_info {
TOK_INFO(TOK_CONST_FALSE, "False"),
TOK_INFO(TOK_IDENT, NULL),
{ TOK_END , NULL, NULL }
{ TOK_NOPE , NULL, NULL }
#undef TOK_INFO
};
@ -305,7 +305,7 @@ read_single_tok(struct msph_token *ptr, struct msph_token_stream *s)
return (-1);
max_m = 0;
for (m = 1; token_matchers[m].type != TOK_END; m++) {
for (m = 1; token_matchers[m].type != TOK_NOPE; m++) {
res = tok_match(ctx, src, &token_matchers[m]);
if (res == -1)
@ -358,7 +358,7 @@ msph_token_copy(struct msph_ctx *ctx, struct msph_token *token)
info = NULL;
for (i = 0; token_info[i].type != TOK_END; i++) {
for (i = 0; token_info[i].type != TOK_NOPE; i++) {
if (token_info[i].type == token->type) {
info = &token_info[i];
break;
@ -769,7 +769,7 @@ static const char *
tok_base_str(struct msph_token *tok)
{
size_t i;
for (i = 0; token_info[i].type != TOK_END; i++) {
for (i = 0; token_info[i].type != TOK_NOPE; i++) {
if (token_info[i].type == tok->type)
return (token_info[i].dbg_str);
}

File diff suppressed because it is too large Load diff

View file

@ -19,20 +19,21 @@ spho_prebind_create(struct spho_scope *sc)
return (NULL);
}
if ((bind->binds = calloc(sc->n_noms, sizeof(*bind->binds))) == NULL) {
if ((bind->binds = calloc(sc->nom_cnt, sizeof(*bind->binds))) == NULL) {
SPHO_ERR(sc->ctx, SPHO_ERR_SYS);
free(bind);
return (NULL);
}
bind->sc = sc;
bind->sz = sc->n_noms;
bind->sz = sc->nom_cnt;
i = 0;
SLIST_FOREACH(nom, &sc->noms, next) {
SLIST_FOREACH(nom, &sc->noms, entries) {
SPHO_ASSERT(i < bind->sz);
bind->binds[i++] = (struct spho_prebind_pair) { NULL, 0, NULL };
bind->binds[i++] =
(struct spho_prebind_pair) { nom, 0, { NULL } };
}
return (bind);

View file

@ -37,28 +37,31 @@ spho_ctx_create(void)
c = NULL;
if ((c = malloc(sizeof(struct spho_ctx))) == NULL)
if ((c = calloc(1, sizeof(struct spho_ctx))) == NULL)
return (NULL);
c->err = 0;
c->err_info = 0;
if (spho_scope_init(&c->glob, c, NULL) == -1) {
free(c);
return (NULL);
}
SPHO_POSTCOND(c != NULL);
spho_ctx_init(c);
return (c);
}
void
spho_ctx_init(struct spho_ctx *ctx)
{
ctx->err = 0;
ctx->err_info = 0;
ctx->nom_cnt = 0;
spho_scope_init(&ctx->glob, ctx, NULL);
}
void
spho_ctx_destroy(struct spho_ctx *ctx)
{
SPHO_PRECOND(ctx != NULL);
spho_scope_term(&ctx->glob);
spho_scope_cleanup(&ctx->glob);
free(ctx);
}

View file

@ -8,41 +8,59 @@
#include "spho/scope.h"
#include "spho/bind.h"
static void spho_nom_term(struct spho_nom *);
static int scope_nom_lookup_str_local(struct spho_scope *, const char *,
size_t, struct spho_nom **);
static int scope_nom_in_local(struct spho_scope *, struct spho_nom *);
int
void
spho_scope_init(struct spho_scope *sc, struct spho_ctx *ctx,
struct spho_scope *p)
{
sc->ctx = ctx;
sc->parent = p;
SLIST_INIT(&sc->subs);
STAILQ_INIT(&sc->subs);
SLIST_INIT(&sc->noms);
sc->n_noms = 0;
sc->nom_cnt = 0;
TAILQ_INIT(&sc->tps);
STAILQ_INIT(&sc->tps);
sc->bind_loc = NULL;
return (0);
}
void
spho_scope_term(struct spho_scope *sc)
spho_scope_cleanup(struct spho_scope *sc)
{
SPHO_UTIL_SLIST_DESTROY(&sc->subs, spho_scope, next, spho_scope_term);
struct spho_scope *sub;
struct spho_nom *nom;
struct spho_tp_alloc *tp_alloc;
SPHO_UTIL_SLIST_DESTROY(&sc->noms, spho_nom, next, spho_nom_term);
/* XXX is doable without recursive call, but cba */
while (! STAILQ_EMPTY(&sc->subs)) {
sub = STAILQ_FIRST(&sc->subs);
STAILQ_REMOVE_HEAD(&sc->subs, entries);
spho_scope_cleanup(sub);
free(sub);
}
/* all type structs are allocated from scope */
while (! STAILQ_EMPTY(&sc->tps)) {
tp_alloc = STAILQ_FIRST(&sc->tps);
STAILQ_REMOVE_HEAD(&sc->tps, entries);
free(tp_alloc);
}
/* names are allocated in scope too */
while (! SLIST_EMPTY(&sc->noms)) {
nom = SLIST_FIRST(&sc->noms);
SLIST_REMOVE_HEAD(&sc->noms, entries);
free(nom);
}
sc->parent = NULL;
if (sc->bind_loc == NULL)
if (sc->bind_loc != NULL)
spho_prebind_free(sc->bind_loc);
sc->bind_loc = NULL;
}
@ -57,7 +75,7 @@ spho_scope_global(struct spho_ctx *ctx)
struct spho_scope *
spho_scope_create(struct spho_scope *sc)
spho_scope_create_subscope(struct spho_scope *sc)
{
struct spho_scope *sub;
@ -66,35 +84,24 @@ spho_scope_create(struct spho_scope *sc)
return (NULL);
}
if (spho_scope_init(sub, sc->ctx, sc) == -1) {
free(sub);
return (NULL);
}
spho_scope_init(sub, sc->ctx, sc);
SLIST_INSERT_HEAD(&sc->subs, sub, next);
STAILQ_INSERT_TAIL(&sc->subs, sub, entries);
return (sub);
}
static void
spho_nom_term(__attribute__((unused)) struct spho_nom *nom)
{
return;
}
void
spho_scope_destroy(struct spho_scope *sc)
spho_scope_free(struct spho_scope *sc)
{
struct spho_scope *p;
p = sc->parent;
SLIST_REMOVE(&p->subs, sc, spho_scope, next);
spho_scope_term(sc);
STAILQ_REMOVE(&p->subs, sc, spho_scope, entries);
spho_scope_cleanup(sc);
free(sc);
}
struct spho_nom *
spho_scope_nom_add(struct spho_scope *sc, const char *nomstr, size_t sz)
{
@ -122,8 +129,8 @@ spho_scope_nom_add(struct spho_scope *sc, const char *nomstr, size_t sz)
goto err;
}
SLIST_INSERT_HEAD(&sc->noms, nom, next);
sc->n_noms++;
SLIST_INSERT_HEAD(&sc->noms, nom, entries);
sc->nom_cnt++;
return (nom);
err:
@ -133,7 +140,7 @@ err:
int
spho_scope_nom_lookup_str(struct spho_scope *sc, const char *nomstr, size_t sz,
spho_scope_nom_lookup(struct spho_scope *sc, const char *nomstr, size_t sz,
struct spho_nom **out)
{
struct spho_nom *nom;
@ -147,7 +154,7 @@ spho_scope_nom_lookup_str(struct spho_scope *sc, const char *nomstr, size_t sz,
*out = NULL;
while (*out == NULL && sc != NULL) {
SLIST_FOREACH(nom, &sc->noms, next) {
SLIST_FOREACH(nom, &sc->noms, entries) {
if (strncmp(nom->s, nomstr, sz) == 0) {
*out = nom;
break;
@ -160,10 +167,10 @@ spho_scope_nom_lookup_str(struct spho_scope *sc, const char *nomstr, size_t sz,
}
int
spho_scope_nom_lookup_str_strict(struct spho_scope *sc, const char *nomstr,
spho_scope_nom_lookup_strict(struct spho_scope *sc, const char *nomstr,
size_t sz, struct spho_nom **out)
{
if (spho_scope_nom_lookup_str(sc, nomstr, sz, out) == -1)
if (spho_scope_nom_lookup(sc, nomstr, sz, out) == -1)
return (-1);
if (*out == NULL) {
@ -177,10 +184,8 @@ spho_scope_nom_lookup_str_strict(struct spho_scope *sc, const char *nomstr,
int
spho_scope_prebind_init(struct spho_scope *sc)
{
if ((sc->bind_loc = spho_prebind_create(sc))
== NULL) {
if ((sc->bind_loc = spho_prebind_create(sc)) == NULL)
return (-1);
}
return (0);
}
@ -234,7 +239,7 @@ scope_nom_lookup_str_local(struct spho_scope *sc, const char *nomstr,
}
*out = NULL;
SLIST_FOREACH(nom, &sc->noms, next) {
SLIST_FOREACH(nom, &sc->noms, entries) {
if (strncmp(nom->s, nomstr, sz) == 0) {
*out = nom;
break;
@ -249,7 +254,7 @@ scope_nom_in_local(struct spho_scope *sc, struct spho_nom *nom)
{
struct spho_nom *sc_nom;
SLIST_FOREACH(sc_nom, &sc->noms, next) {
SLIST_FOREACH(sc_nom, &sc->noms, entries) {
if (sc_nom == nom)
return (1);
}

View file

@ -20,7 +20,7 @@ spho_tp_alloc(struct spho_scope *sc)
}
((struct spho_tp *)tp_alloc)->sc = sc;
TAILQ_INSERT_TAIL(&sc->tps, tp_alloc, allocs);
STAILQ_INSERT_TAIL(&sc->tps, tp_alloc, entries);
return ((struct spho_tp *)tp_alloc);
}
@ -36,25 +36,11 @@ spho_tp_op_alloc(struct spho_scope *sc)
}
((struct spho_tp_op *)tp_alloc)->sc = sc;
TAILQ_INSERT_TAIL(&sc->tps, tp_alloc, allocs);
STAILQ_INSERT_TAIL(&sc->tps, tp_alloc, entries);
return ((struct spho_tp_op *)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)
@ -270,45 +256,3 @@ spho_tp_op_create(struct spho_scope *sc, struct spho_scope *op_sc, struct spho_t
return (op);
}
/* Free type structure. External data (like nom) are freed elsewhere. */
void
spho_tp_destroy(struct spho_tp *tp)
{
struct spho_tp *arg;
switch (tp->kind & SPHO_TP_FORM_MASK) {
case SPHO_TP_FORM_TRUE:
case SPHO_TP_FORM_FALSE:
case SPHO_TP_FORM_NAME:
case SPHO_TP_FORM_VAR:
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:
spho_tp_destroy(tp->d.fa.tp);
break;
case SPHO_TP_FORM_MEMBER:
spho_tp_destroy(tp->d.memb.tp);
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);
}