This file is indexed.

/usr/include/falcon/gencode.h is in falconpl-dev 0.9.6.9-git20120606-2.1+b1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
/*
   FALCON - The Falcon Programming Language.
   FILE: gencode.h

   Generates a compiler-debug oriented representation of the input symtree.
   -------------------------------------------------------------------
   Author: Giancarlo Niccolai
   Begin: sab giu 5 2004

   -------------------------------------------------------------------
   (C) Copyright 2004: the FALCON developers (see list in AUTHORS file)

   See LICENSE file for licensing details.
*/
#ifndef FALCON_GENCODE_H
#define FALCON_GENCODE_H

#include <falcon/generator.h>
#include <falcon/syntree.h>
#include <falcon/genericlist.h>
#include <falcon/genericvector.h>
#include <falcon/stringstream.h>

namespace Falcon
{

class LineMap;

class FALCON_DYN_CLASS GenCode: public Generator
{
   typedef enum {
      e_parND,
      e_parNIL,
      e_parUND,
      e_parVAL,
      e_parVAR,
      e_parINT32,
      e_parSYM,
      e_parA,
      e_parB,
      e_parS1,
      e_parL1,
      e_parL2,
      e_parLBIND,
      e_parTRUE,
      e_parFALSE,
      e_parNTD32,
      e_parNTD64,
      e_parSTRID
   } t_paramType;


   class c_jmptag
   {
      /* Varpar and jmptag are never newed, so they don't need operator new */
      uint32 m_defs[4];
      List m_queries[4];
      GenericVector m_elifDefs;
		GenericVector m_elifQueries;

      uint32 m_tries;
      uint32 m_offset;
      bool m_bIsForLast;
      const StmtForin* m_ForinLoop;
      Stream *m_stream;

      uint32 addQuery( uint32 id, uint32 pos );
      void define( uint32 id  );

   public:
      c_jmptag( Stream *stream, uint32 offset = 0 );

      uint32 addQueryBegin( uint32 blocks=1 ) { return addQuery( 0, blocks ); }
      uint32 addQueryEnd( uint32 blocks=1 ) { return addQuery( 1, blocks ); }
      uint32 addQueryNext( uint32 blocks=1 ) { return addQuery( 2, blocks ); }
      uint32 addQueryPostEnd( uint32 blocks=1 ) { return addQuery( 3, blocks ); }
      void defineBegin() { define( 0 ); }
      void defineEnd() { define( 1 ); }
      void defineNext() { define( 2 ); }
      void definePostEnd() { define( 3 ); }

      uint32 addQueryIfElse( uint32 blocks=1) { return addQuery( 0, blocks ); }
      uint32 addQueryIfEnd( uint32 blocks=1 ) { return addQuery( 1, blocks ); }
      uint32 addQueryElif( uint32 elifID, uint32 blocks=1 );
      uint32 addQuerySwitchBlock( uint32 blockID, uint32 blocks=1 )
      {
         return addQueryElif( blockID, blocks );
      }

      void defineIfElse() { define( 0 ); }
      void defineIfEnd() { define( 1 ); }
      void defineElif( uint32 id );
      void defineSwitchCase( uint32 id )
      {
         defineElif( id );
      }

      void addTry( uint32 count = 1 ) { m_tries += count; }
      void removeTry( uint32 count = 1 ) { m_tries -= count; }
      uint32 tryCount() const { return m_tries; }
      bool isForIn() const { return m_ForinLoop != 0; }
      const StmtForin* ForinLoop() const { return m_ForinLoop; }
      void setForIn( const StmtForin* forin ) { m_ForinLoop = forin; }
      void setForLast( bool l ) { m_bIsForLast = l; }
      bool isForLast() const { return m_bIsForLast; }
   };

   class c_varpar {
   public:
      /* Varpar and jmptag are never newed, so they don't need operator new */
      t_paramType m_type;
      union {
         const Value *value;
         const VarDef *vd;
         const Symbol *sym;
         int32 immediate;
         int64 immediate64;
      } m_content;

