FreeBASIC  0.91.0
parser-compound-with.bas
Go to the documentation of this file.
1 '' WITH..END WITH compound statement parsing
2 ''
3 '' chng: sep/2004 written [v1ctor]
4 
5 
6 #include once "fb.bi"
7 #include once "fbint.bi"
8 #include once "parser.bi"
9 #include once "ast.bi"
10 
11 '' WithStmtBegin = WITH Variable .
13  static as FBARRAYDIM dTB(0)
14  dim as FBSYMBOL ptr sym = any
15  dim as ASTNODE ptr expr = any
16  dim as integer is_ptr = any, options = any
17  dim as FB_CMPSTMTSTK ptr stk = any
18 
19  '' WITH
20  lexSkipToken( )
21 
22  '' Variable
23  expr = cVarOrDeref( FB_VAREXPROPT_ISEXPR )
24  if( expr = NULL ) then
25  errReport( FB_ERRMSG_EXPECTEDIDENTIFIER )
26  '' error recovery: fake a var
27  expr = astNewVAR( symbAddTempVar( FB_DATATYPE_INTEGER ) )
28  else
29  '' not an UDT?
30  if( typeGetDtAndPtrOnly( astGetFullType( expr ) ) <> FB_DATATYPE_STRUCT ) then
31  errReport( FB_ERRMSG_INVALIDDATATYPES )
32  end if
33  end if
34 
35  if( astIsVAR( expr ) ) then
36  '' If it's a simple VAR access, we can just access the
37  '' corresponding variable from inside the WITH.
38  sym = astGetSymbol( expr )
39  is_ptr = FALSE
40  else
41  '' Otherwise, take a reference (a pointer that will be deref'ed
42  '' for accesses from inside the WITH block)
43  '' dim temp as typeof( expr ) ptr = @expr
44  expr = astNewADDROF( expr )
45 
46  options = 0
47  if( fbLangOptIsSet( FB_LANG_OPT_SCOPE ) = FALSE ) then
48  options or= FB_SYMBOPT_UNSCOPE
49  end if
50 
51  sym = symbAddImplicitVar( astGetFullType( expr ), astGetSubType( expr ), options )
52 
53  if( options and FB_SYMBOPT_UNSCOPE ) then
54  astAddUnscoped( astNewDECL( sym, TRUE ) )
55  astAdd( astNewASSIGN( astNewVAR( sym ), expr ) )
56  else
57  astAdd( astNewDECL( sym, FALSE ) )
58  astAdd( astNewASSIGN( astNewVAR( sym ), expr, AST_OPOPT_ISINI ) )
59  end if
60 
61  is_ptr = TRUE
62  end if
63 
64  '' Save current WITH context to the statement stack
65  stk = cCompStmtPush( FB_TK_WITH )
66  stk->with = parser.stmt.with
67 
68  '' And set the new WITH context
69  parser.stmt.with.sym = sym
70  parser.stmt.with.is_ptr = is_ptr
71 end sub
72 
73 '' WithStmtEnd = END WITH .
75  dim as FB_CMPSTMTSTK ptr stk = any
76 
77  stk = cCompStmtGetTOS( FB_TK_WITH )
78  if( stk = NULL ) then
79  hSkipStmt( )
80  exit sub
81  end if
82 
83  '' END WITH
84  lexSkipToken( )
85  lexSkipToken( )
86 
87  '' Restore the previous WITH context
88  parser.stmt.with = stk->with
89  cCompStmtPop( stk )
90 end sub
91