1 //---------------------------------------------------------------------- 2 // COAL LOCAL DEFS 3 //---------------------------------------------------------------------- 4 // 5 // Copyright (C) 2009 Andrew Apted 6 // Copyright (C) 1996-1997 Id Software, Inc. 7 // 8 // Coal is free software; you can redistribute it and/or modify 9 // it under the terms of the GNU General Public License as 10 // published by the Free Software Foundation; either version 2 11 // of the License, or (at your option) any later version. 12 // 13 // Coal is distributed in the hope that it will be useful, but 14 // WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 16 // the GNU General Public License for more details. 17 // 18 //---------------------------------------------------------------------- 19 // 20 // Based on QCC (the Quake-C Compiler) and the corresponding 21 // execution engine from the Quake source code. 22 // 23 //---------------------------------------------------------------------- 24 25 #ifndef __COAL_LOCAL_DEFS_H__ 26 #define __COAL_LOCAL_DEFS_H__ 27 28 #include "c_memory.h" 29 30 typedef unsigned char byte; 31 32 typedef int func_t; 33 typedef int string_t; 34 35 36 #define MAX_NAME 64 37 38 #define MAX_PARMS 16 39 40 41 typedef enum 42 { 43 ev_INVALID = -1, 44 45 ev_void = 0, 46 ev_string, 47 ev_float, 48 ev_vector, 49 ev_entity, 50 ev_field, 51 ev_function, 52 ev_module, 53 ev_pointer 54 } 55 etype_t; 56 57 58 typedef struct 59 { 60 short op; 61 short line; // offset from start of function 62 63 int a, b, c; 64 } 65 statement_t; 66 67 68 enum 69 { 70 OP_NULL = 0, 71 72 OP_CALL, 73 OP_RET, 74 75 OP_PARM_F, 76 OP_PARM_V, 77 78 OP_IF, 79 OP_IFNOT, 80 OP_GOTO, 81 OP_ERROR, 82 83 OP_MOVE_F, 84 OP_MOVE_V, 85 OP_MOVE_S, 86 OP_MOVE_FNC, 87 88 // ---- mathematical ops from here on ---> 89 90 OP_NOT_F, 91 OP_NOT_V, 92 OP_NOT_S, 93 OP_NOT_FNC, 94 95 OP_INC, 96 OP_DEC, 97 98 OP_POWER_F, 99 OP_MUL_F, 100 OP_MUL_V, 101 OP_MUL_FV, 102 OP_MUL_VF, 103 104 OP_DIV_F, 105 OP_DIV_V, 106 OP_MOD_F, 107 108 OP_ADD_F, 109 OP_ADD_V, 110 OP_ADD_S, 111 OP_ADD_SF, 112 OP_ADD_SV, 113 114 OP_SUB_F, 115 OP_SUB_V, 116 117 OP_EQ_F, 118 OP_EQ_V, 119 OP_EQ_S, 120 OP_EQ_FNC, 121 122 OP_NE_F, 123 OP_NE_V, 124 OP_NE_S, 125 OP_NE_FNC, 126 127 OP_LE, 128 OP_GE, 129 OP_LT, 130 OP_GT, 131 132 OP_AND, 133 OP_OR, 134 OP_BITAND, 135 OP_BITOR, 136 137 NUM_OPERATIONS 138 }; 139 140 141 typedef struct 142 { 143 const char *name; 144 145 // where it was defined (last) 146 const char *source_file; 147 int source_line; 148 149 int return_size; 150 151 int parm_num; 152 short parm_ofs[MAX_PARMS]; 153 short parm_size[MAX_PARMS]; 154 155 int locals_ofs; 156 int locals_size; 157 int locals_end; 158 159 int first_statement; // negative numbers are builtins 160 int last_statement; 161 } 162 function_t; 163 164 // offset in global data block (if > 0) 165 // when < 0, it is offset into local stack frame 166 typedef int gofs_t; 167 168 169 170 //============================================================================= 171 172 173 #define OFS_NULL 0 174 #define OFS_RETURN 1 175 #define OFS_DEFAULT 4 176 177 178 #define REF_OP(ofs) ((statement_t *)op_mem.deref(ofs)) 179 #define REF_GLOBAL(ofs) ((double *)global_mem.deref(ofs)) 180 #define REF_STRING(ofs) ((ofs)==0 ? "" : \ 181 (ofs) < 0 ? (char *)temp_strings.deref(-(1+(ofs))) : \ 182 (char *)string_mem.deref(ofs)) 183 184 #define G_FLOAT(ofs) (* REF_GLOBAL(ofs)) 185 #define G_VECTOR(ofs) REF_GLOBAL(ofs) 186 #define G_STRING(ofs) REF_STRING((int) G_FLOAT(ofs)) 187 188 189 class parse_error_x 190 { 191 public: 192 int foo; 193 parse_error_x()194 parse_error_x() { } ~parse_error_x()195 ~parse_error_x() { } 196 }; 197 198 199 200 class exec_error_x 201 { 202 public: 203 int foo; 204 exec_error_x()205 exec_error_x() { } ~exec_error_x()206 ~exec_error_x() { } 207 }; 208 209 210 typedef struct 211 { 212 const char *name; 213 native_func_t func; 214 } 215 reg_native_func_t; 216 217 218 //============================================================// 219 220 #include "c_compile.h" 221 #include "c_execute.h" 222 223 224 class real_vm_c : public vm_c 225 { 226 public: 227 /* API functions */ 228 229 real_vm_c(); 230 ~real_vm_c(); 231 232 void SetPrinter(print_func_t func); 233 234 void AddNativeModule(const char *name); 235 void AddNativeFunction(const char *name, native_func_t func); 236 237 bool CompileFile(char *buffer, const char *filename); 238 void ShowStats(); 239 240 void SetAsmDump(bool enable); 241 void SetTrace (bool enable); 242 243 int FindFunction(const char *name); 244 int FindVariable(const char *name); 245 246 int Execute(int func_id); 247 248 double * AccessParam(int p); 249 const char * AccessParamString(int p); 250 251 void ReturnFloat(double f); 252 void ReturnVector(double *v); 253 void ReturnString(const char *s, int len = -1); 254 255 private: 256 print_func_t printer; 257 258 bmaster_c op_mem; 259 bmaster_c global_mem; 260 bmaster_c string_mem; 261 bmaster_c temp_strings; 262 263 std::vector< function_t* > functions; 264 std::vector< reg_native_func_t* > native_funcs; 265 266 compiling_c comp; 267 execution_c exec; 268 269 // c_compile.cc 270 private: 271 void GLOB_Globals(); 272 void GLOB_Module(); 273 void GLOB_Constant(); 274 void GLOB_Variable(); 275 void GLOB_Function(); 276 int GLOB_FunctionBody(def_t *func_def, type_t *type, const char *func_name); 277 278 void STAT_Statement(bool allow_def); 279 void STAT_Assignment(def_t *e); 280 void STAT_If_Else(); 281 void STAT_Assert(); 282 void STAT_WhileLoop(); 283 void STAT_RepeatLoop(); 284 void STAT_ForLoop(); 285 void STAT_Return(); 286 287 def_t * EXP_Expression(int priority, bool *lvalue = NULL); 288 def_t * EXP_FieldQuery(def_t *e, bool lvalue); 289 def_t * EXP_ShortCircuit(def_t *e, int n); 290 def_t * EXP_Term(); 291 def_t * EXP_VarValue(); 292 def_t * EXP_FunctionCall(def_t *func); 293 def_t * EXP_Literal(); 294 295 def_t * DeclareDef(type_t *type, char *name, scope_c *scope); 296 def_t * FindDef (type_t *type, char *name, scope_c *scope); 297 298 void StoreLiteral(int ofs); 299 def_t * FindLiteral(); 300 301 def_t * NewTemporary(type_t *type); 302 void FreeTemporaries(); 303 304 def_t * NewGlobal(type_t *type); 305 def_t * NewLocal(type_t *type); 306 307 char * ParseName(); 308 type_t * ParseType(); 309 type_t * FindType(type_t *type); 310 311 int EmitCode(short op, int a=0, int b=0, int c=0); 312 int EmitMove(type_t *type, int a, int b); 313 314 315 void LEX_Next(); 316 void LEX_Whitespace(); 317 void LEX_NewLine(); 318 void LEX_SkipPastError(); 319 320 bool LEX_Check (const char *str); 321 void LEX_Expect(const char *str); 322 323 void LEX_String(); 324 float LEX_Number(); 325 void LEX_Vector(); 326 void LEX_Name(); 327 void LEX_Punctuation(); 328 329 void CompileError(const char *error, ...); 330 331 332 // c_execute.cc 333 private: 334 void DoExecute(int func_id); 335 336 void EnterNative (int func, int argc); 337 void EnterFunction(int func); 338 void LeaveFunction(); 339 340 int GetNativeFunc(const char *name, const char *module); 341 int InternaliseString(const char *new_s); 342 343 int STR_Concat(const char * s1, const char * s2); 344 int STR_ConcatFloat (const char * s, double f); 345 int STR_ConcatVector(const char * s, double *v); 346 347 void RunError(const char *error, ...); 348 349 void StackTrace(); 350 void PrintStatement(function_t *f, int s); 351 const char * RegString(statement_t *st, int who); 352 353 void ASM_DumpFunction(function_t *f); 354 void ASM_DumpAll(); 355 356 static void default_printer(const char *msg, ...); 357 static void default_aborter(const char *msg, ...); 358 }; 359 360 361 #endif /* __COAL_LOCAL_DEFS_H__ */ 362 363 //--- editor settings --- 364 // vi:ts=4:sw=4:noexpandtab 365