FreeBASIC  0.91.0
parser-inlineasm.bas
Go to the documentation of this file.
1 '' inline asm parsing
2 ''
3 '' chng: sep/2004 written [v1ctor]
4 
5 
6 #include once "fb.bi"
7 #include once "fbint.bi"
8 #include once "list.bi"
9 #include once "parser.bi"
10 #include once "ast.bi"
11 #include once "emit.bi"
12 
14 
15 '':::::
16 ''AsmCode = (Text !(END|Comment|NEWLINE))*
17 ''
18 sub cAsmCode()
19  static as zstring * FB_MAXLITLEN+1 text
20  dim as FBSYMCHAIN ptr chain_ = any
21  dim as FBSYMBOL ptr sym = any
22  dim as ASTNODE ptr expr = any
23  dim as ASTASMTOK ptr head = any, tail = any
24  dim as integer doskip = any, thisTok = any
25 
26  head = NULL
27  tail = NULL
28  do
29  '' !(END|Comment|NEWLINE)
30  thisTok = lexGetToken( LEX_FLAGS )
31  select case as const thisTok
32  case FB_TK_END, FB_TK_EOL, FB_TK_COMMENT, FB_TK_REM, FB_TK_EOF
33  exit do
34  end select
35 
36  text = *lexGetText( )
37  sym = NULL
38  doskip = FALSE
39 
40  select case as const lexGetClass( LEX_FLAGS )
41 
42  '' id?
43  case FB_TKCLASS_IDENTIFIER, FB_TKCLASS_QUIRKWD
44  if thistok = FB_TK_SIZEOF then
45  '' SIZEOF( valid expression )?
46  expr = cMathFunct( thisTok, TRUE )
47  if( expr ) then
48  '' constant expression?
49  if( astIsCONST( expr ) ) then
50  '' text replacement
51  text = astConstFlushToStr( expr )
52  else
53  errReport( FB_ERRMSG_EXPECTEDCONST )
54  '' skip emission
55  doskip = TRUE
56  end if
57  else
58  errReport( FB_ERRMSG_SYNTAXERROR )
59  '' skip emission
60  doskip = TRUE
61  end if
62 
63  elseif( (env.clopt.backend = FB_BACKEND_GCC) orelse emitIsKeyword( lcase(text) ) = FALSE ) then
64  dim as FBSYMBOL ptr base_parent = any
65 
66  chain_ = cIdentifier( base_parent )
67  do while( chain_ <> NULL )
68  dim as FBSYMBOL ptr s = chain_->sym
69  do
70  select case symbGetClass( s )
71  case FB_SYMBCLASS_PROC, FB_SYMBCLASS_LABEL
72  sym = s
73  exit do, do
74 
75  '' const?
76  case FB_SYMBCLASS_CONST
77  text = symbGetConstValueAsStr( s )
78  exit do, do
79 
80  case FB_SYMBCLASS_VAR
81  '' var?
82  sym = symbFindByClass( chain_, FB_SYMBCLASS_VAR )
83 
84  if( sym <> NULL ) then
85  symbSetIsAccessed( sym )
86  end if
87  exit do, do
88 
89  end select
90 
91  s = s->hash.next
92  loop while( s <> NULL )
93 
94  chain_ = symbChainGetNext( chain_ )
95  loop
96  end if
97 
98  '' lit number?
99  case FB_TKCLASS_NUMLITERAL
100  expr = cNumLiteral( FALSE )
101  if( expr <> NULL ) then
102  text = astConstFlushToStr( expr )
103  end if
104 
105  '' lit string?
106  case FB_TKCLASS_STRLITERAL
107  expr = cStrLiteral( FALSE )
108  if( expr <> NULL ) then
109  dim as FBSYMBOL ptr litsym = astGetStrLitSymbol( expr )
110  if( litsym <> NULL ) then
111  text = """"
112  if( symbGetType( litsym ) <> FB_DATATYPE_WCHAR ) then
113  text += *symbGetVarLitText( litsym )
114  else
115  text += *symbGetVarLitTextW( litsym )
116  end if
117  text += """"
118  end if
119 
120  astDelTree( expr )
121  end if
122 
123  ''
124  case FB_TKCLASS_KEYWORD
125  select case thisTok
126  case FB_TK_FUNCTION
127  '' FUNCTION?
128  sym = symbGetProcResult( parser.currproc )
129  if( sym = NULL ) then
130  errReport( FB_ERRMSG_SYNTAXERROR )
131  doskip = TRUE
132  else
133  symbSetIsAccessed( sym )
134  end if
135 
136  case FB_TK_CINT
137  '' CINT( valid expression )?
138  expr = cTypeConvExpr( thisTok, TRUE )
139  if( expr <> NULL ) then
140  '' constant expression?
141  if( astIsCONST( expr ) ) then
142  '' text replacement
143  text = astConstFlushToStr( expr )
144  else
145  errReport( FB_ERRMSG_EXPECTEDCONST )
146  '' skip emission
147  doskip = TRUE
148  end if
149  else
150  errReport( FB_ERRMSG_SYNTAXERROR )
151  '' skip emission
152  doskip = TRUE
153  end if
154  end select
155  end select
156 
157  ''
158  if( doskip = FALSE ) then
159  if( sym ) then
160  tail = astAsmAppendSymb( tail, sym )
161  else
162  tail = astAsmAppendText( tail, text )
163  end if
164  if( head = NULL ) then
165  head = tail
166  end if
167  end if
168 
170  loop
171 
172  '' One ASM node per line of asm, with as many asm tokens as needed each
173  if( head <> NULL ) then
174  astAdd( astNewASM( head ) )
175  end if
176 end sub
177 
178 '':::::
179 ''AsmBlock = ASM Comment? SttSeparator
180 '' (AsmCode Comment? NewLine)+
181 '' END ASM .
182 function cAsmBlock as integer
183  dim as integer issingleline = any
184 
185  function = FALSE
186 
187  '' ASM?
188  if( lexGetToken( ) <> FB_TK_ASM ) then
189  exit function
190  end if
191 
192  if( cCompStmtIsAllowed( FB_CMPSTMT_MASK_CODE ) = FALSE ) then
193  '' error recovery: skip the whole compound stmt
194  hSkipCompound( FB_TK_ASM )
195  exit function
196  end if
197 
198  lexSkipToken( )
199 
200  '' (Comment SttSeparator)?
201  issingleline = FALSE
202  if( cComment( ) ) then
203  '' emit the current line in text form
204  hEmitCurrLine( )
205 
206  if( cStmtSeparator( ) = FALSE ) then
207  errReport( FB_ERRMSG_EXPECTEDEOL )
208  '' error recovery: skip until next line
209  hSkipUntil( FB_TK_EOL, TRUE )
210  end if
211  else
212  if( cStmtSeparator( ) = FALSE ) then
213  issingleline = TRUE
214  end if
215  end if
216 
217  '' (AsmCode Comment? NewLine)+
218  do
219  if( issingleline = FALSE ) then
220  astAdd( astNewDBG( AST_OP_DBG_LINEINI, lexLineNum( ) ) )
221  end if
222 
223  cAsmCode( )
224 
225  '' Comment?
227 
228  '' emit the current line in text form
229  hEmitCurrLine( )
230 
231  '' NewLine
232  select case lexGetToken( )
233  case FB_TK_EOL
234  if( issingleline ) then
235  exit do
236  end if
237 
238  lexSkipToken( )
239 
240  case FB_TK_EOF
241  exit do
242 
243  case FB_TK_END
244  exit do
245 
246  case else
247  errReport( FB_ERRMSG_EXPECTEDEOL )
248  '' error recovery: skip until next line
249  hSkipUntil( FB_TK_EOL, TRUE )
250  end select
251 
252  if( issingleline = FALSE ) then
253  astAdd( astNewDBG( AST_OP_DBG_LINEEND ) )
254  end if
255  loop
256 
257  if( issingleline = FALSE ) then
258  '' END ASM
259  if( hMatch( FB_TK_END ) = FALSE ) then
260  errReport( FB_ERRMSG_EXPECTEDENDASM )
261  elseif( hMatch( FB_TK_ASM ) = FALSE ) then
262  errReport( FB_ERRMSG_EXPECTEDENDASM )
263  end if
264  end if
265 
266  function = TRUE
267 
268 end function
269