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