1 /* 2 =========================================================================== 3 4 Doom 3 GPL Source Code 5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). 8 9 Doom 3 Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 #ifndef __SCRIPT_COMPILER_H__ 29 #define __SCRIPT_COMPILER_H__ 30 31 #include "idlib/Parser.h" 32 33 #include "script/Script_Program.h" 34 35 const char * const RESULT_STRING = "<RESULT>"; 36 37 typedef struct opcode_s { 38 const char *name; 39 const char *opname; 40 int priority; 41 bool rightAssociative; 42 idVarDef *type_a; 43 idVarDef *type_b; 44 idVarDef *type_c; 45 } opcode_t; 46 47 // These opcodes are no longer necessary: 48 // OP_PUSH_OBJ: 49 // OP_PUSH_OBJENT: 50 51 enum { 52 OP_RETURN, 53 54 OP_UINC_F, 55 OP_UINCP_F, 56 OP_UDEC_F, 57 OP_UDECP_F, 58 OP_COMP_F, 59 60 OP_MUL_F, 61 OP_MUL_V, 62 OP_MUL_FV, 63 OP_MUL_VF, 64 OP_DIV_F, 65 OP_MOD_F, 66 OP_ADD_F, 67 OP_ADD_V, 68 OP_ADD_S, 69 OP_ADD_FS, 70 OP_ADD_SF, 71 OP_ADD_VS, 72 OP_ADD_SV, 73 OP_SUB_F, 74 OP_SUB_V, 75 76 OP_EQ_F, 77 OP_EQ_V, 78 OP_EQ_S, 79 OP_EQ_E, 80 OP_EQ_EO, 81 OP_EQ_OE, 82 OP_EQ_OO, 83 84 OP_NE_F, 85 OP_NE_V, 86 OP_NE_S, 87 OP_NE_E, 88 OP_NE_EO, 89 OP_NE_OE, 90 OP_NE_OO, 91 92 OP_LE, 93 OP_GE, 94 OP_LT, 95 OP_GT, 96 97 OP_INDIRECT_F, 98 OP_INDIRECT_V, 99 OP_INDIRECT_S, 100 OP_INDIRECT_ENT, 101 OP_INDIRECT_BOOL, 102 OP_INDIRECT_OBJ, 103 104 OP_ADDRESS, 105 106 OP_EVENTCALL, 107 OP_OBJECTCALL, 108 OP_SYSCALL, 109 110 OP_STORE_F, 111 OP_STORE_V, 112 OP_STORE_S, 113 OP_STORE_ENT, 114 OP_STORE_BOOL, 115 OP_STORE_OBJENT, 116 OP_STORE_OBJ, 117 OP_STORE_ENTOBJ, 118 119 OP_STORE_FTOS, 120 OP_STORE_BTOS, 121 OP_STORE_VTOS, 122 OP_STORE_FTOBOOL, 123 OP_STORE_BOOLTOF, 124 125 OP_STOREP_F, 126 OP_STOREP_V, 127 OP_STOREP_S, 128 OP_STOREP_ENT, 129 OP_STOREP_FLD, 130 OP_STOREP_BOOL, 131 OP_STOREP_OBJ, 132 OP_STOREP_OBJENT, 133 134 OP_STOREP_FTOS, 135 OP_STOREP_BTOS, 136 OP_STOREP_VTOS, 137 OP_STOREP_FTOBOOL, 138 OP_STOREP_BOOLTOF, 139 140 OP_UMUL_F, 141 OP_UMUL_V, 142 OP_UDIV_F, 143 OP_UDIV_V, 144 OP_UMOD_F, 145 OP_UADD_F, 146 OP_UADD_V, 147 OP_USUB_F, 148 OP_USUB_V, 149 OP_UAND_F, 150 OP_UOR_F, 151 152 OP_NOT_BOOL, 153 OP_NOT_F, 154 OP_NOT_V, 155 OP_NOT_S, 156 OP_NOT_ENT, 157 158 OP_NEG_F, 159 OP_NEG_V, 160 161 OP_INT_F, 162 OP_IF, 163 OP_IFNOT, 164 165 OP_CALL, 166 OP_THREAD, 167 OP_OBJTHREAD, 168 169 OP_PUSH_F, 170 OP_PUSH_V, 171 OP_PUSH_S, 172 OP_PUSH_ENT, 173 OP_PUSH_OBJ, 174 OP_PUSH_OBJENT, 175 OP_PUSH_FTOS, 176 OP_PUSH_BTOF, 177 OP_PUSH_FTOB, 178 OP_PUSH_VTOS, 179 OP_PUSH_BTOS, 180 181 OP_GOTO, 182 183 OP_AND, 184 OP_AND_BOOLF, 185 OP_AND_FBOOL, 186 OP_AND_BOOLBOOL, 187 OP_OR, 188 OP_OR_BOOLF, 189 OP_OR_FBOOL, 190 OP_OR_BOOLBOOL, 191 192 OP_BITAND, 193 OP_BITOR, 194 195 OP_BREAK, // placeholder op. not used in final code 196 OP_CONTINUE, // placeholder op. not used in final code 197 198 NUM_OPCODES 199 }; 200 201 class idCompiler { 202 private: 203 static bool punctuationValid[ 256 ]; 204 static const char *punctuation[]; 205 206 idParser parser; 207 idParser *parserPtr; 208 idToken token; 209 210 idTypeDef *immediateType; 211 eval_t immediate; 212 213 bool eof; 214 bool console; 215 bool callthread; 216 int braceDepth; 217 int loopDepth; 218 int currentLineNumber; 219 int currentFileNumber; 220 int errorCount; 221 222 idVarDef *scope; // the function being parsed, or NULL 223 const idVarDef *basetype; // for accessing fields 224 225 float Divide( float numerator, float denominator ); 226 void Error( const char *error, ... ) const id_attribute((format(printf,2,3))); 227 void Warning( const char *message, ... ) const id_attribute((format(printf,2,3))); 228 idVarDef *OptimizeOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ); 229 idVarDef *EmitOpcode( const opcode_t *op, idVarDef *var_a, idVarDef *var_b ); 230 idVarDef *EmitOpcode( int op, idVarDef *var_a, idVarDef *var_b ); 231 bool EmitPush( idVarDef *expression, const idTypeDef *funcArg ); 232 void NextToken( void ); 233 void ExpectToken( const char *string ); 234 bool CheckToken( const char *string ); 235 void ParseName( idStr &name ); 236 void SkipOutOfFunction( void ); 237 void SkipToSemicolon( void ); 238 idTypeDef *CheckType( void ); 239 idTypeDef *ParseType( void ); 240 idVarDef *FindImmediate( const idTypeDef *type, const eval_t *eval, const char *string ) const; 241 idVarDef *GetImmediate( idTypeDef *type, const eval_t *eval, const char *string ); 242 idVarDef *VirtualFunctionConstant( idVarDef *func ); 243 idVarDef *SizeConstant( int size ); 244 idVarDef *JumpConstant( int value ); 245 idVarDef *JumpDef( int jumpfrom, int jumpto ); 246 idVarDef *JumpTo( int jumpto ); 247 idVarDef *JumpFrom( int jumpfrom ); 248 idVarDef *ParseImmediate( void ); 249 idVarDef *EmitFunctionParms( int op, idVarDef *func, int startarg, int startsize, idVarDef *object ); 250 idVarDef *ParseFunctionCall( idVarDef *func ); 251 idVarDef *ParseObjectCall( idVarDef *object, idVarDef *func ); 252 idVarDef *ParseEventCall( idVarDef *object, idVarDef *func ); 253 idVarDef *ParseSysObjectCall( idVarDef *func ); 254 idVarDef *LookupDef( const char *name, const idVarDef *baseobj ); 255 idVarDef *ParseValue( void ); 256 idVarDef *GetTerm( void ); 257 bool TypeMatches( etype_t type1, etype_t type2 ) const; 258 idVarDef *GetExpression( int priority ); 259 idTypeDef *GetTypeForEventArg( char argType ); 260 void PatchLoop( int start, int continuePos ); 261 void ParseReturnStatement( void ); 262 void ParseWhileStatement( void ); 263 void ParseForStatement( void ); 264 void ParseDoWhileStatement( void ); 265 void ParseIfStatement( void ); 266 void ParseStatement( void ); 267 void ParseObjectDef( const char *objname ); 268 idTypeDef *ParseFunction( idTypeDef *returnType, const char *name ); 269 void ParseFunctionDef( idTypeDef *returnType, const char *name ); 270 void ParseVariableDef( idTypeDef *type, const char *name ); 271 void ParseEventDef( idTypeDef *type, const char *name ); 272 void ParseDefs( void ); 273 void ParseNamespace( idVarDef *newScope ); 274 275 public : 276 static const opcode_t opcodes[]; 277 278 idCompiler(); 279 void CompileFile( const char *text, const char *filename, bool console ); 280 }; 281 282 #endif /* !__SCRIPT_COMPILER_H__ */ 283