      c_varpar():
         m_type( e_parND )
      {}

      c_varpar( t_paramType t ):
         m_type( t )
      {}

      explicit c_varpar( bool val ):
         m_type( val ? e_parTRUE : e_parFALSE )
      {}

      c_varpar( const Value *val ):
         m_type( e_parVAL )
      {
         if ( val->isNil() )
            m_type = e_parNIL;
         else if( val->isUnbound() )
            m_type = e_parUND;
         else
            m_content.value = val;
      }

      c_varpar( const VarDef *vd ):
         m_type( e_parVAR )
      {
         if ( vd->isNil() )
            m_type = e_parNIL;
         else
            m_content.vd = vd;
      }

      c_varpar( const Symbol *sym ):
         m_type( e_parSYM )
      {
         m_content.sym = sym;
      }

      c_varpar( const int32 immediate ):
         m_type( e_parINT32 )
      {
         m_content.immediate = immediate;
      }

      c_varpar( const c_varpar &other ):
         m_type( other.m_type ),
         m_content( other.m_content )
      {}

      void generate( GenCode *owner ) const;

   };

   friend class c_varpar;

   c_varpar c_param_fixed( uint32 num ) {
      c_varpar ret( e_parNTD32 );
      ret.m_content.immediate = num;
      return ret;
   }

   c_varpar c_param_str( uint32 num ) {
      c_varpar ret( e_parSTRID );
      ret.m_content.immediate = num;
      return ret;
   }

   void gen_pcode( byte pcode )
   {
      gen_pcode( pcode, e_parND, e_parND, e_parND );
   }

   void gen_pcode( byte pcode, const c_varpar &first )
   {
      gen_pcode( pcode, first, e_parND, e_parND );
   }

   void gen_pcode( byte pcode, const c_varpar &first, const c_varpar &second )
   {
      gen_pcode( pcode, first, second, e_parND );
   }

   void gen_pcode( byte pcode, const c_varpar &first, const c_varpar &second, const c_varpar &third );
   byte gen_pdef( const c_varpar &elem );
   void gen_var( const VarDef &def );

   /* Pushes a label with a certain displacement.
      This function marks the position of a label in the next N int32 blocks, where
      N is the parameter. Usually, the jump or similar instruction has the jump
      target in the first int32 parameter, so the default for the param is 1.

      In case the position of the label target cannot be determined in advance,
      output operations must be perfomed manually, but at the moment all the functions
      with jump targets have only one or more int32 parmeters.

      \param displacement the distance in int32 block from current write position where label
             value must be written.
   */

   /** Writes a previously recorede label.
      This pops the label definition from the stack, writes the current file position
      and moves the file pointer back to where it was.

      This is the only operation causing write pointer to move (except for write).
   */
   void pop_label();

   void gen_function( const StmtFunction *func );
   void gen_block( const StatementList *slist );
   void gen_statement( const Statement *stmt );
   void gen_condition( const Value *stmt, int mode=-1 );
   void gen_value( const Value *stmt );

   typedef enum {
      l_value,
      p_value,
      v_value
   } t_valType;

