FreeBASIC  0.91.0
ast.bas
Go to the documentation of this file.
1 '' [A]bstract [S]yntax [T]ree core
2 ''
3 '' obs: 1) each AST only stores a single expression and its atoms (inc. arrays and functions)
4 '' 2) after the AST is optimized (constants folding, arithmetic associations, etc),
5 '' its sent to IR, where the expression becomes three-address-codes
6 '' 3) AST optimizations don't include common-sub-expression/dead-code elimination,
7 '' that must be done by the DAG module
8 ''
9 '' chng: sep/2004 written [v1ctor]
10 
11 
12 #include once "fb.bi"
13 #include once "fbint.bi"
14 #include once "list.bi"
15 #include once "ir.bi"
16 #include once "ast.bi"
17 
18 dim shared as ASTCTX ast
19 
20 type AST_LOADCALLBACK as function( byval n as ASTNODE ptr ) as IRVREG ptr
21 
22 '' same order as AST_NODECLASS
23 dim shared as AST_LOADCALLBACK ast_loadcallbacks( 0 to AST_CLASSES-1 ) => _
24 { _
25  @astLoadNOP , _ '' AST_NODECLASS_NOP
26  @astLoadLOAD , _ '' AST_NODECLASS_LOAD
27  @astLoadASSIGN , _ '' AST_NODECLASS_ASSIGN
28  @astLoadBOP , _ '' AST_NODECLASS_BOP
29  @astLoadUOP , _ '' AST_NODECLASS_UOP
30  @astLoadCONV , _ '' AST_NODECLASS_CONV
31  @astLoadADDROF , _ '' AST_NODECLASS_ADDROF
32  @astLoadBRANCH , _ '' AST_NODECLASS_BRANCH
33  @astLoadJMPTB , _ '' AST_NODECLASS_JMPTB
34  @astLoadCALL , _ '' AST_NODECLASS_CALL
35  @astLoadCALLCTOR , _ '' AST_NODECLASS_CALLCTOR
36  @astLoadSTACK , _ '' AST_NODECLASS_STACK
37  @astLoadMEM , _ '' AST_NODECLASS_MEM
38  @astLoadLOOP , _ '' AST_NODECLASS_LOOP
39  NULL , _ '' AST_NODECLASS_COMP
40  @astLoadLINK , _ '' AST_NODECLASS_LINK
41  @astLoadCONST , _ '' AST_NODECLASS_CONST
42  @astLoadVAR , _ '' AST_NODECLASS_VAR
43  @astLoadIDX , _ '' AST_NODECLASS_IDX
44  @astLoadFIELD , _ '' AST_NODECLASS_FIELD
45  @astLoadDEREF , _ '' AST_NODECLASS_DEREF
46  @astLoadLABEL , _ '' AST_NODECLASS_LABEL
47  NULL , _ '' AST_NODECLASS_ARG
48  @astLoadOFFSET , _ '' AST_NODECLASS_OFFSET
49  @astLoadDECL , _ '' AST_NODECLASS_DECL
50  @astLoadNIDXARRAY , _ '' AST_NODECLASS_NIDXARRAY
51  @astLoadIIF , _ '' AST_NODECLASS_IIF
52  @astLoadLIT , _ '' AST_NODECLASS_LIT
53  @astLoadASM , _ '' AST_NODECLASS_ASM
54  NULL , _ '' AST_NODECLASS_DATASTMT
55  @astLoadDBG , _ '' AST_NODECLASS_DBG
56  @astLoadBOUNDCHK , _ '' AST_NODECLASS_BOUNDCHK
57  @astLoadPTRCHK , _ '' AST_NODECLASS_PTRCHK
58  @astLoadSCOPEBEGIN , _ '' AST_NODECLASS_SCOPEBEGIN
59  @astLoadSCOPEEND , _ '' AST_NODECLASS_SCOPEEND
60  NULL , _ '' AST_NODECLASS_SCOPE_BREAK
61  NULL , _ '' AST_NODECLASS_TYPEINI
62  NULL , _ '' AST_NODECLASS_TYPEINI_PAD
63  NULL , _ '' AST_NODECLASS_TYPEINI_ASSIGN
64  NULL , _ '' AST_NODECLASS_TYPEINI_CTORCALL
65  NULL , _ '' AST_NODECLASS_TYPEINI_CTORLIST
66  NULL , _ '' AST_NODECLASS_TYPEINI_SCOPEINI
67  NULL , _ '' AST_NODECLASS_TYPEINI_SCOPEEND
68  NULL _ '' AST_NODECLASS_PROC
69 }
70 
71 '' same order as AST_OP
72 dim shared ast_opTB( 0 to AST_OPCODES-1 ) as AST_OPINFO => _
73 { _
74  (AST_NODECLASS_ASSIGN, AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"let" ), _ '' AST_OP_ASSIGN
75  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"+=" , AST_OP_ADD ), _ '' AST_OP_ADD_SELF
76  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"-=" , AST_OP_SUB ), _ '' AST_OP_SUB_SELF
77  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"*=" , AST_OP_MUL ), _ '' AST_OP_MUL_SELF
78  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"/=" , AST_OP_DIV ), _ '' AST_OP_DIV_SELF
79  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"/=" , AST_OP_INTDIV ), _ '' AST_OP_INTDIV_SELF
80  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"mod=" , AST_OP_MOD ), _ '' AST_OP_MOD_SELF
81  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"and=" , AST_OP_AND ), _ '' AST_OP_AND_SELF
82  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"or=" , AST_OP_OR ), _ '' AST_OP_OR_SELF
83  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"andalso=", AST_OP_ANDALSO), _ '' AST_OP_ANDALSO_SELF
84  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"orelse=" , AST_OP_ORELSE ), _ '' AST_OP_ORELSE_SELF
85  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"xor=" , AST_OP_XOR ), _ '' AST_OP_XOR_SELF
86  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"eqv=" , AST_OP_EQV ), _ '' AST_OP_EQV_SELF
87  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"imp=" , AST_OP_IMP ), _ '' AST_OP_IMP_SELF
88  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"shl=" , AST_OP_SHL ), _ '' AST_OP_SHL_SELF
89  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"shr=" , AST_OP_SHR ), _ '' AST_OP_SHR_SELF
90  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"pow=" , AST_OP_POW ), _ '' AST_OP_POW_SELF
91  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"&=" , AST_OP_CONCAT ), _ '' AST_OP_CONCAT_SELF
92  (AST_NODECLASS_MEM , AST_OPFLAGS_SELF, @"new" ), _ '' AST_OP_NEW_SELF
93  (AST_NODECLASS_MEM , AST_OPFLAGS_SELF, @"new[]" ), _ '' AST_OP_NEW_VEC_SELF
94  (AST_NODECLASS_MEM , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"delete" ), _ '' AST_OP_DEL_SELF
95  (AST_NODECLASS_MEM , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"delete[]"), _ '' AST_OP_DEL_VEC_SELF
96  (AST_NODECLASS_ADDROF, AST_OPFLAGS_SELF, @"@" ), _ '' AST_OP_ADDROF
97  (AST_NODECLASS_BOP , AST_OPFLAGS_SELF, @"[]" ), _ '' AST_OP_PTRINDEX
98  (AST_NODECLASS_COMP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"for" ), _ '' AST_OP_FOR
99  (AST_NODECLASS_COMP , AST_OPFLAGS_SELF or AST_OPFLAGS_NORES, @"step" ), _ '' AST_OP_STEP
100  (AST_NODECLASS_COMP , AST_OPFLAGS_SELF, @"next" ), _ '' AST_OP_NEXT
101  (AST_NODECLASS_CONV , AST_OPFLAGS_SELF, @"cast" ), _ '' AST_OP_CAST
102  (AST_NODECLASS_BOP , AST_OPFLAGS_COMM, @"+" , AST_OP_ADD_SELF ), _ '' AST_OP_ADD
103  (AST_NODECLASS_BOP , AST_OPFLAGS_NONE, @"-" , AST_OP_SUB_SELF ), _ '' AST_OP_SUB
104  (AST_NODECLASS_BOP , AST_OPFLAGS_COMM, @"*" , AST_OP_MUL_SELF ), _ '' AST_OP_MUL
105  (AST_NODECLASS_BOP , AST_OPFLAGS_NONE, @"/" , AST_OP_DIV_SELF ), _ '' AST_OP_DIV
106  (AST_NODECLASS_BOP , AST_OPFLAGS_NONE, @"/" , AST_OP_INTDIV_SELF ), _ '' AST_OP_INTDIV
107  (AST_NODECLASS_BOP , AST_OPFLAGS_NONE, @"mod" , AST_OP_MOD_SELF ), _ '' AST_OP_MOD
108  (AST_NODECLASS_BOP , AST_OPFLAGS_COMM, @"and" , AST_OP_AND_SELF ), _ '' AST_OP_AND
109  (AST_NODECLASS_BOP , AST_OPFLAGS_COMM, @"or" , AST_OP_OR_SELF ), _ '' AST_OP_OR
110  (AST_NODECLASS_BOP , AST_OPFLAGS_COMM, @"andalso", AST_OP_ANDALSO_SELF ), _ '' AST_OP_ANDALSO
111  (AST_NODECLASS_BOP , AST_OPFLAGS_COMM, @"orelse" , AST_OP_ORELSE_SELF ), _ '' AST_OP_ORELSE
112  (AST_NODECLASS_BOP , AST_OPFLAGS_COMM, @"xor" , AST_OP_XOR_SELF ), _ '' AST_OP_XOR
113  (AST_NODECLASS_BOP , AST_OPFLAGS_NONE, @"eqv" , AST_OP_EQV_SELF ), _ '' AST_OP_EQV
114  (AST_NODECLASS_BOP , AST_OPFLAGS_NONE, @"imp" , AST_OP_IMP_SELF ), _ '' AST_OP_IMP
115  (AST_NODECLASS_BOP , AST_OPFLAGS_NONE, @"shl" , AST_OP_SHL_SELF ), _ '' AST_OP_SHL
116  (AST_NODECLASS_BOP , AST_OPFLAGS_NONE, @"shr" , AST_OP_SHR_SELF ), _ '' AST_OP_SHR
117  (AST_NODECLASS_BOP , AST_OPFLAGS_NONE, @"pow" , AST_OP_POW_SELF ), _ '' AST_OP_POW
118  (AST_NODECLASS_BOP , AST_OPFLAGS_NONE, @"&" , AST_OP_CONCAT_SELF ), _ '' AST_OP_CONCAT
119  (AST_NODECLASS_COMP , AST_OPFLAGS_COMM, @"=" ), _ '' AST_OP_EQ
120  (AST_NODECLASS_COMP , AST_OPFLAGS_NONE, @">" ), _ '' AST_OP_GT
121  (AST_NODECLASS_COMP , AST_OPFLAGS_NONE, @"<" ), _ '' AST_OP_LT
122  (AST_NODECLASS_COMP , AST_OPFLAGS_COMM, @"<>" ), _ '' AST_OP_NE
123  (AST_NODECLASS_COMP , AST_OPFLAGS_NONE, @">=" ), _ '' AST_OP_GE
124  (AST_NODECLASS_COMP , AST_OPFLAGS_NONE, @"<=" ), _ '' AST_OP_LE
125  (AST_NODECLASS_COMP , AST_OPFLAGS_NONE, @"is" ), _ '' AST_OP_IS
126  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"not" ), _ '' AST_OP_NOT
127  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"+" ), _ '' AST_OP_PLUS
128  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"-" ), _ '' AST_OP_NEG
129  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"HADD" ), _ '' AST_OP_HADD
130  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"abs" ), _ '' AST_OP_ABS
131  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"sgn" ), _ '' AST_OP_SGN
132  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"sin" ), _ '' AST_OP_SIN
133  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"asin" ), _ '' AST_OP_ASIN
134  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"cos" ), _ '' AST_OP_COS
135  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"acos" ), _ '' AST_OP_ACOS
136  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"tan" ), _ '' AST_OP_TAN
137  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"atan" ), _ '' AST_OP_ATAN
138  (AST_NODECLASS_BOP , AST_OPFLAGS_NONE, @"atn2" ), _ '' AST_OP_ATAN2
139  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"sqr" ), _ '' AST_OP_SQRT
140  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"rsqrt" ), _ '' AST_OP_RSQRT
141  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"rcp" ), _ '' AST_OP_RCP
142  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"log" ), _ '' AST_OP_LOG
143  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"exp" ), _ '' AST_OP_EXP
144  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"int" ), _ '' AST_OP_FLOOR
145  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"fix" ), _ '' AST_OP_FIX
146  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"frac" ), _ '' AST_OP_FRAC
147  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"convd2s" ), _ '' AST_OP_CONVFD2FS
148  (AST_NODECLASS_UOP , AST_OPFLAGS_NONE, @"swzrep" ), _ '' AST_OP_SWZ_REPEAT
149  (AST_NODECLASS_ADDROF, AST_OPFLAGS_NONE, @"*" ), _ '' AST_OP_DEREF
150  (AST_NODECLASS_ADDROF, AST_OPFLAGS_NONE, @"->" ), _ '' AST_OP_FLDDEREF
151  (AST_NODECLASS_MEM , AST_OPFLAGS_NONE, @"new" , AST_OP_NEW_SELF ), _ '' AST_OP_NEW
152  (AST_NODECLASS_MEM , AST_OPFLAGS_NONE, @"new[]" , AST_OP_NEW_VEC_SELF), _ '' AST_OP_NEW_VEC
153  (AST_NODECLASS_MEM , AST_OPFLAGS_NONE, @"delete" , AST_OP_DEL_SELF ), _ '' AST_OP_DEL
154  (AST_NODECLASS_MEM , AST_OPFLAGS_NONE, @"delete[]", AST_OP_DEL_VEC_SELF), _ '' AST_OP_DEL_VEC
155  (AST_NODECLASS_CONV , AST_OPFLAGS_NONE, @"cint" ), _ '' AST_OP_TOINT
156  (AST_NODECLASS_CONV , AST_OPFLAGS_NONE, @"cflt" ), _ '' AST_OP_TOFLT
157  (AST_NODECLASS_LOAD , AST_OPFLAGS_NONE, @"load" ), _ '' AST_OP_LOAD
158  (AST_NODECLASS_LOAD , AST_OPFLAGS_NONE, @"lres" ), _ '' AST_OP_LOADRES
159  (AST_NODECLASS_ASSIGN, AST_OPFLAGS_NONE, @"spill" ), _ '' AST_OP_SPILLREGS
160  (AST_NODECLASS_STACK , AST_OPFLAGS_NONE, @"push" ), _ '' AST_OP_PUSH
161  (AST_NODECLASS_STACK , AST_OPFLAGS_NONE, @"pop" ), _ '' AST_OP_POP
162  (AST_NODECLASS_STACK , AST_OPFLAGS_NONE, @"pudt" ), _ '' AST_OP_PUSHUDT
163  (AST_NODECLASS_STACK , AST_OPFLAGS_NONE, @"stka" ), _ '' AST_OP_STACKALIGN
164  (AST_NODECLASS_BRANCH, AST_OPFLAGS_NONE, @"jeq" ), _ '' AST_OP_JEQ
165  (AST_NODECLASS_BRANCH, AST_OPFLAGS_NONE, @"jgt" ), _ '' AST_OP_JGT
166  (AST_NODECLASS_BRANCH, AST_OPFLAGS_NONE, @"jlt" ), _ '' AST_OP_JLT
167  (AST_NODECLASS_BRANCH, AST_OPFLAGS_NONE, @"jne" ), _ '' AST_OP_JNE
168  (AST_NODECLASS_BRANCH, AST_OPFLAGS_NONE, @"jge" ), _ '' AST_OP_JGE
169  (AST_NODECLASS_BRANCH, AST_OPFLAGS_NONE, @"jle" ), _ '' AST_OP_JLE
170  (AST_NODECLASS_BRANCH, AST_OPFLAGS_NONE, @"jmp" ), _ '' AST_OP_JMP
171  (AST_NODECLASS_BRANCH, AST_OPFLAGS_NONE, @"call" ), _ '' AST_OP_CALL
172  (AST_NODECLASS_BRANCH, AST_OPFLAGS_NONE, @"lbl" ), _ '' AST_OP_LABEL
173  (AST_NODECLASS_BRANCH, AST_OPFLAGS_NONE, @"ret" ), _ '' AST_OP_RET
174  (AST_NODECLASS_CALL , AST_OPFLAGS_NONE, @"calf" ), _ '' AST_OP_CALLFUNC
175  (AST_NODECLASS_CALL , AST_OPFLAGS_NONE, @"calp" ), _ '' AST_OP_CALLPTR
176  (AST_NODECLASS_CALL , AST_OPFLAGS_NONE, @"jmpp" ), _ '' AST_OP_JUMPPTR
177  (AST_NODECLASS_MEM , AST_OPFLAGS_NONE, @"mmov" ), _ '' AST_OP_MEMMOVE
178  (AST_NODECLASS_MEM , AST_OPFLAGS_NONE, @"mswp" ), _ '' AST_OP_MEMSWAP
179  (AST_NODECLASS_MEM , AST_OPFLAGS_NONE, @"mclr" ), _ '' AST_OP_MEMCLEAR
180  (AST_NODECLASS_MEM , AST_OPFLAGS_NONE, @"stkc" ), _ '' AST_OP_STKCLEAR
181  (AST_NODECLASS_DBG , AST_OPFLAGS_NONE, @"lini" ), _ '' AST_OP_DBG_LINEINI
182  (AST_NODECLASS_DBG , AST_OPFLAGS_NONE, @"lend" ), _ '' AST_OP_DBG_LINEEND
183  (AST_NODECLASS_DBG , AST_OPFLAGS_NONE, @"sini" ), _ '' AST_OP_DBG_SCOPEINI
184  (AST_NODECLASS_DBG , AST_OPFLAGS_NONE, @"send" ), _ '' AST_OP_DBG_SCOPEEND
185  (AST_NODECLASS_LIT , AST_OPFLAGS_NONE, @"rem" ), _ '' AST_OP_LIT_COMMENT
186  (AST_NODECLASS_LIT , AST_OPFLAGS_NONE, @"asm" ) _ '' AST_OP_ASM
187 }
188 
189 dim shared as uinteger ast_bitmaskTB( 0 to ... ) = _
190 { _
191  0, _
192  1, 3, 7, 15, 31, 63, 127, 255, _
193  511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, _
194  131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, _
195  33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647, 4294967295 _
196 }
197 
198 sub astInit( )
199  listInit( @ast.astTB, AST_INITNODES, len( ASTNODE ), LIST_FLAGS_NOCLEAR )
200 
201  ast.doemit = TRUE
202  ast.typeinicount = 0
203  ast.bitfieldcount = 0
204  ast.currblock = NULL
205  ast.warn_convoverflow = TRUE
206 
207  astCallInit( )
208  astProcListInit( )
209  astDataStmtInit( )
210  astMiscInit( )
211 
212  listInit( @ast.asmtoklist, 16, sizeof( ASTASMTOK ), LIST_FLAGS_NOCLEAR )
213 end sub
214 
215 sub astEnd( )
216  listEnd( @ast.asmtoklist )
217 
218  astMiscEnd( )
219  astProcListEnd( )
220  astCallEnd( )
221 
222  listEnd( @ast.astTB )
223 end sub
224 
225 function astCloneTree( byval n as ASTNODE ptr ) as ASTNODE ptr
226  '' note: never clone a tree with side-effects (ie: function call nodes)
227 
228  dim as ASTNODE ptr c = any, t = any
229 
230  ''
231  if( n = NULL ) then
232  return NULL
233  end if
234 
235  ''
236  c = astNewNode( INVALID, FB_DATATYPE_INVALID )
237  astCopy( c, n )
238 
239  '' walk
240  t = n->l
241  if( t <> NULL ) then
242  c->l = astCloneTree( t )
243  end if
244 
245  t = n->r
246  if( t <> NULL ) then
247  c->r = astCloneTree( t )
248  end if
249 
250  select case( n->class )
251  case AST_NODECLASS_VAR
252  '' When cloning a temp VAR access, the AST dtorlist must be
253  '' told about the additional reference
254  if( c->sym ) then
255  if( symbIsVar( c->sym ) and symbIsTemp( c->sym ) ) then
256  astDtorListAddRef( c->sym )
257  end if
258  end if
259 
260  '' call nodes are too complex, let a helper function clone it
261  case AST_NODECLASS_CALL
262  astCloneCALL( n, c )
263 
264  '' IIF nodes have labels, that can't be just cloned or you get dupes
265  '' at the assembler.
266  case AST_NODECLASS_IIF
267  astReplaceSymbolOnTree( c, c->iif.falselabel, symbAddLabel( NULL ) )
268 
269  case AST_NODECLASS_LOOP
270  astReplaceSymbolOnTree( c, c->op.ex, symbAddLabel( NULL ) )
271 
272  case AST_NODECLASS_TYPEINI
273  ast.typeinicount += 1
274 
275  '' The scope that some TYPEINI have is not duplicated,
276  '' much less the temp vars (astTypeIniClone() should be used
277  '' for that), so better not leave a dangling pointer...
278  c->typeini.scp = NULL
279 
280  case AST_NODECLASS_FIELD
281  if( astGetDataType( c->l ) = FB_DATATYPE_BITFIELD ) then
282  ast.bitfieldcount += 1
283  end if
284 
285 #if __FB_DEBUG__
286  case AST_NODECLASS_LIT, AST_NODECLASS_JMPTB
287  '' These nodes contain dynamically allocated memory,
288  '' which currently isn't handled here
289  assert( FALSE )
290 #endif
291 
292  end select
293 
294  function = c
295 end function
296 
297 '':::::
298 function astRemSideFx( byref n as ASTNODE ptr ) as ASTNODE ptr
299  '' note: this should only be done with VAR, IDX, PTR and FIELD nodes
300 
301  dim as FBSYMBOL ptr tmp = any, subtype = any
302  dim as integer dtype = any
303  dim as ASTNODE ptr t = any
304 
305  '' Handle string concatenation here. Since the expression will be taken
306  '' out of its original context (e.g. string ASSIGN or ARG), we are now
307  '' responsible for doing this.
308  n = astUpdStrConcat( n )
309 
310  dtype = astGetFullType( n )
311  subtype = astGetSubType( n )
312 
313  select case as const typeGet( dtype )
314  '' complex type? convert to pointer..
315  case FB_DATATYPE_STRUCT, _ ' FB_DATATYPE_CLASS
316  FB_DATATYPE_STRING, FB_DATATYPE_FIXSTR, FB_DATATYPE_CHAR, FB_DATATYPE_WCHAR
317 
318  tmp = symbAddTempVar( typeAddrOf( dtype ), subtype )
319 
320  '' tmp = @b
321  function = astNewASSIGN( astNewVAR( tmp ), astNewADDROF( n ) )
322 
323  '' repatch original expression to just *tmp
324  n = astNewDEREF( astNewVAR( tmp ) )
325 
326  '' simple type..
327  case else
328  tmp = symbAddTempVar( dtype, subtype )
329 
330  '' tmp = n
331  function = astNewASSIGN( astNewVAR( tmp ), n )
332 
333  '' repatch original expression to just access the temp var
334  n = astNewVAR( tmp )
335 
336  end select
337 end function
338 
339 '':::::
340 sub astDelTree _
341  ( _
342  byval n as ASTNODE ptr _
343  )
344 
345  dim as ASTNODE ptr t = any
346 
347  ''
348  if( n = NULL ) then
349  exit sub
350  end if
351 
352  '' call nodes are too complex, let a helper function del it
353  if( n->class = AST_NODECLASS_CALL ) then
354  astDelCALL( n )
355  end if
356 
357  '' walk
358  t = n->l
359  if( t <> NULL ) then
360  astDelTree( t )
361  end if
362 
363  t = n->r
364  if( t <> NULL ) then
365  astDelTree( t )
366  end if
367 
368  ''
369  astDelNode( n )
370 
371 end sub
372 
373 '':::::
374 function astNewNode _
375  ( _
376  byval class_ as integer, _
377  byval dtype as integer, _
378  byval subtype as FBSYMBOL ptr _
379  ) as ASTNODE ptr
380 
381  dim as ASTNODE ptr n = listNewNode( @ast.astTB )
382 
383  astInitNode( n, class_, dtype, subtype )
384 
385  function = n
386 
387 end function
388 
389 '':::::
390 sub astDelNode _
391  ( _
392  byval n as ASTNODE ptr _
393  ) static
394 
395  if( n = NULL ) then
396  exit sub
397  end if
398 
399  if( astIsVAR( n ) ) then
400  if( n->sym ) then
401  if( symbIsVar( n->sym ) and symbIsTemp( n->sym ) ) then
402  astDtorListRemoveRef( n->sym )
403  end if
404  end if
405  end if
406 
407  listDelNode( @ast.astTB, n )
408 
409 end sub
410 
411 '':::::
412 function astGetInverseLogOp _
413  ( _
414  byval op as integer _
415  ) as integer static
416 
417  select case as const op
418  case AST_OP_EQ
419  op = AST_OP_NE
420  case AST_OP_NE
421  op = AST_OP_EQ
422  case AST_OP_GT
423  op = AST_OP_LE
424  case AST_OP_LT
425  op = AST_OP_GE
426  case AST_OP_GE
427  op = AST_OP_LT
428  case AST_OP_LE
429  op = AST_OP_GT
430  end select
431 
432  function = op
433 
434 end function
435 
436 function astLoad( byval n as ASTNODE ptr ) as IRVREG ptr
437  if( n ) then
438  function = ast_loadcallbacks(n->class)( n )
439  end if
440 end function
441