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