123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- #ifndef _TURMIT_H_
- #define _TURMIT_H_
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <errno.h>
- #include <ctype.h>
-
- /**@Todo For the moment there is no way to track wether a variable is used
- * or not in result processing */
-
- typedef unsigned long long int turmit_int;
- typedef struct turmit_op_s turmit_op_t;
- typedef struct turmit_s turmit_t;
- typedef struct turmit_sym_s turmit_sym_t;
- typedef void (*turmit_op_f)(turmit_t*);
-
- #define SCUR(t) (t->stack[t->stack_cur])
- #define SDEC(t) (t->stack_cur = (t->stack_cur>0?t->stack_cur:t->stack_sz) -1)
- #define SINC(t) (t->stack_cur = (t->stack_cur + 1) % t->stack_sz)
- #define SPOP(t) (__SPOP(t))
- #define SPUSH(t, v) (t->stack[SINC(t)] = v % t->int_max)
-
- #define TURMIT_JMP(t, v) (((t->op_expr_sz - t->op_cur) <= v)?\
- (t->op_end=1):\
- (t->op_cur += (v>0?v-1:0) ))
-
- #define TURMIT_STACK_GROW 0xFF
- #define TURMIT_STACK_MAX 0xFFF
- #define TURMIT_EXPR_MAX_SZ 0xFFFFFFFF
-
- #define TURMIT_LAZY 0
- #define TURMIT_AUTOCOMP 1
- #define TURMIT_UNSIGNED 0
- #define TURMIT_SIGNED 2
-
- #define TURMIT_OK 0
- #define TURMIT_ERROR -1
-
- #define TURMIT_SYM_OP 1
- #define TURMIT_SYM_VAL 2
- #define TURMIT_SYM_VAR 3
-
- #define TURMIT_VAR_L "xyrgb"
-
- #define TURMIT_OPSYM(NAME) {#NAME, NULL, turmit_op_##NAME}
- #define TURMIT_OPSYMALIAS(NAME, alias) {#NAME, alias, turmit_op_##NAME}
-
- // OPSYMALIAS has to be first !
- #define TURMIT_OP_LST {\
- TURMIT_OPSYMALIAS(add, "+"),\
- TURMIT_OPSYMALIAS(sub, "-"),\
- TURMIT_OPSYMALIAS(mul, "*"),\
- TURMIT_OPSYMALIAS(div, "/"),\
- TURMIT_OPSYMALIAS(mod, "%"),\
- TURMIT_OPSYMALIAS(bin_or, "|"),\
- TURMIT_OPSYMALIAS(bin_and, "&"),\
- TURMIT_OPSYMALIAS(bin_xor, "^"),\
- TURMIT_OPSYMALIAS(lshift, "<<"),\
- TURMIT_OPSYM(mem_sz),\
- TURMIT_OPSYM(dup),\
- TURMIT_OPSYM(pop),\
- TURMIT_OPSYM(swp),\
- TURMIT_OPSYM(jmp),\
- TURMIT_OPSYM(jz),\
- TURMIT_OPSYM(jcmp),\
- NULL,\
- }
-
- struct turmit_sym_s
- {
- char *str;
- char *alias;
- turmit_op_f op_fun;
- };
-
- union turmit_op_u
- {
- turmit_op_f op;
- turmit_int val;
- short var; /*!< interpreted % 5 */
- };
-
- struct turmit_op_s
- {
- union turmit_op_u op;
- /** 0 for NULL, 1 if operation pointer, 2 if value, 3 if variable */
- short value;
- };
-
- struct turmit_s
- {
- char *expr;
- unsigned char flags;
- ssize_t int_max;
-
- turmit_op_t *op_expr;
- ssize_t op_expr_sz;
- ssize_t op_cur;
- short op_end;
-
- ssize_t stack_sz;
- turmit_int *stack;
- ssize_t stack_cur;
-
- /**@brief 0 if no error
- * @note only for compilation error for the moment
- */
- char err;
- char *err_str;
- };
-
- inline static turmit_int __SPOP(turmit_t *t) {
- turmit_int r = t->stack[t->stack_cur];
- SDEC(t);
- return r;
- }
-
-
- #define TURMIT_OP(NAME) void turmit_op_##NAME (turmit_t *turmit)
-
- /**@brief Allocate memory and initialise a turmit
- * @param const char* The turmit expression
- * @param unsigned char One of TURMIT_LAZY or TURMIT_AUTOCOMP.
- * @return A pointer on the new turmit
- */
- turmit_t *turmit_alloc(ssize_t stack_sz, ssize_t int_max, const char *expr,
- unsigned char flags);
-
- /**@brief Initialize a turmit
- * @param turmit_t* The turmit to initialize
- * @param const char* The turmit expression
- * @param unsigned char One of TURMIT_LAZY or TURMIT_AUTOCOMP.
- * @return The pointer on the turmit
- */
- turmit_t *turmit_init(turmit_t *turmit, ssize_t stack_sz, ssize_t int_max,
- const char *expr, unsigned char flags);
-
- turmit_t *turmit_copy(turmit_t *turmit);
-
- void turmit_clean(turmit_t *turmit);
-
- /**@brief Free memory of a turmit
- * @param turmit the turmit to free
- */
- void turmit_free(turmit_t *turmit);
-
- /**@brief Exec a turmit expr
- * @param turmit_t* Concerned turmit
- * @param turmit_int* Arguments ( see @ref TURMIT_VAL_L )
- * @return Processed value
- */
- turmit_int turmit_exec(turmit_t *turmit, const turmit_int args[5]);
-
- /**@brief Populate turmit_t.op_expr and set op_expr_sz
- * @return 0 if no errors
- */
- int turmit_compile(turmit_t *turmit);
-
- void _turmit_stack_dump(turmit_t *turmit);
-
- TURMIT_OP(mem_sz);
-
- TURMIT_OP(add);
-
- TURMIT_OP(sub);
-
- TURMIT_OP(bin_and);
-
- TURMIT_OP(dup);
-
- TURMIT_OP(lshift);
-
- TURMIT_OP(mod);
-
- TURMIT_OP(mul);
-
- TURMIT_OP(div);
-
- TURMIT_OP(bin_or);
-
- TURMIT_OP(bin_xor);
-
- TURMIT_OP(pop);
-
- TURMIT_OP(swp);
-
- TURMIT_OP(jmp);
-
- TURMIT_OP(jz);
-
- TURMIT_OP(jcmp);
-
- #endif
|