123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- /*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: Details at https://graphviz.org
- *************************************************************************/
- #pragma once
- #ifdef __cplusplus
- extern "C" {
- #endif
- /*
- * Glenn Fowler
- * AT&T Research
- *
- * expression library definitions
- */
- #include <ast/ast.h>
- #include <inttypes.h>
- #include <expr/exparse.h>
- #include <assert.h>
- #include <cdt.h>
- #include <stdarg.h>
- #include <stdbool.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <util/agxbuf.h>
- #include <vmalloc/vmalloc.h>
- #define EX_VERSION 20000101L
- /*
- * flags
- */
- #define EX_CHARSTRING (1<<0) /* '...' same as "..." */
- #define EX_UNDECLARED (1<<9) /* allow undeclared identifiers */
- #define EX_ARRAY (-3) /* getval() array elt */
- #define EX_CALL (-2) /* getval() function call elt */
- #define EX_SCALAR (-1) /* getval() scalar elt */
- #define EX_NAMELEN 32 /* default Exid_t.name length */
- #define EX_ID(n, l, i, t) {{0}, (l), (i), (t), 0, 0, 0, 0, n}
- #define DELETE_T MINTOKEN /* exexpr() delete `type' */
- #define INTEGRAL(t) ((t)>=INTEGER&&(t)<=CHARACTER)
- #define BUILTIN(t) ((t) > MINTOKEN)
- /* function type mechanism
- * types are encoded in TBITS
- * Thus, maximum # of parameters, including return type,
- * is sizeof(Exid_t.type)/TBITS. Also see T in exgram.h
- */
- /*
- * arg 0 is the return value type
- */
- #define F 01 /* FLOATING */
- #define I 02 /* INTEGER */
- #define S 03 /* STRING */
- #define TBITS 4
- #define TMASK ((1<<TBITS)-1)
- #define A(n,t) ((t)<<((n)*TBITS)) /* function arg n is type t */
- #define N(t) ((t)>>=TBITS) /* shift for next arg */
- #define exalloc(p,n) vmalloc((p)->vm, (n))
- typedef EX_STYPE Extype_t;
- typedef union Exdata_u Exdata_t;
- typedef struct Exdisc_s Exdisc_t;
- typedef struct Exnode_s Exnode_t;
- typedef struct Expr_s Expr_t;
- typedef struct Exref_s Exref_t;
- typedef void (*Exerror_f) (Expr_t *, Exdisc_t *, int, const char *, ...);
- typedef void (*Exexit_f)(void *, int);
- typedef struct Exid_s /* id symbol table info */
- {
- Dtlink_t link; /* symbol table link */
- long lex; /* lex class */
- long index; /* user defined index */
- long type; /* symbol and arg types */
- long index_type; /* index type for arrays */
- long flags; /* user defined flags */
- Exnode_t* value; /* value */
- void *local; ///< user defined local stuff
- char name[EX_NAMELEN];/* symbol name */
- } Exid_t;
- struct Exref_s /* . reference list */
- {
- Exref_t* next; /* next in list */
- Exid_t* symbol; /* reference id symbol */
- Exnode_t* index; /* optional reference index */
- };
- union Exdata_u
- {
- struct
- {
- Extype_t value; /* constant value */
- Exid_t* reference; /* conversion reference symbol */
- } constant; /* variable reference */
- struct
- {
- Exnode_t* left; /* left operand */
- Exnode_t* right; /* right operand */
- Exnode_t* last; /* for cons */
- } operand; /* operands */
- struct
- {
- Exnode_t* statement; /* case label statement(s) */
- Exnode_t* next; /* next case item */
- Extype_t** constant; /* case label constant array */
- } select; /* case item */
- struct
- {
- Exid_t* symbol; /* id symbol table entry */
- Exref_t* reference; /* . reference list */
- Exnode_t* index; /* array index expression */
- Exnode_t* dyna; /* dynamic expression */
- } variable; /* variable reference */
- #ifdef _EX_DATA_PRIVATE_
- _EX_DATA_PRIVATE_
- #endif
- };
- struct Exnode_s /* expression tree node */
- {
- long type; ///< value type
- long op; ///< operator
- bool binary; ///< data.operand.{left,right} ok
- union
- {
- double (*floating)(char**); /* FLOATING return value */
- long long (*integer)(char **); ///< INTEGER|UNSIGNED return value
- char* (*string)(char**); /* STRING return value */
- } compiled; /* compiled function pointer */
- Exdata_t data; /* node data */
- #ifdef _EX_NODE_PRIVATE_
- _EX_NODE_PRIVATE_
- #endif
- };
- struct Exdisc_s /* discipline */
- {
- uint64_t version; /* EX_VERSION */
- uint64_t flags; /* EX_* flags */
- Exid_t* symbols; /* static symbols */
- char** data; /* compiled function arg data */
- int (*castf)(Expr_t*, Exnode_t*, const char*, int, Exid_t*, int, Exdisc_t*);
- /* unknown cast function */
- int (*convertf)(Exnode_t *, long, int);
- /* type conversion function */
- int (*binaryf) (Exnode_t *, Exnode_t *, Exnode_t *, int);
- /* binary operator function */
- char *(*typename)(long);
- /* application type names */
- int (*stringof) (Expr_t *, Exnode_t *, int);
- /* value to string conversion */
- Extype_t (*keyf)(Extype_t, long);
- /* dictionary key for external type objects */
- Exerror_f errorf; /* error function */
- Extype_t (*getf)(Expr_t*, Exnode_t*, Exid_t*, Exref_t*, void*, int, Exdisc_t*);
- /* get value function */
- Extype_t (*reff)(Expr_t*, Exnode_t*, Exid_t*, Exref_t*);
- /* reference value function */
- int (*setf)(Expr_t*, Exnode_t*, Exid_t*, Exref_t*, void*, Extype_t);
- /* set value function */
- /* exit function */
- Exexit_f exitf;
- int* types;
- void* user;
- };
- struct Expr_s /* ex program state */
- {
- const char* id; /* library id */
- Dt_t* symbols; /* symbol table */
- FILE* file[10]; /* io streams */
- Vmalloc_t* vm; /* program store */
- #ifdef _EX_PROG_PRIVATE_
- _EX_PROG_PRIVATE_
- #endif
- };
- extern Exnode_t *excast(Expr_t *, Exnode_t *, long, Exnode_t *, int);
- extern Exnode_t* exnoncast(Exnode_t *);
- extern void exclose(Expr_t*, int);
- /** Compile an expression
- *
- * The callee takes ownership of the pointer \p prefix and will free it during
- * \p expop or \p exclose.
- *
- * \param p Program structure to store result in
- * \param name Filename of originating source file
- * \param line Line number of originating source file
- * \param fp Handle to source file
- * \param prefix Optional program text to include ahead of the file content
- * \return 0 on success
- */
- extern int excomp(Expr_t *p, const char *name, int line, FILE *fp,
- char *prefix);
- extern char* excontext(Expr_t*, char*, int);
- extern int exdump(Expr_t*, Exnode_t*, agxbuf*);
- #ifdef __GNUC__
- __attribute__((format(printf, 1, 2)))
- #endif
- extern void exerror(const char*, ...);
- #ifdef __GNUC__
- __attribute__((format(printf, 1, 2)))
- #endif
- extern void exwarn(const char *, ...);
- extern Extype_t exeval(Expr_t*, Exnode_t*, void*);
- extern Exnode_t* exexpr(Expr_t*, const char*, Exid_t*, int);
- extern void exfreenode(Expr_t*, Exnode_t*);
- extern Exnode_t *exnewnode(Expr_t *, long, bool, long, Exnode_t *, Exnode_t *);
- extern char* exnospace(void);
- extern Expr_t* exopen(Exdisc_t*);
- extern int expop(Expr_t*);
- extern int expush(Expr_t*, const char*, int, FILE*);
- extern int extoken_fn(Expr_t*);
- extern char* exstring(Expr_t *, char *);
- extern void* exstralloc(Expr_t *, size_t);
- extern char* extype(long int);
- extern Extype_t exzero(long int);
- extern char *exopname(long);
- extern void exinit(void);
- extern char *extypename(Expr_t *p, long);
- extern int exisAssign(Exnode_t *);
- /** Construct a vmalloc-backed string.
- *
- * \param vm Allocator to use.
- * \param fmt printf-style format sting.
- * \param ... printf-style varargs.
- * \return Dynamically allocated string.
- */
- #ifdef __GNUC__
- __attribute__((format(printf, 2, 3)))
- #endif
- static inline char *exprintf(Vmalloc_t *vm, const char *fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- // how many bytes do we need for this string?
- va_list ap2;
- va_copy(ap2, ap);
- int len = vsnprintf(NULL, 0, fmt, ap2);
- assert(len >= 0 && "invalid vsnprintf call");
- ++len; // for NUL terminator
- va_end(ap2);
- // ask vmalloc for enough space for this
- char *s = vmalloc(vm, (size_t)len);
- if (s == NULL) {
- va_end(ap);
- return exnospace();
- }
- // construct the output string
- (void)vsnprintf(s, (size_t)len, fmt, ap);
- va_end(ap);
- return s;
- }
- #ifdef __cplusplus
- }
- #endif
|