3 * only can be included by userspace compiler
12 #define MAX_INT ((int)(~0U>>1))
15 #define MAX_SIZET ((size_t)(~(size_t)0)-2)
17 #define KTAP_ERRSYNTAX 3
20 * KTAP_IDSIZE gives the maximum size for the description of the source
21 * of a function in debug information.
22 * CHANGE it if you want a different size.
24 #define KTAP_IDSIZE 60
27 #define FIRST_RESERVED 257
30 * maximum depth for nested C calls and syntactical nested non-terminals
31 * in a program. (Value must fit in an unsigned short int.)
33 #define KTAP_MAXCCALLS 200
35 #define KTAP_MULTRET (-1)
38 #define SHRT_MAX UCHAR_MAX
40 #define MAXUPVAL UCHAR_MAX
43 /* maximum stack for a ktap function */
46 #define islalpha(c) (isalpha(c) || (c) == '_')
47 #define islalnum(c) (isalnum(c) || (c) == '_')
49 #define isreserved(s) ((s)->tsv.tt == KTAP_TSHRSTR && (s)->tsv.extra > 0)
51 #define ktap_numeq(a,b) ((a)==(b))
52 #define ktap_numisnan(L,a) (!ktap_numeq((a), (a)))
54 #define ktap_numunm(a) (-(a))
57 * ** Comparison and arithmetic functions
60 #define KTAP_OPADD 0 /* ORDER TM */
74 * WARNING: if you change the order of this enumeration,
75 * grep "ORDER RESERVED"
78 /* terminal symbols denoted by reserved words */
79 TK_TRACE = FIRST_RESERVED, TK_TRACE_END,
80 TK_ARGEVENT, TK_ARGNAME,
81 TK_ARG1, TK_ARG2, TK_ARG3, TK_ARG4, TK_ARG5, TK_ARG6, TK_ARG7, TK_ARG8,
82 TK_ARG9, TK_PROFILE, TK_TICK,
84 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
85 TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
86 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
87 /* other terminal symbols */
88 TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_INCR, TK_DBCOLON,
89 TK_EOS, TK_NUMBER, TK_NAME, TK_STRING
92 /* number of reserved words */
93 #define NUM_RESERVED ((int)(TK_WHILE-FIRST_RESERVED + 1))
95 #define EOZ (0) /* end of stream */
100 } ktap_seminfo; /* semantics information */
103 typedef struct ktap_token {
105 ktap_seminfo seminfo;
108 typedef struct ktap_mbuffer {
114 #define mbuff_init(buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
115 #define mbuff(buff) ((buff)->buffer)
116 #define mbuff_reset(buff) ((buff)->n = 0, memset((buff)->buffer, 0, (buff)->buffsize))
117 #define mbuff_len(buff) ((buff)->n)
118 #define mbuff_size(buff) ((buff)->buffsize)
120 #define mbuff_resize(buff, size) \
121 (ktapc_realloc((buff)->buffer, (buff)->buffsize, size, char), \
122 (buff)->buffsize = size)
124 #define mbuff_free(buff) mbuff_resize(buff, 0)
128 * state of the lexer plus state of the parser when shared by all
131 typedef struct ktap_lexstate {
132 char *ptr; /* source file reading position */
133 int current; /* current character (charint) */
134 int linenumber; /* input line counter */
135 int lastline; /* line of last token `consumed' */
136 ktap_token t; /* current token */
137 ktap_token lookahead; /* look ahead token */
138 struct ktap_funcstate *fs; /* current function (parser) */
139 ktap_mbuffer *buff; /* buffer for tokens */
140 struct ktap_dyndata *dyd; /* dynamic structures used by the parser */
141 ktap_string *source; /* current source name */
142 ktap_string *envn; /* environment variable name */
143 char decpoint; /* locale decimal point */
149 * Expression descriptor
152 VVOID, /* no value */
156 VK, /* info = index of constant in `k' */
157 VKNUM, /* nval = numerical value */
158 VNONRELOC, /* info = result register */
159 VLOCAL, /* info = local register */
160 VUPVAL, /* info = index of upvalue in 'upvalues' */
161 VINDEXED, /* t = table register/upvalue; idx = index R/K */
162 VJMP, /* info = instruction pc */
163 VRELOCABLE, /* info = instruction pc */
164 VCALL, /* info = instruction pc */
165 VVARARG, /* info = instruction pc */
172 #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED)
173 #define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL)
175 typedef struct ktap_expdesc {
178 struct { /* for indexed variables (VINDEXED) */
179 short idx; /* index (R/K) */
180 u8 t; /* table (register or upvalue) */
181 u8 vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
183 int info; /* for generic use */
184 ktap_number nval; /* for VKNUM */
186 int t; /* patch list of `exit when true' */
187 int f; /* patch list of `exit when false' */
191 typedef struct ktap_vardesc {
192 short idx; /* variable index in stack */
196 /* description of pending goto statements and label statements */
197 typedef struct ktap_labeldesc {
198 ktap_string *name; /* label identifier */
199 int pc; /* position in code */
200 int line; /* line where it appeared */
201 u8 nactvar; /* local level where it appears in current block */
205 /* list of labels or gotos */
206 typedef struct ktap_labellist {
207 ktap_labeldesc *arr; /* array */
208 int n; /* number of entries in use */
209 int size; /* array size */
213 /* dynamic structures used by the parser */
214 typedef struct ktap_dyndata {
215 struct { /* list of active local variables */
220 ktap_labellist gt; /* list of pending gotos */
221 ktap_labellist label; /* list of active labels */
225 /* control of blocks */
226 struct ktap_blockcnt; /* defined in lparser.c */
229 /* state needed to generate code for a given function */
230 typedef struct ktap_funcstate {
231 ktap_proto *f; /* current function header */
232 ktap_table *h; /* table to find (and reuse) elements in `k' */
233 struct ktap_funcstate *prev; /* enclosing function */
234 struct ktap_lexstate *ls; /* lexical state */
235 struct ktap_blockcnt *bl; /* chain of current blocks */
236 int pc; /* next position to code (equivalent to `ncode') */
237 int lasttarget; /* 'label' of last 'jump label' */
238 int jpc; /* list of pending jumps to `pc' */
239 int nk; /* number of elements in `k' */
240 int np; /* number of elements in `p' */
241 int firstlocal; /* index of first local var (in ktap_dyndata array) */
242 short nlocvars; /* number of elements in 'f->locvars' */
243 u8 nactvar; /* number of active local variables */
244 u8 nups; /* number of upvalues */
245 u8 freereg; /* first free register */
250 * Marks the end of a patch list. It is an invalid value both as an absolute
251 * address, and as a list link (would link an element to itself).
257 * grep "ORDER OPR" if you change these enums (ORDER OP)
259 typedef enum BinOpr {
260 OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
262 OPR_EQ, OPR_LT, OPR_LE,
263 OPR_NE, OPR_GT, OPR_GE,
269 typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
272 #define getcode(fs,e) ((fs)->f->code[(e)->u.info])
274 #define codegen_codeAsBx(fs,o,A,sBx) codegen_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
276 #define codegen_setmultret(fs,e) codegen_setreturns(fs, e, KTAP_MULTRET)
278 #define codegen_jumpto(fs,t) codegen_patchlist(fs, codegen_jump(fs), t)
281 #define ktapc_realloc(v, osize, nsize, t) \
282 ((v) = (t *)ktapc_reallocv(v, osize * sizeof(t), nsize * sizeof(t)))
284 #define ktapc_reallocvector(v,oldn,n,t) ktapc_realloc(v,oldn,n,t)
287 #define ktapc_growvector(v,nelems,size,t,limit,e) \
288 if ((nelems)+1 > (size)) \
289 ((v)=(t *)ktapc_growaux(v,&(size),sizeof(t),limit,e))
293 ktap_string *lex_newstring(ktap_lexstate *ls, const char *str, size_t l);
294 const char *lex_token2str(ktap_lexstate *ls, int token);
295 void lex_syntaxerror(ktap_lexstate *ls, const char *msg);
296 void lex_setinput(ktap_lexstate *ls, char *ptr, ktap_string *source, int firstchar);
297 void lex_next(ktap_lexstate *ls);
298 int lex_lookahead(ktap_lexstate *ls);
299 void lex_read_string_until(ktap_lexstate *ls, int c);
300 ktap_closure *ktapc_parser(char *pos, const char *name);
301 ktap_string *ktapc_ts_new(const char *str);
302 int ktapc_ts_eqstr(ktap_string *a, ktap_string *b);
303 ktap_string *ktapc_ts_newlstr(const char *str, size_t l);
304 ktap_proto *ktapc_newproto();
305 ktap_table *ktapc_table_new();
306 const ktap_value *ktapc_table_get(ktap_table *t, const ktap_value *key);
307 void ktapc_table_setvalue(ktap_table *t, const ktap_value *key, ktap_value *val);
308 ktap_closure *ktapc_newlclosure(int n);
309 char *ktapc_sprintf(const char *fmt, ...);
311 void *ktapc_reallocv(void *block, size_t osize, size_t nsize);
312 void *ktapc_growaux(void *block, int *size, size_t size_elems, int limit,
315 void ktapio_exit(void);
316 int ktapio_create(const char *output_filename);
318 ktap_string *ktapc_parse_eventdef(ktap_string *eventdef);
319 void cleanup_event_resources(void);
322 #define verbose_printf(...) \
324 printf("[verbose] " __VA_ARGS__);
326 #define ktapc_equalobj(t1, t2) kp_equalobjv(NULL, t1, t2)
329 #include "../include/ktap_opcodes.h"
331 int codegen_stringK(ktap_funcstate *fs, ktap_string *s);
332 void codegen_indexed(ktap_funcstate *fs, ktap_expdesc *t, ktap_expdesc *k);
333 void codegen_setreturns(ktap_funcstate *fs, ktap_expdesc *e, int nresults);
334 void codegen_reserveregs(ktap_funcstate *fs, int n);
335 void codegen_exp2nextreg(ktap_funcstate *fs, ktap_expdesc *e);
336 void codegen_nil(ktap_funcstate *fs, int from, int n);
337 void codegen_patchlist(ktap_funcstate *fs, int list, int target);
338 void codegen_patchclose(ktap_funcstate *fs, int list, int level);
339 int codegen_jump(ktap_funcstate *fs);
340 void codegen_patchtohere(ktap_funcstate *fs, int list);
341 int codegen_codeABx(ktap_funcstate *fs, OpCode o, int a, unsigned int bc);
342 void codegen_ret(ktap_funcstate *fs, int first, int nret);
343 void codegen_exp2anyregup(ktap_funcstate *fs, ktap_expdesc *e);
344 void codegen_exp2val(ktap_funcstate *fs, ktap_expdesc *e);
345 int codegen_exp2RK(ktap_funcstate *fs, ktap_expdesc *e);
346 int codegen_codeABC(ktap_funcstate *fs, OpCode o, int a, int b, int c);
347 void codegen_setlist(ktap_funcstate *fs, int base, int nelems, int tostore);
348 void codegen_fixline (ktap_funcstate *fs, int line);
349 void codegen_dischargevars(ktap_funcstate *fs, ktap_expdesc *e);
350 void codegen_self(ktap_funcstate *fs, ktap_expdesc *e, ktap_expdesc *key);
351 void codegen_prefix(ktap_funcstate *fs, UnOpr op, ktap_expdesc *e, int line);
352 void codegen_infix(ktap_funcstate *fs, BinOpr op, ktap_expdesc *v);
353 void codegen_posfix(ktap_funcstate *fs, BinOpr op, ktap_expdesc *e1, ktap_expdesc *e2, int line);
354 void codegen_setoneret(ktap_funcstate *fs, ktap_expdesc *e);
355 void codegen_storevar(ktap_funcstate *fs, ktap_expdesc *var, ktap_expdesc *ex);
356 void codegen_storeincr(ktap_funcstate *fs, ktap_expdesc *var, ktap_expdesc *ex);
357 void codegen_goiftrue(ktap_funcstate *fs, ktap_expdesc *e);
358 int codegen_getlabel(ktap_funcstate *fs);
359 int codegen_codek(ktap_funcstate *fs, int reg, int k);
360 int codegen_numberK(ktap_funcstate *fs, ktap_number r);
361 void codegen_checkstack(ktap_funcstate *fs, int n);
362 void codegen_goiffalse(ktap_funcstate *fs, ktap_expdesc *e);
363 void codegen_concat(ktap_funcstate *fs, int *l1, int l2);
364 int codegen_exp2anyreg(ktap_funcstate *fs, ktap_expdesc *e);
366 typedef int (*ktap_writer)(const void* p, size_t sz, void* ud);
367 int ktapc_dump(const ktap_proto *f, ktap_writer w, void *data, int strip);
369 void ktapc_chunkid(char *out, const char *source, size_t bufflen);
370 int ktapc_str2d(const char *s, size_t len, ktap_number *result);
371 int ktapc_hexavalue(int c);
372 ktap_number ktapc_arith(int op, ktap_number v1, ktap_number v2);
373 int ktapc_int2fb(unsigned int x);
375 bool strglobmatch(const char *str, const char *pat);