sphophi decorating with types

This commit is contained in:
Ellen Arvidsson 2025-05-01 18:16:10 +02:00
parent 17be15d7b5
commit a22c9726cd
19 changed files with 1762 additions and 380 deletions

View file

@ -22,10 +22,8 @@ set(SPHO_HEADER_DIR ${INCLUDE_DIR}/spho)
set(SPHO_HEADER
${SPHO_HEADER_DIR}/ctx.h
${SPHO_HEADER_DIR}/data.h
${SPHO_HEADER_DIR}/err.h
${SPHO_HEADER_DIR}/loc.h
${SPHO_HEADER_DIR}/parse.h
${SPHO_HEADER_DIR}/scope.h
${SPHO_HEADER_DIR}/tp.h
${SPHO_HEADER_DIR}/spho.h
@ -57,6 +55,7 @@ target_compile_definitions(devcheck PRIVATE
set(MSPH_SRC
${SRC_DIR}/msph/token.c
${SRC_DIR}/msph/tree.c
${SRC_DIR}/msph/sphophi.c
${SRC_DIR}/msph/msph.c
)
@ -65,6 +64,8 @@ set(MSPH_HEADER
${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
)
add_executable(msph ${MSPH_SRC} ${MSPH_HEADER})

20
example/ex4.msph Normal file
View file

@ -0,0 +1,20 @@
nominal M
nominal N
nominal O
nominal P
type A = {
member member1: & N M
member member2: | M N
}
type B = forall X. {
member member1 : & X A
}
member outer1 : box {
member member1: & B True
type T = & B A
member member2 : | (& T O) P
type S = & B False
}

View file

@ -2,6 +2,7 @@
#define _MSPH_COMMON_H
#include "msph/err.h"
#include "spho/ctx.h"
#define MSPH_IDENT_LEN 128
#define MSPH_NAME_LEN 1024
@ -11,6 +12,8 @@ struct msph_ctx {
int err_info;
char errbuf[SPHO_ERR_BUF_LEN];
struct spho_ctx *spho;
#ifdef SPHO_DEBUG
char filebuf[SPHO_ERR_FILEBUF_LEN];
int errline;

33
include/msph/decor.h Normal file
View file

@ -0,0 +1,33 @@
#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 */

View file

@ -17,6 +17,10 @@
#define MSPH_ERR_TREE_EOF 0x2002
#define MSPH_ERR_TREE_NOMATCH 0x2003
#define MSPH_ERR_TYPE_INVAL 0x3001
#define MSPH_ERR_SPHOPHI 0x10001
// TODO add more diagnostics

15
include/msph/sphophi.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef _MSPH_TYPE_H
#define _MSPH_TYPE_H
#include "msph/tree.h"
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(struct msph_tree_root *);
int msph_sphoxex(struct msph_tree_root *);
#endif

View file

@ -5,6 +5,7 @@
#include "msph/common.h"
#include "msph/token.h"
#include "msph/decor.h"
/*
* TYPES:
@ -99,7 +100,7 @@ struct msph_tree_ident;
struct msph_tree_tpexpr;
struct msph_tree_root {
struct msph_tree tr;
struct msph_tree htr;
struct msph_ctx *ctx;
@ -107,145 +108,154 @@ struct msph_tree_root {
};
struct msph_tree_unit {
struct msph_tree tr;
struct msph_tree htr;
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 tr;
struct msph_tree htr;
struct msph_text_pos pos;
};
struct msph_tree_body {
struct msph_tree tr;
struct msph_tree htr;
STAILQ_HEAD(msph_tree_dir_l, msph_tree_dir) head;
};
struct msph_tree_dir {
struct msph_tree tr;
struct msph_tree_text htxt;
STAILQ_ENTRY(msph_tree_dir) entries;
};
struct msph_tree_tpdef {
struct msph_tree_dir dir;
struct msph_tree_dir hdir;
struct msph_tree_ident *id;
struct msph_tree_tpexpr *tp;
};
struct msph_tree_nomindecl {
struct msph_tree_dir dir;
struct msph_tree_dir hdir;
struct msph_tree_ident *id;
};
struct msph_tree_membdecl {
struct msph_tree_dir dir;
struct msph_tree_dir hdir;
struct msph_tree_ident *id;
struct msph_tree_tpexpr *tp;
};
struct msph_tree_assert {
struct msph_tree_dir dir;
struct msph_tree_dir hdir;
struct msph_tree_tpexpr *ltp;
struct msph_tree_tpexpr *rtp;
};
struct msph_tree_tpexpr {
struct msph_tree tr;
struct msph_tree_text htxt;
STAILQ_ENTRY(msph_tree_tpexpr) entries;
struct msph_tp_decor dec;
};
struct msph_tree_true {
struct msph_tree_tpexpr tp;
struct msph_tree_tpexpr htpe;
};
struct msph_tree_false {
struct msph_tree_tpexpr tp;
struct msph_tree_tpexpr htpe;
};
struct msph_tree_name {
struct msph_tree_tpexpr tp;
struct msph_tree_tpexpr htpe;
struct msph_tree_ident *id;
};
struct msph_tree_appl {
struct msph_tree_tpexpr tp;
struct msph_tree_tpexpr htpe;
struct msph_tree_ident *id;
STAILQ_HEAD(msph_tree_tpexpr_l, msph_tree_tpexpr) head;
};
struct msph_tree_trait {
struct msph_tree_tpexpr tp;
struct msph_tree_tpexpr htpe;
struct msph_tree_body *body;
struct msph_scope_decor dec;
};
struct msph_tree_conj {
struct msph_tree_tpexpr tp;
struct msph_tree_tpexpr htpe;
struct msph_tree_tpexpr *ltp;
struct msph_tree_tpexpr *rtp;
};
struct msph_tree_disj {
struct msph_tree_tpexpr tp;
struct msph_tree_tpexpr htpe;
struct msph_tree_tpexpr *ltp;
struct msph_tree_tpexpr *rtp;
};
struct msph_tree_impl {
struct msph_tree_tpexpr tp;
struct msph_tree_tpexpr htpe;
struct msph_tree_tpexpr *ltp;
struct msph_tree_tpexpr *rtp;
};
struct msph_tree_arrow {
struct msph_tree_tpexpr tp;
struct msph_tree_tpexpr htpe;
struct msph_tree_tpexpr *ltp;
struct msph_tree_tpexpr *rtp;
};
struct msph_tree_box {
struct msph_tree_tpexpr tp;
struct msph_tree_tpexpr htpe;
struct msph_tree_tpexpr *inner;
};
struct msph_tree_forall {
struct msph_tree_tpexpr tp;
struct msph_tree_tpexpr htpe;
struct msph_tree_ident *ident;
struct msph_tree_ident *id;
struct msph_tree_tpexpr *inner;
struct msph_scope_decor dec;
};
struct msph_tree_paren {
struct msph_tree_tpexpr tp;
struct msph_tree_tpexpr htpe;
struct msph_tree_tpexpr *inner;
};
struct msph_tree_ident {
struct msph_tree tr;
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 *);
@ -254,4 +264,7 @@ 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

View file

@ -1,12 +0,0 @@
#ifndef _SPHO_DATA_H
#define _SPHO_DATA_H
struct spho_nom {
char s[128];
SLIST_ENTRY(spho_nom) next;
};
SLIST_HEAD(spho_nom_l, spho_nom);
#endif /* _SPHO_DATA_H */

View file

@ -12,7 +12,8 @@
#define SPHO_ERR_INTERNAL 0x010001
#define SPHO_ERR_TOOBIG 0x010002
#define SPHO_ERR_ARGINVAL 0x010003
#define SPHO_ERR_NAMEINUSE 0x010004
#define SPHO_ERR_NOM_INUSE 0x020001
#define SPHO_ERR_NOM_NOTINSCOPE 0x020002
#define SPHO_ERR_IS_SYSERR(err) (SPHO_ERR_SYS == err)

View file

@ -1,7 +0,0 @@
#ifndef _SPHO_PARSE_H
#define _SPHO_PARSE_H
#endif

View file

@ -1,7 +1,118 @@
#ifndef _SPHO_SCOPE_H
#define _SPHO_SCOPE_H
#include "spho/data.h"
#include <sys/queue.h>
#include <stdlib.h>
#define SPHO_NOM_LEN 128
struct spho_nom {
char s[SPHO_NOM_LEN];
SLIST_ENTRY(spho_nom) next;
};
SLIST_HEAD(spho_nom_l, spho_nom);
#define TP_KONST_KEY_TRUE 0x43445 /* don't change!!!!! */
#define TP_KONST_KEY_FALSE 0x66a57 /* don't change!1! */
struct spho_var {
struct spho_nom nom;
STAILQ_ENTRY(spho_var) next;
};
STAILQ_HEAD(spho_var_l, spho_var);
struct spho_bind {
struct spho_nom nom;
struct spho_tpop *op;
};
struct spho_tpop {
struct spho_var_l params;
struct spho_tp *def;
};
struct spho_rec {
struct spho_nom mnom;
struct spho_tp *tp;
};
/* type data */
struct tp_binop_data {
struct spho_tp *left;
struct spho_tp *right;
};
struct tp_unop_data {
struct spho_tp *operand;
};
struct tp_binding_data {
struct spho_nom *nom;
struct spho_tp *bound;
};
struct tp_nom_data {
struct spho_nom *nom;
};
struct tp_appl_data {
struct spho_nom *nom;
struct spho_tp_l *args;
};
struct tp_konst_data {
int key;
const char *str;
};
extern const struct tp_konst_data tp_konst_true;
extern const struct tp_konst_data tp_konst_false;
#define SPHO_K_TRUE (&tp_konst_true)
#define SPHO_K_FALSE (&tp_konst_false)
/* type data union */
union tp_data {
struct tp_binop_data binop;
struct tp_unop_data unop;
struct tp_binding_data bind;
struct tp_appl_data appl;
struct tp_nom_data nom;
struct tp_konst_data konst;
};
/* sappho type */
struct spho_tp {
struct spho_scope *sc;
int form;
union tp_data d;
STAILQ_ENTRY(spho_tp) entries;
};
STAILQ_HEAD(spho_tp_l, spho_tp);
struct spho_tp_ptr {
struct spho_tp *p;
STAILQ_ENTRY(spho_tp_ptr) entries;
};
STAILQ_HEAD(spho_tp_ptr_l, spho_tp_ptr);
struct spho_tp_alloc {
struct spho_tp tp;
TAILQ_ENTRY(spho_tp_alloc) allocs;
};
TAILQ_HEAD(spho_tp_alloc_l, spho_tp_alloc);
SLIST_HEAD(spho_scope_l, spho_scope);
@ -11,6 +122,7 @@ struct spho_scope {
struct spho_scope_l subs;
struct spho_nom_l noms;
struct spho_tp_alloc_l tps;
SLIST_ENTRY(spho_scope) next;
};
@ -24,11 +136,13 @@ void spho_scope_term(struct spho_scope *);
struct spho_scope *spho_scope_global(struct spho_ctx *);
struct spho_scope *spho_scope_create(struct spho_scope *);
void spho_scope_destroy(struct spho_scope *);
struct spho_nom *spho_scope_nom_add(struct spho_scope *, const char *, size_t);
int spho_scope_nom_get(struct spho_scope *, const char *, size_t,
struct spho_nom **);
// int spho_scope_nom_del(struct spho_nom *);
int spho_scope_nom_lookup(struct spho_scope *, const char *, size_t,
struct spho_nom **);
#endif /* _SPHO_SCOPE_H */

View file

@ -1,160 +1,55 @@
#ifndef _SPHO_TP_H
#define _SPHO_TP_H
/* base defs */
#define SPHO_KONST_S_SZ 128
#define SPHO_KONST_K_TRUE 0x43445 /* don't change!!!!! */
#define SPHO_KONST_K_FALSE 0x66a57 /* don't change!1! */
struct spho_konst {
const char *s;
int k;
};
const struct spho_konst SPHO_K_TRUE_V = { "True", SPHO_KONST_K_TRUE };
const struct spho_konst SPHO_K_FALSE_V = { "False", SPHO_KONST_K_FALSE };
#define SPHO_K_TRUE (&SPHO_K_TRUE_V)
#define SPHO_K_FALSE (&SPHO_K_FALSE_V)
struct spho_var {
struct spho_nom nom;
STAILQ_ENTRY(spho_var) next;
};
STAILQ_HEAD(spho_var_l, spho_var);
struct spho_bind {
struct spho_nom nom;
struct spho_tpop *op;
};
struct spho_tpop {
struct spho_var_l params;
struct spho_tp *def;
};
struct spho_rec {
struct spho_nom mnom;
struct spho_tp *tp;
};
/* type data */
struct tp_bin_data {
struct spho_tp *left;
struct spho_tp *right;
};
struct tp_box_data {
struct spho_tp *inr;
};
struct tp_forall_data {
struct spho_var *var;
struct spho_tp *inr;
};
struct tp_bappl_data {
struct spho_bind *bind;
struct spho_tp_l *args;
};
struct tp_konst_data {
const struct spho_konst *k;
};
struct tp_var_data {
struct spho_var *v;
};
struct tp_nominal_data {
struct spho_nom *n;
};
struct tp_record_data {
struct spho_rec *r;
};
/* type data union */
union tp_data {
struct tp_bin_data binop;
struct tp_box_data box;
struct tp_forall_data fa;
struct tp_bappl_data bappl;
struct tp_konst_data konst;
struct tp_var_data var;
struct tp_nominal_data nom; // XXX
struct tp_record_data rec;
};
#include "spho/scope.h"
#define SPHO_TP_FORM_UNKNOWN 0x00
#define SPHO_TP_FORM_DISJ 0x10
#define SPHO_TP_FORM_CONJ 0x11
#define SPHO_TP_FORM_CONJ 0x10
#define SPHO_TP_FORM_DISJ 0x11
#define SPHO_TP_FORM_IMPL 0x12
#define SPHO_TP_FORM_BOX 0x13
#define SPHO_TP_FORM_ARROW 0x14
#define SPHO_TP_FORM_ARROW 0x13
#define SPHO_TP_FORM_BOX 0x14
#define SPHO_TP_FORM_FORALL 0x15
#define SPHO_TP_FORM_BAPPL 0x16
#define SPHO_TP_FORM_APPL 0x16
#define SPHO_TP_FORM_FALSE 0x20
#define SPHO_TP_FORM_TRUE 0x21
#define SPHO_TP_FORM_VAR 0x22
#define SPHO_TP_FORM_TRUE 0x20
#define SPHO_TP_FORM_FALSE 0x21
#define SPHO_TP_FORM_NOM 0x23
#define SPHO_TP_FORM_REC 0x23
#define SPHO_TP_FORM_MEMBER 0x24
// #define SPHO_TP_FORM_SUB 0x96
#define SPHO_TP_FORM_IS_VALID(f) \
(f) >= SPHO_TP_FORM_DISJ && (f) <= SPHO_TP_FORM_BAPPL || \
(f) >= SPHO_TP_FORM_FALSE && (f) <= SPHO_TP_FORM_NOM || \
(f) == SPHO_TP_FORM_REC
/* sappho type */
struct spho_tp {
struct spho_scope *sc;
int form;
union tp_data data;
STAILQ_ENTRY(spho_tp) next;
};
STAILQ_HEAD(spho_tp_l, spho_tp);
#define SPHO_TP_ERR(tp, err) SPHO_ERR((tp)->sc->ctx, (err))
struct spho_var *spho_var_create(struct spho_scope *, char *, size_t);
struct spho_var *spho_var_get(struct spho_scope *, char *, size_t);
//struct spho_var *spho_var_create(struct spho_scope *, char *, size_t);
//struct spho_var *spho_var_get(struct spho_scope *, char *, size_t);
//struct spho_tp *spho_tp_create_disj(struct spho_scope *, struct spho_tp *,
// struct spho_tp *, struct spho_tp *);
//struct spho_tp *spho_tp_create_conj(struct spho_scope *, struct spho_tp *,
// struct spho_tp *, struct spho_tp *);
//struct spho_tp *spho_tp_create_impl(struct spho_scope *, struct spho_tp *,
// struct spho_tp *, struct spho_tp *);
//struct spho_tp *spho_tp_create_box(struct spho_scope *, struct spho_tp *,
// struct spho_tp *);
//struct spho_tp *spho_tp_create_arrow(struct spho_scope *, struct spho_tp *,
// struct spho_tp *);
//struct spho_tp *spho_tp_create_forall(struct spho_scope *, struct spho_name *,
// struct spho_tp *);
struct spho_tp *spho_tp_create_conj(struct spho_scope *, struct spho_tp *,
struct spho_tp *);
struct spho_tp *spho_tp_create_disj(struct spho_scope *, struct spho_tp *,
struct spho_tp *);
struct spho_tp *spho_tp_create_impl(struct spho_scope *, struct spho_tp *,
struct spho_tp *);
struct spho_tp *spho_tp_create_arrow(struct spho_scope *, struct spho_tp *,
struct spho_tp *);
struct spho_tp *spho_tp_create_box(struct spho_scope *, struct spho_tp *);
struct spho_tp *spho_tp_create_forall(struct spho_scope *, struct spho_nom *,
struct spho_tp *);
struct spho_tp *spho_tp_create_true(struct spho_scope *);
struct spho_tp *spho_tp_create_false(struct spho_scope *);
struct spho_tp *spho_tp_create_name(struct spho_scope *,
struct spho_nom *);
struct spho_tp *spho_tp_create_appl(struct spho_scope *, struct spho_nom *,
struct spho_tp_l *);
struct spho_tp *spho_tp_create_member(struct spho_scope *, struct spho_nom *,
struct spho_tp *);
//struct spho_tp *spho_tp_create_const(struct spho_scope *, struct spho_const *);
//struct spho_tp *spho_tp_create_nominal(struct spho_scope *,
// struct spho_nom *);
//struct spho_tp *spho_tp_create_var(struct spho_scope *, struct spho_var *);
//struct spho_tp *spho_tp_create_record(struct spho_scope *, struct spho_rec *);
//struct spho_tp *spho_tp_create_sub(struct spho_scope *, struct spho_tp *,
// struct spho_tp *spho_tp_create_var(struct spho_scope *, struct spho_var *);
// struct spho_tp *spho_tp_create_sub(struct spho_scope *, struct spho_tp *,
// struct spho_tp *);
void spho_tp_destroy(struct spho_tp*);
void spho_tp_free(struct spho_tp *);
void spho_tp_destroy(struct spho_tp *);
#endif

View file

@ -5,12 +5,7 @@
#include "msph/err.h"
#include "msph/token.h"
#include "msph/tree.h"
#define PRINTERR(ctx) \
do { \
fprintf(stderr, "msph_err: %x (%d)\n", (ctx).err, \
(ctx).err_info); \
} while (0)
#include "msph/sphophi.h"
struct msph_opts {
int tokenize_only;
@ -30,7 +25,6 @@ struct msph_opts {
"\t-t - print tokenization\n" \
"\t-o - output path\n"
void
print_usage(void)
{
@ -88,6 +82,8 @@ run(struct msph_opts *opts)
FILE *in, *out;
in = out = NULL;
s = NULL;
root = NULL;
msph_ctx_init(&ctx);
@ -134,6 +130,9 @@ run(struct msph_opts *opts)
if (msph_tree_fprint(out, (struct msph_tree *)root) < 0)
goto err;
if (msph_sphophi(root) != 0)
goto err;
exit:
if (msph_token_stream_close(s) == -1)
goto err;
@ -141,7 +140,13 @@ exit:
return (0);
err:
PRINTERR(ctx);
if (root != NULL && ctx.err == MSPH_ERR_SPHOPHI) {
fprintf(stderr, "ERROR:%s\n",
spho_ctx_strerror(ctx.spho));
} else {
fprintf(stderr, "ERROR:msph_err: %x (%d)\n", (ctx).err,
(ctx).err_info);
}
if (in)
fclose(in);
@ -149,3 +154,14 @@ err:
fclose(out);
return (-1);
}
void
msph_ctx_init(struct msph_ctx *ctx)
{
ctx->err = 0;
ctx->err_info = 0;
ctx->spho = NULL;
}

1136
src/msph/sphophi.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -110,12 +110,6 @@ static int read_single_tok(struct msph_token *, struct msph_token_stream *);
static const char *tok_base_str(struct msph_token *);
void msph_ctx_init(struct msph_ctx *ctx)
{
ctx->err = 0;
ctx->err_info = 0;
}
struct msph_token_stream *
msph_token_stream_file(struct msph_ctx *ctx, const char *name, FILE *f)
{

View file

@ -21,7 +21,6 @@ struct tree_parse {
#define CURR_TOKEN(parse) (&parse->curr)
#define T(ptr) ((struct msph_tree *)ptr)
#define CTX(parse) ((parse)->s->ctx)
static void tree_parse_init(struct tree_parse *,
@ -261,7 +260,8 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_NOMINDECL:
nomd = (struct msph_tree_nomindecl *)tree;
if ((res = ind_fprintf(f, indent, "(nomindecl\n")) < 0)
if ((res = ind_fprintf(f, indent, "(nomindecl:%u,%u\n",
TXT(nomd)->pos.line, TXT(nomd)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(nomd->id))) < 0)
@ -273,7 +273,8 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_ASSERT:
ass = (struct msph_tree_assert *)tree;
if ((res = ind_fprintf(f, indent, "(assert\n")) < 0)
if ((res = ind_fprintf(f, indent, "(assert:%u,%u\n",
TXT(ass)->pos.line, TXT(ass)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(ass->ltp))) < 0)
@ -288,7 +289,8 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_TPDEF:
tpdef = (struct msph_tree_tpdef *)tree;
if ((res = ind_fprintf(f, indent, "(tpdef\n")) < 0)
if ((res = ind_fprintf(f, indent, "(tpdef:%u,%u\n",
TXT(tpdef)->pos.line, TXT(tpdef)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(tpdef->id))) < 0)
@ -303,8 +305,11 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_MEMBDECL:
membdecl = (struct msph_tree_membdecl *)tree;
if ((res = ind_fprintf(f, indent, "(membdecl:%s\n",
membdecl->id->str)) < 0)
if ((res = ind_fprintf(f, indent, "(membdecl:%u,%u\n",
TXT(membdecl)->pos.line, TXT(membdecl)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(membdecl->id))) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(membdecl->tp))) < 0)
@ -316,7 +321,8 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_CONJ:
conj = (struct msph_tree_conj *)tree;
if ((res = ind_fprintf(f, indent, "(conj\n")) < 0)
if ((res = ind_fprintf(f, indent, "(conj:%u,%u\n",
TXT(conj)->pos.line, TXT(conj)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(conj->ltp))) < 0)
@ -331,7 +337,8 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_DISJ:
disj = (struct msph_tree_disj *)tree;
if ((res = ind_fprintf(f, indent, "(disj\n")) < 0)
if ((res = ind_fprintf(f, indent, "(disj:%u,%u\n",
TXT(disj)->pos.line, TXT(disj)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(disj->ltp))) < 0)
@ -346,7 +353,8 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_IMPL:
impl = (struct msph_tree_impl *)tree;
if ((res = ind_fprintf(f, indent, "(impl\n")) < 0)
if ((res = ind_fprintf(f, indent, "(impl:%u,%u\n",
TXT(impl)->pos.line, TXT(impl)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(impl->ltp))) < 0)
@ -361,7 +369,8 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_ARROW:
arrow = (struct msph_tree_arrow *)tree;
if ((res = ind_fprintf(f, indent, "(arrow\n")) < 0)
if ((res = ind_fprintf(f, indent, "(arrow:%u,%u\n",
TXT(arrow)->pos.line, TXT(arrow)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(arrow->ltp))) < 0)
@ -376,7 +385,8 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_BOX:
box = (struct msph_tree_box *)tree;
if ((res = ind_fprintf(f, indent, "(box\n")) < 0)
if ((res = ind_fprintf(f, indent, "(box:%u,%u\n",
TXT(box)->pos.line, TXT(box)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(box->inner))) < 0)
@ -388,10 +398,11 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_FORALL:
forall = (struct msph_tree_forall *)tree;
if ((res = ind_fprintf(f, indent, "(forall:\n")) < 0)
if ((res = ind_fprintf(f, indent, "(forall:%u,%u\n",
TXT(forall)->pos.line, TXT(forall)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(forall->ident))) < 0)
if ((res = tree_ind_fprint(f, indent+1, T(forall->id))) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(forall->inner))) < 0)
@ -403,7 +414,8 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_PAREN:
paren = (struct msph_tree_paren *)tree;
if ((res = ind_fprintf(f, indent, "(paren\n")) < 0)
if ((res = ind_fprintf(f, indent, "(paren:%u,%u\n",
TXT(paren)->pos.line, TXT(paren)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(paren->inner))) < 0)
@ -415,7 +427,8 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_APPL:
appl = (struct msph_tree_appl *)tree;
if ((res = ind_fprintf(f, indent, "(appl\n")) < 0)
if ((res = ind_fprintf(f, indent, "(appl:%u,%u\n",
TXT(appl)->pos.line, TXT(appl)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(appl->id))) < 0)
@ -432,7 +445,8 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_NAME:
name = (struct msph_tree_name *)tree;
if ((res = ind_fprintf(f, indent, "(name\n")) < 0)
if ((res = ind_fprintf(f, indent, "(name:%u,%u\n",
TXT(name)->pos.line, TXT(name)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(name->id))) < 0)
@ -444,7 +458,8 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_TRAIT:
trait = (struct msph_tree_trait *)tree;
if ((res = ind_fprintf(f, indent, "(trait\n")) < 0)
if ((res = ind_fprintf(f, indent, "(trait:%u,%u\n",
TXT(trait)->pos.line, TXT(trait)->pos.col)) < 0)
return (res);
ret += res;
if ((res = tree_ind_fprint(f, indent+1, T(trait->body))) < 0)
@ -456,18 +471,21 @@ tree_ind_fprint(FILE *f, int indent, struct msph_tree *tree)
break;
case MSPH_TREE_IDENT:
ident = (struct msph_tree_ident *)tree;
if ((res = ind_fprintf(f, indent, "(ident:%s)\n", ident->str))
if ((res = ind_fprintf(f, indent, "(ident:%u,%u:%s)\n",
TXT(ident)->pos.line, TXT(ident)->pos.col, ident->str))
< 0)
return (res);
ret += res;
break;
case MSPH_TREE_TRUE:
if ((res = ind_fprintf(f, indent, "(true)\n")) < 0)
if ((res = ind_fprintf(f, indent, "(true:%u,%u)\n",
TXT(tree)->pos.line, TXT(tree)->pos.col)) < 0)
return (res);
ret += res;
break;
case MSPH_TREE_FALSE:
if ((res = ind_fprintf(f, indent, "(false)\n")) < 0)
if ((res = ind_fprintf(f, indent, "(false:%u,%u)\n",
TXT(tree)->pos.line, TXT(tree)->pos.col)) < 0)
return (res);
ret += res;
break;
@ -526,6 +544,7 @@ tree_parse_unit(struct tree_parse *p, struct msph_tree *parent)
}
T(unit)->type = MSPH_TREE_UNIT;
T(unit)->parent = parent;
SCOPE_DECOR_INIT(&unit->dec);
unit->body = NULL;
if ((namelen = strlcpy(unit->name, p->s->name, sizeof(unit->name)))
@ -623,6 +642,8 @@ tree_parse_tpdef(struct tree_parse *p, struct msph_tree *parent)
}
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
EXPECT_READ_NEXT(res, p, MSPH_TREE_TPDEF, goto err);
if ((def->id = tree_parse_ident(p, T(def))) == NULL)
@ -646,7 +667,6 @@ tree_parse_ident(struct tree_parse *p, struct msph_tree *parent)
{
struct msph_tree_ident *id;
SPHO_DEBUG_PRINT("parsing ident\n");
EXPECT_CURR_TOKEN(p, TOK_IDENT, MSPH_TREE_IDENT, return (NULL));
if ((id = malloc(sizeof(*id))) == NULL) {
@ -655,6 +675,8 @@ tree_parse_ident(struct tree_parse *p, struct msph_tree *parent)
}
T(id)->type = MSPH_TREE_IDENT;
T(id)->parent = parent;
TXT(id)->pos = CURR_TOKEN(p)->pos;
NOM_DECOR_INIT(&id->dec);
if (SPHO_STRLCPY(id->str, CURR_TOKEN(p)->data.str, sizeof(id->str))
>= sizeof(id->str)) {
@ -675,47 +697,36 @@ tree_parse_tpexpr(struct tree_parse *p, struct msph_tree *parent)
switch (CURR_TOKEN(p)->type) {
case TOK_AMP:
SPHO_DEBUG_PRINT("parsing conj\n");
tp = tree_parse_conj(p, parent);
break;
case TOK_PIPE:
SPHO_DEBUG_PRINT("parsing disj\n");
tp = tree_parse_disj(p, parent);
break;
case TOK_IMPL:
SPHO_DEBUG_PRINT("parsing impl\n");
tp = tree_parse_impl(p, parent);
break;
case TOK_RARROW:
SPHO_DEBUG_PRINT("parsing arrow\n");
tp = tree_parse_arrow(p, parent);
break;
case TOK_KW_BOX:
SPHO_DEBUG_PRINT("parsing box\n");
tp = tree_parse_box(p, parent);
break;
case TOK_KW_FORALL:
SPHO_DEBUG_PRINT("parsing forall\n");
tp = tree_parse_forall(p, parent);
break;
case TOK_IDENT:
SPHO_DEBUG_PRINT("parsing name\n");
tp = tree_parse_name(p, parent);
break;
case TOK_CONST_TRUE:
SPHO_DEBUG_PRINT("parsing true\n");
tp = tree_parse_true(p, parent);
break;
case TOK_CONST_FALSE:
SPHO_DEBUG_PRINT("parsing false\n");
tp = tree_parse_false(p, parent);
break;
case TOK_LPAREN:
SPHO_DEBUG_PRINT("parsing paren\n");
tp = tree_parse_paren(p, parent);
break;
case TOK_LBRACE:
SPHO_DEBUG_PRINT("parsing trait\n");
tp = tree_parse_trait(p, parent);
break;
default:
@ -741,6 +752,8 @@ tree_parse_conj(struct tree_parse *p, struct msph_tree *parent)
}
T(conj)->type = MSPH_TREE_CONJ;
T(conj)->parent = parent;
TXT(conj)->pos = CURR_TOKEN(p)->pos;
TP_DECOR_INIT(&conj->htpe.dec);
conj->ltp = NULL;
conj->rtp = NULL;
@ -775,6 +788,8 @@ tree_parse_disj(struct tree_parse *p, struct msph_tree *parent)
}
T(disj)->type = MSPH_TREE_DISJ;
T(disj)->parent = parent;
TXT(disj)->pos = CURR_TOKEN(p)->pos;
TP_DECOR_INIT(&disj->htpe.dec);
disj->ltp = NULL;
disj->rtp = NULL;
@ -809,6 +824,8 @@ tree_parse_impl(struct tree_parse *p, struct msph_tree *parent)
}
T(impl)->type = MSPH_TREE_IMPL;
T(impl)->parent = parent;
TXT(impl)->pos = CURR_TOKEN(p)->pos;
TP_DECOR_INIT(&impl->htpe.dec);
impl->ltp = NULL;
impl->rtp = NULL;
@ -843,6 +860,8 @@ tree_parse_arrow(struct tree_parse *p, struct msph_tree *parent)
}
T(arrow)->type = MSPH_TREE_ARROW;
T(arrow)->parent = parent;
TXT(arrow)->pos = CURR_TOKEN(p)->pos;
TP_DECOR_INIT(&arrow->htpe.dec);
arrow->ltp = NULL;
arrow->rtp = NULL;
@ -877,6 +896,8 @@ tree_parse_box(struct tree_parse *p, struct msph_tree *parent)
}
T(box)->type = MSPH_TREE_BOX;
T(box)->parent = parent;
TXT(box)->pos = CURR_TOKEN(p)->pos;
TP_DECOR_INIT(&box->htpe.dec);
box->inner = NULL;
EXPECT_READ_NEXT(res, p, MSPH_TREE_BOX, goto err);
@ -903,11 +924,14 @@ tree_parse_forall(struct tree_parse *p, struct msph_tree *parent)
}
T(fa)->type = MSPH_TREE_FORALL;
T(fa)->parent = parent;
fa->ident = NULL;
TXT(fa)->pos = CURR_TOKEN(p)->pos;
TP_DECOR_INIT(&fa->htpe.dec);
SCOPE_DECOR_INIT(&fa->dec);
fa->id = NULL;
fa->inner = NULL;
EXPECT_READ_NEXT(res, p, MSPH_TREE_FORALL, goto err);
if ((fa->ident = tree_parse_ident(p, T(fa))) == NULL)
if ((fa->id = tree_parse_ident(p, T(fa))) == NULL)
goto err;
EXPECT_READ_NEXT(res, p, MSPH_TREE_FORALL, goto err);
@ -964,6 +988,8 @@ tree_parse_name(struct tree_parse *p, struct msph_tree *parent)
T(name)->type = MSPH_TREE_NAME;
T(name)->parent = parent;
TXT(name)->pos = TXT(id)->pos;
TP_DECOR_INIT(&name->htpe.dec);
T(id)->parent = T(name);
name->id = id;
@ -1001,6 +1027,7 @@ tree_parse_applargs(struct tree_parse *p, struct msph_tree_ident *id,
}
T(appl)->type = MSPH_TREE_APPL;
T(appl)->parent = parent;
TP_DECOR_INIT(&appl->htpe.dec);
appl->id = NULL;
STAILQ_INIT(&appl->head);
@ -1035,7 +1062,9 @@ tree_parse_applargs(struct tree_parse *p, struct msph_tree_ident *id,
}
/* finally, appl takes ownership of id */
T(id)->parent = T(appl);
appl->id = id;
TXT(appl)->pos = TXT(id)->pos;
return ((struct msph_tree_tpexpr *)appl);
err:
@ -1057,6 +1086,8 @@ tree_parse_true(struct tree_parse *p, struct msph_tree *parent)
}
T(t)->type = MSPH_TREE_TRUE;
T(t)->parent = parent;
TXT(t)->pos = CURR_TOKEN(p)->pos;
TP_DECOR_INIT(&t->htpe.dec);
return ((struct msph_tree_tpexpr *)t);
}
@ -1074,6 +1105,8 @@ tree_parse_false(struct tree_parse *p, struct msph_tree *parent)
}
T(f)->type = MSPH_TREE_FALSE;
T(f)->parent = parent;
TXT(f)->pos = CURR_TOKEN(p)->pos;
TP_DECOR_INIT(&f->htpe.dec);
return ((struct msph_tree_tpexpr *)f);
}
@ -1092,6 +1125,8 @@ tree_parse_paren(struct tree_parse *p, struct msph_tree *parent)
}
T(par)->type = MSPH_TREE_PAREN;
T(par)->parent = parent;
TXT(par)->pos = CURR_TOKEN(p)->pos;
TP_DECOR_INIT(&par->htpe.dec);
par->inner = NULL;
EXPECT_READ_NEXT(res, p, MSPH_TREE_PAREN, goto err);
@ -1123,6 +1158,9 @@ tree_parse_trait(struct tree_parse *p, struct msph_tree *parent)
}
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);
trait->body = NULL;
if ((trait->body = tree_parse_body(p, T(trait))) == NULL)
@ -1153,9 +1191,10 @@ tree_parse_nomindecl(struct tree_parse *p, struct msph_tree *parent)
}
T(nomd)->type = MSPH_TREE_NOMINDECL;
T(nomd)->parent = parent;
TXT(nomd)->pos = CURR_TOKEN(p)->pos;
nomd->id = NULL;
EXPECT_READ_NEXT(res, p, MSPH_TREE_NOMINDECL, return (NULL));
EXPECT_READ_NEXT(res, p, MSPH_TREE_NOMINDECL, goto err);
if ((nomd->id = tree_parse_ident(p, T(nomd))) == NULL)
goto err;
@ -1174,7 +1213,6 @@ tree_parse_membdecl(struct tree_parse *p, struct msph_tree *parent)
EXPECT_CURR_TOKEN(p, TOK_KW_MEMBER, MSPH_TREE_MEMBDECL,
return (NULL));
EXPECT_READ_NEXT(res, p, MSPH_TREE_MEMBDECL, return (NULL));
if ((membd = malloc(sizeof(*membd))) == NULL) {
MSPH_ERR(CTX(p), MSPH_ERR_SYS);
@ -1182,9 +1220,11 @@ tree_parse_membdecl(struct tree_parse *p, struct msph_tree *parent)
}
T(membd)->type = MSPH_TREE_MEMBDECL;
T(membd)->parent = parent;
TXT(membd)->pos = CURR_TOKEN(p)->pos;
membd->id = NULL;
membd->tp = NULL;
EXPECT_READ_NEXT(res, p, MSPH_TREE_MEMBDECL, goto err);
if ((membd->id = tree_parse_ident(p, T(membd))) == NULL)
goto err;
@ -1211,7 +1251,6 @@ tree_parse_assert(struct tree_parse *p, struct msph_tree *parent)
EXPECT_CURR_TOKEN(p, TOK_KW_ASSERT, MSPH_TREE_ASSERT,
return (NULL));
EXPECT_READ_NEXT(res, p, MSPH_TREE_ASSERT, return (NULL));
if ((ass = malloc(sizeof(*ass))) == NULL) {
MSPH_ERR(CTX(p), MSPH_ERR_SYS);
@ -1219,9 +1258,11 @@ tree_parse_assert(struct tree_parse *p, struct msph_tree *parent)
}
T(ass)->type = MSPH_TREE_ASSERT;
T(ass)->parent = parent;
TXT(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)
goto err;
@ -1243,8 +1284,8 @@ err:
static void
free_the_tree(struct msph_tree *tree)
{
/* no one will free the tree :´( */
/* will anyone ever free the tree? :´( */
SPHO_POSTCOND((void *)tree != (void *)free);
SPHO_POSTCOND(0);
// SPHO_POSTCOND(0);
}

View file

@ -16,10 +16,13 @@ struct spho_err {
struct spho_err spho_errmsgs[] = {
{ SPHO_ERR_SYS, "spho system error" },
{ SPHO_ERR_INTERNAL, "spho internal error" },
{ SPHO_ERR_TOOBIG, "parameter size too big" },
{ SPHO_ERR_ARGINVAL, "invalid argument" },
{ SPHO_ERR_NAMEINUSE, "name in use" },
{ SPHO_ERR_NOM_INUSE, "name already declared in current scope" },
{ SPHO_ERR_NOM_NOTINSCOPE, "name not in scope" },
{ -1, NULL }
};
@ -60,7 +63,6 @@ spho_ctx_destroy(struct spho_ctx *ctx)
const char *
spho_ctx_strerror(struct spho_ctx *ctx)
{
int res;
const char *msg;
SPHO_PRECOND(ctx != NULL);
@ -87,8 +89,8 @@ spho_ctx_sys_strerror(struct spho_ctx *ctx)
#ifdef SPHO_DEBUG
res = snprintf(ctx->errbuf, sizeof(ctx->errbuf),
"%s:%d:spho_syserr:%s (%d)", ctx->filebuf, ctx->errline,
strerror(ctx->err_info), ctx->err_info);
"spho_syserr: %s (%d) (%s:%d)", strerror(ctx->err_info),
ctx->err_info, ctx->filebuf, ctx->errline);
if (res >= sizeof(ctx->errbuf))
ctx->errbuf[sizeof(ctx->errbuf) - 1] = '\0';
#else
@ -110,20 +112,20 @@ spho_ctx_intern_strerror(struct spho_ctx *ctx)
SPHO_PRECOND(ctx != NULL);
for (i = 0; spho_errmsgs[i].msg != NULL; i++) {
for (i = 0; spho_errmsgs[i].err != -1; i++) {
if (spho_errmsgs[i].err == ctx->err) {
#ifdef SPHO_DEBUG
res = snprintf(ctx->errbuf, sizeof(ctx->errbuf),
"%s:%d:spho_intern_err:%s", ctx->filebuf,
ctx->errline, spho_errmsgs[i].msg);
"spho_err: %s (%s:%d)", spho_errmsgs[i].msg,
ctx->filebuf, ctx->errline);
#else
res = snprintf(ctx->errbuf, sizeof(ctx->errbuf),
"spho_intern_err:%s", ctx->errbuf);
"spho_err: %s", ctx->errbuf);
#endif
}
}
SPHO_POSTCOND(res != -1);
SPHO_POSTCOND(! (res == -1 && res >= (int)sizeof(ctx->errbuf)));
return (ctx->errbuf);
}

