diff --git a/.gitignore b/.gitignore index bda0148..4929d75 100644 --- a/.gitignore +++ b/.gitignore @@ -66,6 +66,9 @@ compile_commands.json # clangd .clangd +# ctags tagfile +tags + # other stuff local/ diff --git a/CMakeLists.txt b/CMakeLists.txt index cd65d36..f22b1e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,8 @@ set(CMAKE_C_STANDARD_REQUIRED True) string(JOIN " " CMAKE_C_FLAGS "-Wall -Wextra -Wformat=2" "-Wconversion -Wsign-conversion -Wimplicit-fallthrough" - "-Werror=implicit -Werror=incompatible-pointer-types" + "-Werror=implicit" + "-Werror=incompatible-pointer-types" "-Werror=int-conversion") set(CMAKE_VERBOSE_MAKEFILE ON) @@ -21,19 +22,19 @@ set(SRC_DIR src) set(SPHO_HEADER_DIR ${INCLUDE_DIR}/spho) set(SPHO_HEADER + ${SPHO_HEADER_DIR}/bind.h ${SPHO_HEADER_DIR}/ctx.h ${SPHO_HEADER_DIR}/err.h ${SPHO_HEADER_DIR}/scope.h - ${SPHO_HEADER_DIR}/tp.h - ${SPHO_HEADER_DIR}/bind.h ${SPHO_HEADER_DIR}/spho.h + ${SPHO_HEADER_DIR}/tp.h ) set(SPHO_SRC + ${SRC_DIR}/spho/bind.c ${SRC_DIR}/spho/ctx.c ${SRC_DIR}/spho/scope.c ${SRC_DIR}/spho/tp.c - ${SRC_DIR}/spho/bind.c ) check_symbol_exists(strlcpy "string.h" HAVE_STRLCPY) @@ -54,19 +55,18 @@ target_compile_definitions(devcheck PRIVATE set(MSPH_SRC + ${SRC_DIR}/msph/msph.c + ${SRC_DIR}/msph/sphophi.c ${SRC_DIR}/msph/token.c ${SRC_DIR}/msph/tree.c - ${SRC_DIR}/msph/sphophi.c - ${SRC_DIR}/msph/msph.c ) set(MSPH_HEADER - ${INCLUDE_DIR}/msph/token.h - ${INCLUDE_DIR}/msph/tree.h ${INCLUDE_DIR}/msph/common.h ${INCLUDE_DIR}/msph/err.h - ${INCLUDE_DIR}/msph/decor.h ${INCLUDE_DIR}/msph/sphophi.h + ${INCLUDE_DIR}/msph/token.h + ${INCLUDE_DIR}/msph/tree.h ) add_executable(msph ${MSPH_SRC} ${MSPH_HEADER}) diff --git a/include/msph/decor.h b/include/msph/decor.h deleted file mode 100644 index db302d3..0000000 --- a/include/msph/decor.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _MSPH_DECOR_H -#define _MSPH_DECOR_H - -struct msph_tp_decor { - struct spho_tp *tp; -}; - -#define TP_DECOR_INIT(ptr) \ - do { \ - (ptr)->tp = NULL; \ - } while (0) - -struct msph_scope_decor { - struct spho_scope *sc; -}; - -#define SCOPE_DECOR_INIT(ptr) \ - do { \ - (ptr)->sc = NULL; \ - } while (0) - -struct msph_nom_decor { - struct spho_nom *nom; -}; - -#define NOM_DECOR_INIT(ptr) \ - do { \ - (ptr)->nom = NULL; \ - } while (0) - -#define GET_SCOPE(ptr) ((ptr)->dec.sc) - -#endif /* _MSPH_DECOR_H */ diff --git a/include/msph/sphophi.h b/include/msph/sphophi.h index fa723be..65508f1 100644 --- a/include/msph/sphophi.h +++ b/include/msph/sphophi.h @@ -7,7 +7,7 @@ int msph_sphophi_init(struct msph_tree_root *); int msph_sphophi_scope(struct msph_tree_root *); int msph_sphophi_nom_lookup(struct msph_tree_root *); int msph_sphophi_tp(struct msph_tree_root *); -int msph_sphophi_bind_static_tp_names(struct msph_tree_root *); +int msph_sphophi_tp_prebind(struct msph_tree_root *); int msph_sphophi(struct msph_tree_root *); diff --git a/include/msph/tree.h b/include/msph/tree.h index a41a939..028f329 100644 --- a/include/msph/tree.h +++ b/include/msph/tree.h @@ -5,59 +5,16 @@ #include "msph/common.h" #include "msph/token.h" -#include "msph/decor.h" -/* - * TYPES: - * Conj - * Disj - * Impl - * Arrow - * Box - * (Sub) - * Forall - * - * True - * False - * Var - * Nominal - * - * Record - * - * DEFINITIONS/DIRECTIVES: - * Type definition (type A[X..] = T) - * Nominal definition (nominal N) - * Member definition (member mname : T) - * - * { - * member a: A - * member b: B - * } - * - * Subtyping assert (assert A <: B, asserts that A <: B) - * - * EXTRA DEFINITIONS - * Class definition (class C[...] { ... }, shorthand) - * - * EXPRESSIONS - * Conj - * Disj - * Impl - * Arrow - * Box - * (Sub) - * Forall - * - * True - * False - * Var - * Nominal - * - * Trait ({ ... }, creates scoping) - */ +/* tree decorations */ +struct msph_decor { + struct spho_scope *sc; + struct spho_tp *tp; + struct spho_nom *nom; +}; -#define MSPH_TREE_ROOT (0x0000 | MSPH_TREE_FLAG_SCOPE) -#define MSPH_TREE_UNIT (0x0001 | MSPH_TREE_FLAG_SCOPE) +#define MSPH_TREE_ROOT 0x0000 +#define MSPH_TREE_UNIT 0x0001 #define MSPH_TREE_BODY 0x0010 @@ -70,31 +27,76 @@ #define MSPH_TREE_TPEXPR 0x0040 #define MSPH_TREE_TRUE 0x0041 #define MSPH_TREE_FALSE 0x0042 -#define MSPH_TREE_NAME 0x0043 -#define MSPH_TREE_APPL 0x0044 -#define MSPH_TREE_TRAIT (0x0045 | MSPH_TREE_FLAG_SCOPE) +#define MSPH_TREE_TPNAME 0x0043 +#define MSPH_TREE_TPAPPL 0x0044 +#define MSPH_TREE_TRAIT 0x0045 #define MSPH_TREE_CONJ 0x0046 #define MSPH_TREE_DISJ 0x0047 #define MSPH_TREE_IMPL 0x0048 #define MSPH_TREE_ARROW 0x0049 #define MSPH_TREE_BOX 0x004a -#define MSPH_TREE_FORALL (0x004b | MSPH_TREE_FLAG_SCOPE) +#define MSPH_TREE_FORALL 0x004b #define MSPH_TREE_PAREN 0x004c -#define MSPH_TREE_IDENT 0x0080 +#define MSPH_TREE_IDENT 0x0100 +#define MSPH_TREE_NAMEDECL 0x0101 +#define MSPH_TREE_NAMEREF 0x0102 -#define MSPH_TREE_MASK_ID 0x0fff -#define MSPH_TREE_MASK_FLAGS 0xf000 +#define MSPH_TREE_FLAG_OFFSET 16 -#define MSPH_TREE_FLAG_SCOPE 0x1000 -#define MSPH_TREE_FLAG_STATIC_BIND 0x2000 +#define MSPH_TREE_FLAG_SCOPE (1 << (MSPH_TREE_FLAG_OFFSET)) +#define MSPH_TREE_FLAG_TP (1 << (MSPH_TREE_FLAG_OFFSET + 1)) +#define MSPH_TREE_FLAG_NOM (1 << (MSPH_TREE_FLAG_OFFSET + 2)) -#define MSPH_TREE_SCOPE(type) (type & MSPH_TREE_FLAG_SCOPE) -#define MSPH_TREE_STATIC_BIND(type) (type & MSPH_TREE_FLAG_STATIC_BIND) +#define MSPH_TREE_MASK_FLAGS ((~0x0u) << MSPH_TREE_FLAG_OFFSET) +#define MSPH_TREE_MASK_ID ((~0x0u) ^ MSPH_TREE_MASK_FLAGS) + +#define ADD_FLAG(tree, flag) \ + do { \ + TREE(tree)->type |= flag; \ + } while (0) +#define HAS_FLAG(tree, flag) (TREE(tree)->type & (flag)) + +#define TREE(tree) ((struct msph_tree *)tree) +#define TEXT(tree) ((struct msph_tree_text *)tree) +#define IDENT(tree) ((struct msph_tree_ident *)tree) +#define TPEXPR(tree) ((struct msph_tree_tpexpr *)tree) + +#define HAS_SCOPE(tree) HAS_FLAG((tree), MSPH_TREE_FLAG_SCOPE) +#define HAS_TP(tree) HAS_FLAG((tree), MSPH_TREE_FLAG_TP) +#define HAS_NOM(tree) HAS_FLAG((tree), MSPH_TREE_FLAG_NOM) + +#define HAS_PARAMS(tpdef) (! STAILQ_EMPTY(&(tpdef)->params)) + +#define TREE_ID(tree) (((struct msph_tree *)tree)->type & \ + MSPH_TREE_MASK_ID) + +#define DECOR(tree) (TREE(tree)->decor) +#define SCOPE(tree) (TREE(tree)->decor.sc) +#define TP(tree) (TREE(tree)->decor.tp) +#define NOM(tree) (TREE(tree)->decor.nom) + +#define DECOR_INIT(tree) \ + do { \ + DECOR(tree) = (struct msph_decor) { NULL, NULL, NULL }; \ + } while (0) struct msph_tree { - int type; + unsigned int type; struct msph_tree *parent; + struct msph_decor decor; +}; + + +struct msph_tree_text { + struct msph_tree hd_tr; + struct msph_text_pos pos; +}; + +struct msph_tree_ident { + struct msph_tree_text hd_txt; + + char str[MSPH_IDENT_LEN]; }; struct msph_tree_root; @@ -108,7 +110,7 @@ struct msph_tree_ident; struct msph_tree_tpexpr; struct msph_tree_root { - struct msph_tree htr; + struct msph_tree hd_tr; struct msph_ctx *ctx; @@ -116,155 +118,144 @@ struct msph_tree_root { }; struct msph_tree_unit { - struct msph_tree htr; + struct msph_tree hd_tr; char name[MSPH_NAME_LEN]; struct msph_tree_body *body; - struct msph_scope_decor dec; STAILQ_ENTRY(msph_tree_unit) entries; }; -struct msph_tree_text { - struct msph_tree htr; - struct msph_text_pos pos; -}; - struct msph_tree_body { - struct msph_tree htr; + struct msph_tree hd_tr; STAILQ_HEAD(msph_tree_dir_l, msph_tree_dir) head; }; struct msph_tree_dir { - struct msph_tree_text htxt; + struct msph_tree_text hd_txt; STAILQ_ENTRY(msph_tree_dir) entries; }; struct msph_tree_tpdef { - struct msph_tree_dir hdir; + struct msph_tree_dir hd_dir; - struct msph_tree_ident *id; + struct msph_tree_namedecl *name; + STAILQ_HEAD(msph_tree_namedecl_l, msph_tree_namedecl) params; struct msph_tree_tpexpr *tp; }; struct msph_tree_nomindecl { - struct msph_tree_dir hdir; + struct msph_tree_dir hd_dir; - struct msph_tree_ident *id; - struct msph_tree_tpexpr *tp; + struct msph_tree_namedecl *name; }; struct msph_tree_membdecl { - struct msph_tree_dir hdir; + struct msph_tree_dir hd_dir; - struct msph_tree_ident *id; - struct msph_tree_tpexpr *tp; + struct msph_tree_namedecl *name; + struct msph_tree_tpexpr *tp; }; struct msph_tree_assert { - struct msph_tree_dir hdir; + struct msph_tree_dir hd_dir; struct msph_tree_tpexpr *ltp; struct msph_tree_tpexpr *rtp; }; -struct msph_tree_tpexpr { - struct msph_tree_text htxt; +struct msph_tree_namedecl { + struct msph_tree_ident hd_id; - STAILQ_ENTRY(msph_tree_tpexpr) entries; - - struct msph_tp_decor dec; + STAILQ_ENTRY(msph_tree_namedecl) entries; }; +struct msph_tree_tpexpr { + struct msph_tree_text hd_txt; + + STAILQ_ENTRY(msph_tree_tpexpr) entries; +}; struct msph_tree_true { - struct msph_tree_tpexpr htpe; + struct msph_tree_tpexpr hd_tpe; }; struct msph_tree_false { - struct msph_tree_tpexpr htpe; + struct msph_tree_tpexpr hd_tpe; }; -struct msph_tree_name { - struct msph_tree_tpexpr htpe; - - struct msph_tree_ident *id; +struct msph_tree_nameref { + struct msph_tree_ident hd_id; }; -struct msph_tree_appl { - struct msph_tree_tpexpr htpe; +struct msph_tree_tpname { + struct msph_tree_tpexpr hd_tpe; - struct msph_tree_ident *id; - STAILQ_HEAD(msph_tree_tpexpr_l, msph_tree_tpexpr) head; + struct msph_tree_nameref *name; +}; + +struct msph_tree_tpappl { + struct msph_tree_tpexpr hd_tpe; + + struct msph_tree_nameref *name; + STAILQ_HEAD(msph_tree_tpexpr_l, msph_tree_tpexpr) args; }; struct msph_tree_trait { - struct msph_tree_tpexpr htpe; + struct msph_tree_tpexpr hd_tpe; struct msph_tree_body *body; - - struct msph_scope_decor dec; }; struct msph_tree_conj { - struct msph_tree_tpexpr htpe; + struct msph_tree_tpexpr hd_tpe; struct msph_tree_tpexpr *ltp; struct msph_tree_tpexpr *rtp; }; struct msph_tree_disj { - struct msph_tree_tpexpr htpe; + struct msph_tree_tpexpr hd_tpe; struct msph_tree_tpexpr *ltp; struct msph_tree_tpexpr *rtp; }; struct msph_tree_impl { - struct msph_tree_tpexpr htpe; + struct msph_tree_tpexpr hd_tpe; struct msph_tree_tpexpr *ltp; struct msph_tree_tpexpr *rtp; }; struct msph_tree_arrow { - struct msph_tree_tpexpr htpe; + struct msph_tree_tpexpr hd_tpe; struct msph_tree_tpexpr *ltp; struct msph_tree_tpexpr *rtp; }; struct msph_tree_box { - struct msph_tree_tpexpr htpe; + struct msph_tree_tpexpr hd_tpe; struct msph_tree_tpexpr *inner; }; struct msph_tree_forall { - struct msph_tree_tpexpr htpe; + struct msph_tree_tpexpr hd_tpe; - struct msph_tree_ident *id; - struct msph_tree_tpexpr *inner; - - struct msph_scope_decor dec; + struct msph_tree_namedecl *name; + struct msph_tree_tpexpr *inner; }; struct msph_tree_paren { - struct msph_tree_tpexpr htpe; + struct msph_tree_tpexpr hd_tpe; struct msph_tree_tpexpr *inner; }; -struct msph_tree_ident { - struct msph_tree_text htxt; - - char str[MSPH_IDENT_LEN]; - STAILQ_ENTRY(msph_tree_ident) entries; - - struct msph_nom_decor dec; -}; struct msph_tree_root *msph_tree_makeroot(struct msph_ctx *); @@ -272,7 +263,4 @@ int msph_tree_parse(struct msph_token_stream *, struct msph_tree_root *); ssize_t msph_tree_fprint(FILE *, struct msph_tree *); -#define T(ptr) ((struct msph_tree *)ptr) -#define TXT(ptr) ((struct msph_tree_text *)ptr) - #endif diff --git a/include/spho/bind.h b/include/spho/bind.h index 9a19b38..3cdd75d 100644 --- a/include/spho/bind.h +++ b/include/spho/bind.h @@ -5,50 +5,49 @@ #include "spho/scope.h" -#define SPHO_BIND_KIND_TP 1 -#define SPHO_BIND_KIND_TPOP 2 +#define SPHO_BIND_UNDECLARED 0x0 +#define SPHO_BIND_UNDEFINED 0x01 +#define SPHO_BIND_TP 0x11 +#define SPHO_BIND_TP_OP 0x12 +#define SPHO_BIND_MEMB_TP 0x13 -union spho_bound { - struct spho_tp *tp; - struct spho_tpop *op; +union spho_prebind_val { + const void *undef; + const struct spho_tp *tp; + const struct spho_tp_op *op; }; -struct spho_binding { - struct spho_nom *nom; +struct spho_prebind_pair { + const struct spho_nom *nom; - int kind; - union spho_bound bound; + int kind; + union spho_prebind_val val; }; -struct spho_bind_scope { - struct spho_scope *sc; +struct spho_prebind { + struct spho_scope *sc; - size_t cap_bds; - size_t n_bds; - struct spho_binding *bds; + size_t sz; + struct spho_prebind_pair *binds; }; struct spho_bind { - struct spho_ctx *ctx; - struct spho_bind_scope *binder; + struct spho_prebind *local; struct spho_bind *parent; }; -struct spho_bind_scope *spho_bind_scope_create(struct spho_scope *); +struct spho_prebind *spho_prebind_create(struct spho_scope *); -int spho_bind_scope_add_tp(struct spho_bind_scope *, struct spho_nom *, - struct spho_tp *); -int spho_bind_scope_add_tpop(struct spho_bind_scope *, struct spho_nom *, - struct spho_tpop *); +int spho_prebind_undef(struct spho_prebind *, const struct spho_nom *); +int spho_prebind_tp(struct spho_prebind *, const struct spho_nom *, + const struct spho_tp *); +int spho_prebind_tp_op(struct spho_prebind *, const struct spho_nom *, + const struct spho_tp_op *); +int spho_prebind_member_tp(struct spho_prebind *, const struct spho_nom *, + const struct spho_tp *); -void spho_bind_scope_destroy(struct spho_bind_scope *); +struct spho_prebind *spho_prebind_dupl(const struct spho_prebind *); -struct spho_bind *spho_bind_create(struct spho_ctx *, struct spho_bind_scope *, - struct spho_bind *); - -int spho_bind_lkp(int, struct spho_bind *, struct spho_nom *, - union spho_bound **); - -void spho_bind_destroy(struct spho_bind *); +void spho_prebind_destroy(struct spho_prebind *); #endif diff --git a/include/spho/err.h b/include/spho/err.h index 29ce9d1..2f56532 100644 --- a/include/spho/err.h +++ b/include/spho/err.h @@ -14,7 +14,8 @@ #define SPHO_ERR_ARGINVAL 0x010003 #define SPHO_ERR_NOM_INUSE 0x020001 #define SPHO_ERR_NOM_NOTINSCOPE 0x020002 -#define SPHO_ERR_BIND_EXISTS 0x030001 +#define SPHO_ERR_BIND_DUPL 0x030001 +#define SPHO_ERR_BIND_NOTFOUND 0x030002 #define SPHO_ERR_IS_SYSERR(err) (SPHO_ERR_SYS == err) @@ -42,54 +43,6 @@ (ctx)->errline = __LINE__; \ } while (0) -#define SPHO_STRINGIFY(a) #a -#define SPHO_MACRO_STR(b) SPHO_STRINGIFY(b) - -#define __LINE__S SPHO_MACRO_STR(__LINE__) - -#define SPHO_PRECOND(cond) \ - do { \ - if (! (cond) ) { \ - fprintf(stderr, "SPHO_PRECOND(" #cond ")@" \ - __FILE__ ":" __LINE__S \ - " failed. Aborting.\n"); \ - abort(); \ - } \ - } while (0) - -#define SPHO_ASSERT(cond) \ - do { \ - if (! (cond) ) { \ - fprintf(stderr, "SPHO_ASSERT(" #cond ")@" \ - __FILE__ ":" __LINE__S \ - " failed. Aborting.\n"); \ - abort(); \ - } \ - } while (0) - -#define SPHO_POSTCOND(cond) \ - do { \ - if (! (cond) ) { \ - fprintf(stderr, "SPHO_POSTCOND(" #cond ")@" \ - __FILE__ ":" __LINE__S \ - " failed. Aborting.\n"); \ - abort(); \ - } \ - } while (0) - - -#ifdef SPHO_ENABLE_DEBUG_PRINT - -#define SPHO_DEBUG_PRINT(fmt, ...) \ - do { \ - fprintf(stderr, fmt __VA_OPT__(,) __VA_ARGS__); \ - } while (0) - -#else /* SPHO_ENABLE_DEBUG_PRINT */ - -#define SPHO_DEBUG_PRINT(fmt, ...) - -#endif /* SPHO_ENABLE_DEBUG_PRINT */ #else /* SPHO_DEBUG */ diff --git a/include/spho/scope.h b/include/spho/scope.h index 5042c8f..a9f7526 100644 --- a/include/spho/scope.h +++ b/include/spho/scope.h @@ -80,6 +80,13 @@ struct spho_tp { STAILQ_ENTRY(spho_tp) entries; }; +struct spho_tp_op { + struct spho_scope *sc; + + struct spho_scope *op_sc; + struct spho_tp *op_tp; +}; + STAILQ_HEAD(spho_tp_l, spho_tp); struct spho_tp_ptr { @@ -90,18 +97,16 @@ struct spho_tp_ptr { STAILQ_HEAD(spho_tp_ptr_l, spho_tp_ptr); struct spho_tp_alloc { - struct spho_tp tp; + union { + struct spho_tp tp; + struct spho_tp_op tp_op; + } alloc; TAILQ_ENTRY(spho_tp_alloc) allocs; }; TAILQ_HEAD(spho_tp_alloc_l, spho_tp_alloc); -struct spho_tpop { - struct spho_scope *sc; - struct spho_tp *tp; -}; - SLIST_HEAD(spho_scope_l, spho_scope); /* defined in spho/bind.h */ @@ -112,10 +117,12 @@ struct spho_scope { struct spho_scope *parent; struct spho_scope_l subs; + + size_t n_noms; struct spho_nom_l noms; struct spho_tp_alloc_l tps; - struct spho_bind_scope *stat_bind; + struct spho_prebind *bind; SLIST_ENTRY(spho_scope) next; }; @@ -138,8 +145,11 @@ int spho_scope_nom_lookup_str(struct spho_scope *, const char *, size_t, int spho_scope_nom_lookup_str_strict(struct spho_scope *, const char *, size_t, struct spho_nom **); -int spho_scope_tp_bind_init(struct spho_scope *); -int spho_scope_tp_bind_nom(struct spho_scope *, struct spho_nom *, +int spho_scope_prebind_init(struct spho_scope *); +int spho_scope_prebind_tp(struct spho_scope *, struct spho_nom *, struct spho_tp *); +int spho_scope_prebind_tp_op(struct spho_scope *, struct spho_nom *, + struct spho_tp_op *); +int spho_scope_prebind_undef(struct spho_scope *, struct spho_nom *); #endif /* _SPHO_SCOPE_H */ diff --git a/include/spho/spho.h b/include/spho/spho.h index 7674bf1..c3daaa0 100644 --- a/include/spho/spho.h +++ b/include/spho/spho.h @@ -23,6 +23,64 @@ do { \ #else #define SPHO_STRLCPY(dst, src, len) \ (size_t)snprintf(dst, len, "%s", src) -#endif +#endif /* ifdef SPHO_USE_STRLCPY */ + +#define SPHO_STRINGIFY(a) #a +#define SPHO_MACRO_STR(b) SPHO_STRINGIFY(b) + +#define SPHO_RIP(msg) \ + do { \ + fprintf(stderr, "SPHO_RIP(" msg ")@" \ + __FILE__ ":" __LINE__S \ + " failed. Aborting.\n"); \ + abort(); \ + } while (0) + + +#ifdef SPHO_DEBUG + +#define __LINE__S SPHO_MACRO_STR(__LINE__) + +#define SPHO_PRECOND(cond) \ + do { \ + if (! (cond) ) { \ + fprintf(stderr, "SPHO_PRECOND(" #cond ")@" \ + __FILE__ ":" __LINE__S \ + " failed. Aborting.\n"); \ + abort(); \ + } \ + } while (0) + +#define SPHO_ASSERT(cond) \ + do { \ + if (! (cond) ) { \ + fprintf(stderr, "SPHO_ASSERT(" #cond ")@" \ + __FILE__ ":" __LINE__S \ + " failed. Aborting.\n"); \ + abort(); \ + } \ + } while (0) + +#define SPHO_POSTCOND(cond) \ + do { \ + if (! (cond) ) { \ + fprintf(stderr, "SPHO_POSTCOND(" #cond ")@" \ + __FILE__ ":" __LINE__S \ + " failed. Aborting.\n"); \ + abort(); \ + } \ + } while (0) + + +#ifdef SPHO_ENABLE_DEBUG_PRINT +#define SPHO_DEBUG_PRINT(fmt, ...) \ + do { \ + fprintf(stderr, fmt __VA_OPT__(,) __VA_ARGS__); \ + } while (0) +#else +#define SPHO_DEBUG_PRINT(fmt, ...) +#endif /* ifdef SPHO_ENABLE_DEBUG_PRINT */ + +#endif /* ifdef SPHO_DEBUG */ #endif diff --git a/include/spho/tp.h b/include/spho/tp.h index 1279eb6..c15eb76 100644 --- a/include/spho/tp.h +++ b/include/spho/tp.h @@ -19,6 +19,8 @@ #define SPHO_TP_FORM_FALSE 0x21 #define SPHO_TP_FORM_NAME 0x23 +#define SPHO_TP_FORM_VAR 0x40 + #define SPHO_TP_FORM_MASK 0xff #define SPHO_TP_MOD_FIRST (SPHO_TP_FORM_MASK + 1) @@ -50,6 +52,9 @@ struct spho_tp *spho_tp_create_member(struct spho_scope *, struct spho_nom *, struct spho_tp *spho_tp_create_var(struct spho_scope *, struct spho_nom *); struct spho_tp *spho_tp_create_nominal(struct spho_scope *, struct spho_nom *); +struct spho_tp_op *spho_tp_op_create(struct spho_scope *, + struct spho_scope *, struct spho_tp *); + void spho_tp_destroy(struct spho_tp *); #endif diff --git a/src/msph/sphophi.c b/src/msph/sphophi.c index 74414a4..0e3c662 100644 --- a/src/msph/sphophi.c +++ b/src/msph/sphophi.c @@ -1,5 +1,7 @@ #include +#include "msph/tree.h" +#include "spho/scope.h" #include "spho/spho.h" #include "spho/tp.h" @@ -9,15 +11,20 @@ typedef int (*msph_tree_sphophi_f)(struct spho_scope *, struct msph_tree *); static int msph_tree_sphophi_decor_scope(struct spho_scope *, struct msph_tree *); -static int msph_tree_sphophi_decor_nom_lookup(struct spho_scope *, +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_bind_static_tp_name(struct spho_scope *, +static int msph_tree_sphophi_tp_prebind(struct spho_scope *, struct msph_tree *); -static int msph_tree_sphophi_get_scope(struct msph_tree *, struct - spho_scope **); +/* is the tree a name binding? */ +#define IS_BINDING(tree) (TREE_ID(tree) == MSPH_TREE_TPDEF || \ + TREE_ID(tree) == MSPH_TREE_NOMINDECL || \ + TREE_ID(tree) == MSPH_TREE_MEMBDECL || \ + TREE_ID(tree) == MSPH_TREE_FORALL) +/* is the tree a type expression? */ +#define IS_TPEXPR(tree) ((tree)->type & MSPH_TREE_TPEXPR) /* foreach_pre: top down foreach */ static int msph_sphophi_foreach_pre(msph_tree_sphophi_f, @@ -32,6 +39,10 @@ static int msph_sphophi_foreach_pre_assert(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_assert *); static int msph_sphophi_foreach_pre_membdecl(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_membdecl *); +static int msph_sphophi_foreach_pre_namedecl(msph_tree_sphophi_f, + struct spho_scope *, struct msph_tree_namedecl *); +static int msph_sphophi_foreach_pre_nameref(msph_tree_sphophi_f, + struct spho_scope *, struct msph_tree_nameref *); static int msph_sphophi_foreach_pre_tpdef(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_tpdef *); static int msph_sphophi_foreach_pre_nomindecl(msph_tree_sphophi_f, @@ -42,10 +53,10 @@ static int msph_sphophi_foreach_pre_true(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_true *); static int msph_sphophi_foreach_pre_false(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_false *); -static int msph_sphophi_foreach_pre_name(msph_tree_sphophi_f, - struct spho_scope *, struct msph_tree_name *); -static int msph_sphophi_foreach_pre_appl(msph_tree_sphophi_f, - struct spho_scope *, struct msph_tree_appl *); +static int msph_sphophi_foreach_pre_tpname(msph_tree_sphophi_f, + struct spho_scope *, struct msph_tree_tpname *); +static int msph_sphophi_foreach_pre_tpappl(msph_tree_sphophi_f, + struct spho_scope *, struct msph_tree_tpappl *); static int msph_sphophi_foreach_pre_trait(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_trait *); static int msph_sphophi_foreach_pre_conj(msph_tree_sphophi_f, @@ -62,8 +73,6 @@ static int msph_sphophi_foreach_pre_forall(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_forall *); static int msph_sphophi_foreach_pre_paren(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_paren *); -static int msph_sphophi_foreach_pre_ident(msph_tree_sphophi_f, - struct spho_scope *, struct msph_tree_ident *); /* foreach_post: bottom up foreach */ static int msph_sphophi_foreach_post(msph_tree_sphophi_f, @@ -88,10 +97,10 @@ static int msph_sphophi_foreach_post_true(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_true *); static int msph_sphophi_foreach_post_false(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_false *); -static int msph_sphophi_foreach_post_name(msph_tree_sphophi_f, - struct spho_scope *, struct msph_tree_name *); -static int msph_sphophi_foreach_post_appl(msph_tree_sphophi_f, - struct spho_scope *, struct msph_tree_appl *); +static int msph_sphophi_foreach_post_tpname(msph_tree_sphophi_f, + struct spho_scope *, struct msph_tree_tpname *); +static int msph_sphophi_foreach_post_tpappl(msph_tree_sphophi_f, + struct spho_scope *, struct msph_tree_tpappl *); static int msph_sphophi_foreach_post_trait(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_trait *); static int msph_sphophi_foreach_post_conj(msph_tree_sphophi_f, @@ -108,8 +117,10 @@ static int msph_sphophi_foreach_post_forall(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_forall *); static int msph_sphophi_foreach_post_paren(msph_tree_sphophi_f, struct spho_scope *, struct msph_tree_paren *); -static int msph_sphophi_foreach_post_ident(msph_tree_sphophi_f, - struct spho_scope *, struct msph_tree_ident *); +static int msph_sphophi_foreach_post_namedecl(msph_tree_sphophi_f, + struct spho_scope *, struct msph_tree_namedecl *); +static int msph_sphophi_foreach_post_nameref(msph_tree_sphophi_f, + struct spho_scope *, struct msph_tree_nameref *); int msph_sphophi_init(struct msph_tree_root *root) { @@ -130,7 +141,7 @@ msph_sphophi_scope(struct msph_tree_root *root) int msph_sphophi_nom_lookup(struct msph_tree_root *root) { - return (msph_sphophi_foreach_pre(msph_tree_sphophi_decor_nom_lookup, + return (msph_sphophi_foreach_pre(msph_tree_sphophi_decor_tpexpr_nom, root)); } @@ -141,9 +152,9 @@ msph_sphophi_tp(struct msph_tree_root *root) } int -msph_sphophi_bind_static_tp_names(struct msph_tree_root *root) +msph_sphophi_tp_prebind(struct msph_tree_root *root) { - return (msph_sphophi_foreach_pre(msph_tree_sphophi_bind_static_tp_name, + return (msph_sphophi_foreach_pre(msph_tree_sphophi_tp_prebind, root)); } @@ -159,53 +170,47 @@ 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) + if ((ret = msph_sphophi_tp_prebind(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) static int msph_tree_sphophi_decor_scope(struct spho_scope *sc, struct msph_tree *tree) { int ret; - struct msph_tree_unit *unit; - struct msph_tree_trait *trait; - struct msph_tree_forall *forall; struct msph_tree_ident *ident; + struct msph_tree_tpdef *tpdef; ret = 0; - switch (tree->type) { + switch (TREE_ID(tree)) { case MSPH_TREE_UNIT: - unit = (struct msph_tree_unit *)tree; - if ((unit->dec.sc = spho_scope_create(sc)) == NULL) - ret = -1; - break; case MSPH_TREE_TRAIT: - trait = (struct msph_tree_trait *)tree; - if ((trait->dec.sc = spho_scope_create(sc)) == NULL) - ret = -1; - break; case MSPH_TREE_FORALL: - forall = (struct msph_tree_forall *)tree; - if ((forall->dec.sc = spho_scope_create(sc)) == NULL) + if ((SCOPE(tree) = spho_scope_create(sc)) == NULL) ret = -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; + } + ADD_FLAG(tree, MSPH_TREE_FLAG_SCOPE); break; case MSPH_TREE_IDENT: if (! IS_BINDING(tree->parent)) break; ident = (struct msph_tree_ident *)tree; - if ((ident->dec.nom = spho_scope_nom_add(sc, ident->str, + if ((NOM(ident) = spho_scope_nom_add(sc, ident->str, sizeof(ident->str))) == NULL) ret = -1; + ADD_FLAG(tree, MSPH_TREE_FLAG_NOM); break; default: break; @@ -215,7 +220,7 @@ msph_tree_sphophi_decor_scope(struct spho_scope *sc, struct msph_tree *tree) } static int -msph_tree_sphophi_decor_nom_lookup(struct spho_scope *sc, +msph_tree_sphophi_decor_tpexpr_nom(struct spho_scope *sc, struct msph_tree *tree) { int ret; @@ -223,13 +228,14 @@ msph_tree_sphophi_decor_nom_lookup(struct spho_scope *sc, ret = 0; - switch (tree->type) { + switch (TREE_ID(tree)) { case MSPH_TREE_IDENT: - if (tree->parent->type != MSPH_TREE_NAME) + 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), &ident->dec.nom); + sizeof(ident->str), &NOM(ident)); + break; default: break; @@ -238,20 +244,17 @@ msph_tree_sphophi_decor_nom_lookup(struct spho_scope *sc, return (ret); } -#define TP(ptr) ((ptr)->dec.tp) -#define NOM(ptr) ((ptr)->dec.nom) - static int msph_tree_sphophi_decor_tp(struct spho_scope *sc, struct msph_tree *tree) { int ret; - struct msph_tree_tpexpr *tpexpr, *tpexpr_i; + struct msph_tree_tpexpr *tpexpr_i; struct msph_tree_conj *conj; struct msph_tree_disj *disj; struct msph_tree_impl *impl; struct msph_tree_arrow *arrow; - struct msph_tree_name *name; - struct msph_tree_appl *appl; + struct msph_tree_tpname *tpname; + struct msph_tree_tpappl *tpappl; struct msph_tree_box *box; struct msph_tree_forall *forall; struct msph_tree_paren *paren; @@ -271,90 +274,99 @@ msph_tree_sphophi_decor_tp(struct spho_scope *sc, struct msph_tree *tree) if (! (tree->type & MSPH_TREE_TPEXPR)) return (0); - tpexpr = (struct msph_tree_tpexpr *)tree; - - switch (tree->type) { + switch (TREE_ID(tree)) { case MSPH_TREE_CONJ: conj = (struct msph_tree_conj *)tree; - if ((tpexpr->dec.tp = spho_tp_create_conj(sc, TP(conj->ltp), + if ((TP(conj) = spho_tp_create_conj(sc, TP(conj->ltp), 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 ((tpexpr->dec.tp = spho_tp_create_conj(sc, TP(disj->ltp), + if ((TP(disj) = spho_tp_create_conj(sc, TP(disj->ltp), 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 ((tpexpr->dec.tp = spho_tp_create_conj(sc, TP(impl->ltp), + if ((TP(impl) = spho_tp_create_conj(sc, TP(impl->ltp), TP(impl->rtp))) == NULL) goto cleanup; + ADD_FLAG(impl, MSPH_TREE_FLAG_TP); break; case MSPH_TREE_ARROW: arrow = (struct msph_tree_arrow *)tree; - if ((tpexpr->dec.tp = spho_tp_create_conj(sc, TP(arrow->ltp), + if ((TP(arrow) = spho_tp_create_conj(sc, TP(arrow->ltp), TP(arrow->rtp))) == NULL) goto cleanup; + ADD_FLAG(arrow, MSPH_TREE_FLAG_TP); break; - case MSPH_TREE_NAME: - name = (struct msph_tree_name *)tree; - if ((tpexpr->dec.tp = spho_tp_create_name(sc, NOM(name->id))) + case MSPH_TREE_TPNAME: + tpname = (struct msph_tree_tpname *)tree; + if ((TP(tpname) = spho_tp_create_name(sc, NOM(tpname->name))) == NULL) goto cleanup; + ADD_FLAG(tpname, MSPH_TREE_FLAG_TP); break; - case MSPH_TREE_APPL: - appl = (struct msph_tree_appl *)tree; + case MSPH_TREE_TPAPPL: + tpappl = (struct msph_tree_tpappl *)tree; if ((tps = malloc(sizeof(*tps))) == NULL) { SPHO_SC_ERR(sc, SPHO_ERR_SYS); goto cleanup; } STAILQ_INIT(tps); - STAILQ_FOREACH(tpexpr_i, &appl->head, entries) { - STAILQ_INSERT_TAIL(tps, tpexpr_i->dec.tp, entries); + STAILQ_FOREACH(tpexpr_i, &tpappl->args, entries) { + STAILQ_INSERT_TAIL(tps, TP(tpexpr_i), entries); } - if ((tpexpr->dec.tp = spho_tp_create_appl(sc, NOM(appl->id), + if ((TP(tpappl) = spho_tp_create_appl(sc, NOM(tpappl->name), tps)) == NULL) goto cleanup; tps = NULL; + ADD_FLAG(tpappl, MSPH_TREE_FLAG_TP); break; case MSPH_TREE_TRUE: - if ((tpexpr->dec.tp = spho_tp_create_true(sc)) == NULL) + if ((TP(tree) = spho_tp_create_true(sc)) == NULL) goto cleanup; + ADD_FLAG(tree, MSPH_TREE_FLAG_TP); break; case MSPH_TREE_FALSE: - if ((tpexpr->dec.tp = spho_tp_create_false(sc)) == NULL) + if ((TP(tree) = spho_tp_create_false(sc)) == NULL) goto cleanup; + ADD_FLAG(tree, MSPH_TREE_FLAG_TP); break; case MSPH_TREE_FORALL: forall = (struct msph_tree_forall *)tree; - if ((tpexpr->dec.tp = spho_tp_create_forall(sc, - NOM(forall->id), TP(forall->inner))) == NULL) + if ((TP(forall) = spho_tp_create_forall(sc, + NOM(forall->name), TP(forall->inner))) == NULL) goto cleanup; + ADD_FLAG(forall, MSPH_TREE_FLAG_TP); break; case MSPH_TREE_BOX: box = (struct msph_tree_box *)tree; - if ((tpexpr->dec.tp = spho_tp_create_box(sc, TP(box->inner))) + if ((TP(box) = spho_tp_create_box(sc, TP(box->inner))) == NULL) goto cleanup; + ADD_FLAG(box, MSPH_TREE_FLAG_TP); break; case MSPH_TREE_PAREN: paren = (struct msph_tree_paren *)tree; - if ((tpexpr->dec.tp = TP(paren->inner)) == NULL) + if ((TP(paren) = TP(paren->inner)) == NULL) goto cleanup; + ADD_FLAG(paren, MSPH_TREE_FLAG_TP); break; case MSPH_TREE_TRAIT: trait = (struct msph_tree_trait *)tree; STAILQ_FOREACH(dir, &trait->body->head, entries) { - if (T(dir)->type != MSPH_TREE_MEMBDECL) + if (TREE_ID(dir) != MSPH_TREE_MEMBDECL) continue; membd = (struct msph_tree_membdecl *)dir; // TODO check that we make sure to dealloc when // spho has stabilized a bit - if ((tp_memb = spho_tp_create_member(sc, membd->id->dec.nom, - membd->tp->dec.tp)) == NULL) + if ((tp_memb = spho_tp_create_member(sc, NOM(membd->name), + TP(membd->tp))) == NULL) goto cleanup; if (tp == NULL) { tp = tp_memb; @@ -363,8 +375,12 @@ msph_tree_sphophi_decor_tp(struct spho_scope *sc, struct msph_tree *tree) == NULL) goto cleanup; } - tpexpr->dec.tp = tp; } + if (tp == NULL) + tp = spho_tp_create_true(sc); + SPHO_ASSERT(tp != NULL); + TP(trait) = tp; + ADD_FLAG(trait, MSPH_TREE_FLAG_TP); break; default: SPHO_ASSERT(0); @@ -381,70 +397,60 @@ cleanup: } static int -msph_tree_sphophi_bind_static_tp_name(struct spho_scope *sc, +msph_tree_sphophi_tp_prebind(struct spho_scope *sc, struct msph_tree *tree) { int ret; - struct spho_scope *sub_sc; + struct spho_tp_op *op; struct msph_tree_tpdef *tpdef; - struct msph_tree_nomindecl *nomdecl; + struct msph_tree_namedecl *name; 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; + if (HAS_SCOPE(tree)) { + if (spho_scope_prebind_init(SCOPE(tree)) == -1) + return (-1); } - switch (tree->type) { + switch (TREE_ID(tree)) { 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); + if (HAS_PARAMS(tpdef)) { + SPHO_ASSERT(HAS_SCOPE(tpdef)); + SPHO_ASSERT(SCOPE(tpdef) != NULL); + SPHO_ASSERT(SCOPE(tpdef)->bind != NULL); + + STAILQ_FOREACH(name, &tpdef->params, entries) { + if (spho_scope_prebind_undef(SCOPE(tpdef), + NOM(name)) == -1) { + return (-1); + } + } + + if ((op = spho_tp_op_create(sc, SCOPE(tpdef), + TP(tpdef->tp))) == NULL) { + return (-1); + } + + if ((ret = spho_scope_prebind_tp_op(sc, NOM(name), op)) + == -1) { + return (-1); + } + } else { + if ((ret = spho_scope_prebind_tp(sc, NOM(tpdef->name), + TP(tpdef->tp))) == -1) { + return (-1); + } + } 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) @@ -453,17 +459,14 @@ msph_sphophi_foreach_pre(msph_tree_sphophi_f f, struct msph_tree_root *root) struct spho_scope *sc; struct msph_tree_unit *unit; - if (root == NULL || root->ctx == NULL) - return (-1); - - if (root->ctx->spho == NULL) { - MSPH_ERR(root->ctx, MSPH_ERR_TYPE_INVAL); - return (-1); - } + SPHO_PRECOND(f != NULL); + SPHO_PRECOND(root != NULL); + SPHO_PRECOND(root->ctx != NULL); + SPHO_PRECOND(root->ctx->spho != NULL); sc = spho_scope_global(root->ctx->spho); - if ((ret = f(sc, T(root))) != 0) { + if ((ret = f(sc, TREE(root))) != 0) { goto err; } @@ -485,10 +488,13 @@ msph_sphophi_foreach_pre_unit(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; - if ((ret = f(sc, T(unit))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(unit != NULL); + + if ((ret = f(sc, TREE(unit))) != 0) return (ret); - sc = GET_SCOPE(unit); + sc = SCOPE(unit); return (msph_sphophi_foreach_pre_body(f, sc, unit->body)); } @@ -500,7 +506,10 @@ msph_sphophi_foreach_pre_body(msph_tree_sphophi_f f, struct spho_scope *sc, int ret; struct msph_tree_dir *dir; - if ((ret = f(sc, T(body))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(body != NULL); + + if ((ret = f(sc, TREE(body))) != 0) return (ret); ret = 0; @@ -518,8 +527,11 @@ msph_sphophi_foreach_pre_dir(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(dir != NULL); + ret = -1; - switch (dir->htxt.htr.type) { + switch (TREE_ID(dir)) { case MSPH_TREE_TPDEF: ret = msph_sphophi_foreach_pre_tpdef(f, sc, (struct msph_tree_tpdef *)dir); @@ -549,13 +561,26 @@ msph_sphophi_foreach_pre_tpdef(msph_tree_sphophi_f f, struct spho_scope *sc, struct msph_tree_tpdef *tpdef) { int ret; + struct msph_tree_namedecl *name; - if ((ret = f(sc, T(tpdef))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(tpdef != NULL); + + if ((ret = f(sc, TREE(tpdef))) != 0) return (ret); - if ((ret = msph_sphophi_foreach_pre_ident(f, sc, tpdef->id)) != 0) + if ((ret = msph_sphophi_foreach_pre_namedecl(f, sc, tpdef->name)) != 0) return (ret); + sc = HAS_SCOPE(tpdef) ? SCOPE(tpdef) : sc; + + STAILQ_FOREACH(name, &tpdef->params, entries) { + if ((ret = msph_sphophi_foreach_pre_namedecl(f, sc, name)) + != 0) { + return (ret); + } + } + return (msph_sphophi_foreach_pre_tpexpr(f, sc, tpdef->tp)); } @@ -565,10 +590,13 @@ msph_sphophi_foreach_pre_nomindecl(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; - if ((ret = f(sc, T(nomd))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(nomd != NULL); + + if ((ret = f(sc, TREE(nomd))) != 0) return (ret); - return (msph_sphophi_foreach_pre_ident(f, sc, nomd->id)); + return (msph_sphophi_foreach_pre_namedecl(f, sc, nomd->name)); } static int @@ -577,10 +605,13 @@ msph_sphophi_foreach_pre_membdecl(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; - if ((ret = f(sc, T(membd))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(membd != NULL); + + if ((ret = f(sc, TREE(membd))) != 0) return (ret); - if (msph_sphophi_foreach_pre_ident(f, sc, membd->id) != 0) + if (msph_sphophi_foreach_pre_namedecl(f, sc, membd->name) != 0) return (ret); if (msph_sphophi_foreach_pre_tpexpr(f, sc, membd->tp) != 0) return (ret); @@ -594,7 +625,7 @@ msph_sphophi_foreach_pre_assert(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; - if ((ret = f(sc, T(ass))) != 0) + if ((ret = f(sc, TREE(ass))) != 0) return (ret); if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, ass->ltp)) != 0) @@ -606,10 +637,23 @@ msph_sphophi_foreach_pre_assert(msph_tree_sphophi_f f, struct spho_scope *sc, } static int -msph_sphophi_foreach_pre_ident(msph_tree_sphophi_f f, struct spho_scope *sc, - struct msph_tree_ident *ident) +msph_sphophi_foreach_pre_namedecl(msph_tree_sphophi_f f, struct spho_scope *sc, + struct msph_tree_namedecl *name) { - return (f(sc, T(ident))); + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(name != NULL); + + return (f(sc, TREE(name))); +} + +static int +msph_sphophi_foreach_pre_nameref(msph_tree_sphophi_f f, struct spho_scope *sc, + struct msph_tree_nameref *name) +{ + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(name != NULL); + + return (f(sc, TREE(name))); } static int @@ -618,9 +662,12 @@ msph_sphophi_foreach_pre_tpexpr(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(tpexpr != NULL); + ret = -1; - switch (tpexpr->htxt.htr.type) { + switch (TREE_ID(tpexpr)) { case MSPH_TREE_CONJ: ret = msph_sphophi_foreach_pre_conj(f, sc, (struct msph_tree_conj *)tpexpr); @@ -637,13 +684,13 @@ msph_sphophi_foreach_pre_tpexpr(msph_tree_sphophi_f f, struct spho_scope *sc, ret = msph_sphophi_foreach_pre_arrow(f, sc, (struct msph_tree_arrow *)tpexpr); break; - case MSPH_TREE_NAME: - ret = msph_sphophi_foreach_pre_name(f, sc, - (struct msph_tree_name *)tpexpr); + case MSPH_TREE_TPNAME: + ret = msph_sphophi_foreach_pre_tpname(f, sc, + (struct msph_tree_tpname *)tpexpr); break; - case MSPH_TREE_APPL: - ret = msph_sphophi_foreach_pre_appl(f, sc, - (struct msph_tree_appl *)tpexpr); + case MSPH_TREE_TPAPPL: + ret = msph_sphophi_foreach_pre_tpappl(f, sc, + (struct msph_tree_tpappl *)tpexpr); break; case MSPH_TREE_TRAIT: ret = msph_sphophi_foreach_pre_trait(f, sc, @@ -670,7 +717,7 @@ msph_sphophi_foreach_pre_tpexpr(msph_tree_sphophi_f f, struct spho_scope *sc, (struct msph_tree_false *)tpexpr); break; default: - SPHO_ASSERT(0); + SPHO_RIP("default-reach"); break; } @@ -683,7 +730,10 @@ msph_sphophi_foreach_pre_conj(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; - if ((ret = f(sc, T(conj))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(conj != NULL); + + if ((ret = f(sc, TREE(conj))) != 0) return (ret); if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, conj->ltp)) != 0) @@ -698,7 +748,10 @@ msph_sphophi_foreach_pre_disj(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; - if ((ret = f(sc, T(disj))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(disj != NULL); + + if ((ret = f(sc, TREE(disj))) != 0) return (ret); if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, disj->ltp)) != 0) return (ret); @@ -711,7 +764,10 @@ msph_sphophi_foreach_pre_impl(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; - if ((ret = f(sc, T(impl))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(impl != NULL); + + if ((ret = f(sc, TREE(impl))) != 0) return (ret); if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, impl->ltp)) != 0) @@ -725,7 +781,10 @@ msph_sphophi_foreach_pre_arrow(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; - if ((ret = f(sc, T(arrow))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(arrow != NULL); + + if ((ret = f(sc, TREE(arrow))) != 0) return (ret); if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, arrow->ltp)) != 0) @@ -734,29 +793,35 @@ msph_sphophi_foreach_pre_arrow(msph_tree_sphophi_f f, struct spho_scope *sc, } static int -msph_sphophi_foreach_pre_name(msph_tree_sphophi_f f, struct spho_scope *sc, - struct msph_tree_name *name) +msph_sphophi_foreach_pre_tpname(msph_tree_sphophi_f f, struct spho_scope *sc, + struct msph_tree_tpname *name) { int ret; - if ((ret = f(sc, T(name))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(name != NULL); + + if ((ret = f(sc, TREE(name))) != 0) return (ret); - return (msph_sphophi_foreach_pre_ident(f, sc, name->id)); + return (msph_sphophi_foreach_pre_nameref(f, sc, name->name)); } static int -msph_sphophi_foreach_pre_appl(msph_tree_sphophi_f f, struct spho_scope *sc, - struct msph_tree_appl *appl) +msph_sphophi_foreach_pre_tpappl(msph_tree_sphophi_f f, struct spho_scope *sc, + struct msph_tree_tpappl *appl) { int ret; struct msph_tree_tpexpr *tp; - if ((ret = f(sc, T(appl))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(appl != NULL); + + if ((ret = f(sc, TREE(appl))) != 0) return (ret); ret = 0; - STAILQ_FOREACH(tp, &appl->head, entries) { + STAILQ_FOREACH(tp, &appl->args, entries) { if ((ret = msph_sphophi_foreach_pre_tpexpr(f, sc, tp)) != 0) return (ret); } @@ -769,10 +834,14 @@ msph_sphophi_foreach_pre_trait(msph_tree_sphophi_f f, struct spho_scope *sc, struct msph_tree_trait *trait) { int ret; - if ((ret = f(sc, T(trait))) != 0) + + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(trait != NULL); + + if ((ret = f(sc, TREE(trait))) != 0) return (ret); - sc = GET_SCOPE(trait); + sc = SCOPE(trait); return (msph_sphophi_foreach_pre_body(f, sc, trait->body)); } @@ -783,7 +852,10 @@ msph_sphophi_foreach_pre_box(msph_tree_sphophi_f f,struct spho_scope *sc, { int ret; - if ((ret = f(sc, T(box))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(box != NULL); + + if ((ret = f(sc, TREE(box))) != 0) return (ret); return (msph_sphophi_foreach_pre_tpexpr(f, sc, box->inner)); @@ -794,11 +866,14 @@ msph_sphophi_foreach_pre_forall(msph_tree_sphophi_f f, struct spho_scope *sc, struct msph_tree_forall *forall) { int ret; - - if ((ret = f(sc, T(forall))) != 0) + + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(forall != NULL); + + if ((ret = f(sc, TREE(forall))) != 0) return (ret); - sc = GET_SCOPE(forall); + sc = SCOPE(forall); return (msph_sphophi_foreach_pre_tpexpr(f, sc, forall->inner)); } @@ -809,7 +884,10 @@ msph_sphophi_foreach_pre_paren(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; - if ((ret = f(sc, T(paren))) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(paren != NULL); + + if ((ret = f(sc, TREE(paren))) != 0) return (ret); return (msph_sphophi_foreach_pre_tpexpr(f, sc, paren->inner)); @@ -819,14 +897,20 @@ static int msph_sphophi_foreach_pre_true(msph_tree_sphophi_f f, struct spho_scope *sc, struct msph_tree_true *tru) { - return (f(sc, T(tru))); + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(tru != NULL); + + return (f(sc, TREE(tru))); } static int msph_sphophi_foreach_pre_false(msph_tree_sphophi_f f, struct spho_scope *sc, struct msph_tree_false *fls) { - return (f(sc, T(fls))); + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(fls != NULL); + + return (f(sc, TREE(fls))); } @@ -838,13 +922,10 @@ msph_sphophi_foreach_post(msph_tree_sphophi_f f, struct msph_tree_root *root) struct spho_scope *sc; struct msph_tree_unit *unit; - if (root == NULL || root->ctx == NULL) - return (-1); - - if (root->ctx->spho == NULL) { - MSPH_ERR(root->ctx, MSPH_ERR_TYPE_INVAL); - return (-1); - } + SPHO_PRECOND(f != NULL); + SPHO_PRECOND(root != NULL); + SPHO_PRECOND(root->ctx != NULL); + SPHO_PRECOND(root->ctx->spho != NULL); sc = spho_scope_global(root->ctx->spho); @@ -854,7 +935,7 @@ msph_sphophi_foreach_post(msph_tree_sphophi_f f, struct msph_tree_root *root) goto err; } - if ((ret = f(sc, T(root))) != 0) + if ((ret = f(sc, TREE(root))) != 0) goto err; return (ret); @@ -870,13 +951,17 @@ msph_sphophi_foreach_post_unit(msph_tree_sphophi_f f, struct spho_scope *sc, int ret; struct spho_scope *inner_sc; - inner_sc = GET_SCOPE(unit); + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(unit != NULL); + + inner_sc = SCOPE(unit); if ((ret = msph_sphophi_foreach_post_body(f, inner_sc, unit->body)) - != 0) + != 0) { return (ret); + } - return (f(sc, T(unit))); + return (f(sc, TREE(unit))); } static int @@ -886,13 +971,16 @@ msph_sphophi_foreach_post_body(msph_tree_sphophi_f f, struct spho_scope *sc, int ret; struct msph_tree_dir *dir; + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(body != NULL); + ret = 0; STAILQ_FOREACH(dir, &body->head, entries) { if ((ret = msph_sphophi_foreach_post_dir(f, sc, dir)) != 0) return (ret); } - return (f(sc, T(body))); + return (f(sc, TREE(body))); } static int @@ -901,8 +989,11 @@ msph_sphophi_foreach_post_dir(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(dir != NULL); + ret = -1; - switch (dir->htxt.htr.type) { + switch (TREE_ID(dir)) { case MSPH_TREE_TPDEF: ret = msph_sphophi_foreach_post_tpdef(f, sc, (struct msph_tree_tpdef *)dir); @@ -932,13 +1023,32 @@ msph_sphophi_foreach_post_tpdef(msph_tree_sphophi_f f, struct spho_scope *sc, struct msph_tree_tpdef *tpdef) { int ret; + struct spho_scope *sub_sc; + struct msph_tree_namedecl *name; - if ((ret = msph_sphophi_foreach_post_ident(f, sc, tpdef->id)) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(tpdef != NULL); + + + if ((ret = msph_sphophi_foreach_post_namedecl(f, sc, tpdef->name)) + != 0) { return (ret); - if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, tpdef->tp)) != 0) + } + + sub_sc = HAS_SCOPE(tpdef) ? SCOPE(tpdef) : sc; + + STAILQ_FOREACH(name, &tpdef->params, entries) { + if ((ret = msph_sphophi_foreach_post_namedecl(f, sub_sc, name)) + != 0) { + return (ret); + } + } + + if ((ret = msph_sphophi_foreach_post_tpexpr(f, sub_sc, tpdef->tp)) + != 0) return (ret); - return (f(sc, T(tpdef))); + return (f(sc, TREE(tpdef))); } static int @@ -947,10 +1057,13 @@ msph_sphophi_foreach_post_nomindecl(msph_tree_sphophi_f f, { int ret; - if ((ret = msph_sphophi_foreach_post_ident(f, sc, nomd->id)) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(nomd != NULL); + + if ((ret = msph_sphophi_foreach_post_namedecl(f, sc, nomd->name)) != 0) return (ret); - return (f(sc, T(nomd))); + return (f(sc, TREE(nomd))); } static int @@ -959,12 +1072,15 @@ msph_sphophi_foreach_post_membdecl(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; - if ((ret = msph_sphophi_foreach_post_ident(f, sc, membd->id)) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(membd != NULL); + + if ((ret = msph_sphophi_foreach_post_namedecl(f, sc, membd->name)) != 0) return (ret); if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, membd->tp)) != 0) return (ret); - return (f(sc, T(membd))); + return (f(sc, TREE(membd))); } static int @@ -973,19 +1089,35 @@ msph_sphophi_foreach_post_assert(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; + 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) return (ret); - return (f(sc, T(ass))); + return (f(sc, TREE(ass))); } static int -msph_sphophi_foreach_post_ident(msph_tree_sphophi_f f, struct spho_scope *sc, - struct msph_tree_ident *ident) +msph_sphophi_foreach_post_namedecl(msph_tree_sphophi_f f, struct spho_scope *sc, + struct msph_tree_namedecl *name) { - return (f(sc, T(ident))); + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(name != NULL); + + return (f(sc, TREE(name))); +} + +static int +msph_sphophi_foreach_post_nameref(msph_tree_sphophi_f f, struct spho_scope *sc, + struct msph_tree_nameref *name) +{ + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(name != NULL); + + return (f(sc, TREE(name))); } static int @@ -994,9 +1126,12 @@ msph_sphophi_foreach_post_tpexpr(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(tpexpr != NULL); + ret = -1; - switch (tpexpr->htxt.htr.type) { + switch (TREE_ID(tpexpr)) { case MSPH_TREE_CONJ: ret = msph_sphophi_foreach_post_conj(f, sc, (struct msph_tree_conj *)tpexpr); @@ -1013,13 +1148,13 @@ msph_sphophi_foreach_post_tpexpr(msph_tree_sphophi_f f, struct spho_scope *sc, ret = msph_sphophi_foreach_post_arrow(f, sc, (struct msph_tree_arrow *)tpexpr); break; - case MSPH_TREE_NAME: - ret = msph_sphophi_foreach_post_name(f, sc, - (struct msph_tree_name *)tpexpr); + case MSPH_TREE_TPNAME: + ret = msph_sphophi_foreach_post_tpname(f, sc, + (struct msph_tree_tpname *)tpexpr); break; - case MSPH_TREE_APPL: - ret = msph_sphophi_foreach_post_appl(f, sc, - (struct msph_tree_appl *)tpexpr); + case MSPH_TREE_TPAPPL: + ret = msph_sphophi_foreach_post_tpappl(f, sc, + (struct msph_tree_tpappl *)tpexpr); break; case MSPH_TREE_TRAIT: ret = msph_sphophi_foreach_post_trait(f, sc, @@ -1059,12 +1194,15 @@ msph_sphophi_foreach_post_conj(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(conj != NULL); + if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, conj->ltp)) != 0) return (ret); if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, conj->rtp)) != 0) return (ret); - return (f(sc, T(conj))); + return (f(sc, TREE(conj))); } @@ -1074,12 +1212,15 @@ msph_sphophi_foreach_post_disj(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(disj != NULL); + if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, disj->ltp)) != 0) return (ret); if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, disj->rtp)) != 0) return (ret); - return (f(sc, T(disj))); + return (f(sc, TREE(disj))); } static int @@ -1088,12 +1229,15 @@ msph_sphophi_foreach_post_impl(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(impl != NULL); + if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, impl->ltp)) != 0) return (ret); if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, impl->rtp)) != 0) return (ret); - return (f(sc, T(impl))); + return (f(sc, TREE(impl))); } static int @@ -1102,41 +1246,46 @@ msph_sphophi_foreach_post_arrow(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(arrow != NULL); + if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, arrow->ltp)) != 0) return (ret); if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, arrow->rtp)) != 0) return (ret); - return (f(sc, T(arrow))); + return (f(sc, TREE(arrow))); } static int -msph_sphophi_foreach_post_name(msph_tree_sphophi_f f, struct spho_scope *sc, - struct msph_tree_name *name) +msph_sphophi_foreach_post_tpname(msph_tree_sphophi_f f, struct spho_scope *sc, + struct msph_tree_tpname *name) { int ret; - if ((ret = msph_sphophi_foreach_post_ident(f, sc, name->id)) != 0) + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(name != NULL); + + if ((ret = msph_sphophi_foreach_post_nameref(f, sc, name->name)) != 0) return (ret); - return (f(sc, T(name))); - + return (f(sc, TREE(name))); } static int -msph_sphophi_foreach_post_appl(msph_tree_sphophi_f f, struct spho_scope *sc, - struct msph_tree_appl *appl) +msph_sphophi_foreach_post_tpappl(msph_tree_sphophi_f f, struct spho_scope *sc, + struct msph_tree_tpappl *appl) { int ret; struct msph_tree_tpexpr *tp; ret = 0; - STAILQ_FOREACH(tp, &appl->head, entries) { + STAILQ_FOREACH(tp, &appl->args, entries) { if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, tp)) != 0) return (ret); } - return (f(sc, T(appl))); + return (f(sc, TREE(appl))); } static int @@ -1146,13 +1295,17 @@ msph_sphophi_foreach_post_trait(msph_tree_sphophi_f f, struct spho_scope *sc, int ret; struct spho_scope *inner_sc; - inner_sc = GET_SCOPE(trait); + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(trait != NULL); + + inner_sc = SCOPE(trait); if ((ret = msph_sphophi_foreach_post_body(f, inner_sc, trait->body)) - != 0) + != 0) { return (ret); + } - return (f(sc, T(trait))); + return (f(sc, TREE(trait))); } static int @@ -1161,10 +1314,13 @@ msph_sphophi_foreach_post_box(msph_tree_sphophi_f f,struct spho_scope *sc, { int ret; + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(box != NULL); + if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, box->inner)) != 0) return (ret); - return (f(sc, T(box))); + return (f(sc, TREE(box))); } static int @@ -1174,13 +1330,16 @@ msph_sphophi_foreach_post_forall(msph_tree_sphophi_f f, struct spho_scope *sc, int ret; struct spho_scope *inner_sc; - inner_sc = GET_SCOPE(forall); + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(forall != NULL); + + inner_sc = SCOPE(forall); if ((ret = msph_sphophi_foreach_post_tpexpr(f, inner_sc, forall->inner)) != 0) return (ret); - return (f(sc, T(forall))); + return (f(sc, TREE(forall))); } @@ -1190,10 +1349,13 @@ msph_sphophi_foreach_post_paren(msph_tree_sphophi_f f, struct spho_scope *sc, { int ret; + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(paren != NULL); + if ((ret = msph_sphophi_foreach_post_tpexpr(f, sc, paren->inner)) != 0) return (ret); - return (f(sc, T(paren))); + return (f(sc, TREE(paren))); } @@ -1201,12 +1363,18 @@ static int msph_sphophi_foreach_post_true(msph_tree_sphophi_f f, struct spho_scope *sc, struct msph_tree_true *tru) { - return (f(sc, T(tru))); + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(tru != NULL); + + return (f(sc, TREE(tru))); } static int msph_sphophi_foreach_post_false(msph_tree_sphophi_f f, struct spho_scope *sc, struct msph_tree_false *fls) { - return (f(sc, T(fls))); + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(fls != NULL); + + return (f(sc, TREE(fls))); } diff --git a/src/msph/token.c b/src/msph/token.c index 1c0adb2..e83a11d 100644 --- a/src/msph/token.c +++ b/src/msph/token.c @@ -5,9 +5,12 @@ #include #include +#include "spho/spho.h" + #include "msph/err.h" #include "msph/token.h" + struct msph_matcher { size_t off; size_t matchlen; diff --git a/src/msph/tree.c b/src/msph/tree.c index 89d7221..199628c 100644 --- a/src/msph/tree.c +++ b/src/msph/tree.c @@ -6,7 +6,7 @@ #include #include -#include "spho/util.h" +#include "spho/spho.h" #include "msph/tree.h" @@ -26,7 +26,8 @@ struct tree_parse { static void tree_parse_init(struct tree_parse *, struct msph_token_stream *); static int tree_parse_next_token(struct tree_parse *); -static void tree_parse_push_token(struct tree_parse *, struct msph_token *); +static void tree_parse_push_token(struct tree_parse *, + struct msph_token *); static ssize_t tree_ind_fprint(FILE *, int, struct msph_tree *); @@ -36,8 +37,13 @@ static struct msph_tree_unit *tree_parse_unit(struct tree_parse *, struct msph_tree *); static struct msph_tree_body *tree_parse_body(struct tree_parse *, struct msph_tree *); -static struct msph_tree_ident *tree_parse_ident(struct tree_parse *, - struct msph_tree *); +static struct msph_tree_ident *tree_parse_ident_extsize(struct tree_parse *, + struct msph_tree *, size_t); + +static struct msph_tree_namedecl *tree_parse_namedecl(struct tree_parse *, + struct msph_tree *); +static struct msph_tree_nameref *tree_parse_nameref(struct tree_parse *, + struct msph_tree *); static struct msph_tree_dir *tree_parse_tpdef(struct tree_parse *, struct msph_tree *); @@ -50,16 +56,18 @@ static struct msph_tree_dir *tree_parse_membdecl( struct tree_parse *, struct msph_tree *); + static struct msph_tree_tpexpr *tree_parse_tpexpr(struct tree_parse *, struct msph_tree *); static struct msph_tree_tpexpr *tree_parse_true(struct tree_parse *, struct msph_tree *); static struct msph_tree_tpexpr *tree_parse_false(struct tree_parse *, struct msph_tree *); -static struct msph_tree_tpexpr *tree_parse_name(struct tree_parse *, +static struct msph_tree_tpexpr *tree_parse_tpname_or_tpappl( + struct tree_parse *, struct msph_tree *); -static struct msph_tree_tpexpr *tree_parse_applargs(struct tree_parse *, - struct msph_tree_ident*, +static struct msph_tree_tpexpr *tree_parse_tpapplargs(struct tree_parse *, + struct msph_tree_nameref*, struct msph_tree *); static struct msph_tree_tpexpr *tree_parse_trait(struct tree_parse *, struct msph_tree *); @@ -87,8 +95,8 @@ msph_tree_makeroot(struct msph_ctx *ctx) MSPH_ERR(ctx, MSPH_ERR_SYS); return (NULL); } - T(root)->type = MSPH_TREE_ROOT; - T(root)->parent = NULL; + TREE(root)->type = MSPH_TREE_ROOT; + TREE(root)->parent = NULL; root->ctx = ctx; @@ -138,14 +146,14 @@ msph_tree_parse(struct msph_token_stream *s, struct msph_tree_root *root) struct tree_parse p; struct msph_tree_unit *unit; - if (T(root)->type != MSPH_TREE_ROOT) { + if (TREE(root)->type != MSPH_TREE_ROOT) { MSPH_ERR(s->ctx, MSPH_ERR_INVAL); return (-1); } tree_parse_init(&p, s); - if ((unit = tree_parse_unit(&p, T(root))) == NULL) + if ((unit = tree_parse_unit(&p, TREE(root))) == NULL) return (-1); STAILQ_INSERT_TAIL(&root->head, unit, entries); @@ -162,7 +170,7 @@ msph_tree_fprint(FILE *f, struct msph_tree *tree) { __attribute__((format(printf, 3, 4))) static ssize_t -ind_fprintf(FILE *f, int indent, const char *fmt, ...) +indent_fprintf(FILE *f, int indent, const char *fmt, ...) { int res; ssize_t ret; @@ -208,284 +216,298 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree) struct msph_tree_arrow *arrow; struct msph_tree_box *box; struct msph_tree_forall *forall; - struct msph_tree_appl *appl; + struct msph_tree_tpappl *tpappl; struct msph_tree_trait *trait; - struct msph_tree_name *name; + struct msph_tree_tpname *name; struct msph_tree_paren *paren; struct msph_tree_ident *ident; struct msph_tree_tpexpr *tp; ret = 0; - switch (tree->type) { + switch (TREE_ID(tree)) { case MSPH_TREE_ROOT: root = (struct msph_tree_root *)tree; - if ((res = ind_fprintf(f, indent, "(root\n")) < 0) + if ((res = indent_fprintf(f, indent, "(root\n")) < 0) return (res); STAILQ_FOREACH(unit, &root->head, entries) { - if ((res = tree_ind_fprint(f, indent+1, T(unit))) + if ((res = tree_ind_fprint(f, indent+1, TREE(unit))) < 0) return (res); ret += res; } - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); break; case MSPH_TREE_UNIT: unit = (struct msph_tree_unit *)tree; - if ((res = ind_fprintf(f, indent, "(unit:%s\n", unit->name)) + if ((res = indent_fprintf(f, indent, "(unit:%s\n", unit->name)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(unit->body))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(unit->body))) < 0) return (res); ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_BODY: body = (struct msph_tree_body *)tree; - if ((res = ind_fprintf(f, indent, "(body\n")) < 0) + if ((res = indent_fprintf(f, indent, "(body\n")) < 0) return (res); ret += res; STAILQ_FOREACH(dir, &body->head, entries) { - if ((res = tree_ind_fprint(f, indent+1, T(dir))) + if ((res = tree_ind_fprint(f, indent+1, TREE(dir))) < 0) return (res); ret += res; } - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_NOMINDECL: nomd = (struct msph_tree_nomindecl *)tree; - if ((res = ind_fprintf(f, indent, "(nomindecl:%u,%u\n", - TXT(nomd)->pos.line, TXT(nomd)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(nomindecl:%u,%u\n", + TEXT(nomd)->pos.line, TEXT(nomd)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(nomd->id))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(nomd->name))) < 0) return (res); ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_ASSERT: ass = (struct msph_tree_assert *)tree; - if ((res = ind_fprintf(f, indent, "(assert:%u,%u\n", - TXT(ass)->pos.line, TXT(ass)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(assert:%u,%u\n", + TEXT(ass)->pos.line, TEXT(ass)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(ass->ltp))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(ass->ltp))) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(ass->rtp))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(ass->rtp))) < 0) return (res); ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_TPDEF: tpdef = (struct msph_tree_tpdef *)tree; - if ((res = ind_fprintf(f, indent, "(tpdef:%u,%u\n", - TXT(tpdef)->pos.line, TXT(tpdef)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(tpdef:%u,%u\n", + TEXT(tpdef)->pos.line, TEXT(tpdef)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(tpdef->id))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(tpdef->name))) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(tpdef->tp))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(tpdef->tp))) < 0) return (res); ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_MEMBDECL: membdecl = (struct msph_tree_membdecl *)tree; - if ((res = ind_fprintf(f, indent, "(membdecl:%u,%u\n", - TXT(membdecl)->pos.line, TXT(membdecl)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(membdecl:%u,%u\n", + TEXT(membdecl)->pos.line, TEXT(membdecl)->pos.col)) < 0) { return (res); + } ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(membdecl->id))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(membdecl->name))) + < 0) { return (res); + } ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(membdecl->tp))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(membdecl->tp))) + < 0) { return (res); + } ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_CONJ: conj = (struct msph_tree_conj *)tree; - if ((res = ind_fprintf(f, indent, "(conj:%u,%u\n", - TXT(conj)->pos.line, TXT(conj)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(conj:%u,%u\n", + TEXT(conj)->pos.line, TEXT(conj)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(conj->ltp))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(conj->ltp))) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(conj->rtp))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(conj->rtp))) < 0) return (res); ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_DISJ: disj = (struct msph_tree_disj *)tree; - if ((res = ind_fprintf(f, indent, "(disj:%u,%u\n", - TXT(disj)->pos.line, TXT(disj)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(disj:%u,%u\n", + TEXT(disj)->pos.line, TEXT(disj)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(disj->ltp))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(disj->ltp))) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(disj->rtp))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(disj->rtp))) < 0) return (res); ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_IMPL: impl = (struct msph_tree_impl *)tree; - if ((res = ind_fprintf(f, indent, "(impl:%u,%u\n", - TXT(impl)->pos.line, TXT(impl)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(impl:%u,%u\n", + TEXT(impl)->pos.line, TEXT(impl)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(impl->ltp))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(impl->ltp))) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(impl->rtp))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(impl->rtp))) < 0) return (res); ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_ARROW: arrow = (struct msph_tree_arrow *)tree; - if ((res = ind_fprintf(f, indent, "(arrow:%u,%u\n", - TXT(arrow)->pos.line, TXT(arrow)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(arrow:%u,%u\n", + TEXT(arrow)->pos.line, TEXT(arrow)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(arrow->ltp))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(arrow->ltp))) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(arrow->rtp))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(arrow->rtp))) < 0) return (res); ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_BOX: box = (struct msph_tree_box *)tree; - if ((res = ind_fprintf(f, indent, "(box:%u,%u\n", - TXT(box)->pos.line, TXT(box)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(box:%u,%u\n", + TEXT(box)->pos.line, TEXT(box)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(box->inner))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(box->inner))) < 0) return (res); ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_FORALL: forall = (struct msph_tree_forall *)tree; - if ((res = ind_fprintf(f, indent, "(forall:%u,%u\n", - TXT(forall)->pos.line, TXT(forall)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(forall:%u,%u\n", + TEXT(forall)->pos.line, TEXT(forall)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(forall->id))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(forall->name))) + < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(forall->inner))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(forall->inner))) + < 0) { return (res); + } ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_PAREN: paren = (struct msph_tree_paren *)tree; - if ((res = ind_fprintf(f, indent, "(paren:%u,%u\n", - TXT(paren)->pos.line, TXT(paren)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(paren:%u,%u\n", + TEXT(paren)->pos.line, TEXT(paren)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(paren->inner))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(paren->inner))) + < 0) { return (res); + } ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; - case MSPH_TREE_APPL: - appl = (struct msph_tree_appl *)tree; - if ((res = ind_fprintf(f, indent, "(appl:%u,%u\n", - TXT(appl)->pos.line, TXT(appl)->pos.col)) < 0) + case MSPH_TREE_TPAPPL: + tpappl = (struct msph_tree_tpappl *)tree; + if ((res = indent_fprintf(f, indent, "(tpappl:%u,%u\n", + TEXT(tpappl)->pos.line, TEXT(tpappl)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(appl->id))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(tpappl->name))) < 0) return (res); ret += res; - STAILQ_FOREACH(tp, &appl->head, entries) { - if ((res = tree_ind_fprint(f, indent+1, T(tp))) < 0) + STAILQ_FOREACH(tp, &tpappl->args, entries) { + if ((res = tree_ind_fprint(f, indent+1, TREE(tp))) < 0) return (res); ret += res; } - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; - case MSPH_TREE_NAME: - name = (struct msph_tree_name *)tree; - if ((res = ind_fprintf(f, indent, "(name:%u,%u\n", - TXT(name)->pos.line, TXT(name)->pos.col)) < 0) + case MSPH_TREE_TPNAME: + name = (struct msph_tree_tpname *)tree; + if ((res = indent_fprintf(f, indent, "(name:%u,%u\n", + TEXT(name)->pos.line, TEXT(name)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(name->id))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(name->name))) < 0) return (res); ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; case MSPH_TREE_TRAIT: trait = (struct msph_tree_trait *)tree; - if ((res = ind_fprintf(f, indent, "(trait:%u,%u\n", - TXT(trait)->pos.line, TXT(trait)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(trait:%u,%u\n", + TEXT(trait)->pos.line, TEXT(trait)->pos.col)) < 0) return (res); ret += res; - if ((res = tree_ind_fprint(f, indent+1, T(trait->body))) < 0) + if ((res = tree_ind_fprint(f, indent+1, TREE(trait->body))) + < 0) { return (res); + } ret += res; - if ((res = ind_fprintf(f, indent, ")\n")) < 0) + if ((res = indent_fprintf(f, indent, ")\n")) < 0) return (res); ret += res; break; + case MSPH_TREE_NAMEDECL: + case MSPH_TREE_NAMEREF: case MSPH_TREE_IDENT: - ident = (struct msph_tree_ident *)tree; - if ((res = ind_fprintf(f, indent, "(ident:%u,%u:%s)\n", - TXT(ident)->pos.line, TXT(ident)->pos.col, ident->str)) + ident = IDENT(tree); + if ((res = indent_fprintf(f, indent, "(ident:%u,%u:%s)\n", + TEXT(ident)->pos.line, TEXT(ident)->pos.col, ident->str)) < 0) return (res); ret += res; break; case MSPH_TREE_TRUE: - if ((res = ind_fprintf(f, indent, "(true:%u,%u)\n", - TXT(tree)->pos.line, TXT(tree)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(true:%u,%u)\n", + TEXT(tree)->pos.line, TEXT(tree)->pos.col)) < 0) return (res); ret += res; break; case MSPH_TREE_FALSE: - if ((res = ind_fprintf(f, indent, "(false:%u,%u)\n", - TXT(tree)->pos.line, TXT(tree)->pos.col)) < 0) + if ((res = indent_fprintf(f, indent, "(false:%u,%u)\n", + TEXT(tree)->pos.line, TEXT(tree)->pos.col)) < 0) return (res); ret += res; break; @@ -542,9 +564,9 @@ tree_parse_unit(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(unit)->type = MSPH_TREE_UNIT; - T(unit)->parent = parent; - SCOPE_DECOR_INIT(&unit->dec); + TREE(unit)->type = MSPH_TREE_UNIT; + TREE(unit)->parent = parent; + DECOR_INIT(unit); unit->body = NULL; if ((namelen = strlcpy(unit->name, p->s->name, sizeof(unit->name))) @@ -553,13 +575,13 @@ tree_parse_unit(struct tree_parse *p, struct msph_tree *parent) goto err; } - if ((unit->body = tree_parse_body(p, T(unit))) == NULL) + if ((unit->body = tree_parse_body(p, TREE(unit))) == NULL) goto err; return (unit); err: - free_the_tree(T(unit)); + free_the_tree(TREE(unit)); return (NULL); } @@ -576,8 +598,8 @@ tree_parse_body(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(body)->type = MSPH_TREE_BODY; - T(body)->parent = parent; + TREE(body)->type = MSPH_TREE_BODY; + TREE(body)->parent = parent; STAILQ_INIT(&body->head); while ((res = tree_parse_next_token(p)) > 0) { @@ -585,16 +607,16 @@ tree_parse_body(struct tree_parse *p, struct msph_tree *parent) switch(CURR_TOKEN(p)->type) { case TOK_KW_TYPE: SPHO_DEBUG_PRINT("parsing tpdef\n"); - dir = tree_parse_tpdef(p, T(body)); + dir = tree_parse_tpdef(p, TREE(body)); break; case TOK_KW_NOMINAL: - dir = tree_parse_nomindecl(p, T(body)); + dir = tree_parse_nomindecl(p, TREE(body)); break; case TOK_KW_MEMBER: - dir = tree_parse_membdecl(p, T(body)); + dir = tree_parse_membdecl(p, TREE(body)); break; case TOK_KW_ASSERT: - dir = tree_parse_assert(p, T(body)); + dir = tree_parse_assert(p, TREE(body)); break; default: if ((tok = msph_token_copy(CTX(p), CURR_TOKEN(p))) @@ -615,7 +637,7 @@ tree_parse_body(struct tree_parse *p, struct msph_tree *parent) ret: return (body); err: - free_the_tree(T(body)); + free_the_tree(TREE(body)); return (NULL); } @@ -633,6 +655,7 @@ tree_parse_tpdef(struct tree_parse *p, struct msph_tree *parent) { int res; struct msph_tree_tpdef *def; + struct msph_tree_namedecl *name; EXPECT_CURR_TOKEN(p, TOK_KW_TYPE, MSPH_TREE_TPDEF, return (NULL)); @@ -640,43 +663,98 @@ tree_parse_tpdef(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(def)->type = MSPH_TREE_TPDEF; - T(def)->parent = parent; - TXT(def)->pos = CURR_TOKEN(p)->pos; - // TODO add scope decor when generalizing to type operators + TREE(def)->type = MSPH_TREE_TPDEF; + TREE(def)->parent = parent; + TEXT(def)->pos = CURR_TOKEN(p)->pos; + STAILQ_INIT(&def->params); + DECOR_INIT(def); EXPECT_READ_NEXT(res, p, MSPH_TREE_TPDEF, goto err); - if ((def->id = tree_parse_ident(p, T(def))) == NULL) + if ((def->name = tree_parse_namedecl(p, TREE(def))) == NULL) goto err; EXPECT_READ_NEXT(res, p, MSPH_TREE_TPDEF, goto err); + + if (CURR_TOKEN(p)->type == TOK_LBRAK) { + ADD_FLAG(TREE(def), MSPH_TREE_FLAG_SCOPE); + + do { + EXPECT_READ_NEXT(res, p, MSPH_TREE_TPDEF, goto err); + name = tree_parse_namedecl(p, TREE(def)); + if (name == NULL) + goto err; + STAILQ_INSERT_TAIL(&def->params, name, entries); + + EXPECT_READ_NEXT(res, p, MSPH_TREE_TPDEF, goto err); + } while (CURR_TOKEN(p)->type == TOK_COMMA); + + EXPECT_CURR_TOKEN(p, TOK_RBRAK, MSPH_TREE_TPDEF, goto err); + } EXPECT_CURR_TOKEN(p, TOK_EQUALS, MSPH_TREE_TPDEF, goto err); EXPECT_READ_NEXT(res, p, MSPH_TREE_TPDEF, goto err); - if ((def->tp = tree_parse_tpexpr(p, T(def))) == NULL) + if ((def->tp = tree_parse_tpexpr(p, TREE(def))) == NULL) goto err; return ((struct msph_tree_dir *)def); err: - free_the_tree(T(def)); + free_the_tree(TREE(def)); return (NULL); } +struct msph_tree_namedecl * +tree_parse_namedecl(struct tree_parse *p, struct msph_tree *parent) +{ + struct msph_tree_namedecl *name; + + EXPECT_CURR_TOKEN(p, TOK_IDENT, MSPH_TREE_NAMEDECL, return (NULL)); + + name = (struct msph_tree_namedecl *)tree_parse_ident_extsize(p, parent, + sizeof(*name)); + if (name == NULL) + return (NULL); + + SPHO_ASSERT(TREE(name)->type == MSPH_TREE_IDENT); + TREE(name)->type |= MSPH_TREE_NAMEDECL; + + return (name); +} + +struct msph_tree_nameref * +tree_parse_nameref(struct tree_parse *p, struct msph_tree *parent) +{ + struct msph_tree_nameref *name; + + EXPECT_CURR_TOKEN(p, TOK_IDENT, MSPH_TREE_NAMEREF, return (NULL)); + + name = (struct msph_tree_nameref *)tree_parse_ident_extsize(p, parent, + sizeof(*name)); + if (name == NULL) + return (NULL); + + SPHO_ASSERT(TREE(name)->type == MSPH_TREE_IDENT); + TREE(name)->type |= MSPH_TREE_NAMEREF; + + return (name); +} + struct msph_tree_ident * -tree_parse_ident(struct tree_parse *p, struct msph_tree *parent) +tree_parse_ident_extsize(struct tree_parse *p, struct msph_tree *parent, + size_t size) { struct msph_tree_ident *id; + SPHO_PRECOND(size >= sizeof(struct msph_tree_ident)); EXPECT_CURR_TOKEN(p, TOK_IDENT, MSPH_TREE_IDENT, return (NULL)); - if ((id = malloc(sizeof(*id))) == NULL) { + if ((id = malloc(sizeof(size))) == NULL) { MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(id)->type = MSPH_TREE_IDENT; - T(id)->parent = parent; - TXT(id)->pos = CURR_TOKEN(p)->pos; - NOM_DECOR_INIT(&id->dec); + TREE(id)->type = MSPH_TREE_IDENT; + TREE(id)->parent = parent; + TEXT(id)->pos = CURR_TOKEN(p)->pos; + DECOR_INIT(id); if (SPHO_STRLCPY(id->str, CURR_TOKEN(p)->data.str, sizeof(id->str)) >= sizeof(id->str)) { @@ -686,7 +764,7 @@ tree_parse_ident(struct tree_parse *p, struct msph_tree *parent) return (id); err: - free_the_tree(T(id)); + free_the_tree(TREE(id)); return (NULL); } @@ -715,7 +793,7 @@ tree_parse_tpexpr(struct tree_parse *p, struct msph_tree *parent) tp = tree_parse_forall(p, parent); break; case TOK_IDENT: - tp = tree_parse_name(p, parent); + tp = tree_parse_tpname_or_tpappl(p, parent); break; case TOK_CONST_TRUE: tp = tree_parse_true(p, parent); @@ -734,7 +812,7 @@ tree_parse_tpexpr(struct tree_parse *p, struct msph_tree *parent) tp = NULL; } - SPHO_DEBUG_PRINT("returning tp type=%x\n", T(tp)->type); + SPHO_DEBUG_PRINT("returning tp type=%x\n", TREE(tp)->type); return (tp); } @@ -750,20 +828,20 @@ tree_parse_conj(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(conj)->type = MSPH_TREE_CONJ; - T(conj)->parent = parent; - TXT(conj)->pos = CURR_TOKEN(p)->pos; - TP_DECOR_INIT(&conj->htpe.dec); + TREE(conj)->type = MSPH_TREE_CONJ; + TREE(conj)->parent = parent; + TEXT(conj)->pos = CURR_TOKEN(p)->pos; + DECOR_INIT(conj); conj->ltp = NULL; conj->rtp = NULL; EXPECT_READ_NEXT(res, p, MSPH_TREE_CONJ, goto err); - if ((conj->ltp = tree_parse_tpexpr(p, T(conj))) + if ((conj->ltp = tree_parse_tpexpr(p, TREE(conj))) == NULL) goto err; EXPECT_READ_NEXT(res, p, MSPH_TREE_CONJ, goto err); - if ((conj->rtp = tree_parse_tpexpr(p, T(conj))) + if ((conj->rtp = tree_parse_tpexpr(p, TREE(conj))) == NULL) goto err; @@ -786,10 +864,10 @@ tree_parse_disj(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(disj)->type = MSPH_TREE_DISJ; - T(disj)->parent = parent; - TXT(disj)->pos = CURR_TOKEN(p)->pos; - TP_DECOR_INIT(&disj->htpe.dec); + TREE(disj)->type = MSPH_TREE_DISJ; + TREE(disj)->parent = parent; + TEXT(disj)->pos = CURR_TOKEN(p)->pos; + DECOR_INIT(disj); disj->ltp = NULL; disj->rtp = NULL; @@ -822,10 +900,10 @@ tree_parse_impl(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(impl)->type = MSPH_TREE_IMPL; - T(impl)->parent = parent; - TXT(impl)->pos = CURR_TOKEN(p)->pos; - TP_DECOR_INIT(&impl->htpe.dec); + TREE(impl)->type = MSPH_TREE_IMPL; + TREE(impl)->parent = parent; + TEXT(impl)->pos = CURR_TOKEN(p)->pos; + DECOR_INIT(impl); impl->ltp = NULL; impl->rtp = NULL; @@ -858,10 +936,10 @@ tree_parse_arrow(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(arrow)->type = MSPH_TREE_ARROW; - T(arrow)->parent = parent; - TXT(arrow)->pos = CURR_TOKEN(p)->pos; - TP_DECOR_INIT(&arrow->htpe.dec); + TREE(arrow)->type = MSPH_TREE_ARROW; + TREE(arrow)->parent = parent; + TEXT(arrow)->pos = CURR_TOKEN(p)->pos; + DECOR_INIT(arrow); arrow->ltp = NULL; arrow->rtp = NULL; @@ -894,19 +972,19 @@ tree_parse_box(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(box)->type = MSPH_TREE_BOX; - T(box)->parent = parent; - TXT(box)->pos = CURR_TOKEN(p)->pos; - TP_DECOR_INIT(&box->htpe.dec); + TREE(box)->type = MSPH_TREE_BOX; + TREE(box)->parent = parent; + TEXT(box)->pos = CURR_TOKEN(p)->pos; + DECOR_INIT(box); box->inner = NULL; EXPECT_READ_NEXT(res, p, MSPH_TREE_BOX, goto err); - if ((box->inner = tree_parse_tpexpr(p, T(box))) == NULL) + if ((box->inner = tree_parse_tpexpr(p, TREE(box))) == NULL) goto err; return ((struct msph_tree_tpexpr *)box); err: - free_the_tree(T(box)); + free_the_tree(TREE(box)); return (NULL); } @@ -922,51 +1000,50 @@ tree_parse_forall(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(fa)->type = MSPH_TREE_FORALL; - T(fa)->parent = parent; - TXT(fa)->pos = CURR_TOKEN(p)->pos; - TP_DECOR_INIT(&fa->htpe.dec); - SCOPE_DECOR_INIT(&fa->dec); - fa->id = NULL; + TREE(fa)->type = MSPH_TREE_FORALL; + TREE(fa)->parent = parent; + TEXT(fa)->pos = CURR_TOKEN(p)->pos; + DECOR_INIT(fa); + fa->name = NULL; fa->inner = NULL; EXPECT_READ_NEXT(res, p, MSPH_TREE_FORALL, goto err); - if ((fa->id = tree_parse_ident(p, T(fa))) == NULL) + if ((fa->name = tree_parse_namedecl(p, TREE(fa))) == NULL) goto err; EXPECT_READ_NEXT(res, p, MSPH_TREE_FORALL, goto err); EXPECT_CURR_TOKEN(p, TOK_DOT, MSPH_TREE_FORALL, goto err); EXPECT_READ_NEXT(res, p, MSPH_TREE_FORALL, goto err); - if ((fa->inner = tree_parse_tpexpr(p, T(fa))) == NULL) + if ((fa->inner = tree_parse_tpexpr(p, TREE(fa))) == NULL) goto err; return ((struct msph_tree_tpexpr *)fa); err: - free_the_tree(T(fa)); + free_the_tree(TREE(fa)); return (NULL); } /* parse name or appl */ struct msph_tree_tpexpr * -tree_parse_name(struct tree_parse *p, struct msph_tree *parent) +tree_parse_tpname_or_tpappl(struct tree_parse *p, struct msph_tree *parent) { int res; - struct msph_tree_ident *id; - struct msph_tree_name *name; + struct msph_tree_tpname *tpname; struct msph_tree_tpexpr *ret; + struct msph_tree_nameref *nameref; struct msph_token *tok; ret = NULL; - name = NULL; + nameref = NULL; - if ((id = tree_parse_ident(p, NULL)) == NULL) + if ((nameref = tree_parse_nameref(p, NULL)) == NULL) return (NULL); - SPHO_DEBUG_PRINT("parsed ident=%s\n", id->str); if ((res = tree_parse_next_token(p)) == 1) { if (CURR_TOKEN(p)->type == TOK_LBRAK) { - if ((ret = tree_parse_applargs(p, id, parent)) == NULL) + if ((ret = tree_parse_tpapplargs(p, nameref, parent)) + == NULL) goto err; return (ret); } @@ -980,22 +1057,21 @@ tree_parse_name(struct tree_parse *p, struct msph_tree *parent) goto err; } - SPHO_DEBUG_PRINT("ident is name\n"); - if ((name = malloc(sizeof(*name))) == NULL) { + if ((tpname = malloc(sizeof(*tpname))) == NULL) { MSPH_ERR(CTX(p), MSPH_ERR_SYS); goto err; } - T(name)->type = MSPH_TREE_NAME; - T(name)->parent = parent; + TREE(tpname)->type = MSPH_TREE_TPNAME; + TREE(tpname)->parent = parent; - TXT(name)->pos = TXT(id)->pos; - TP_DECOR_INIT(&name->htpe.dec); - T(id)->parent = T(name); - name->id = id; + TEXT(tpname)->pos = TEXT(nameref)->pos; + DECOR_INIT(tpname); + TREE(nameref)->parent = TREE(tpname); + tpname->name = nameref; - return ((struct msph_tree_tpexpr *)name); + return ((struct msph_tree_tpexpr *)tpname); err: - free_the_tree(T(id)); + free_the_tree(TREE(nameref)); return (NULL); } @@ -1010,26 +1086,26 @@ err: * @return tpexpr node representing A[...]. */ struct msph_tree_tpexpr * -tree_parse_applargs(struct tree_parse *p, struct msph_tree_ident *id, +tree_parse_tpapplargs(struct tree_parse *p, struct msph_tree_nameref *name, struct msph_tree *parent) { int res; - struct msph_tree_appl *appl; + struct msph_tree_tpappl *tpappl; struct msph_tree_tpexpr *tp; tp = NULL; - EXPECT_CURR_TOKEN(p, TOK_LBRAK, MSPH_TREE_APPL, return (NULL)); + EXPECT_CURR_TOKEN(p, TOK_LBRAK, MSPH_TREE_TPAPPL, return (NULL)); - if ((appl = malloc(sizeof(*appl))) == NULL) { + if ((tpappl = malloc(sizeof(*tpappl))) == NULL) { MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(appl)->type = MSPH_TREE_APPL; - T(appl)->parent = parent; - TP_DECOR_INIT(&appl->htpe.dec); - appl->id = NULL; - STAILQ_INIT(&appl->head); + TREE(tpappl)->type = MSPH_TREE_TPAPPL; + TREE(tpappl)->parent = parent; + DECOR_INIT(tpappl); + tpappl->name = NULL; + STAILQ_INIT(&tpappl->args); /* parse the argument list */ while ((res = tree_parse_next_token(p)) == 1) { @@ -1037,38 +1113,38 @@ tree_parse_applargs(struct tree_parse *p, struct msph_tree_ident *id, if (CURR_TOKEN(p)->type == TOK_RBRAK) break; - /* if not start of argument list, check for comma and step - * tokenizer */ + /* if not at start of argument list, check for comma to know if + * we should parse another argument */ if (tp != NULL) { - EXPECT_CURR_TOKEN(p, TOK_COMMA, MSPH_TREE_APPL, + EXPECT_CURR_TOKEN(p, TOK_COMMA, MSPH_TREE_TPAPPL, goto err); - EXPECT_READ_NEXT(res, p, MSPH_TREE_APPL, goto err); + EXPECT_READ_NEXT(res, p, MSPH_TREE_TPAPPL, goto err); } - if ((tp = tree_parse_tpexpr(p, T(appl))) == NULL) + if ((tp = tree_parse_tpexpr(p, TREE(tpappl))) == NULL) goto err; - STAILQ_INSERT_TAIL(&appl->head, tp, entries); + STAILQ_INSERT_TAIL(&tpappl->args, tp, entries); } - /* system error */ + /* SYS_ERROR set in tree_parse_next_token */ if (res == -1) goto err; /* did not read final ']' because of EOF */ if (res == 0) { - MSPH_ERR_INFO(CTX(p), MSPH_ERR_TREE_EOF, MSPH_TREE_APPL); + MSPH_ERR_INFO(CTX(p), MSPH_ERR_TREE_EOF, MSPH_TREE_TPAPPL); goto err; } /* finally, appl takes ownership of id */ - T(id)->parent = T(appl); - appl->id = id; - TXT(appl)->pos = TXT(id)->pos; + TREE(name)->parent = TREE(tpappl); + tpappl->name = name; + TEXT(tpappl)->pos = TEXT(name)->pos; - return ((struct msph_tree_tpexpr *)appl); + return ((struct msph_tree_tpexpr *)tpappl); err: - free_the_tree(T(appl)); + free_the_tree(TREE(tpappl)); return (NULL); } @@ -1084,10 +1160,10 @@ tree_parse_true(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(t)->type = MSPH_TREE_TRUE; - T(t)->parent = parent; - TXT(t)->pos = CURR_TOKEN(p)->pos; - TP_DECOR_INIT(&t->htpe.dec); + TREE(t)->type = MSPH_TREE_TRUE; + TREE(t)->parent = parent; + TEXT(t)->pos = CURR_TOKEN(p)->pos; + DECOR_INIT(t); return ((struct msph_tree_tpexpr *)t); } @@ -1103,10 +1179,10 @@ tree_parse_false(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(f)->type = MSPH_TREE_FALSE; - T(f)->parent = parent; - TXT(f)->pos = CURR_TOKEN(p)->pos; - TP_DECOR_INIT(&f->htpe.dec); + TREE(f)->type = MSPH_TREE_FALSE; + TREE(f)->parent = parent; + TEXT(f)->pos = CURR_TOKEN(p)->pos; + DECOR_INIT(f); return ((struct msph_tree_tpexpr *)f); } @@ -1123,15 +1199,15 @@ tree_parse_paren(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(par)->type = MSPH_TREE_PAREN; - T(par)->parent = parent; - TXT(par)->pos = CURR_TOKEN(p)->pos; - TP_DECOR_INIT(&par->htpe.dec); + TREE(par)->type = MSPH_TREE_PAREN; + TREE(par)->parent = parent; + TEXT(par)->pos = CURR_TOKEN(p)->pos; + DECOR_INIT(par); par->inner = NULL; EXPECT_READ_NEXT(res, p, MSPH_TREE_PAREN, goto err); - if ((par->inner = tree_parse_tpexpr(p, T(par))) == NULL) + if ((par->inner = tree_parse_tpexpr(p, TREE(par))) == NULL) goto err; EXPECT_READ_NEXT(res, p, MSPH_TREE_PAREN, goto err); @@ -1139,7 +1215,7 @@ tree_parse_paren(struct tree_parse *p, struct msph_tree *parent) return ((struct msph_tree_tpexpr *)par); err: - free_the_tree(T(par)); + free_the_tree(TREE(par)); return (NULL); } @@ -1156,14 +1232,13 @@ tree_parse_trait(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(trait)->type = MSPH_TREE_TRAIT; - T(trait)->parent = parent; - TXT(trait)->pos = CURR_TOKEN(p)->pos; - TP_DECOR_INIT(&trait->htpe.dec); - SCOPE_DECOR_INIT(&trait->dec); + TREE(trait)->type = MSPH_TREE_TRAIT; + TREE(trait)->parent = parent; + TEXT(trait)->pos = CURR_TOKEN(p)->pos; + DECOR_INIT(trait); trait->body = NULL; - if ((trait->body = tree_parse_body(p, T(trait))) == NULL) + if ((trait->body = tree_parse_body(p, TREE(trait))) == NULL) goto err; EXPECT_READ_NEXT(res, p, MSPH_TREE_TRAIT, goto err); @@ -1171,7 +1246,7 @@ tree_parse_trait(struct tree_parse *p, struct msph_tree *parent) return ((struct msph_tree_tpexpr *)trait); err: - free_the_tree(T(trait)); + free_the_tree(TREE(trait)); return (NULL); } @@ -1180,46 +1255,30 @@ 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; + struct msph_tree_namedecl *name; + struct msph_tree_nomindecl *nomind; EXPECT_CURR_TOKEN(p, TOK_KW_NOMINAL, MSPH_TREE_NOMINDECL, return (NULL)); - if ((nomd = malloc(sizeof(*nomd))) == NULL) { + if ((nomind = malloc(sizeof(*nomind))) == NULL) { MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(nomd)->type = MSPH_TREE_NOMINDECL; - T(nomd)->parent = parent; - TXT(nomd)->pos = CURR_TOKEN(p)->pos; - nomd->id = NULL; - nomd->tp = NULL; + TREE(nomind)->type = MSPH_TREE_NOMINDECL; + TREE(nomind)->parent = parent; + TEXT(nomind)->pos = CURR_TOKEN(p)->pos; + nomind->name = NULL; EXPECT_READ_NEXT(res, p, MSPH_TREE_NOMINDECL, goto err); - if ((id = tree_parse_ident(p, T(nomd))) == NULL) + if ((name = tree_parse_namedecl(p, TREE(nomind))) == 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); + nomind->name = name; - 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); + return ((struct msph_tree_dir *)nomind); err: - free_the_tree(T(nomd)); + free_the_tree(TREE(nomind)); return (NULL); } @@ -1237,14 +1296,14 @@ tree_parse_membdecl(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(membd)->type = MSPH_TREE_MEMBDECL; - T(membd)->parent = parent; - TXT(membd)->pos = CURR_TOKEN(p)->pos; - membd->id = NULL; + TREE(membd)->type = MSPH_TREE_MEMBDECL; + TREE(membd)->parent = parent; + TEXT(membd)->pos = CURR_TOKEN(p)->pos; + membd->name = NULL; membd->tp = NULL; EXPECT_READ_NEXT(res, p, MSPH_TREE_MEMBDECL, goto err); - if ((membd->id = tree_parse_ident(p, T(membd))) == NULL) + if ((membd->name = tree_parse_namedecl(p, TREE(membd))) == NULL) goto err; EXPECT_READ_NEXT(res, p, MSPH_TREE_MEMBDECL, goto err); @@ -1252,12 +1311,12 @@ tree_parse_membdecl(struct tree_parse *p, struct msph_tree *parent) goto err); EXPECT_READ_NEXT(res, p, MSPH_TREE_MEMBDECL, goto err); - if ((membd->tp = tree_parse_tpexpr(p, T(membd))) == NULL) + if ((membd->tp = tree_parse_tpexpr(p, TREE(membd))) == NULL) goto err; return ((struct msph_tree_dir *)membd); err: - free_the_tree(T(membd)); + free_the_tree(TREE(membd)); return (NULL); } @@ -1275,14 +1334,14 @@ tree_parse_assert(struct tree_parse *p, struct msph_tree *parent) MSPH_ERR(CTX(p), MSPH_ERR_SYS); return (NULL); } - T(ass)->type = MSPH_TREE_ASSERT; - T(ass)->parent = parent; - TXT(ass)->pos = CURR_TOKEN(p)->pos; + TREE(ass)->type = MSPH_TREE_ASSERT; + TREE(ass)->parent = parent; + TEXT(ass)->pos = CURR_TOKEN(p)->pos; ass->ltp = NULL; ass->rtp = NULL; EXPECT_READ_NEXT(res, p, MSPH_TREE_ASSERT, goto err); - if ((ass->ltp = tree_parse_tpexpr(p, T(ass))) == NULL) + if ((ass->ltp = tree_parse_tpexpr(p, TREE(ass))) == NULL) goto err; EXPECT_READ_NEXT(res, p, MSPH_TREE_ASSERT, goto err); @@ -1290,12 +1349,12 @@ tree_parse_assert(struct tree_parse *p, struct msph_tree *parent) goto err); EXPECT_READ_NEXT(res, p, MSPH_TREE_ASSERT, goto err); - if ((ass->rtp = tree_parse_tpexpr(p, T(ass))) == NULL) + if ((ass->rtp = tree_parse_tpexpr(p, TREE(ass))) == NULL) goto err; return ((struct msph_tree_dir *)ass); err: - free_the_tree(T(ass)); + free_the_tree(TREE(ass)); return (NULL); } diff --git a/src/spho/bind.c b/src/spho/bind.c index dd55a51..714b323 100644 --- a/src/spho/bind.c +++ b/src/spho/bind.c @@ -1,77 +1,165 @@ #include +#include -#include "spho/ctx.h" +#include "spho/spho.h" +#include "spho/scope.h" #include "spho/bind.h" -struct spho_bind * -spho_bind_create(struct spho_ctx *ctx, struct spho_bind_scope *binder, - struct spho_bind *parent) +struct spho_prebind * +spho_prebind_create(struct spho_scope *sc) { - struct spho_bind *bind; + size_t i; + struct spho_nom *nom; + struct spho_prebind *bind; - SPHO_PRECOND(ctx != NULL); - SPHO_PRECOND(binder != NULL); + SPHO_PRECOND(sc != NULL); - if ((bind = malloc(sizeof(*bind))) == NULL) { - SPHO_ERR(binder->sc->ctx, SPHO_ERR_SYS); + if ((bind = calloc(1, sizeof(*bind))) == NULL) { + SPHO_ERR(sc->ctx, SPHO_ERR_SYS); return (NULL); } - bind->ctx = ctx; - bind->binder = binder; - bind->parent = parent; + if ((bind->binds = calloc(sc->n_noms, sizeof(*bind->binds))) == NULL) { + SPHO_ERR(sc->ctx, SPHO_ERR_SYS); + free(bind); + return (NULL); + } + + bind->sc = sc; + bind->sz = sc->n_noms; + + + i = 0; + SLIST_FOREACH(nom, &sc->noms, next) { + SPHO_ASSERT(i < bind->sz); + bind->binds[i++] = (struct spho_prebind_pair) { NULL, 0, NULL }; + } return (bind); } int -spho_bind_lkp(int, struct spho_bind *bind, struct spho_nom *nom, - union spho_bound **out) +spho_prebind_undef(struct spho_prebind *bind, + const struct spho_nom *nom) { - // TODO + size_t i; + SPHO_PRECOND(bind != NULL); + SPHO_PRECOND(nom != NULL); + + for (i = 0; i < bind->sz; i++) { + if (nom == bind->binds[i].nom) { + if (bind->binds[i].kind != SPHO_BIND_UNDECLARED) { + SPHO_ERR(bind->sc->ctx, SPHO_ERR_BIND_DUPL); + return (-1); + } + bind->binds[i].kind = SPHO_BIND_UNDEFINED; + } + } + + return (0); +} +int +spho_prebind_tp(struct spho_prebind *bind, const struct spho_nom *nom, + const struct spho_tp *tp) +{ + size_t i; + + SPHO_PRECOND(bind != NULL); + SPHO_PRECOND(nom != NULL); + SPHO_PRECOND(tp != NULL); + + for (i = 0; i < bind->sz; i++) { + if (nom == bind->binds[i].nom) { + if (bind->binds[i].kind != SPHO_BIND_UNDECLARED) { + SPHO_ERR(bind->sc->ctx, SPHO_ERR_BIND_DUPL); + return (-1); + } + bind->binds[i].kind = SPHO_BIND_TP; + bind->binds[i].val = (union spho_prebind_val) tp; + return (0); + } + } + + SPHO_ERR(bind->sc->ctx, SPHO_ERR_BIND_NOTFOUND); return (-1); } -void -spho_bind_destroy(struct spho_bind *bind) +int +spho_prebind_tp_op(struct spho_prebind *bind, const struct spho_nom *nom, + const struct spho_tp_op *op) { - free(bind); -} + size_t i; + SPHO_PRECOND(bind != NULL); + SPHO_PRECOND(nom != NULL); + SPHO_PRECOND(op != NULL); -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); + for (i = 0; i < bind->sz; i++) { + if (nom == bind->binds[i].nom) { + if (bind->binds[i].kind != SPHO_BIND_UNDECLARED) { + SPHO_ERR(bind->sc->ctx, SPHO_ERR_BIND_DUPL); + return (-1); + } + bind->binds[i].kind = SPHO_BIND_TP_OP; + bind->binds[i].val = (union spho_prebind_val) op; + return (0); + } } - 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); + SPHO_ERR(bind->sc->ctx, SPHO_ERR_BIND_NOTFOUND); + return (-1); } int -spho_binder_add_tp(struct spho_bind_scope *bdr, struct spho_nom *nom, - struct spho_tp *tp) +spho_prebind_member_tp(struct spho_prebind *bind, const struct spho_nom *nom, + const struct spho_tp *memb_tp) { - + size_t i; + + SPHO_PRECOND(bind != NULL); + SPHO_PRECOND(nom != NULL); + SPHO_PRECOND(memb_tp != NULL); + + for (i = 0; i < bind->sz; i++) { + if (nom == bind->binds[i].nom) { + if (bind->binds[i].kind != SPHO_BIND_UNDECLARED) { + SPHO_ERR(bind->sc->ctx, SPHO_ERR_BIND_DUPL); + return (-1); + } + bind->binds[i].kind = SPHO_BIND_MEMB_TP; + bind->binds[i].val = (union spho_prebind_val) memb_tp; + return (0); + } + } + + SPHO_ERR(bind->sc->ctx, SPHO_ERR_BIND_NOTFOUND); + return (-1); +} + +struct spho_prebind * +spho_prebind_dupl(const struct spho_prebind *bind) +{ + struct spho_prebind *cp; + + if ((cp = calloc(1, sizeof(*cp))) == NULL) { + SPHO_ERR(bind->sc->ctx, SPHO_ERR_SYS); + return (NULL); + } + + if ((cp->binds = calloc(bind->sz, sizeof(*cp->binds))) == NULL) { + SPHO_ERR(bind->sc->ctx, SPHO_ERR_SYS); + free(cp); + return (NULL); + } + + memcpy(cp->binds, bind->binds, bind->sz * sizeof(*bind->binds)); + + return (cp); +} + +void +spho_prebind_destroy(struct spho_prebind *bind) +{ + free(bind->binds); + free(bind); } diff --git a/src/spho/ctx.c b/src/spho/ctx.c index fbb0e9d..cd43288 100644 --- a/src/spho/ctx.c +++ b/src/spho/ctx.c @@ -4,7 +4,7 @@ #include #include -#include "spho/ctx.h" +#include "spho/spho.h" static const char *spho_ctx_sys_strerror(struct spho_ctx *); static const char *spho_ctx_intern_strerror(struct spho_ctx *); @@ -23,6 +23,10 @@ struct spho_err spho_errmsgs[] = { { SPHO_ERR_NOM_INUSE, "name already declared in current scope" }, { SPHO_ERR_NOM_NOTINSCOPE, "name not in scope" }, + + { SPHO_ERR_BIND_NOTFOUND, "binding name not found in scope" }, + { SPHO_ERR_BIND_DUPL, "duplicate binding" }, + { -1, NULL } }; @@ -91,7 +95,7 @@ spho_ctx_sys_strerror(struct spho_ctx *ctx) res = snprintf(ctx->errbuf, sizeof(ctx->errbuf), "spho_syserr: %s (%d) (%s:%d)", strerror(ctx->err_info), ctx->err_info, ctx->filebuf, ctx->errline); - if (res >= sizeof(ctx->errbuf)) + if (res >= (ssize_t)sizeof(ctx->errbuf)) ctx->errbuf[sizeof(ctx->errbuf) - 1] = '\0'; #else res = snprintf(ctx->errbuf, sizeof(ctx->errbuf), diff --git a/src/spho/scope.c b/src/spho/scope.c index c5347a0..589b8d7 100644 --- a/src/spho/scope.c +++ b/src/spho/scope.c @@ -10,9 +10,9 @@ static void spho_nom_term(struct spho_nom *); -static int scope_nom_lookup_str_loc(struct spho_scope *, const char *, +static int scope_nom_lookup_str_local(struct spho_scope *, const char *, size_t, struct spho_nom **); -static int scope_nom_in_loc(struct spho_scope *, struct spho_nom *); +static int scope_nom_in_local(struct spho_scope *, struct spho_nom *); int spho_scope_init(struct spho_scope *sc, struct spho_ctx *ctx, @@ -22,10 +22,13 @@ spho_scope_init(struct spho_scope *sc, struct spho_ctx *ctx, sc->parent = p; SLIST_INIT(&sc->subs); + SLIST_INIT(&sc->noms); + sc->n_noms = 0; + TAILQ_INIT(&sc->tps); - sc->stat_bind = NULL; + sc->bind = NULL; return (0); } @@ -39,9 +42,9 @@ spho_scope_term(struct spho_scope *sc) sc->parent = NULL; - if (sc->stat_bind == NULL) - spho_bind_scope_destroy(sc->stat_bind); - sc->stat_bind = NULL; + if (sc->bind == NULL) + spho_prebind_destroy(sc->bind); + sc->bind = NULL; } struct spho_scope * @@ -95,16 +98,12 @@ spho_scope_destroy(struct spho_scope *sc) struct spho_nom * spho_scope_nom_add(struct spho_scope *sc, const char *nomstr, size_t sz) { -#ifdef SPHO_USE_STRLCPY size_t res; -#else - ssize_t res; -#endif struct spho_nom *nom; nom = NULL; - if (scope_nom_lookup_str_loc(sc, nomstr, sz, &nom) == -1) + if (scope_nom_lookup_str_local(sc, nomstr, sz, &nom) == -1) return (NULL); if (nom != NULL) { @@ -117,25 +116,14 @@ spho_scope_nom_add(struct spho_scope *sc, const char *nomstr, size_t sz) return (NULL); } -#ifdef SPHO_USE_STRLCPY res = strlcpy(nom->s, nomstr, sizeof(nom->s)); if (res >= sizeof(nom->s)) { SPHO_SC_ERR(sc, SPHO_ERR_TOOBIG); goto err; } -#else - res = snprintf(nom->s, sizeof(nom->s), "%s", nomstr); - if (res < 0) { - SPHO_SC_ERR(sc, SPHO_ERR_SYS); - goto err; - } - if (res >= (ssize_t)sizeof(nom->s)) { - SPHO_SC_ERR(sc, SPHO_ERR_TOOBIG); - goto err; - } -#endif SLIST_INSERT_HEAD(&sc->noms, nom, next); + sc->n_noms++; return (nom); err: @@ -187,9 +175,9 @@ spho_scope_nom_lookup_str_strict(struct spho_scope *sc, const char *nomstr, } int -spho_scope_static_bind_init(struct spho_scope *sc) +spho_scope_prebind_init(struct spho_scope *sc) { - if ((sc->stat_bind = spho_bind_scope_create(sc)) + if ((sc->bind = spho_prebind_create(sc)) == NULL) { return (-1); } @@ -198,19 +186,42 @@ spho_scope_static_bind_init(struct spho_scope *sc) } int -spho_scope_static_bind_add_tp(struct spho_scope *sc, struct spho_nom *nom, +spho_scope_prebind_tp(struct spho_scope *sc, struct spho_nom *nom, struct spho_tp *tp) { - if (! scope_nom_in_loc(sc, nom)) { + if (! scope_nom_in_local(sc, nom)) { SPHO_ERR(sc->ctx, SPHO_ERR_NOM_NOTINSCOPE); return (-1); } - return (spho_bind_scope_add_tp(sc->stat_bind, nom, tp)); + return (spho_prebind_tp(sc->bind, nom, tp)); +} + +int +spho_scope_prebind_tp_op(struct spho_scope *sc, struct spho_nom *nom, + struct spho_tp_op *tp_op) +{ + if (! scope_nom_in_local(sc, nom)) { + SPHO_ERR(sc->ctx, SPHO_ERR_NOM_NOTINSCOPE); + return (-1); + } + + return (spho_prebind_tp_op(sc->bind, nom, tp_op)); +} + +int +spho_scope_prebind_undef(struct spho_scope *sc, struct spho_nom *nom) +{ + if (! scope_nom_in_local(sc, nom)) { + SPHO_ERR(sc->ctx, SPHO_ERR_NOM_NOTINSCOPE); + return (-1); + } + + return (spho_prebind_undef(sc->bind, nom)); } static int -scope_nom_lookup_str_loc(struct spho_scope *sc, const char *nomstr, +scope_nom_lookup_str_local(struct spho_scope *sc, const char *nomstr, size_t sz, struct spho_nom **out) { struct spho_nom *nom; @@ -234,7 +245,7 @@ scope_nom_lookup_str_loc(struct spho_scope *sc, const char *nomstr, } static int -scope_nom_in_loc(struct spho_scope *sc, struct spho_nom *nom) +scope_nom_in_local(struct spho_scope *sc, struct spho_nom *nom) { struct spho_nom *sc_nom; diff --git a/src/spho/tp.c b/src/spho/tp.c index 3f6e4aa..4140633 100644 --- a/src/spho/tp.c +++ b/src/spho/tp.c @@ -2,8 +2,7 @@ #include -#include "spho/ctx.h" -#include "spho/scope.h" +#include "spho/spho.h" #include "spho/tp.h" @@ -26,6 +25,22 @@ spho_tp_alloc(struct spho_scope *sc) return ((struct spho_tp *)tp_alloc); } +static struct spho_tp_op * +spho_tp_op_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_op *)tp_alloc)->sc = sc; + TAILQ_INSERT_TAIL(&sc->tps, tp_alloc, allocs); + + return ((struct spho_tp_op *)tp_alloc); +} + static void spho_tp_free(struct spho_tp *tp) { @@ -222,7 +237,39 @@ spho_tp_create_nominal(struct spho_scope *sc, struct spho_nom *nom) return (ret); } +struct spho_tp * +spho_tp_create_var(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_VAR; + ret->d.nom.nom = nom; + + return (ret); +} + + +struct spho_tp_op * +spho_tp_op_create(struct spho_scope *sc, struct spho_scope *op_sc, struct spho_tp *tp) +{ + struct spho_tp_op *op; + + SPHO_PRECOND(sc != NULL); + SPHO_PRECOND(op_sc != NULL); + SPHO_PRECOND(tp != NULL); + + if ((op = spho_tp_op_alloc(sc)) == NULL) + return (NULL); + + op->sc = sc; + op->op_sc = op_sc; + op->op_tp = tp; + + return (op); +} /* Free type structure. External data (like nom) are freed elsewhere. */ void @@ -234,6 +281,7 @@ spho_tp_destroy(struct spho_tp *tp) 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: