FreeBASIC  0.91.0
symb-label.bas
Go to the documentation of this file.
1 '' symbol table module for labels
2 ''
3 '' chng: sep/2004 written [v1ctor]
4 '' jan/2005 updated to use real linked-lists [v1ctor]
5 
6 
7 #include once "fb.bi"
8 #include once "fbint.bi"
9 #include once "parser.bi"
10 #include once "hash.bi"
11 #include once "list.bi"
12 #include once "lex.bi"
13 
14 '':::::
15 function symbAddLabel _
16  ( _
17  byval symbol as zstring ptr, _
18  byval options as FB_SYMBOPT _
19  ) as FBSYMBOL ptr
20 
21  dim as zstring ptr id = any, id_alias = any
22  dim as FBSYMBOL ptr l = any
23  dim as FBSYMBOLTB ptr symtb = any
24  dim as FBHASHTB ptr hashtb = any
25  dim as integer isglobal = any
26 
27  function = NULL
28 
29  if( symbol <> NULL ) then
30  '' check if label already exists
31  l = symbLookupByNameAndClass( symbGetCurrentNamespc( ), _
32  symbol, _
33  FB_SYMBCLASS_LABEL, _
34  FALSE )
35  if( l <> NULL ) then
36  if( (options and FB_SYMBOPT_DECLARING) <> 0 ) then
37  '' dup definition?
38  if( l->lbl.declared ) then
39  exit function
40  end if
41 
42  '' set the right values
43  l->lbl.declared = TRUE
44  l->lbl.parent = parser.currblock
45  l->lbl.stmtnum = parser.stmt.cnt
46  l->scope = parser.scope
47  return l
48 
49  else
50  return l
51  end if
52  end if
53 
54  '' add the new label
55  if( (options and FB_SYMBOPT_CREATEALIAS) = 0 ) then
56  id_alias = symbol
57  else
58  id_alias = symbUniqueLabel( )
59  end if
60 
61  id = symbol
62  else
63  id = NULL
64  id_alias = symbUniqueLabel( )
65  end if
66 
67  if( (options and FB_SYMBOPT_MOVETOGLOB) <> 0 ) then
68  isglobal = TRUE
69 
70  symtb = @symbGetGlobalTb( )
71  hashtb = @symbGetGlobalHashTb( )
72 
73  else
74  '' parsing main? add to global tb
75  if( fbIsModLevel( ) ) then
76  isglobal = TRUE
77 
78  '' unless inside a namespace..
79  if( symbIsGlobalNamespc() = FALSE ) then
80  symtb = symb.symtb
81  hashtb = symb.hashtb
82  else
83  symtb = @symbGetGlobalTb( )
84  hashtb = @symbGetGlobalHashTb( )
85  end if
86 
87  '' otherside the current proc sym table must be used, not the
88  '' current scope because labels inside scopes are unique,
89  '' and branching to them from other scopes must be allowed
90  else
91  isglobal = FALSE
92 
93  symtb = @parser.currproc->proc.symtb
94  hashtb = symb.hashtb
95  end if
96  end if
97 
98  l = symbNewSymbol( iif( symbol = NULL, FB_SYMBOPT_NONE, FB_SYMBOPT_DOHASH ), _
99  NULL, _
100  symtb, hashtb, _
101  FB_SYMBCLASS_LABEL, _
102  id, id_alias, _
103  FB_DATATYPE_INVALID, NULL, _
104  iif( isglobal, FB_SYMBATTRIB_NONE, FB_SYMBATTRIB_LOCAL ) )
105  if( l = NULL ) then
106  exit function
107  end if
108 
109  if( (options and FB_SYMBOPT_DECLARING) <> 0 ) then
110  '' label parent won't be the current proc block as
111  '' it's been defined inside a scope block
112  l->lbl.parent = parser.currblock
113  l->lbl.stmtnum = parser.stmt.cnt
114 
115  l->lbl.declared = TRUE
116  else
117  l->lbl.declared = FALSE
118  end if
119 
120  function = l
121 
122 end function
123 
124 '':::::
125 function symbCloneLabel _
126  ( _
127  byval sym as FBSYMBOL ptr _
128  ) as FBSYMBOL ptr
129 
130  function = symbAddLabel( NULL )
131 
132 end function
133 
134 '':::::
135 sub symbDelLabel _
136  ( _
137  byval s as FBSYMBOL ptr _
138  )
139 
140  if( s = NULL ) then
141  exit sub
142  end if
143 
144  symbFreeSymbol( s )
145 
146 end sub
147 
148 function symbCheckLabels _
149  ( _
150  byval symtbhead as FBSYMBOL ptr _
151  ) as integer
152 
153  dim as integer count = 0
154 
155  '' Check for any undeclared labels
156  dim as FBSYMBOL ptr s = symtbhead
157  while (s)
158  if (s->class = FB_SYMBCLASS_LABEL) then
159  if (s->lbl.declared = FALSE) then
160  if (symbGetName(s)) then
161  errReportEx(FB_ERRMSG_UNDEFINEDLABEL, *symbGetName(s), -1)
162  count += 1
163  end if
164  end if
165  end if
166  s = s->next
167  wend
168 
169  return count
170 end function
171