View file

@ -9,13 +9,18 @@
static void spho_nom_term(struct spho_nom *);
static int spho_scope_nom_get_norec(struct spho_scope *, const char *, size_t ,
struct spho_nom **);
int
spho_scope_init(struct spho_scope *sc, struct spho_ctx *ctx,
struct spho_scope *p)
{
SLIST_INIT(&sc->subs);
SLIST_INIT(&sc->noms);
TAILQ_INIT(&sc->tps);
sc->ctx = ctx;
sc->parent = p;
return (0);
@ -70,7 +75,6 @@ spho_nom_term(struct spho_nom *nom)
void
spho_scope_destroy(struct spho_scope *sc)
{
struct spho_scope *sub;
struct spho_scope *p;
p = sc->parent;
@ -90,12 +94,13 @@ spho_scope_nom_add(struct spho_scope *sc, const char *nomstr, size_t sz)
#endif
struct spho_nom *nom;
nom = NULL;
if (spho_scope_nom_get(sc, nomstr, sz, &nom) == -1)
if (spho_scope_nom_get_norec(sc, nomstr, sz, &nom) == -1)
return (NULL);
if (nom != NULL) {
SPHO_SC_ERR(sc, SPHO_ERR_NAMEINUSE);
SPHO_SC_ERR(sc, SPHO_ERR_NOM_INUSE);
return (NULL);
}
@ -144,7 +149,50 @@ spho_scope_nom_get(struct spho_scope *sc, const char *nomstr, size_t sz,
return (-1);
}
out = NULL;
*out = NULL;
while (*out == NULL && sc != NULL) {
SLIST_FOREACH(nom, &sc->noms, next) {
if (strncmp(nom->s, nomstr, sz) == 0) {
*out = nom;
break;
}
}
sc = sc->parent;
}
return (0);
}
int
spho_scope_nom_lookup(struct spho_scope *sc, const char *nomstr, size_t sz,
struct spho_nom **out)
{
int ret;
if (spho_scope_nom_get(sc, nomstr, sz, out) == -1)
return (-1);
if (*out == NULL) {
SPHO_SC_ERR(sc, SPHO_ERR_NOM_NOTINSCOPE);
return (-1);
}
return (0);
}
static int
spho_scope_nom_get_norec(struct spho_scope *sc, const char *nomstr, size_t sz,
struct spho_nom **out)
{
struct spho_nom *nom;
nom = NULL;
if (sz > sizeof(nom->s)) {
SPHO_ERR(sc->ctx, SPHO_ERR_TOOBIG);
return (-1);
}
*out = NULL;
SLIST_FOREACH(nom, &sc->noms, next) {
if (strncmp(nom->s, nomstr, sz) == 0) {
*out = nom;

View file

@ -7,6 +7,9 @@
#include "spho/tp.h"
const struct tp_konst_data tp_konst_true = { TP_KONST_KEY_TRUE, "True" };
const struct tp_konst_data tp_konst_false = { TP_KONST_KEY_FALSE, "False" };
//struct spho_tp *
//spho_tp_create_disj(struct spho_ctx *, struct spho_tp *, struct spho_tp *,
// struct spho_tp *)
@ -14,177 +17,239 @@
//
//}
struct spho_tp *
spho_tp_alloc(struct spho_scope *sc, int form)
static struct spho_tp *
spho_tp_alloc(struct spho_scope *sc)
{
struct spho_tp *tp;
struct spho_tp_alloc *tp_alloc;
SPHO_PRECOND(SPHO_TP_FORM_IS_VALID(form));
if ((tp = calloc(1, sizeof(struct spho_tp))) == NULL) {
if ((tp_alloc = calloc(1, sizeof(*tp_alloc))) == NULL) {
SPHO_SC_ERR(sc, SPHO_ERR_SYS);
return (NULL);
}
tp->sc = sc;
tp->form = form;
((struct spho_tp *)tp_alloc)->sc = sc;
TAILQ_INSERT_TAIL(&sc->tps, tp_alloc, allocs);
return ((struct spho_tp *)tp_alloc);
}
static void
spho_tp_free(struct spho_tp *tp)
{
struct spho_scope *sc;
struct spho_tp_alloc *tp_alloc;
sc = tp->sc;
tp_alloc = (struct spho_tp_alloc *)tp;
TAILQ_REMOVE(&sc->tps, tp_alloc, allocs);
free(tp_alloc);
}
struct spho_tp *
spho_tp_create_conj(struct spho_scope *sc, struct spho_tp *ltp,
struct spho_tp *rtp)
{
struct spho_tp *tp;
if ((tp = spho_tp_alloc(sc)) == NULL)
return (NULL);
tp->form = SPHO_TP_FORM_CONJ;
tp->d.binop.left = ltp;
tp->d.binop.right = rtp;
return (tp);
}
int
spho_tp_init_disj(struct spho_tp *tp, struct spho_tp *a, struct spho_tp *b)
struct spho_tp *
spho_tp_create_disj(struct spho_scope *sc, struct spho_tp *ltp,
struct spho_tp *rtp)
{
if (tp->form != SPHO_TP_FORM_DISJ) {
SPHO_TP_ERR(tp, SPHO_ERR_ARGINVAL);
return (-1);
}
struct spho_tp *tp;
tp->data.binop.left = a;
tp->data.binop.right = b;
if ((tp = spho_tp_alloc(sc)) == NULL)
return (NULL);
return (0);
tp->form = SPHO_TP_FORM_DISJ;
tp->d.binop.left = ltp;
tp->d.binop.right = rtp;
return (tp);
}
int
spho_tp_init_conj(struct spho_tp *tp, struct spho_tp *a, struct spho_tp *b)
struct spho_tp *
spho_tp_create_impl(struct spho_scope *sc, struct spho_tp *ltp,
struct spho_tp *rtp)
{
if (tp->form != SPHO_TP_FORM_CONJ) {
SPHO_TP_ERR(tp, SPHO_ERR_ARGINVAL);
return (-1);
}
struct spho_tp *tp;
tp->data.binop.left = a;
tp->data.binop.right = b;
if ((tp = spho_tp_alloc(sc)) == NULL)
return (NULL);
return (0);
tp->form = SPHO_TP_FORM_IMPL;
tp->d.binop.left = ltp;
tp->d.binop.right = rtp;
return (tp);
}
int
spho_tp_init_impl(struct spho_tp *tp, struct spho_tp *a, struct spho_tp *b)
struct spho_tp *
spho_tp_create_arrow(struct spho_scope *sc, struct spho_tp *ltp,
struct spho_tp *rtp)
{
if (tp->form != SPHO_TP_FORM_IMPL) {
SPHO_TP_ERR(tp, SPHO_ERR_ARGINVAL);
return (-1);
}
struct spho_tp *tp;
tp->data.binop.left = a;
tp->data.binop.right = b;
if ((tp = spho_tp_alloc(sc)) == NULL)
return (NULL);
return (0);
tp->form = SPHO_TP_FORM_ARROW;
tp->d.binop.left = ltp;
tp->d.binop.right = rtp;
return (tp);
}
int
spho_tp_init_arrow(struct spho_tp *tp, struct spho_tp *a, struct spho_tp *b)
struct spho_tp *
spho_tp_create_box(struct spho_scope *sc, struct spho_tp *inner)
{
if (tp->form != SPHO_TP_FORM_ARROW) {
SPHO_TP_ERR(tp, SPHO_ERR_ARGINVAL);
return (-1);
}
struct spho_tp *tp;
tp->data.binop.left = a;
tp->data.binop.right = b;
if ((tp = spho_tp_alloc(sc)) == NULL)
return (NULL);
return (0);
tp->form = SPHO_TP_FORM_BOX;
tp->d.unop.operand = inner;
return (tp);
}
int
spho_tp_init_box(struct spho_tp *tp, struct spho_tp *inr)
struct spho_tp *
spho_tp_create_forall(struct spho_scope *sc, struct spho_nom *nom,
struct spho_tp *tp)
{
if (tp->form != SPHO_TP_FORM_BOX) {
SPHO_TP_ERR(tp, SPHO_ERR_ARGINVAL);
return (-1);
}
struct spho_tp *ret;
tp->data.box.inr = inr;
if ((ret = spho_tp_alloc(sc)) == NULL)
return (NULL);
return (0);
ret->form = SPHO_TP_FORM_FORALL;
ret->d.bind.nom = nom;
ret->d.bind.bound = tp;
return (ret);
}
int
spho_tp_init_forall(struct spho_tp *tp, struct spho_var *var,
struct spho_tp *inr)
struct spho_tp *
spho_tp_create_true(struct spho_scope *sc)
{
if (tp->form != SPHO_TP_FORM_FORALL) {
SPHO_TP_ERR(tp, SPHO_ERR_ARGINVAL);
return (-1);
}
struct spho_tp *ret;
tp->data.fa.var = var;
tp->data.fa.inr = inr;
if ((ret = spho_tp_alloc(sc)) == NULL)
return (NULL);
return (0);
ret->form = SPHO_TP_FORM_TRUE;
ret->d.konst = tp_konst_true;
return (ret);
}
int
spho_tp_init_bappl(struct spho_tp *tp, struct spho_bind *bind,
struct spho_tp *
spho_tp_create_false(struct spho_scope *sc)
{
struct spho_tp *ret;
if ((ret = spho_tp_alloc(sc)) == NULL)
return (NULL);
ret->form = SPHO_TP_FORM_FALSE;
ret->d.konst = tp_konst_false;
return (ret);
}
struct spho_tp *
spho_tp_create_name(struct spho_scope *sc, struct spho_nom *nom)
{
struct spho_tp *ret;
if ((ret = spho_tp_alloc(sc)) == NULL)
return (NULL);
ret->form = SPHO_TP_FORM_NOM;
ret->d.nom.nom = nom;
return (ret);
}
struct spho_tp *
spho_tp_create_appl(struct spho_scope *sc, struct spho_nom *nom,
struct spho_tp_l *args)
{
struct spho_tp *ret;
if ((ret = spho_tp_alloc(sc)) == NULL)
return (NULL);
ret->form = SPHO_TP_FORM_APPL;
ret->d.appl.nom = nom;
ret->d.appl.args = args;
return (ret);
}
struct spho_tp *
spho_tp_create_member(struct spho_scope *sc, struct spho_nom *nom,
struct spho_tp *tp)
{
struct spho_tp *ret;
if ((ret = spho_tp_alloc(sc)) == NULL)
return (NULL);
ret->form = SPHO_TP_FORM_MEMBER;
ret->d.bind.nom = nom;
ret->d.bind.bound = tp;
return (ret);
}
/* Free type structure. External data (like nom) are freed elsewhere. */
void
spho_tp_destroy(struct spho_tp *tp)
{
struct spho_tp *arg;
if (tp->form != SPHO_TP_FORM_BAPPL) {
SPHO_TP_ERR(tp, SPHO_ERR_ARGINVAL);
return (-1);
switch (tp->form) {
case SPHO_TP_FORM_TRUE:
case SPHO_TP_FORM_FALSE:
case SPHO_TP_FORM_NOM:
break;
case SPHO_TP_FORM_CONJ:
case SPHO_TP_FORM_DISJ:
case SPHO_TP_FORM_IMPL:
case SPHO_TP_FORM_ARROW:
spho_tp_destroy(tp->d.binop.left);
spho_tp_destroy(tp->d.binop.right);
break;
case SPHO_TP_FORM_BOX:
spho_tp_destroy(tp->d.unop.operand);
break;
case SPHO_TP_FORM_FORALL:
case SPHO_TP_FORM_MEMBER:
spho_tp_destroy(tp->d.bind.bound);
break;
case SPHO_TP_FORM_APPL:
STAILQ_FOREACH(arg, tp->d.appl.args, entries) {
spho_tp_destroy(arg);
}
free(tp->d.appl.args);
break;
default:
SPHO_ASSERT(0);
break;
}
tp->data.bappl.bind = bind;
tp->data.bappl.args = args;
return (0);
spho_tp_free(tp);
}
int
spho_tp_init_false(struct spho_tp *tp)
{
if (tp->form != SPHO_TP_FORM_FALSE) {
SPHO_TP_ERR(tp, SPHO_ERR_ARGINVAL);
return (-1);
}
tp->data.konst.k = SPHO_K_FALSE;
return (0);
}
int
spho_tp_init_true(struct spho_tp *tp)
{
if (tp->form != SPHO_TP_FORM_TRUE) {
SPHO_TP_ERR(tp, SPHO_ERR_ARGINVAL);
return (-1);
}
tp->data.konst.k = SPHO_K_TRUE;
return (0);
}
int
spho_tp_init_var(struct spho_tp *tp, struct spho_var *var)
{
if (tp->form != SPHO_TP_FORM_VAR) {
SPHO_TP_ERR(tp, SPHO_ERR_ARGINVAL);
return (-1);
}
tp->data.var.v = var;
return (0);
}
int
spho_tp_init_rec(struct spho_tp *tp, struct spho_rec *rec)
{
if (tp->form != SPHO_TP_FORM_REC) {
SPHO_TP_ERR(tp, SPHO_ERR_ARGINVAL);
return (-1);
}
tp->data.rec.r = rec;
return (0);
}