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 dkms.conf
# vim # vim
.swp
.swo
.*.swp .*.swp
.*.swo .*.swo

View file

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

View file

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

View file

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

View file

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

View file

@ -7,13 +7,22 @@
#define SPHO_NOM_LEN 128 #define SPHO_NOM_LEN 128
/* name */
struct spho_nom { union spho_ext_data {
char s[SPHO_NOM_LEN]; void *ptr;
SLIST_ENTRY(spho_nom) next; // TODO change to allocs 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!!!!! */ #define TP_KONST_KEY_TRUE 0x43445 /* don't change!!!!! */
@ -76,6 +85,7 @@ struct spho_tp {
int kind; int kind;
union tp_data d; union tp_data d;
union spho_ext_data ext_data;
STAILQ_ENTRY(spho_tp) entries; STAILQ_ENTRY(spho_tp) entries;
}; };
@ -85,30 +95,20 @@ struct spho_tp_op {
struct spho_scope *op_sc; struct spho_scope *op_sc;
struct spho_tp *op_tp; struct spho_tp *op_tp;
union spho_ext_data ext_data;
}; };
STAILQ_HEAD(spho_tp_l, spho_tp); 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 { struct spho_tp_alloc {
union { union {
struct spho_tp tp; struct spho_tp tp;
struct spho_tp_op tp_op; struct spho_tp_op tp_op;
} alloc; } 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 */ /* defined in spho/bind.h */
struct spho_bind; struct spho_bind;
@ -116,33 +116,38 @@ struct spho_scope {
struct spho_ctx *ctx; struct spho_ctx *ctx;
struct spho_scope *parent; struct spho_scope *parent;
struct spho_scope_l subs; STAILQ_HEAD(
spho_scope_l,
size_t n_noms; spho_scope) subs;
struct spho_nom_l noms; STAILQ_HEAD(
struct spho_tp_alloc_l tps; 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; 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)) #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 *); 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_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); 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 **); 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 **); size_t, struct spho_nom **);
int spho_scope_prebind_init(struct spho_scope *); int spho_scope_prebind_init(struct spho_scope *);

View file

@ -9,10 +9,12 @@
struct msph_opts { struct msph_opts {
int tokenize_only; int tokenize_only;
int parser;
const char *in_path; const char *in_path;
const char *out_path; const char *out_path;
} run_opts = { } run_opts = {
0, 0,
MSPH_PARSE_INFIX,
NULL, NULL,
NULL NULL
}; };
@ -20,10 +22,12 @@ struct msph_opts {
#define USAGE \ #define USAGE \
"msph: micro sappho\n" \ "msph: micro sappho\n" \
"\tUsage: msph [-t] [-o out_path] [in_path]\n" \ " Usage: msph [-t] [-o out_path] [-p i|p] [in_path]\n" \
"\n" \ "\n" \
"\t-t - print tokenization\n" \ " -t - print tokenization\n" \
"\t-o - output path\n" " -o - output path\n" \
" -p i[nfix]|p[refix] - infix or prefix &, |, =>, -> parsing\n" \
" (default infix)\n"
void void
print_usage(void) print_usage(void)
@ -38,7 +42,7 @@ main(int argc, char *argv[])
{ {
int opt; int opt;
while ((opt = getopt(argc, argv, "hto:")) != -1) { while ((opt = getopt(argc, argv, "hto:p:")) != -1) {
switch (opt) { switch (opt) {
case 't': case 't':
run_opts.tokenize_only = 1; run_opts.tokenize_only = 1;
@ -46,6 +50,19 @@ main(int argc, char *argv[])
case 'o': case 'o':
run_opts.out_path = optarg; run_opts.out_path = optarg;
break; 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': case 'h':
print_usage(); print_usage();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@ -122,7 +139,7 @@ run(struct msph_opts *opts)
goto err; goto err;
} }
if (msph_tree_parse(s, root) == -1) if (msph_tree_parse(s, root, opts->parser) == -1)
goto err; goto err;
printf("msph tree successfully parsed :)\n"); 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 *); struct msph_tree *);
static int msph_tree_sphophi_decor_tp(struct spho_scope *, static int msph_tree_sphophi_decor_tp(struct spho_scope *,
struct msph_tree *); 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 *); struct msph_tree *);
/* is the tree a name binding? */ /* 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 *); struct spho_scope *, struct msph_tree_disj *);
static int msph_sphophi_foreach_pre_impl(msph_tree_sphophi_f, static int msph_sphophi_foreach_pre_impl(msph_tree_sphophi_f,
struct spho_scope *, struct msph_tree_impl *); 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, static int msph_sphophi_foreach_pre_arrow(msph_tree_sphophi_f,
struct spho_scope *, struct msph_tree_arrow *); struct spho_scope *, struct msph_tree_arrow *);
static int msph_sphophi_foreach_pre_box(msph_tree_sphophi_f, 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 *); struct spho_scope *, struct msph_tree_disj *);
static int msph_sphophi_foreach_post_impl(msph_tree_sphophi_f, static int msph_sphophi_foreach_post_impl(msph_tree_sphophi_f,
struct spho_scope *, struct msph_tree_impl *); 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, static int msph_sphophi_foreach_post_arrow(msph_tree_sphophi_f,
struct spho_scope *, struct msph_tree_arrow *); struct spho_scope *, struct msph_tree_arrow *);
static int msph_sphophi_foreach_post_box(msph_tree_sphophi_f, static int msph_sphophi_foreach_post_box(msph_tree_sphophi_f,
@ -154,7 +158,7 @@ msph_sphophi_tp(struct msph_tree_root *root)
int int
msph_sphophi_tp_prebind(struct msph_tree_root *root) 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)); 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_UNIT:
case MSPH_TREE_TRAIT: case MSPH_TREE_TRAIT:
case MSPH_TREE_FORALL: case MSPH_TREE_FORALL:
if ((SCOPE(tree) = spho_scope_create(sc)) == NULL) if ((SCOPE(tree) = spho_scope_create_subscope(sc)) == NULL)
ret = -1; return (-1);
ADD_FLAG(tree, MSPH_TREE_FLAG_SCOPE); ADD_FLAG(tree, MSPH_TREE_FLAG_SCOPE);
break; break;
case MSPH_TREE_TPDEF: case MSPH_TREE_TPDEF:
tpdef = (struct msph_tree_tpdef *)tree; tpdef = (struct msph_tree_tpdef *)tree;
if (! STAILQ_EMPTY(&tpdef->params) && if (STAILQ_EMPTY(&tpdef->params))
((SCOPE(tpdef) = spho_scope_create(sc)) == NULL)) { break;
ret = -1; if (((SCOPE(tpdef) = spho_scope_create_subscope(sc)) == NULL))
} return (-1);
ADD_FLAG(tree, MSPH_TREE_FLAG_SCOPE); ADD_FLAG(tree, MSPH_TREE_FLAG_SCOPE);
break; break;
case MSPH_TREE_IDENT: case MSPH_TREE_NAMEDECL:
if (! IS_BINDING(tree->parent)) SPHO_ASSERT(IS_BINDING(tree->parent));
break;
ident = (struct msph_tree_ident *)tree; ident = (struct msph_tree_ident *)tree;
if ((NOM(ident) = spho_scope_nom_add(sc, ident->str, if ((NOM(ident) = spho_scope_nom_add(sc, ident->str,
sizeof(ident->str))) == NULL) sizeof(ident->str))) == NULL) {
ret = -1; return (-1);
}
ADD_FLAG(tree, MSPH_TREE_FLAG_NOM); ADD_FLAG(tree, MSPH_TREE_FLAG_NOM);
break; break;
default: default:
@ -230,12 +234,14 @@ msph_tree_sphophi_decor_tpexpr_nom(struct spho_scope *sc,
switch (TREE_ID(tree)) { switch (TREE_ID(tree)) {
case MSPH_TREE_IDENT: case MSPH_TREE_IDENT:
if (! IS_TPEXPR(tree->parent)) SPHO_ASSERT(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));
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; break;
default: default:
break; 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_trait *trait;
struct msph_tree_dir *dir; struct msph_tree_dir *dir;
struct msph_tree_membdecl *membd; struct msph_tree_membdecl *membd;
struct msph_tree_subt *subt;
struct spho_tp_l *tps; struct spho_tp_l *tps;
struct spho_tp *tp, *tp_memb; 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; dir = NULL;
membd = NULL; membd = NULL;
if (! (tree->type & MSPH_TREE_TPEXPR)) if (! IS_TPEXPR(tree))
return (0); return (0);
switch (TREE_ID(tree)) { switch (TREE_ID(tree)) {
case MSPH_TREE_CONJ: case MSPH_TREE_CONJ:
conj = (struct msph_tree_conj *)tree; conj = (struct msph_tree_conj *)tree;
if ((TP(conj) = spho_tp_create_conj(sc, TP(conj->ltp), if ((TP(conj) = spho_tp_create_conj(sc, TP(conj->ltp),
TP(conj->rtp))) == NULL) TP(conj->rtp))) == NULL) {
goto cleanup; goto cleanup;
}
ADD_FLAG(conj, MSPH_TREE_FLAG_TP); ADD_FLAG(conj, MSPH_TREE_FLAG_TP);
break; break;
case MSPH_TREE_DISJ: case MSPH_TREE_DISJ:
disj = (struct msph_tree_disj *)tree; disj = (struct msph_tree_disj *)tree;
if ((TP(disj) = spho_tp_create_conj(sc, TP(disj->ltp), if ((TP(disj) = spho_tp_create_conj(sc, TP(disj->ltp),
TP(disj->rtp))) == NULL) TP(disj->rtp))) == NULL) {
goto cleanup; goto cleanup;
}
ADD_FLAG(disj, MSPH_TREE_FLAG_TP); ADD_FLAG(disj, MSPH_TREE_FLAG_TP);
break; break;
case MSPH_TREE_IMPL: case MSPH_TREE_IMPL:
impl = (struct msph_tree_impl *)tree; impl = (struct msph_tree_impl *)tree;
if ((TP(impl) = spho_tp_create_conj(sc, TP(impl->ltp), if ((TP(impl) = spho_tp_create_conj(sc, TP(impl->ltp),
TP(impl->rtp))) == NULL) TP(impl->rtp))) == NULL) {
goto cleanup; goto cleanup;
}
ADD_FLAG(impl, MSPH_TREE_FLAG_TP); ADD_FLAG(impl, MSPH_TREE_FLAG_TP);
break; 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: case MSPH_TREE_ARROW:
arrow = (struct msph_tree_arrow *)tree; arrow = (struct msph_tree_arrow *)tree;
if ((TP(arrow) = spho_tp_create_conj(sc, TP(arrow->ltp), if ((TP(arrow) = spho_tp_create_conj(sc, TP(arrow->ltp),
TP(arrow->rtp))) == NULL) TP(arrow->rtp))) == NULL) {
goto cleanup; goto cleanup;
}
ADD_FLAG(arrow, MSPH_TREE_FLAG_TP); ADD_FLAG(arrow, MSPH_TREE_FLAG_TP);
break; break;
case MSPH_TREE_TPNAME: case MSPH_TREE_TPNAME:
tpname = (struct msph_tree_tpname *)tree; tpname = (struct msph_tree_tpname *)tree;
if ((TP(tpname) = spho_tp_create_name(sc, NOM(tpname->name))) if ((TP(tpname) = spho_tp_create_name(sc, NOM(tpname->name)))
== NULL) == NULL) {
goto cleanup; goto cleanup;
}
ADD_FLAG(tpname, MSPH_TREE_FLAG_TP); ADD_FLAG(tpname, MSPH_TREE_FLAG_TP);
break; break;
case MSPH_TREE_TPAPPL: 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); ADD_FLAG(trait, MSPH_TREE_FLAG_TP);
break; break;
default: default:
SPHO_ASSERT(0); SPHO_RIP("impossible-default-reached");
break; break;
} }
@ -397,7 +420,7 @@ cleanup:
} }
static int static int
msph_tree_sphophi_tp_prebind(struct spho_scope *sc, msph_tree_sphophi_prebind(struct spho_scope *sc,
struct msph_tree *tree) struct msph_tree *tree)
{ {
int ret; int ret;
@ -444,6 +467,8 @@ msph_tree_sphophi_tp_prebind(struct spho_scope *sc,
} }
} }
break; break;
case MSPH_TREE_NOMINDECL:
break;
default: default:
break; 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) if ((ret = f(sc, TREE(ass))) != 0)
return (ret); return (ret);
if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, ass->ltp)) != 0) if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, ass->tp)) != 0)
return (ret);
if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, ass->rtp)) != 0)
return (ret); return (ret);
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, ret = msph_sphophi_foreach_pre_impl(f, sc,
(struct msph_tree_impl *)tpexpr); (struct msph_tree_impl *)tpexpr);
break; break;
case MSPH_TREE_SUBT:
ret = msph_sphophi_foreach_pre_subt(f, sc,
(struct msph_tree_subt *)tpexpr);
break;
case MSPH_TREE_ARROW: case MSPH_TREE_ARROW:
ret = msph_sphophi_foreach_pre_arrow(f, sc, ret = msph_sphophi_foreach_pre_arrow(f, sc,
(struct msph_tree_arrow *)tpexpr); (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); (struct msph_tree_false *)tpexpr);
break; break;
default: default:
SPHO_RIP("default-reach"); SPHO_RIP("impossible-default-reached");
break; 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)); 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 static int
msph_sphophi_foreach_pre_arrow(msph_tree_sphophi_f f, struct spho_scope *sc, msph_sphophi_foreach_pre_arrow(msph_tree_sphophi_f f, struct spho_scope *sc,
struct msph_tree_arrow *arrow) 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(sc != NULL);
SPHO_PRECOND(ass != NULL); SPHO_PRECOND(ass != NULL);
if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, ass->ltp)) != 0) if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, ass->tp)) != 0)
return (ret);
if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, ass->rtp)) != 0)
return (ret); return (ret);
return (f(sc, TREE(ass))); 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, ret = msph_sphophi_foreach_post_impl(f, sc,
(struct msph_tree_impl *)tpexpr); (struct msph_tree_impl *)tpexpr);
break; break;
case MSPH_TREE_SUBT:
ret = msph_sphophi_foreach_post_subt(f, sc,
(struct msph_tree_subt *)tpexpr);
break;
case MSPH_TREE_ARROW: case MSPH_TREE_ARROW:
ret = msph_sphophi_foreach_post_arrow(f, sc, ret = msph_sphophi_foreach_post_arrow(f, sc,
(struct msph_tree_arrow *)tpexpr); (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))); 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 static int
msph_sphophi_foreach_post_arrow(msph_tree_sphophi_f f, struct spho_scope *sc, msph_sphophi_foreach_post_arrow(msph_tree_sphophi_f f, struct spho_scope *sc,
struct msph_tree_arrow *arrow) struct msph_tree_arrow *arrow)

View file

@ -48,7 +48,7 @@ struct msph_matcher token_matchers[] = {
{ 0, 0, TOK_CONST_FALSE }, { 0, 0, TOK_CONST_FALSE },
{ 0, 0, TOK_IDENT }, { 0, 0, TOK_IDENT },
{ 0, 0, TOK_END } { 0, 0, TOK_NOPE }
}; };
struct msph_matcher wspace = { 0, 0, TOK_WSPACE }; 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_CONST_FALSE, "False"),
TOK_INFO(TOK_IDENT, NULL), TOK_INFO(TOK_IDENT, NULL),
{ TOK_END , NULL, NULL } { TOK_NOPE , NULL, NULL }
#undef TOK_INFO #undef TOK_INFO
}; };
@ -305,7 +305,7 @@ read_single_tok(struct msph_token *ptr, struct msph_token_stream *s)
return (-1); return (-1);
max_m = 0; 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]); res = tok_match(ctx, src, &token_matchers[m]);
if (res == -1) if (res == -1)
@ -358,7 +358,7 @@ msph_token_copy(struct msph_ctx *ctx, struct msph_token *token)
info = NULL; 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) { if (token_info[i].type == token->type) {
info = &token_info[i]; info = &token_info[i];
break; break;
@ -769,7 +769,7 @@ static const char *
tok_base_str(struct msph_token *tok) tok_base_str(struct msph_token *tok)
{ {
size_t i; 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) if (token_info[i].type == tok->type)
return (token_info[i].dbg_str); 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); 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); SPHO_ERR(sc->ctx, SPHO_ERR_SYS);
free(bind); free(bind);
return (NULL); return (NULL);
} }
bind->sc = sc; bind->sc = sc;
bind->sz = sc->n_noms; bind->sz = sc->nom_cnt;
i = 0; i = 0;
SLIST_FOREACH(nom, &sc->noms, next) { SLIST_FOREACH(nom, &sc->noms, entries) {
SPHO_ASSERT(i < bind->sz); 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); return (bind);

View file

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

View file

@ -8,41 +8,59 @@
#include "spho/scope.h" #include "spho/scope.h"
#include "spho/bind.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 *, static int scope_nom_lookup_str_local(struct spho_scope *, const char *,
size_t, struct spho_nom **); size_t, struct spho_nom **);
static int scope_nom_in_local(struct spho_scope *, 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, spho_scope_init(struct spho_scope *sc, struct spho_ctx *ctx,
struct spho_scope *p) struct spho_scope *p)
{ {
sc->ctx = ctx; sc->ctx = ctx;
sc->parent = p; sc->parent = p;
SLIST_INIT(&sc->subs); STAILQ_INIT(&sc->subs);
SLIST_INIT(&sc->noms); SLIST_INIT(&sc->noms);
sc->n_noms = 0; sc->nom_cnt = 0;
TAILQ_INIT(&sc->tps); STAILQ_INIT(&sc->tps);
sc->bind_loc = NULL; sc->bind_loc = NULL;
return (0);
} }
void 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; sc->parent = NULL;
if (sc->bind_loc == NULL) if (sc->bind_loc != NULL)
spho_prebind_free(sc->bind_loc); spho_prebind_free(sc->bind_loc);
sc->bind_loc = NULL; sc->bind_loc = NULL;
} }
@ -57,7 +75,7 @@ spho_scope_global(struct spho_ctx *ctx)
struct spho_scope * struct spho_scope *
spho_scope_create(struct spho_scope *sc) spho_scope_create_subscope(struct spho_scope *sc)
{ {
struct spho_scope *sub; struct spho_scope *sub;
@ -66,35 +84,24 @@ spho_scope_create(struct spho_scope *sc)
return (NULL); return (NULL);
} }
if (spho_scope_init(sub, sc->ctx, sc) == -1) { spho_scope_init(sub, sc->ctx, sc);
free(sub);
return (NULL);
}
SLIST_INSERT_HEAD(&sc->subs, sub, next); STAILQ_INSERT_TAIL(&sc->subs, sub, entries);
return (sub); return (sub);
} }
static void
spho_nom_term(__attribute__((unused)) struct spho_nom *nom)
{
return;
}
void void
spho_scope_destroy(struct spho_scope *sc) spho_scope_free(struct spho_scope *sc)
{ {
struct spho_scope *p; struct spho_scope *p;
p = sc->parent; p = sc->parent;
SLIST_REMOVE(&p->subs, sc, spho_scope, next); STAILQ_REMOVE(&p->subs, sc, spho_scope, entries);
spho_scope_term(sc); spho_scope_cleanup(sc);
free(sc); free(sc);
} }
struct spho_nom * struct spho_nom *
spho_scope_nom_add(struct spho_scope *sc, const char *nomstr, size_t sz) 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; goto err;
} }
SLIST_INSERT_HEAD(&sc->noms, nom, next); SLIST_INSERT_HEAD(&sc->noms, nom, entries);
sc->n_noms++; sc->nom_cnt++;
return (nom); return (nom);
err: err:
@ -133,7 +140,7 @@ err:
int 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 **out)
{ {
struct spho_nom *nom; 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; *out = NULL;
while (*out == NULL && sc != 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) { if (strncmp(nom->s, nomstr, sz) == 0) {
*out = nom; *out = nom;
break; break;
@ -160,10 +167,10 @@ spho_scope_nom_lookup_str(struct spho_scope *sc, const char *nomstr, size_t sz,
} }
int 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) 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); return (-1);
if (*out == NULL) { if (*out == NULL) {
@ -177,10 +184,8 @@ spho_scope_nom_lookup_str_strict(struct spho_scope *sc, const char *nomstr,
int int
spho_scope_prebind_init(struct spho_scope *sc) spho_scope_prebind_init(struct spho_scope *sc)
{ {
if ((sc->bind_loc = spho_prebind_create(sc)) if ((sc->bind_loc = spho_prebind_create(sc)) == NULL)
== NULL) {
return (-1); return (-1);
}
return (0); return (0);
} }
@ -234,7 +239,7 @@ scope_nom_lookup_str_local(struct spho_scope *sc, const char *nomstr,
} }
*out = NULL; *out = NULL;
SLIST_FOREACH(nom, &sc->noms, next) { SLIST_FOREACH(nom, &sc->noms, entries) {
if (strncmp(nom->s, nomstr, sz) == 0) { if (strncmp(nom->s, nomstr, sz) == 0) {
*out = nom; *out = nom;
break; break;
@ -249,7 +254,7 @@ scope_nom_in_local(struct spho_scope *sc, struct spho_nom *nom)
{ {
struct spho_nom *sc_nom; struct spho_nom *sc_nom;
SLIST_FOREACH(sc_nom, &sc->noms, next) { SLIST_FOREACH(sc_nom, &sc->noms, entries) {
if (sc_nom == nom) if (sc_nom == nom)
return (1); return (1);
} }

View file

@ -20,7 +20,7 @@ spho_tp_alloc(struct spho_scope *sc)
} }
((struct spho_tp *)tp_alloc)->sc = 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); 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; ((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); 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 * struct spho_tp *
spho_tp_create_conj(struct spho_scope *sc, struct spho_tp *ltp, spho_tp_create_conj(struct spho_scope *sc, struct spho_tp *ltp,
struct spho_tp *rtp) 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); 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);
}