FreeBASIC  0.91.0
parser-quirk-gfx.bas
Go to the documentation of this file.
1 '' quirk graphic statements and functions (SCREEN, PSET, LINE, ...) parsing
2 ''
3 '' chng: dec/2004 written [v1ctor]
4 
5 
6 #include once "fb.bi"
7 #include once "fbint.bi"
8 #include once "parser.bi"
9 #include once "rtl.bi"
10 #include once "ast.bi"
11 
15 
22 
23 const FBGFX_DEFAULT_COLOR_FLAG = &h80000000
24 const FBGFX_DEFAULT_AUX_COLOR_FLAG = &h40000000
25 const FBGFX_VIEW_SCREEN_FLAG = &h00000001
26 
27 '' match, not using a token, but a raw text value
28 '':::::
29 function hMakeArrayIndex _
30  ( _
31  byval sym as FBSYMBOL ptr, _
32  byval varexpr as ASTNODE ptr _
33  ) as ASTNODE ptr
34 
35  dim as ASTNODE ptr idxexpr, dataOffset
36 
37  '' field? (assuming field arrays can't be dynamic)
38  if( astIsFIELD( varexpr ) ) then
39  return varexpr
40  end if
41 
42  '' argument passed by descriptor?
43  if( symbIsParamByDesc( sym ) ) then
44  '' deref descriptor->data
45  idxexpr = astNewDEREF( astNewVAR( sym, 0, FB_DATATYPE_INTEGER ), _
46  FB_DATATYPE_INTEGER, NULL, symb.fbarray_data )
47 
48  '' descriptor->dimTB(0).lBound
49  dataOffset = astNewDEREF( astNewVAR( sym, 0, FB_DATATYPE_INTEGER ), _
50  FB_DATATYPE_INTEGER, NULL, _
51  symb.fbarray_dimtb + symb.fbarraydim_lbound )
52 
53  '' lBound * elemLen
54  dataOffset = astNewBOP( AST_OP_MUL, _
55  dataOffset, _
56  astNewCONSTi( symbGetLen( sym ), FB_DATATYPE_UINT ) )
57 
58  '' add above to data ptr
59  idxexpr = astNewBOP( AST_OP_ADD, idxexpr, dataOffset )
60 
61  '' ...
62  astNewLOAD( idxexpr, FB_DATATYPE_INTEGER )
63 
64  '' can't reuse varexpr
65  astDelTree( varexpr )
66  varexpr = astNewVAR( sym, 0, FB_DATATYPE_INTEGER )
67 
68  '' dynamic array? (this will handle common's too)
69  elseif( symbGetIsDynamic( sym ) ) then
70  '' deref descriptor.data
71  idxexpr = astNewVAR( symbGetArrayDescriptor( sym ), _
72  symb.fbarray_data, FB_DATATYPE_INTEGER )
73 
74  '' descriptor->dimTB(0).lBound
75  dataOffset = astNewVAR( symbGetArrayDescriptor( sym ), _
76  symb.fbarray_dimtb + symb.fbarraydim_lbound, _
77  FB_DATATYPE_INTEGER )
78 
79  '' lBound * elemLen
80  dataOffset = astNewBOP( AST_OP_MUL, _
81  dataOffset, _
82  astNewCONSTi( symbGetLen( sym ), FB_DATATYPE_UINT ) )
83 
84  '' add above to data ptr
85  idxexpr = astNewBOP( AST_OP_ADD, idxexpr, dataOffset )
86 
87  '' ...
88  idxexpr = astNewLOAD( idxexpr, FB_DATATYPE_INTEGER )
89 
90  '' static array..
91  else
92 
93  idxexpr = astNewBOP( AST_OP_MUL, _
94  astNewCONSTi( symbGetArrayFirstDim( sym )->lower ), _
95  astNewCONSTi( symbCalcLen( astGetDataType( varexpr ), _
96  astGetSubType( varexpr ) ), FB_DATATYPE_UINT ) )
97 
98  end if
99 
100  function = astNewIDX( varexpr, idxexpr, _
101  astGetFullType( varexpr ), astGetSubType( varexpr ) )
102 
103 end function
104 
105 '':::::
106 function hGetTarget _
107  ( _
108  byref expr as ASTNODE ptr, _
109  byref isptr as integer, _
110  byval allow_const as integer = FALSE _
111  ) as FBSYMBOL ptr
112 
113  dim as FBSYMBOL ptr s = any
114  dim as integer nidx_array = FALSE
115 
116  function = NULL
117 
118  isptr = FALSE
119  expr = NULL
120 
121  if( lexGetToken( ) = CHAR_LPRNT ) then
122  exit function
123  end if
124 
125  '' flag it as an expression so
126  '' properties don't get confused
127  expr = cVarOrDeref( FB_VAREXPROPT_NOARRAYCHECK or FB_VAREXPROPT_ALLOWADDROF or FB_VAREXPROPT_ISEXPR )
128  if( expr = NULL ) then
129  exit function
130  end if
131 
132  '' remove any casting if they won't do any conversion
133  if( astIsCAST( expr ) ) then
134  if( astGetCASTDoConv( expr ) = FALSE ) then
135  dim as ASTNODE ptr l = astGetLeft( expr )
136  astDelNode( expr )
137  expr = l
138  end if
139  end if
140 
141  select case as const astGetClass( expr )
142  '' ugly hack to deal with arrays w/o indexes
143  case AST_NODECLASS_NIDXARRAY
144  nidx_array = TRUE
145  dim as ASTNODE ptr arrayexpr = astGetLeft( expr )
146  astDelNode( expr )
147  s = astGetSymbol( arrayexpr )
148  expr = hMakeArrayIndex( s, arrayexpr )
149 
150  '' address-of or pointer deref?
151  case AST_NODECLASS_ADDROF, AST_NODECLASS_OFFSET, _
152  AST_NODECLASS_DEREF, AST_NODECLASS_BOP
153 
154  isptr = TRUE
155  s = NULL
156 
157  '' var, idx, ...
158  case else
159  s = astGetSymbol( expr )
160  if( s = NULL ) then
161  '' pointer?
162  if( typeIsPtr( astGetDataType( expr ) ) ) then
163  isptr = TRUE
164  return NULL
165  else
166  exit function
167  end if
168  end if
169 
170  '' ptr?
171  isptr = typeIsPtr( symbGetType( s ) )
172 
173  '' array?
174  if( symbIsArray( s ) ) then
175  '' no index given?
176  if( astIsIDX( expr ) = FALSE ) then
177  expr = hMakeArrayIndex( s, expr )
178  end if
179 
180  '' not a ptr? fail..
181  elseif( isptr = FALSE ) then
182  exit function
183  end if
184 
185  end select
186 
187  '' don't allow a pointer to a const...
188  if( allow_const = FALSE ) then
189  if( (typeGetConstMask( astGetFullType( expr ) ) and (1 shl (FB_DT_CONSTPOS + iif( nidx_array, 0, 1 )))) ) then
190  errReport( FB_ERRMSG_CONSTANTCANTBECHANGED, TRUE )
191  exit function
192  end if
193  end if
194 
195  function = s
196 
197 end function
198 
199 '':::::
200 function hGetMode _
201  ( _
202  byref mode as integer, _
203  byref alphaexpr as ASTNODE ptr, _
204  byref funcexpr as ASTNODE ptr, _
205  byref paramexpr as ASTNODE ptr _
206  ) as integer
207 
208  dim as FBSYMBOL ptr s, arg1, arg2, arg3
209 
210  function = FALSE
211 
212  select case as const lexGetToken
213 
214  case FB_TK_AND
216  mode = FBGFX_PUTMODE_AND
217 
218  case FB_TK_OR
220  mode = FBGFX_PUTMODE_OR
221 
222  case FB_TK_XOR
224  mode = FBGFX_PUTMODE_XOR
225 
226  case else
227  select case ucase( *lexGetText( ) )
228  case "PSET"
229  lexSkipToken( )
230  mode = FBGFX_PUTMODE_PSET
231 
232  case "PRESET"
233  lexSkipToken( )
234  mode = FBGFX_PUTMODE_PRESET
235 
236  case "TRANS"
237  lexSkipToken( )
238  mode = FBGFX_PUTMODE_TRANS
239 
240  case "ADD"
241  lexSkipToken( )
242  mode = FBGFX_PUTMODE_ADD
243 
244  if( hMatch( CHAR_COMMA ) ) then
245  hMatchExpression( alphaexpr )
246  else
247  alphaexpr = astNewCONSTi( 255, FB_DATATYPE_UINT )
248  end if
249 
250  case "ALPHA"
251  lexSkipToken( )
252  mode = FBGFX_PUTMODE_ALPHA
253 
254  if( hMatch( CHAR_COMMA ) ) then
255  hMatchExpression( alphaexpr )
256  mode = FBGFX_PUTMODE_BLEND
257  end if
258 
259  case "CUSTOM"
260  lexSkipToken( )
261 
262  mode = FBGFX_PUTMODE_CUSTOM
263 
264  hMatchCOMMA( )
265 
266  hMatchExpression( funcexpr )
267 
268  if( hMatch( CHAR_COMMA ) ) then
269  hMatchExpression( paramexpr )
270  end if
271 
272  s = astGetSubType( funcexpr )
273  if( s = NULL ) then
274  errReport( FB_ERRMSG_TYPEMISMATCH )
275  exit function
276  end if
277  if( symbIsProc( s ) = FALSE ) then
278  errReport( FB_ERRMSG_TYPEMISMATCH )
279  exit function
280  end if
281  if( ( symbGetType( s ) <> FB_DATATYPE_UINT ) or _
282  ( symbGetProcParams( s ) <> 3 ) ) then
283  errReport( FB_ERRMSG_TYPEMISMATCH )
284  exit function
285  end if
286 
287  arg1 = symbGetProcHeadParam( s )
288 
289  arg2 = symbGetParamNext( arg1 )
290 
291  arg3 = symbGetParamNext( arg2 )
292 
293  if( symbGetProcMode( s ) = FB_FUNCMODE_PASCAL ) then
294  swap arg1, arg3
295  end if
296 
297  if( ( symbGetType( arg1 ) <> FB_DATATYPE_UINT ) or _
298  ( symbGetType( arg2 ) <> FB_DATATYPE_UINT ) or _
299  ( typeIsPtr( symbGetType( arg3 ) ) = FALSE ) or _
300  ( arg1->param.mode <> FB_PARAMMODE_BYVAL ) or _
301  ( arg2->param.mode <> FB_PARAMMODE_BYVAL ) or _
302  ( arg3->param.mode <> FB_PARAMMODE_BYVAL ) ) then
303  errReport( FB_ERRMSG_TYPEMISMATCH )
304  exit function
305  end if
306 
307  case else
308  errReport( FB_ERRMSG_SYNTAXERROR )
309  exit function
310  end select
311  end select
312 
313  function = TRUE
314 
315 end function
316 
317 '':::::
318 '' GfxPset = PSET ( Expr ',' )? STEP? '(' Expr ',' Expr ')' (',' Expr )?
319 ''
320 function cGfxPset( byval ispreset as integer ) as integer
321  dim as integer flags, tisptr
322  dim as ASTNODE ptr xexpr, yexpr, cexpr, texpr
323  dim as FBSYMBOL ptr target
324 
325  function = FALSE
326 
327  '' ( Expr ',' )?
328  target = hGetTarget( texpr, tisptr )
329  if( (target <> NULL) or (tisptr) ) then
330  hMatchCOMMA( )
331  end if
332 
333  '' STEP?
334  if( hMatch( FB_TK_STEP ) ) then
335  flags = FBGFX_COORDTYPE_R
336  else
337  flags = FBGFX_COORDTYPE_A
338  end if
339 
340  '' '(' Expr ',' Expr ')'
341  hMatchLPRNT( )
342 
343  hMatchExpression( xexpr )
344 
345  hMatchCOMMA( )
346 
347  hMatchExpression( yexpr )
348 
349  hMatchRPRNT( )
350 
351  '' (',' Expr )?
352  if( hMatch( CHAR_COMMA ) ) then
353  hMatchExpression( cexpr )
354  else
355  cexpr = astNewCONSTi( 0, FB_DATATYPE_UINT )
356  flags or= FBGFX_DEFAULT_COLOR_FLAG
357  end if
358 
359  ''
360  function = rtlGfxPset( texpr, tisptr, xexpr, yexpr, cexpr, flags, ispreset )
361 
362 end function
363 
364 '':::::
365 '' LINE ( Expr ',' )? STEP? ('(' Expr ',' Expr ')')? '-' STEP? '(' Expr ',' Expr ')' (',' Expr? (',' LIT_STRING? (',' Expr )?)?)?
366 ''
367 function cGfxLine as integer
368  dim as integer flags, linetype, tisptr
369  dim as ASTNODE ptr styleexpr, x1expr, y1expr, x2expr, y2expr, cexpr, texpr
370  dim as FBSYMBOL ptr target
371 
372  function = FALSE
373 
374  '' '-'?
375  if( hMatch( CHAR_MINUS ) ) then
376 
377  flags = FBGFX_COORDTYPE_R
378  x1expr = astNewCONSTf( 0, FB_DATATYPE_SINGLE )
379  y1expr = astNewCONSTf( 0, FB_DATATYPE_SINGLE )
380 
381  else
382 
383  '' ( Expr ',' )?
384  target = hGetTarget( texpr, tisptr )
385  if( (target <> NULL) or (tisptr) ) then
386  hMatchCOMMA( )
387  end if
388 
389  '' STEP?
390  if( hMatch( FB_TK_STEP ) ) then
391  flags = FBGFX_COORDTYPE_R
392  else
393  flags = FBGFX_COORDTYPE_A
394  end if
395 
396  '' ('(' Expr ',' Expr ')')?
397  if( hMatch( CHAR_LPRNT ) ) then
398 
399  hMatchExpression( x1expr )
400 
401  hMatchCOMMA( )
402 
403  hMatchExpression( y1expr )
404 
405  hMatchRPRNT( )
406 
407  else
408  flags = FBGFX_COORDTYPE_R
409  x1expr = astNewCONSTf( 0, FB_DATATYPE_SINGLE )
410  y1expr = astNewCONSTf( 0, FB_DATATYPE_SINGLE )
411  end if
412 
413  '' '-'
414  if( hMatch( CHAR_MINUS ) = FALSE ) then
415  errReport( FB_ERRMSG_EXPECTEDMINUS )
416  exit function
417  end if
418 
419  end if
420 
421  '' STEP?
422  if( hMatch( FB_TK_STEP ) ) then
423  if( flags = FBGFX_COORDTYPE_R ) then
424  flags = FBGFX_COORDTYPE_RR
425  else
426  flags = FBGFX_COORDTYPE_AR
427  end if
428  else
429  if( flags = FBGFX_COORDTYPE_R ) then
430  flags = FBGFX_COORDTYPE_RA
431  else
432  flags = FBGFX_COORDTYPE_AA
433  end if
434  end if
435 
436  '' '(' Expr ',' Expr ')'
437  hMatchLPRNT( )
438 
439  hMatchExpression( x2expr )
440 
441  hMatchCOMMA( )
442 
443  hMatchExpression( y2expr )
444 
445  hMatchRPRNT( )
446 
447  linetype = FBGFX_LINETYPE_LINE
448  styleexpr = NULL
449 
450  '' (',' Expr? (',' LIT_STRING? (',' Expr )?)?)?
451  if( hMatch( CHAR_COMMA ) ) then
452  cexpr = cExpression( )
453  if( cexpr = NULL ) then
454  cexpr = astNewCONSTi( 0, FB_DATATYPE_UINT )
455  flags or= FBGFX_DEFAULT_COLOR_FLAG
456  end if
457 
458  '' ',' LIT_STRING? - linetype
459  if( hMatch( CHAR_COMMA ) ) then
460  select case ucase( *lexGetText( ) )
461  case "B"
462  lexSkipToken( )
463  linetype = FBGFX_LINETYPE_B
464  case "BF"
465  lexSkipToken( )
466  linetype = FBGFX_LINETYPE_BF
467  end select
468 
469  '' (',' Expr )? - style
470  if( hMatch( CHAR_COMMA ) ) then
471  hMatchExpression( styleexpr )
472  end if
473  end if
474  else
475  cexpr = astNewCONSTi( 0, FB_DATATYPE_UINT )
476  flags or= FBGFX_DEFAULT_COLOR_FLAG
477  end if
478 
479  ''
480  function = rtlGfxLine( texpr, tisptr, x1expr, y1expr, x2expr, y2expr, _
481  cexpr, linetype, styleexpr, flags )
482 
483 end function
484 
485 '':::::
486 '' GfxCircle = CIRCLE ( Expr ',' )? STEP? '(' Expr ',' Expr ')' ',' Expr ((',' Expr? (',' Expr? (',' Expr? (',' Expr (',' Expr)? )? )?)?)?)?
487 ''
488 function cGfxCircle as integer
489  dim as integer flags, fillflag, tisptr
490  dim as ASTNODE ptr xexpr, yexpr, cexpr, radexpr, iniexpr, endexpr, aspexpr, texpr
491  dim as FBSYMBOL ptr target
492 
493  function = FALSE
494 
495  '' ( Expr ',' )?
496  target = hGetTarget( texpr, tisptr )
497  if( (target <> NULL) or (tisptr) ) then
498  hMatchCOMMA( )
499  end if
500 
501  '' STEP?
502  if( hMatch( FB_TK_STEP ) ) then
503  flags = FBGFX_COORDTYPE_R
504  else
505  flags = FBGFX_COORDTYPE_A
506  end if
507 
508  '' '(' Expr ',' Expr ')'
509  hMatchLPRNT( )
510 
511  hMatchExpression( xexpr )
512 
513  hMatchCOMMA( )
514 
515  hMatchExpression( yexpr )
516 
517  hMatchRPRNT( )
518 
519  '' ',' Expr - radius
520  hMatchCOMMA( )
521 
522  hMatchExpression( radexpr )
523 
524  aspexpr = NULL
525  iniexpr = NULL
526  endexpr = NULL
527  fillflag = FALSE
528 
529  '' (',' Expr? )? - color
530  if( hMatch( CHAR_COMMA ) ) then
531  cexpr = cExpression( )
532  if( cexpr = NULL ) then
533  cexpr = astNewCONSTi( 0, FB_DATATYPE_UINT )
534  flags or= FBGFX_DEFAULT_COLOR_FLAG
535  end if
536 
537  '' (',' Expr? )? - iniarc
538  if( hMatch( CHAR_COMMA ) ) then
539  iniexpr = cExpression( )
540 
541  '' (',' Expr? )? - endarc
542  if( hMatch( CHAR_COMMA ) ) then
543  endexpr = cExpression( )
544 
545  '' (',' Expr )? - aspect
546  if( hMatch( CHAR_COMMA ) ) then
547  aspexpr = cExpression( )
548 
549  '' (',' Expr )? - fillflag
550  if( hMatch( CHAR_COMMA ) ) then
551  if( ucase( *lexGetText( ) ) <> "F" ) then
552  errReport( FB_ERRMSG_EXPECTEDEXPRESSION )
553  exit function
554  end if
555  lexSkipToken( )
556  fillflag = TRUE
557  end if
558  end if
559  end if
560  end if
561 
562  else
563  cexpr = astNewCONSTi( 0, FB_DATATYPE_UINT )
564  flags or= FBGFX_DEFAULT_COLOR_FLAG
565  end if
566 
567  ''
568  function = rtlGfxCircle( texpr, tisptr, xexpr, yexpr, radexpr, cexpr, _
569  aspexpr, iniexpr, endexpr, fillflag, flags )
570 
571 end function
572 
573 '':::::
574 '' GfxPaint = PAINT ( Expr ',' )? STEP? '(' expr ',' expr ')' (',' expr? (',' expr? ) )
575 ''
576 function cGfxPaint as integer
577  dim as ASTNODE ptr xexpr, yexpr, pexpr, bexpr, texpr
578  dim as integer flags, tisptr
579  dim as FBSYMBOL ptr target
580 
581  function = FALSE
582 
583  '' ( Expr ',' )?
584  target = hGetTarget( texpr, tisptr )
585  if( (target <> NULL) or (tisptr) ) then
586  hMatchCOMMA( )
587  end if
588 
589  '' STEP?
590  if( hMatch( FB_TK_STEP ) ) then
591  flags = FBGFX_COORDTYPE_R
592  else
593  flags = FBGFX_COORDTYPE_A
594  end if
595 
596  '' '(' Expr ',' Expr ')' - x and y
597  hMatchLPRNT( )
598 
599  hMatchExpression( xexpr )
600 
601  hMatchCOMMA( )
602 
603  hMatchExpression( yexpr )
604 
605  hMatchRPRNT( )
606 
607  pexpr = NULL
608  bexpr = NULL
609 
610  '' color/pattern
611  if( hMatch( CHAR_COMMA ) ) then
612  pexpr = cExpression( )
613 
614  '' background color
615  if( hMatch( CHAR_COMMA ) ) then
616  hMatchExpression( bexpr )
617  end if
618  end if
619 
620  if( pexpr = NULL ) then
621  pexpr = astNewCONSTi( 0, FB_DATATYPE_UINT )
622  flags or= FBGFX_DEFAULT_COLOR_FLAG
623  end if
624 
625  if( bexpr = NULL ) then
626  bexpr = astNewCONSTi( 0, FB_DATATYPE_UINT )
628  end if
629 
630  function = rtlGfxPaint( texpr, tisptr, xexpr, yexpr, pexpr, bexpr, flags )
631 
632 end function
633 
634 '':::::
635 '' GfxDrawString = DRAW STRING ( Expr ',' )? STEP? '(' Expr ',' Expr ')' ',' Expr ( ',' Expr ( ',' Expr ( ',' Expr ( ',' Expr )? )? )? )?
636 ''
637 function cGfxDrawString as integer
638  dim as ASTNODE ptr texpr, xexpr, yexpr, sexpr, cexpr, fexpr, alphaexpr, funcexpr, paramexpr
639  dim as integer tisptr, fisptr, flags, mode
640  dim as FBSYMBOL ptr target
641 
642  function = FALSE
643 
644  texpr = NULL
645 
646  '' ( Expr ',' )?
647  target = hGetTarget( texpr, tisptr )
648  if( (target <> NULL) or (tisptr) ) then
649  hMatchCOMMA( )
650  end if
651 
652  '' STEP?
653  if( hMatch( FB_TK_STEP ) ) then
654  flags = FBGFX_COORDTYPE_R
655  else
656  flags = FBGFX_COORDTYPE_A
657  end if
658 
659  '' '(' Expr ',' Expr ')' - x and y
660  hMatchLPRNT( )
661 
662  hMatchExpression( xexpr )
663 
664  hMatchCOMMA( )
665 
666  hMatchExpression( yexpr )
667 
668  hMatchRPRNT( )
669 
670  '' ',' Expr
671  hMatchCOMMA( )
672 
673  hMatchExpression( sexpr )
674 
675  cexpr = NULL
676  fexpr = NULL
677  alphaexpr = NULL
678  funcexpr = NULL
679  paramexpr = NULL
680  mode = FBGFX_PUTMODE_TRANS
681 
682  '' color/font/mode
683  if( hMatch( CHAR_COMMA ) ) then
684  cexpr = cExpression( )
685 
686  '' custom user font
687  if( hMatch( CHAR_COMMA ) ) then
688  target = hGetTarget( fexpr, fisptr, TRUE )
689 
690  '' mode
691  if( hMatch( CHAR_COMMA ) ) then
692  if( hGetMode( mode, alphaexpr, funcexpr, paramexpr ) = FALSE ) then
693  exit function
694  end if
695  end if
696  end if
697  end if
698 
699  if( cexpr = NULL ) then
700  cexpr = astNewCONSTi( 0, FB_DATATYPE_UINT )
701  flags or= FBGFX_DEFAULT_COLOR_FLAG
702  end if
703 
704  function = rtlGfxDrawString( texpr, tisptr, xexpr, yexpr, sexpr, cexpr, fexpr, fisptr, flags, mode, alphaexpr, funcexpr, paramexpr )
705 
706 end function
707 
708 '':::::
709 '' GfxDraw = DRAW ( Expr ',' )? Expr
710 ''
711 function cGfxDraw as integer
712  dim as ASTNODE ptr cexpr, texpr
713  dim as integer tisptr
714  dim as FBSYMBOL ptr target
715 
716  function = FALSE
717 
718  texpr = NULL
719  if( hMatch( FB_TK_STRING ) ) then
720  function = cGfxDrawString
721  exit function
722  else
723  select case lexGetLookAhead( 1 )
724 
725  '' dot handling needed because of the
726  '' "period in symbol" ambiguity -cha0s
727  case CHAR_COMMA, CHAR_DOT
728  target = hGetTarget( texpr, tisptr )
729  if( (target = NULL) and (tisptr = FALSE) ) then
730  errReport( FB_ERRMSG_EXPECTEDEXPRESSION )
731  exit function
732  end if
733  hMatch( CHAR_COMMA )
734  end select
735  end if
736 
737  hMatchExpression( cexpr )
738 
739  function = rtlGfxDraw( texpr, tisptr, cexpr )
740 
741 end function
742 
743 '':::::
744 '' GfxView = VIEW (SCREEN? '(' Expr ',' Expr ')' '-' '(' Expr ',' Expr ')' (',' Expr? (',' Expr)?)? )?
745 ''
746 function cGfxView( byval isview as integer ) as integer
747  dim as integer flags
748  dim as ASTNODE ptr x1expr, y1expr, x2expr, y2expr, fillexpr, bordexpr
749 
750  function = FALSE
751 
752  '' SCREEN?
753  select case lexGetToken()
754  case FB_TK_SCREEN, FB_TK_SCREENQB
756  flags = FBGFX_VIEW_SCREEN_FLAG
757  case else
758  flags = 0
759  end select
760 
761  ''
762  x1expr = NULL
763  y1expr = NULL
764  x2expr = NULL
765  y2expr = NULL
766  fillexpr = NULL
767  bordexpr = NULL
768 
769  if( hMatch( CHAR_LPRNT ) ) then
770  '' '(' Expr ',' Expr ')' - x1 and y1
771  hMatchExpression( x1expr )
772 
773  hMatchCOMMA( )
774 
775  hMatchExpression( y1expr )
776 
777  hMatchRPRNT( )
778 
779  '' '-'
780  if( hMatch( CHAR_MINUS ) = FALSE ) then
781  errReport( FB_ERRMSG_EXPECTEDMINUS )
782  exit function
783  end if
784 
785  '' '(' Expr ',' Expr ')' - x2 and y2
786  hMatchLPRNT( )
787 
788  hMatchExpression( x2expr )
789 
790  hMatchCOMMA( )
791 
792  hMatchExpression( y2expr )
793 
794  hMatchRPRNT( )
795 
796  if( isview ) then
797  '' (',' Expr? )? - color
799  if( hMatch( CHAR_COMMA ) ) then
800  fillexpr = cExpression( )
801  if( fillexpr <> NULL ) then
802  flags and= not FBGFX_DEFAULT_COLOR_FLAG
803  end if
804 
805  '' (',' Expr? )? - border
806  if( hMatch( CHAR_COMMA ) ) then
807  hMatchExpression( bordexpr )
808  flags and= not FBGFX_DEFAULT_AUX_COLOR_FLAG
809  end if
810  end if
811  end if
812 
813  end if
814 
815  ''
816  if( isview ) then
817  function = rtlGfxView( x1expr, y1expr, x2expr, y2expr, fillexpr, bordexpr, flags )
818  else
819  function = rtlGfxWindow( x1expr, y1expr, x2expr, y2expr, flags )
820  end if
821 
822 end function
823 
824 '':::::
825 '' GfxPalette = PALETTE GET? ((USING Variable) | (Expr ',' Expr (',' Expr ',' Expr)?)?)
826 ''
827 function cGfxPalette as integer
828  dim as ASTNODE ptr arrayexpr, attexpr, rexpr, gexpr, bexpr
829  dim as FBSYMBOL ptr s
830  dim as integer isget, isptr
831 
832  function = FALSE
833 
834  if( hMatchText( "GET" ) ) then
835  isget = TRUE
836  else
837  isget = FALSE
838  end if
839 
840  '' this could fail if using was #undef'ed and made a method...
841  if( hMatch( FB_TK_USING ) ) then
842 
843  s = hGetTarget( arrayexpr, isptr, not isget )
844  if( (s = NULL) and (isptr = FALSE) ) then
845  errReport( FB_ERRMSG_EXPECTEDIDENTIFIER )
846  exit function
847  end if
848 
849  function = rtlGfxPaletteUsing( arrayexpr, isptr, isget )
850 
851  else
852 
853  attexpr = NULL
854  rexpr = NULL
855  gexpr = NULL
856  bexpr = NULL
857 
858  attexpr = cExpression( )
859  if( attexpr <> NULL ) then
860  hMatchCOMMA( )
861 
862  if( isget ) then
863  rexpr = cVarOrDeref( )
864  if( rexpr = NULL ) then
865  errReport( FB_ERRMSG_EXPECTEDIDENTIFIER )
866  exit function
867  end if
868  else
869  hMatchExpression( rexpr )
870  end if
871 
872  if( hMatch( CHAR_COMMA ) ) then
873  if( isget ) then
874  gexpr = cVarOrDeref( )
875  if( gexpr = NULL ) then
876  errReport( FB_ERRMSG_EXPECTEDIDENTIFIER )
877  exit function
878  end if
879  else
880  hMatchExpression( gexpr )
881  end if
882 
883  hMatchCOMMA( )
884 
885  if( isget ) then
886  bexpr = cVarOrDeref( )
887  if( bexpr = NULL ) then
888  errReport( FB_ERRMSG_EXPECTEDIDENTIFIER )
889  exit function
890  end if
891  else
892  hMatchExpression( bexpr )
893  end if
894  end if
895  else
896  if( isget ) then
897  errReport( FB_ERRMSG_EXPECTEDEXPRESSION )
898  exit function
899  end if
900  end if
901 
902  dim as integer has_const = FALSE
903  if( isget ) then
904  has_const or= iif( rexpr, typeIsConst( astGetFullType( rexpr ) ), FALSE )
905  has_const or= iif( gexpr, typeIsConst( astGetFullType( gexpr ) ), FALSE )
906  has_const or= iif( bexpr, typeIsConst( astGetFullType( bexpr ) ), FALSE )
907  end if
908 
909  if( has_const ) then
910  errReport( FB_ERRMSG_CONSTANTCANTBECHANGED, TRUE )
911  end if
912 
913  function = rtlGfxPalette( attexpr, rexpr, gexpr, bexpr, isget )
914 
915  end if
916 
917 end function
918 
919 '':::::
920 '' GfxPut = PUT ( Expr ',' )? STEP? '(' Expr ',' Expr ')' ',' ('(' Expr ',' Expr ')' '-' '(' Expr ',' Expr ')' ',')? Variable (',' Mode (',' Alpha)?)?
921 ''
922 function cGfxPut as integer
923  dim as integer coordtype, mode, isptr, tisptr, expectmode
924  dim as ASTNODE ptr xexpr, yexpr, arrayexpr, texpr, alphaexpr, _
925  funcexpr, paramexpr, x1expr, y1expr, x2expr, y2expr
926  dim as FBSYMBOL ptr s, target, arg1, arg2
927 
928  function = FALSE
929 
930  alphaexpr = NULL
931  funcexpr = NULL
932  paramexpr = NULL
933  x1expr = NULL
934 
935  '' ( Expr ',' )?
936  target = hGetTarget( texpr, tisptr )
937  if( (target <> NULL) or (tisptr) ) then
938  hMatchCOMMA( )
939  end if
940 
941  '' STEP?
942  if( hMatch( FB_TK_STEP ) ) then
943  coordtype = FBGFX_COORDTYPE_RA
944  else
945  coordtype = FBGFX_COORDTYPE_AA
946  end if
947 
948  '' '(' Expr ',' Expr ')'
949  hMatchLPRNT( )
950 
951  hMatchExpression( xexpr )
952 
953  hMatchCOMMA( )
954 
955  hMatchExpression( yexpr )
956 
957  hMatchRPRNT( )
958 
959  '' ',' Variable
960  hMatchCOMMA( )
961 
962  s = hGetTarget( arrayexpr, isptr, TRUE )
963  if( (s = NULL) and (isptr = FALSE) ) then
964  errReport( FB_ERRMSG_EXPECTEDIDENTIFIER )
965  exit function
966  end if
967 
968  '' (',' Mode)?
969  mode = FBGFX_PUTMODE_XOR
970  if( hMatch( CHAR_COMMA ) ) then
971 
972  expectmode = TRUE
973 
974  if( hMatch( CHAR_LPRNT ) ) then
975 
976  hMatchExpression( x1expr )
977  hMatchCOMMA( )
978  hMatchExpression( y1expr )
979  hMatchRPRNT( )
980 
981  if( hMatch( CHAR_MINUS ) = FALSE ) then
982  errReport FB_ERRMSG_EXPECTEDMINUS
983  exit function
984  end if
985 
986  '' STEP?
987  if( hMatch( FB_TK_STEP ) ) then
988  if( coordtype = FBGFX_COORDTYPE_RA ) then
989  coordtype = FBGFX_COORDTYPE_RR
990  else
991  coordtype = FBGFX_COORDTYPE_AR
992  end if
993  end if
994 
995  hMatchLPRNT( )
996  hMatchExpression( x2expr )
997  hMatchCOMMA( )
998  hMatchExpression( y2expr )
999  hMatchRPRNT( )
1000 
1001  if( hMatch( CHAR_COMMA ) = FALSE ) then
1002  expectmode = FALSE
1003  end if
1004  end if
1005 
1006  if( expectmode ) then
1007  if( hGetMode( mode, alphaexpr, funcexpr, paramexpr ) = FALSE ) then
1008  exit function
1009  end if
1010  end if
1011  end if
1012 
1013  ''
1014  function = rtlGfxPut( texpr, tisptr, xexpr, yexpr, arrayexpr, isptr, _
1015  x1expr, y1expr, x2expr, y2expr, _
1016  mode, alphaexpr, funcexpr, paramexpr, coordtype )
1017 
1018 end function
1019 
1020 '':::::
1021 '' GfxGet = GET ( Expr ',' )? STEP? '(' Expr ',' Expr ')' '-' STEP? '(' Expr ',' Expr ')' ',' Variable
1022 ''
1023 function cGfxGet as integer
1024  dim as integer coordtype, isptr, tisptr
1025  dim as ASTNODE ptr x1expr, y1expr, x2expr, y2expr, arrayexpr, texpr
1026  dim as FBSYMBOL ptr s, target
1027 
1028  function = FALSE
1029 
1030  '' ( Expr ',' )?
1031  target = hGetTarget( texpr, tisptr, TRUE )
1032  if( (target <> NULL) or (tisptr) ) then
1033  hMatchCOMMA( )
1034  end if
1035 
1036  '' STEP?
1037  if( hMatch( FB_TK_STEP ) ) then
1038  coordtype = FBGFX_COORDTYPE_R
1039  else
1040  coordtype = FBGFX_COORDTYPE_A
1041  end if
1042 
1043  '' '(' Expr ',' Expr ')' - x1 and y1
1044  hMatchLPRNT( )
1045 
1046  hMatchExpression( x1expr )
1047 
1048  hMatchCOMMA( )
1049 
1050  hMatchExpression( y1expr )
1051 
1052  hMatchRPRNT( )
1053 
1054  '' '-'
1055  if( hMatch( CHAR_MINUS ) = FALSE ) then
1056  errReport( FB_ERRMSG_EXPECTEDMINUS )
1057  exit function
1058  end if
1059 
1060  '' STEP?
1061  if( hMatch( FB_TK_STEP ) ) then
1062  if( coordtype = FBGFX_COORDTYPE_R ) then
1063  coordtype = FBGFX_COORDTYPE_RR
1064  else
1065  coordtype = FBGFX_COORDTYPE_AR
1066  end if
1067  else
1068  if( coordtype = FBGFX_COORDTYPE_R ) then
1069  coordtype = FBGFX_COORDTYPE_RA
1070  else
1071  coordtype = FBGFX_COORDTYPE_AA
1072  end if
1073  end if
1074 
1075  '' '(' Expr ',' Expr ')' - x2 and y2
1076  hMatchLPRNT( )
1077 
1078  hMatchExpression( x2expr )
1079 
1080  hMatchCOMMA( )
1081 
1082  hMatchExpression( y2expr )
1083 
1084  hMatchRPRNT( )
1085 
1086  '' ',' Variable
1087  hMatchCOMMA( )
1088 
1089  s = hGetTarget( arrayexpr, isptr )
1090  if( (s = NULL) and (isptr = FALSE) ) then
1091  errReport( FB_ERRMSG_EXPECTEDIDENTIFIER )
1092  exit function
1093  end if
1094 
1095  ''
1096  function = rtlGfxGet( texpr, tisptr, x1expr, y1expr, x2expr, y2expr, _
1097  arrayexpr, isptr, s, coordtype )
1098 
1099 end function
1100 
1101 '':::::
1102 '' GfxScreen = SCREEN (num | ((expr (((',' expr)? ',' expr)? expr)? ',' expr))
1103 ''
1104 function cGfxScreen( byval isqb as integer ) as integer
1105 
1106  function = FALSE
1107 
1108  if( isqb = FALSE ) then
1109  '' Expr?
1110  dim as ASTNODE ptr mexpr = cExpression( )
1111 
1112  '' (',' Expr )?
1113  dim as ASTNODE ptr dexpr = NULL
1114  if( hMatch( CHAR_COMMA ) ) then
1115  dexpr = cExpression( )
1116  end if
1117 
1118  '' (',' Expr )?
1119  dim as ASTNODE ptr pexpr = NULL
1120  if( hMatch( CHAR_COMMA ) ) then
1121  pexpr = cExpression( )
1122  end if
1123 
1124  '' page set?
1125  if( mexpr = NULL ) then
1126  return rtlPageSet( dexpr, pexpr, FALSE ) <> NULL
1127  end if
1128 
1129  '' (',' Expr )?
1130  dim as ASTNODE ptr fexpr = NULL
1131  if( hMatch( CHAR_COMMA ) ) then
1132  fexpr = cExpression( )
1133  end if
1134 
1135  '' (',' Expr )?
1136  dim as ASTNODE ptr rexpr = NULL
1137  if( hMatch( CHAR_COMMA ) ) then
1138  rexpr = cExpression( )
1139  end if
1140 
1141  function = rtlGfxScreenSet( mexpr, dexpr, pexpr, fexpr, rexpr )
1142 
1143  else
1144  '' mode?
1145  dim as ASTNODE ptr mode = cExpression( )
1146 
1147  '' (',' colorswitch )?
1148  if( hMatch( CHAR_COMMA ) ) then
1149  dim as ASTNODE ptr cswitch = cExpression( )
1150  if( cswitch <> NULL ) then
1151  '' unused
1152  astDelTree( cswitch )
1153  end if
1154  end if
1155 
1156  '' (',' active )?
1157  dim as ASTNODE ptr active = NULL
1158  if( hMatch( CHAR_COMMA ) ) then
1159  active = cExpression( )
1160  end if
1161 
1162  '' (',' visible )?
1163  dim as ASTNODE ptr visible = NULL
1164  if( hMatch( CHAR_COMMA ) ) then
1165  visible = cExpression( )
1166  end if
1167 
1168  if( mode = NULL ) then
1169  function = rtlPageSet( active, visible, FALSE ) <> NULL
1170  else
1171  function = rtlGfxScreenSetQB( mode, active, visible )
1172  end if
1173  end if
1174 
1175 end function
1176 
1177 '':::::
1178 '' GfxPoint = POINT '(' Expr ( ',' ( Expr )? ( ',' Expr )? )? ')'
1179 ''
1180 function cGfxPoint( byref funcexpr as ASTNODE ptr ) as integer
1181  dim as ASTNODE ptr xexpr, yexpr, texpr
1182  dim as integer tisptr
1183  dim as FBSYMBOL ptr target
1184 
1185  function = FALSE
1186 
1187  hMatchLPRNT( )
1188 
1189  hMatchExpression( xexpr )
1190 
1191  yexpr = NULL
1192  texpr = NULL
1193 
1194  if( hMatch( CHAR_COMMA ) ) then
1195  hMatchExpression( yexpr )
1196 
1197  if( hMatch( CHAR_COMMA ) ) then
1198  target = hGetTarget( texpr, tisptr, TRUE )
1199  if( (target = NULL) and (tisptr = FALSE) ) then
1200  errReport( FB_ERRMSG_EXPECTEDEXPRESSION )
1201  exit function
1202  end if
1203  end if
1204  end if
1205 
1206  hMatchRPRNT( )
1207 
1208  funcexpr = rtlGfxPoint( texpr, tisptr, xexpr, yexpr )
1209 
1210  function = funcexpr <> NULL
1211 
1212 end function
1213 
1214 '':::::
1215 '' GfxImageCreate = IMAGECREATE '(' Expr ',' Expr ( ',' ( Expr )? ( ',' Expr )? )? ')'
1216 ''
1217 function cGfxImageCreate( byref funcexpr as ASTNODE ptr ) as integer
1218  dim as ASTNODE ptr wexpr, hexpr, cexpr, dexpr
1219  dim as integer flags
1220 
1221  function = FALSE
1222 
1223  hMatchLPRNT( )
1224 
1225  hMatchExpression( wexpr )
1226 
1227  hMatchCOMMA( )
1228 
1229  hMatchExpression( hexpr )
1230 
1231  cexpr = NULL
1232  dexpr = NULL
1233  flags = FBGFX_DEFAULT_COLOR_FLAG
1234 
1235  if( hMatch( CHAR_COMMA ) ) then
1236  cexpr = cExpression( )
1237  if( cexpr <> NULL ) then
1238  flags = 0
1239  end if
1240  if( hMatch( CHAR_COMMA ) ) then
1241  hMatchExpression( dexpr )
1242  end if
1243  end if
1244 
1245  hMatchRPRNT( )
1246 
1247  funcexpr = rtlGfxImageCreate( wexpr, hexpr, cexpr, dexpr, flags )
1248 
1249  function = funcexpr <> NULL
1250 
1251 end function
1252 
1253 #macro CHECK_CODEMASK( )
1254  if( cCompStmtIsAllowed( FB_CMPSTMT_MASK_CODE ) = FALSE ) then
1255  hSkipStmt( )
1256  exit function
1257  end if
1258 #endmacro
1259 
1260 '':::::
1261 function cGfxStmt _
1262  ( _
1263  byval tk as FB_TOKEN _
1264  ) as integer
1265 
1266  function = FALSE
1267 
1268  select case as const tk
1269  case FB_TK_PSET
1270  CHECK_CODEMASK( )
1271  lexSkipToken( )
1272  function = cGfxPSet( FALSE )
1273 
1274  case FB_TK_PRESET
1275  CHECK_CODEMASK( )
1276  lexSkipToken( )
1277  function = cGfxPSet( TRUE )
1278 
1279  case FB_TK_LINE
1280  CHECK_CODEMASK( )
1281  lexSkipToken( )
1282  function = cGfxLine( )
1283 
1284  case FB_TK_CIRCLE
1285  CHECK_CODEMASK( )
1286  lexSkipToken( )
1287  function = cGfxCircle( )
1288 
1289  case FB_TK_PAINT
1290  CHECK_CODEMASK( )
1291  lexSkipToken( )
1292  function = cGfxPaint( )
1293 
1294  case FB_TK_DRAW
1295  CHECK_CODEMASK( )
1296  lexSkipToken( )
1297  function = cGfxDraw( )
1298 
1299  case FB_TK_VIEW
1300  CHECK_CODEMASK( )
1301  lexSkipToken( )
1302  function = cGfxView( TRUE )
1303 
1304  case FB_TK_WINDOW
1305  CHECK_CODEMASK( )
1306  lexSkipToken( )
1307  function = cGfxView( FALSE )
1308 
1309  case FB_TK_PALETTE
1310  CHECK_CODEMASK( )
1311  lexSkipToken( )
1312  function = cGfxPalette( )
1313 
1314  case FB_TK_PUT
1315  CHECK_CODEMASK( )
1316  lexSkipToken( )
1317  function = cGfxPut( )
1318 
1319  case FB_TK_GET
1320  CHECK_CODEMASK( )
1321  lexSkipToken( )
1322  function = cGfxGet( )
1323 
1324  case FB_TK_SCREEN
1325  CHECK_CODEMASK( )
1326  lexSkipToken( )
1327  function = cGfxScreen( FALSE )
1328 
1329  case FB_TK_SCREENQB
1330  CHECK_CODEMASK( )
1331  lexSkipToken( )
1332  function = cGfxScreen( TRUE )
1333 
1334  end select
1335 
1336 end function
1337 
1338 '':::::
1339 function cGfxFunct _
1340  ( _
1341  byval tk as FB_TOKEN _
1342  ) as ASTNODE ptr
1343 
1344  dim as ASTNODE ptr expr = NULL
1345 
1346  select case tk
1347  case FB_TK_POINT
1348  lexSkipToken( )
1349  cGfxPoint( expr )
1350 
1351  case FB_TK_IMAGECREATE
1352  lexSkipToken( )
1353  cGfxImageCreate( expr )
1354 
1355  end select
1356 
1357  function = expr
1358 
1359 end function
1360 
1361