1 /* Copyright (C) 2000-2015 Lavtech.com corp. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2 of the License, or
6    (at your option) any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16 */
17 
18 #ifndef _UDM_PROG_H
19 #define _UDM_PROG_H
20 
21 #include "udm_lex.h"
22 
23 #define UDM_PROG_MAXARG 5
24 
25 typedef enum udm_tmpl_cmd
26 {
27   UDM_PROG_NOP= 0,
28   UDM_PROG_JE,
29   UDM_PROG_JNE,
30   UDM_PROG_JMP,
31   /* Unary integer operators */
32   UDM_PROG_NOT_IREG0,
33   UDM_PROG_INC_IREG0,
34   UDM_PROG_DEC_IREG0,
35   UDM_PROG_INC_DREG0,
36   UDM_PROG_DEC_DREG0,
37   UDM_PROG_INC_CHR_PTR_STACK_OFFSET,
38   UDM_PROG_DEC_CHR_PTR_STACK_OFFSET,
39   UDM_PROG_INC_INT_PTR_STACK_OFFSET,
40   UDM_PROG_DEC_INT_PTR_STACK_OFFSET,
41   UDM_PROG_INC_DBL_PTR_STACK_OFFSET,
42   UDM_PROG_DEC_DBL_PTR_STACK_OFFSET,
43   /* Dynadic integer arithmetic and bit operators */
44   UDM_PROG_MUL_IREG0_IREG1,
45   UDM_PROG_ADD_IREG0_IREG1,
46   UDM_PROG_SUB_IREG0_IREG1,
47   UDM_PROG_AND_IREG0_IREG1,
48   UDM_PROG_OR_IREG0_IREG1,
49   UDM_PROG_XOR_IREG0_IREG1,
50   UDM_PROG_SHL_IREG0_IREG1,
51   UDM_PROG_SHR_IREG0_IREG1,
52   UDM_PROG_DIV_IREG0_IREG1,
53   UDM_PROG_REM_IREG0_IREG1,
54   /* Int comparison operators */
55   UDM_PROG_CMP_IREG0_IREG1_EQ,
56   UDM_PROG_CMP_IREG0_IREG1_LT,
57   UDM_PROG_CMP_IREG0_IREG1_GT,
58   UDM_PROG_CMP_IREG0_IREG1_LE,
59   UDM_PROG_CMP_IREG0_IREG1_GE,
60   UDM_PROG_CMP_IREG0_IREG1_NE,
61 
62 
63   /* Unary double operators */
64   UDM_PROG_MOV_IREG0_0,
65   UDM_PROG_MOV_DREG0_0,
66   UDM_PROG_MOV_IREG1_0,
67   UDM_PROG_MOV_DREG1_0,
68   UDM_PROG_MOV_HREG0_0,
69   UDM_PROG_MOV_SREG0_0,
70   UDM_PROG_MOV_IREG0_INT_PTR_STACK_OFFSET,
71   UDM_PROG_MOV_DREG0_DBL_PTR_STACK_OFFSET,
72   UDM_PROG_MOV_IREG1_INT_PTR_STACK_OFFSET,
73   UDM_PROG_MOV_DREG1_DBL_PTR_STACK_OFFSET,
74   UDM_PROG_MOV_SREG0_STACK_OFFSET,
75   UDM_PROG_MOV_VREG0_STACK_OFFSET,
76   UDM_PROG_MOV_VREG1_STACK_OFFSET,
77   UDM_PROG_MOV_VREG2_STACK_OFFSET,
78   UDM_PROG_MOV_VREG3_STACK_OFFSET,
79   UDM_PROG_MOV_VREG4_STACK_OFFSET,
80 
81   /* Copy operators with constants */
82   UDM_PROG_MOV_IREG0_INT,
83   UDM_PROG_MOV_IREG1_INT,
84   UDM_PROG_MOV_DREG0_DBL,
85   UDM_PROG_MOV_DREG1_DBL,
86   UDM_PROG_MOV_HREG0_PTR,
87 
88   /* Double arithmetic operators */
89   UDM_PROG_MUL_DREG0_DREG1,
90   UDM_PROG_ADD_DREG0_DREG1,
91   UDM_PROG_SUB_DREG0_DREG1,
92   UDM_PROG_DIV_DREG0_DREG1,
93 
94   /* Double comparison operators */
95   UDM_PROG_CMP_DREG0_DREG1_EQ,
96   UDM_PROG_CMP_DREG0_DREG1_LT,
97   UDM_PROG_CMP_DREG0_DREG1_GT,
98   UDM_PROG_CMP_DREG0_DREG1_LE,
99   UDM_PROG_CMP_DREG0_DREG1_GE,
100   UDM_PROG_CMP_DREG0_DREG1_NE,
101 
102   /* Dyadic copy operators */
103   UDM_PROG_MOV_DREG1_DREG0,
104   UDM_PROG_MOV_IREG1_IREG0,
105   UDM_PROG_MOV_INT_PTR_S0_IREG0,
106   UDM_PROG_MOV_DBL_PTR_S0_DREG0,
107   UDM_PROG_MOV_CHR_PTR_S0_IREG0,
108 
109   /* Dyaric copy with conversion */
110   UDM_PROG_MOV_DREG0_IREG0,
111   UDM_PROG_MOV_DREG1_IREG0,
112   UDM_PROG_MOV_IREG0_DREG0,
113   UDM_PROG_MOV_IREG1_DREG1,
114   UDM_PROG_MOV_DREG1_IREG1,
115 
116   /* Exchange operators */
117   UDM_PROG_SWP_DREG0_DREG1,
118   UDM_PROG_SWP_IREG0_IREG1,
119 
120 
121   /* Built-in function and command calls */
122   UDM_PROG_CALL,
123   UDM_PROG_HANDLED,
124   UDM_PROG_EXIT
125 } udm_tmpl_cmd_t;
126 
127 
128 typedef struct udm_tmpl_names_st
129 {
130   const UDM_CONST_STR name;
131   size_t nargs;
132   udm_func_runtime_t exec;
133 } UDM_PROG_CMD;
134 
135 
136 typedef struct
137 {
138   size_t offset;
139   size_t length;
140 } udm_offset_and_length_t;
141 
142 
143 typedef struct
144 {
145   const UDM_VALUE_HANDLER *handler;
146   size_t stack_offset;
147 } UDM_PROG_VAR_VALUE;
148 
149 
150 typedef struct
151 {
152   UDM_CONST_TOKEN name;
153   UDM_PROG_VAR_VALUE value;
154 } UDM_PROG_VAR;
155 
156 
157 typedef struct
158 {
159   char *name;
160   UDM_PROG_VAR_VALUE value;
161 } UDM_PROG_VAR2;
162 
163 
164 typedef struct
165 {
166   size_t nitems;
167   size_t mitems;
168   UDM_PROG_VAR2 *Item;
169   size_t next_stack_offset;
170 } UDM_PROG_VARLIST;
171 
172 
173 typedef struct
174 {
175   size_t nitems;
176   size_t mitems;
177   UDM_PROG_VARLIST *Item;
178 } UDM_PROG_VARLISTLIST;
179 
180 
181 void UdmProgVarListInit(UDM_PROG_VARLIST *List);
182 void UdmProgVarListFree(UDM_PROG_VARLIST *List);
183 udm_rc_t UdmProgVarListAdd(UDM_PROG_VARLIST *List,
184                            const char *name,
185                            const UDM_PROG_VAR_VALUE *Value);
186 const UDM_PROG_VAR2 *UdmProgVarListFind(const UDM_PROG_VARLIST *List,
187                                         const char *name);
188 
189 void UdmProgVarListListInit(UDM_PROG_VARLISTLIST *List);
190 void UdmProgVarListListFree(UDM_PROG_VARLISTLIST *List);
191 udm_rc_t UdmProgVarListListAdd(UDM_PROG_VARLISTLIST *List, const UDM_PROG_VARLIST *Item);
192 
193 
194 typedef struct
195 {
196   size_t stack_offset;
197   udm_offset_and_length_t textdata_addr;
198   const UDM_VALUE_HANDLER *handler;
199 } UDM_PROG_ARG;
200 
201 
202 typedef struct udm_prog_item_st
203 {
204   udm_tmpl_cmd_t cmdnum;
205   char *comment;
206   UDM_PROG_ARG item_args;
207   union
208   {
209     size_t jump;
210     int val_int;
211     double val_double;
212     const void *val_const_ptr;
213     size_t offset;
214     const UDM_FUNCTION *func;
215   } cmdarg;
216   UDM_PROG_CMD *cmd;
217 } UDM_PROG_ITEM;
218 
219 
220 typedef struct udm_tmpl_prg_st
221 {
222   size_t nitems;
223   size_t mitems;
224   UDM_PROG_ITEM *Items;
225   UDM_DSTR textdata;
226 } UDM_PROG;
227 
228 
229 typedef struct udm_prog_executor_arg_st
230 {
231   char *Data;
232 } UDM_PROG_EXECUTOR_ARG;
233 
234 
235 typedef struct udm_prog_global_variables_st
236 {
237   int argc;
238   char **argv;
239   FILE *stdout;
240   UDM_THDHANDLER THDHandler;
241 } UDM_PROG_GLOBAL_VARIABLES;
242 
243 
244 typedef struct udm_prog_execotor_registers_st
245 {
246   int     i[2];
247   double  d[2];
248   size_t  z0;
249   const char *cs0;
250   const UDM_VALUE_HANDLER *h0;
251   char *s0;                    /* e.g. values returned from functions */
252 } UDM_PROG_EXECUTOR_REGISTERS;
253 
254 
255 typedef struct udm_prog_executor_state_st
256 {
257   const UDM_PROG_ITEM *curr;
258   const UDM_PROG *prog;
259   UDM_PROG_EXECUTOR_REGISTERS reg;
260   UDM_DSTR stack;
261   UDM_PROG_EXECUTOR_ARG vreg[UDM_PROG_MAXARG];
262   UDM_PROG_GLOBAL_VARIABLES globals;
263   udm_bool_t fatal_error;
264 } UDM_PROG_EXECUTOR_STATE;
265 
266 #define UDM_FUNC_RETURN_INT(st,x)     ((st)->reg.i[0]= (x))
267 #define UDM_FUNC_RETURN_DOUBLE(st,x)  ((st)->reg.d[0]= (x))
268 
269 typedef struct udm_prog_executor_st
270 {
271   UDM_PROG_EXECUTOR_STATE state;
272 } UDM_PROG_EXECUTOR;
273 
274 
275 typedef enum
276 {
277   UDM_PROG_STMT_IF,
278   UDM_PROG_STMT_FOR,
279   UDM_PROG_STMT_WHILE
280 } udm_tmpl_block_stmt_t;
281 
282 
283 typedef struct udm_tmpl_compile_stack_item_st
284 {
285   size_t beg;
286   size_t jmp;
287   udm_tmpl_block_stmt_t stmt; /* IF FOR WHILE */
288 } UDM_PROG_COMPILE_STACK_ITEM;
289 
290 
291 typedef struct udm_tmpl_compile_stack_st
292 {
293   size_t nitems;
294   size_t mitems;
295   UDM_PROG_COMPILE_STACK_ITEM *Items;
296 } UDM_PROG_COMPILE_STACK;
297 
298 
299 typedef enum
300 {
301   COMMENT_NONE= 0,
302   COMMENT_INLINE= 1,
303   COMMENT_BLOCK= 2
304 } udm_template_comment_type_t;
305 
306 
307 typedef struct udm_template_helper_st
308 {
309   UDM_LEX_SCANNER scanner;
310   UDM_PROG *prg;
311   UDM_PROG_COMPILE_STACK st;
312   UDM_PROG_VARLISTLIST Vars2;
313   udm_template_comment_type_t comment_type;
314   size_t lineno;
315   const char *start;  /* The beginning of the current template section */
316   char errstr[128];
317   size_t pi_count;
318   size_t current_loop_continue;
319   udm_bool_t generate_debug_info;
320 } UDM_PROG_COMPILER;
321 
322 
323 void UdmProgInit(UDM_PROG *p);
324 void UdmProgPrint(const UDM_PROG *p);
325 void UdmProgFree(UDM_PROG *prg);
326 
327 
328 void UdmProgCompilerInit(UDM_PROG_COMPILER *compiler,
329                          size_t lineno, UDM_PROG *prg,
330                          const char *src, size_t srclen);
331 void UdmProgCompilerFree(UDM_PROG_COMPILER *compiler);
332 
333 void UdmProgExecutorInit(UDM_PROG_EXECUTOR *executor,
334                          FILE *stream, UDM_DSTR *dstr);
335 int  UdmProgExecutorExec(UDM_PROG_EXECUTOR *tmpl, const UDM_PROG *prg);
336 void UdmProgExecutorFree(UDM_PROG_EXECUTOR *executor);
337 
338 udm_rc_t UdmCompilePI(UDM_PROG_COMPILER *compiler, const UDM_CONST_STR *src);
339 udm_rc_t UdmCompilePIProgram(UDM_PROG_COMPILER *compiler, const UDM_CONST_STR *src);
340 
341 /******************************/
342 UDM_PROG *UdmProgCompilerGetProg(UDM_PROG_COMPILER *tmpl);
343 
344 void  UdmProgItemInit(UDM_PROG_ITEM *i);
345 udm_rc_t UdmProgAdd(UDM_PROG *prg, UDM_PROG_ITEM *item);
346 udm_rc_t UdmProgAddArg0Simple(UDM_PROG *prog, UDM_PROG_CMD *cmd);
347 udm_rc_t UdmProgAddArg0SimpleOp(UDM_PROG *prog, udm_tmpl_cmd_t op);
348 udm_rc_t UdmProgAddArg1SimpleOpDouble(UDM_PROG *pro, udm_tmpl_cmd_t op, double val);
349 udm_rc_t UdmProgAddArg1SimpleOpInt(UDM_PROG *pro, udm_tmpl_cmd_t op, int val);
350 udm_rc_t UdmProgAddJmp(UDM_PROG *prog, udm_tmpl_cmd_t cmdnum, int addr);
351 void UdmProgFixJumpInRange(UDM_PROG *prg, size_t start, size_t end);
352 udm_rc_t UdmProgAddValueHandler(UDM_PROG *prog, udm_tmpl_cmd_t cmdnum,
353                                 const UDM_VALUE_HANDLER *handler);
354 size_t PrintTextTemplate(UDM_ENV *Env, FILE *stream,
355                          UDM_DSTR *dstr, UDM_VARLIST *vars,
356                          const char *templ,
357                          const char *HlBeg, const char *HlEnd,
358                          udm_bool_t auto_escape);
359 size_t out_string(FILE *stream, UDM_DSTR *dstr, const char * src);
360 
361 void UdmProgExecutorStateInitArgs(UDM_PROG_EXECUTOR_STATE *state);
362 void UdmProgExecutorStateReturnStrn(UDM_PROG_EXECUTOR_STATE *state,
363                                     const char *str, size_t length);
364 void *UdmProgExecutorStateSetupReturnValue(UDM_PROG_EXECUTOR_STATE *state,
365                                            const UDM_VALUE_HANDLER *handler);
366 
367 extern const UDM_FUNCTION udm_builtin_functions[];
368 void UdmFunction_exit(UDM_PROG_EXECUTOR_STATE *state);
369 
370 #endif
371