1 /*
2      PLIB - A Suite of Portable Game Libraries
3      Copyright (C) 1998,2002  Steve Baker
4 
5      This library is free software; you can redistribute it and/or
6      modify it under the terms of the GNU Library General Public
7      License as published by the Free Software Foundation; either
8      version 2 of the License, or (at your option) any later version.
9 
10      This library is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Library General Public License for more details.
14 
15      You should have received a copy of the GNU Library General Public
16      License along with this library; if not, write to the Free Software
17      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 
19      For further information visit http://plib.sourceforge.net
20 
21      $Id: pslCodeGen.cxx 1891 2004-03-18 22:09:07Z sjbaker $
22 */
23 
24 
25 #include "pslLocal.h"
26 
27 
genCodeByte(pslOpcode op)28 void pslCompiler::genCodeByte ( pslOpcode op )
29 {
30   if ( next_code >= MAX_CODE - 1 )
31     error ( "Program too big!" ) ;
32   else
33     code [ next_code++ ] = op ;
34 }
35 
36 
genCodeAddr(pslAddress a)37 void pslCompiler::genCodeAddr ( pslAddress a )
38 {
39   genCodeByte ( a & 0xFF ) ;
40   genCodeByte ( ( a >> 8 ) & 0xFF ) ;
41 }
42 
43 
genLineNumber(int l)44 void pslCompiler::genLineNumber ( int l )
45 {
46   genCodeByte ( OPCODE_LINE_NUMBER ) ;
47   genCodeByte ( l & 0xFF ) ;
48   genCodeByte ( ( l >> 8 ) & 0xFF ) ;
49 }
50 
51 
genCharConstant(char c)52 void pslCompiler::genCharConstant ( char c )
53 {
54   /* A bit wasteful but... */
55 
56   genCodeByte ( OPCODE_PUSH_INT_CONSTANT ) ;
57   genCodeByte ( c ) ;
58   genCodeByte ( 0 ) ;
59   genCodeByte ( 0 ) ;
60   genCodeByte ( 0 ) ;
61 }
62 
63 
genConstant(const char * c)64 void pslCompiler::genConstant ( const char *c )
65 {
66   int isInteger = TRUE ;
67 
68   for ( const char *p = c ; *p != '\0' ; p++ )
69     if ( *p == '.' || *p == 'f' || *p == 'F' )
70     {
71       isInteger = FALSE ;
72       break ;
73     }
74 
75   if ( isInteger )
76     genIntConstant ( c ) ;
77   else
78     genFloatConstant ( c ) ;
79 }
80 
81 
genStringConstant(const char * c)82 void pslCompiler::genStringConstant ( const char *c )
83 {
84   genCodeByte ( OPCODE_PUSH_STRING_CONSTANT ) ;
85 
86   for ( int i = 0 ; c [ i ] != '\0' ; i++ )
87     genCodeByte ( (unsigned char)( c [ i ]) ) ;
88 
89   genCodeByte ( '\0' ) ;
90 }
91 
92 
genIntConstant(int i)93 void pslCompiler::genIntConstant ( int i )
94 {
95   char *ii = (char *) & i ;
96 
97   genCodeByte ( OPCODE_PUSH_INT_CONSTANT ) ;
98   genCodeByte ( ii [ 0 ] ) ;
99   genCodeByte ( ii [ 1 ] ) ;
100   genCodeByte ( ii [ 2 ] ) ;
101   genCodeByte ( ii [ 3 ] ) ;
102 }
103 
genIntConstant(const char * c)104 void pslCompiler::genIntConstant ( const char *c )
105 {
106   int i = (int) strtol ( c, NULL, 0 ) ;
107   genIntConstant ( i ) ;
108 }
109 
genFloatConstant(const char * c)110 void pslCompiler::genFloatConstant ( const char *c )
111 {
112   float f = (float) atof ( c ) ;
113   char *ff = (char *) & f ;
114 
115   genCodeByte ( OPCODE_PUSH_FLOAT_CONSTANT ) ;
116   genCodeByte ( ff [ 0 ] ) ;
117   genCodeByte ( ff [ 1 ] ) ;
118   genCodeByte ( ff [ 2 ] ) ;
119   genCodeByte ( ff [ 3 ] ) ;
120 }
121 
genGetParameter(pslAddress var,int argpos)122 void pslCompiler::genGetParameter ( pslAddress var, int argpos )
123 {
124   genCodeByte ( OPCODE_GET_PARAMETER ) ;
125   genCodeByte ( (unsigned char) var ) ;
126   genCodeByte ( argpos ) ;
127 }
128 
genMakeIntArray(const char * c)129 int pslCompiler::genMakeIntArray ( const char *c )
130 {
131   int a = getVarSymbol ( c ) ;
132 
133   genCodeByte ( OPCODE_SET_INT_ARRAY ) ;
134   genCodeByte ( a ) ;
135   return a ;
136 }
137 
genMakeFloatArray(const char * c)138 int pslCompiler::genMakeFloatArray ( const char *c )
139 {
140   int a = getVarSymbol ( c ) ;
141 
142   genCodeByte ( OPCODE_SET_FLOAT_ARRAY ) ;
143   genCodeByte ( a ) ;
144   return a ;
145 }
146 
genMakeStringArray(const char * c)147 int pslCompiler::genMakeStringArray ( const char *c )
148 {
149   int a = getVarSymbol ( c ) ;
150 
151   genCodeByte ( OPCODE_SET_STRING_ARRAY ) ;
152   genCodeByte ( a ) ;
153   return a ;
154 }
155 
genMakeIntVariable(const char * c)156 int pslCompiler::genMakeIntVariable ( const char *c )
157 {
158   int a = getVarSymbol ( c ) ;
159 
160   genCodeByte ( OPCODE_SET_INT_VARIABLE ) ;
161   genCodeByte ( a ) ;
162   return a ;
163 }
164 
genMakeFloatVariable(const char * c)165 int pslCompiler::genMakeFloatVariable ( const char *c )
166 {
167   int a = getVarSymbol ( c ) ;
168 
169   genCodeByte ( OPCODE_SET_FLOAT_VARIABLE ) ;
170   genCodeByte ( a ) ;
171   return a ;
172 }
173 
genMakeStringVariable(const char * c)174 int pslCompiler::genMakeStringVariable ( const char *c )
175 {
176   int a = getVarSymbol ( c ) ;
177 
178   genCodeByte ( OPCODE_SET_STRING_VARIABLE ) ;
179   genCodeByte ( a ) ;
180   return a ;
181 }
182 
183 
genVariable(const char * c,int array_ref)184 void pslCompiler::genVariable ( const char *c, int array_ref )
185 {
186   int a = getVarSymbol ( c ) ;
187 
188   genIntConstant ( array_ref ) ;
189   genIntConstant ( a ) ;
190 }
191 
genFetch()192 void pslCompiler::genFetch ()
193 {
194   genCodeByte ( OPCODE_FETCH ) ;
195 }
196 
genIncrementFetch()197 void pslCompiler::genIncrementFetch ()
198 {
199   genCodeByte ( OPCODE_INCREMENT_FETCH ) ;
200 }
201 
genDecrementFetch()202 void pslCompiler::genDecrementFetch ()
203 {
204   genCodeByte ( OPCODE_DECREMENT_FETCH ) ;
205 }
206 
genIncrementLValue()207 void pslCompiler::genIncrementLValue ()
208 {
209   genCodeByte ( OPCODE_INCREMENT_LVALUE ) ;
210 }
211 
genDecrementLValue()212 void pslCompiler::genDecrementLValue ()
213 {
214   genCodeByte ( OPCODE_DECREMENT_LVALUE ) ;
215 }
216 
genAssignment()217 void pslCompiler::genAssignment ()
218 {
219   genCodeByte ( OPCODE_POP_VARIABLE ) ;
220 }
221 
genAddAssignment()222 void pslCompiler::genAddAssignment ()
223 {
224   genCodeByte ( OPCODE_POP_ADD_VARIABLE ) ;
225 }
226 
227 
genSubAssignment()228 void pslCompiler::genSubAssignment ()
229 {
230   genCodeByte ( OPCODE_POP_SUB_VARIABLE ) ;
231 }
232 
233 
genMulAssignment()234 void pslCompiler::genMulAssignment ()
235 {
236   genCodeByte ( OPCODE_POP_MUL_VARIABLE ) ;
237 }
238 
239 
genModAssignment()240 void pslCompiler::genModAssignment ()
241 {
242   genCodeByte ( OPCODE_POP_MOD_VARIABLE ) ;
243 }
244 
245 
genDivAssignment()246 void pslCompiler::genDivAssignment ()
247 {
248   genCodeByte ( OPCODE_POP_DIV_VARIABLE ) ;
249 }
250 
251 
genAndAssignment()252 void pslCompiler::genAndAssignment ()
253 {
254   genCodeByte ( OPCODE_POP_AND_VARIABLE ) ;
255 }
256 
257 
genOrAssignment()258 void pslCompiler::genOrAssignment ()
259 {
260   genCodeByte ( OPCODE_POP_OR_VARIABLE ) ;
261 }
262 
263 
genXorAssignment()264 void pslCompiler::genXorAssignment ()
265 {
266   genCodeByte ( OPCODE_POP_XOR_VARIABLE ) ;
267 }
268 
269 
genSHLAssignment()270 void pslCompiler::genSHLAssignment ()
271 {
272   genCodeByte ( OPCODE_POP_SHL_VARIABLE ) ;
273 }
274 
275 
genSHRAssignment()276 void pslCompiler::genSHRAssignment ()
277 {
278   genCodeByte ( OPCODE_POP_SHR_VARIABLE ) ;
279 }
280 
281 
genCall(const char * c,int argc)282 void pslCompiler::genCall ( const char *c, int argc )
283 {
284   int ext = getExtensionSymbol ( c ) ;
285 
286   if ( ext < 0 )
287   {
288     genIntConstant ( argc ) ;
289     genCodeByte ( OPCODE_CALL ) ;
290 
291     int a = getCodeSymbol ( c, next_code ) ;
292 
293     genCodeAddr ( a ) ;
294     genCodeByte ( argc ) ;
295   }
296   else
297   {
298     genCodeByte ( OPCODE_CALLEXT ) ;
299     genCodeByte ( ext ) ;
300     genCodeByte ( argc ) ;
301   }
302 }
303 
genExchange()304 void pslCompiler::genExchange     () { genCodeByte ( OPCODE_EXCHANGE   ) ; }
genReturn()305 void pslCompiler::genReturn       () { genCodeByte ( OPCODE_RETURN     ) ; }
genPop()306 void pslCompiler::genPop          () { genCodeByte ( OPCODE_POP        ) ; }
genSubtract()307 void pslCompiler::genSubtract     () { genCodeByte ( OPCODE_SUB        ) ; }
genAdd()308 void pslCompiler::genAdd          () { genCodeByte ( OPCODE_ADD        ) ; }
genDivide()309 void pslCompiler::genDivide       () { genCodeByte ( OPCODE_DIV        ) ; }
genMultiply()310 void pslCompiler::genMultiply     () { genCodeByte ( OPCODE_MULT       ) ; }
genModulo()311 void pslCompiler::genModulo       () { genCodeByte ( OPCODE_MOD        ) ; }
genNegate()312 void pslCompiler::genNegate       () { genCodeByte ( OPCODE_NEG        ) ; }
genNot()313 void pslCompiler::genNot          () { genCodeByte ( OPCODE_NOT        ) ; }
genTwiddle()314 void pslCompiler::genTwiddle      () { genCodeByte ( OPCODE_TWIDDLE    ) ; }
genOrOr()315 void pslCompiler::genOrOr         () { genCodeByte ( OPCODE_OROR       ) ; }
genAndAnd()316 void pslCompiler::genAndAnd       () { genCodeByte ( OPCODE_ANDAND     ) ; }
genOr()317 void pslCompiler::genOr           () { genCodeByte ( OPCODE_OR         ) ; }
genAnd()318 void pslCompiler::genAnd          () { genCodeByte ( OPCODE_AND        ) ; }
genXor()319 void pslCompiler::genXor          () { genCodeByte ( OPCODE_XOR        ) ; }
genShiftLeft()320 void pslCompiler::genShiftLeft    () { genCodeByte ( OPCODE_SHIFTLEFT  ) ; }
genShiftRight()321 void pslCompiler::genShiftRight   () { genCodeByte ( OPCODE_SHIFTRIGHT ) ; }
322 
genLess()323 void pslCompiler::genLess         () { genCodeByte ( OPCODE_LESS       ) ; }
genLessEqual()324 void pslCompiler::genLessEqual    () { genCodeByte ( OPCODE_LESSEQUAL  ) ; }
genGreater()325 void pslCompiler::genGreater      () { genCodeByte ( OPCODE_GREATER    ) ; }
genGreaterEqual()326 void pslCompiler::genGreaterEqual () { genCodeByte ( OPCODE_GREATEREQUAL); }
genNotEqual()327 void pslCompiler::genNotEqual     () { genCodeByte ( OPCODE_NOTEQUAL   ) ; }
genEqual()328 void pslCompiler::genEqual        () { genCodeByte ( OPCODE_EQUAL      ) ; }
329 
genStackDup()330 void pslCompiler::genStackDup () { genCodeByte ( OPCODE_STACK_DUPLICATE ) ; }
331 
genPeekJumpIfTrue(int l)332 int pslCompiler::genPeekJumpIfTrue  ( int l )
333 {
334   genCodeByte ( OPCODE_PEEK_JUMP_TRUE ) ;
335 
336   int res = next_code ;
337 
338   genCodeAddr ( l ) ;
339 
340   return res ;
341 }
342 
genPeekJumpIfFalse(int l)343 int pslCompiler::genPeekJumpIfFalse  ( int l )
344 {
345   genCodeByte ( OPCODE_PEEK_JUMP_FALSE ) ;
346 
347   int res = next_code ;
348 
349   genCodeAddr ( l ) ;
350 
351   return res ;
352 }
353 
genJumpIfTrue(int l)354 int pslCompiler::genJumpIfTrue  ( int l )
355 {
356   genCodeByte ( OPCODE_JUMP_TRUE ) ;
357 
358   int res = next_code ;
359 
360   genCodeAddr ( l ) ;
361 
362   return res ;
363 }
364 
genJumpIfFalse(int l)365 int pslCompiler::genJumpIfFalse  ( int l )
366 {
367   genCodeByte ( OPCODE_JUMP_FALSE ) ;
368 
369   int res = next_code ;
370 
371   genCodeAddr ( l ) ;
372 
373   return res ;
374 }
375 
genJump(int l)376 int pslCompiler::genJump ( int l )
377 {
378   genCodeByte ( OPCODE_JUMP ) ;
379 
380   int res = next_code ;
381 
382   genCodeAddr ( l ) ;
383 
384   return res ;
385 }
386 
387 
genPauseStatement()388 int pslCompiler::genPauseStatement()
389 {
390   genCodeByte ( OPCODE_PAUSE ) ;
391   return TRUE ;
392 }
393 
394 
395