   /** Generates a complex value.
      Complex values are divided in two classes; expressions and structure constructions.

      Structure construction are namely:
      - range generations
      - array generation
      - dictionary generation
      - symbol reference generation

      Expresions are themselves divided into two kind; the ones that returns a "volatile"
      value, called l-value, and the ones that refer to an assignable, persistent location,
      called x-value. Namely, x-values are divided into p-values (expressions
      terminating with a property accesor) or v-value ( expression terminating with a
      sequence accessor).

      Some l-values:
      \code
         (a+1)
         functionCall()
         (a + b * c)
         var[ accessor ]()
         obj.property()
         obj.property[5].otherProp[2] + 1
      \endcode

      Some p-values:
      \code
         obj.property
         ( #"indirect"() ).property
         obj.property++    // we still refer to obj.property
      \endcode

      Some v-values:
      \code
         var[ accessorGenerator() ]
         obj.property[ x ]
         --var[5]          // we still refer to var[5]
      \endcode

      This distintion must be known, as assignments to l-values should be taken with care;
      for now, we do that and we assign to the A register. Conversely, assignment and auto-expressions
      on x-values is common.

      Instead of analyzing the structure of the expression, we let the underlying calls to the
      expression generators to determine if they are unrolling an l-value or an x-value.

      The parameter x_value is initially false; it gets changed to true if the last expanded
      expression element is an accessor. Operators ++ and -- don't change the character of the
      value, and all the others reset the character to l-value.

      \param value The value to be generated.
      \param x_value At exit, returns characteristic of the value.
   */

   void gen_complex_value( const Value *value, t_valType &x_value );

   /** Non l-value sensible version of complex value generator.
      Some operations do not require to know if the value generated is an l-value expression or not.
      They may use this version instead.
      \param value The value to be generated.
   */
   void gen_complex_value( const Value *value ) { t_valType dummy; gen_complex_value( value, dummy ); }

   /** Generate an expression.
      Expressions are the most common complex value. See gen_complex_value for a description.
      \param expr The expression to be generated.
      \param x_value On exit, characteristic value type of the expression.
      \see gen_complex_value
   */
   void gen_expression( const Expression *expr, t_valType &x_value );

   /** Generate an expression without taking its l-value characteristics.
      \param expr The expression to be generated.
   */
   void gen_expression( const Expression *expr ) { t_valType dummy; gen_expression( expr, dummy ); }

   void gen_dict_decl( const DictDecl *stmt );
   void gen_array_decl( const ArrayDecl *stmt );
   void gen_range_decl( const RangeDecl *stmt );
   /** Geneare a push instruction based on a source value.
      Push is a kinda tricky instruction. Theoretically, if the value holds
      a reference taking expression, one can LDRF on the target and then push A,
      but PSHR is provided to do this in just one step. Hence the need of a specialized
      push generator that is a little smarter than the usual gen_value.
   */
   void gen_push( const Value *val );
   /** Generate a load instruction.
      LD is a kinda tricky instruction. Theoretically, if the source value holds
      a reference taking expression, one can LDRF on the target and then load A into the source
      but LDRF is provided to do this in just one step. Hence the need of a specialized
      load generator that is a little smarter.
   */
   void gen_load( const Value *target, const Value *source );
   void gen_store_to_deep( byte type, const Value *source, const Value *first, const Value *second );

   void gen_inc_prefix( const Value *target );
   void gen_dec_prefix( const Value *target );
   void gen_inc_postfix( const Value *target );
   void gen_dec_postfix( const Value *target );
   void gen_autoassign( byte opcode, const Value *target, const Value *source );
   void gen_store_to_deep_A( byte type, const Value *first, const Value *second );
   void gen_store_to_deep_reg( byte type, const Value *first, const Value *second, t_paramType reg );
   void gen_load_from_deep( byte type, const Value *first, const Value *second );
   void gen_load_from_A( const Value *target );
   void gen_load_from_reg( const Value *target, t_paramType reg );
   int gen_refArray( const ArrayDecl *tarr, bool bGenArray );
   void gen_operand( const Value *stmt );

   /** Generates a function call from an expression. */
   void gen_funcall( const Expression *call, bool fork=false );
   List m_labels;
   List m_labels_loop;

   /** Current context of functions, needed i.e. for states. */
   List m_functions;

   uint32 m_pc;
   StringStream *m_outTemp;
   Module *m_module;

public:
   GenCode( Module *mod );
   virtual ~GenCode();

   virtual void generate( const SourceTree *st );
};

}
#endif

/* end of gencode.h */