aboutsummaryrefslogtreecommitdiff
path: root/src/runner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/runner.cpp')
-rw-r--r--src/runner.cpp1690
1 files changed, 845 insertions, 845 deletions
diff --git a/src/runner.cpp b/src/runner.cpp
index 64ad8e8..766a2f5 100644
--- a/src/runner.cpp
+++ b/src/runner.cpp
@@ -17,10 +17,10 @@
17using Bu::sio; 17using Bu::sio;
18 18
19Runner::Runner( Ast &rAst, Context &rCont ) : 19Runner::Runner( Ast &rAst, Context &rCont ) :
20 rAst( rAst ), 20 rAst( rAst ),
21 rCont( rCont ), 21 rCont( rCont ),
22 pCurTarget( NULL ), 22 pCurTarget( NULL ),
23 pCurRule( NULL ) 23 pCurRule( NULL )
24{ 24{
25} 25}
26 26
@@ -30,897 +30,897 @@ Runner::~Runner()
30 30
31void Runner::initialize() 31void Runner::initialize()
32{ 32{
33 for( Ast::NodeList::const_iterator i = rAst.getNodeBegin(); i; i++ ) 33 for( Ast::NodeList::const_iterator i = rAst.getNodeBegin(); i; i++ )
34 { 34 {
35 if( (*i)->getType() == AstNode::typeFunctionDef ) 35 if( (*i)->getType() == AstNode::typeFunctionDef )
36 { 36 {
37 AstBranch *pFnc = dynamic_cast<AstBranch *>(*i); 37 AstBranch *pFnc = dynamic_cast<AstBranch *>(*i);
38 rCont.addFunction( new FunctionAst( pFnc, this ) ); 38 rCont.addFunction( new FunctionAst( pFnc, this ) );
39 } 39 }
40 else if( (*i)->getType() == AstNode::typeActionDef ) 40 else if( (*i)->getType() == AstNode::typeActionDef )
41 { 41 {
42 AstBranch *pAction = dynamic_cast<AstBranch *>(*i); 42 AstBranch *pAction = dynamic_cast<AstBranch *>(*i);
43 rCont.addAction( new Action( pAction ) ); 43 rCont.addAction( new Action( pAction ) );
44 } 44 }
45 } 45 }
46} 46}
47 47
48Variable Runner::execFunc( const AstBranch *pFunc, Variable &vIn ) 48Variable Runner::execFunc( const AstBranch *pFunc, Variable &vIn )
49{ 49{
50 Bu::String sName = dynamic_cast<const AstLeaf *>( 50 Bu::String sName = dynamic_cast<const AstLeaf *>(
51 (*pFunc->getBranchBegin()).first())->getStrValue(); 51 (*pFunc->getBranchBegin()).first())->getStrValue();
52 52
53 VarList lParams; 53 VarList lParams;
54 for( AstBranch::BranchList::const_iterator p = 54 for( AstBranch::BranchList::const_iterator p =
55 pFunc->getBranchBegin()+1; p; p++ ) 55 pFunc->getBranchBegin()+1; p; p++ )
56 { 56 {
57 lParams.append( execExpr( (*p).begin() ) ); 57 lParams.append( execExpr( (*p).begin() ) );
58 } 58 }
59 59
60 return rCont.call( sName, vIn, lParams ); 60 return rCont.call( sName, vIn, lParams );
61} 61}
62 62
63Variable Runner::execExpr( AstBranch::NodeList::const_iterator e ) 63Variable Runner::execExpr( AstBranch::NodeList::const_iterator e )
64{ 64{
65 Variable vBlank; 65 Variable vBlank;
66 return execExpr( e, vBlank ); 66 return execExpr( e, vBlank );
67} 67}
68 68
69Variable Runner::execExpr( AstBranch::NodeList::const_iterator e, 69Variable Runner::execExpr( AstBranch::NodeList::const_iterator e,
70 const Variable &vIn ) 70 const Variable &vIn )
71{ 71{
72// Variable v( vIn ); 72// Variable v( vIn );
73 VarList lStack; 73 VarList lStack;
74 lStack.push( vIn ); 74 lStack.push( vIn );
75 75
76 for(; e; e++ ) 76 for(; e; e++ )
77 { 77 {
78 if( ((*e)->getType()&AstNode::typeClassMask) == AstNode::typeBranch ) 78 if( ((*e)->getType()&AstNode::typeClassMask) == AstNode::typeBranch )
79 { 79 {
80 const AstBranch *pBranch = dynamic_cast<const AstBranch *>( *e ); 80 const AstBranch *pBranch = dynamic_cast<const AstBranch *>( *e );
81 switch( pBranch->getType() ) 81 switch( pBranch->getType() )
82 { 82 {
83 case AstNode::typeFunction: 83 case AstNode::typeFunction:
84 //sio << "FUNC: " << *pBranch << sio.nl << sio.nl; 84 //sio << "FUNC: " << *pBranch << sio.nl << sio.nl;
85 { 85 {
86 Variable v = lStack.peekPop(); 86 Variable v = lStack.peekPop();
87 lStack.push( execFunc( pBranch, v ) ); 87 lStack.push( execFunc( pBranch, v ) );
88 } 88 }
89 break; 89 break;
90 90
91 case AstNode::typeSet: 91 case AstNode::typeSet:
92 lStack.push( doSet( pBranch ) ); 92 lStack.push( doSet( pBranch ) );
93 break; 93 break;
94 94
95 case AstNode::typeList: 95 case AstNode::typeList:
96 { 96 {
97 Variable vLst( Variable::typeList ); 97 Variable vLst( Variable::typeList );
98 for( AstBranch::BranchList::const_iterator i = 98 for( AstBranch::BranchList::const_iterator i =
99 pBranch->getBranchBegin(); i; i++ ) 99 pBranch->getBranchBegin(); i; i++ )
100 { 100 {
101 vLst.append( execExpr( (*i).begin() ) ); 101 vLst.append( execExpr( (*i).begin() ) );
102 } 102 }
103 lStack.push( vLst ); 103 lStack.push( vLst );
104 } 104 }
105 break; 105 break;
106 106
107 case AstNode::typeExpr: 107 case AstNode::typeExpr:
108 { 108 {
109 sio << "!!! typeExpr in an expr maybe should be an error..." << sio.nl; 109 sio << "!!! typeExpr in an expr maybe should be an error..." << sio.nl;
110 for( AstBranch::BranchList::const_iterator i = 110 for( AstBranch::BranchList::const_iterator i =
111 pBranch->getBranchBegin(); i; i++ ) 111 pBranch->getBranchBegin(); i; i++ )
112 { 112 {
113 lStack.push( 113 lStack.push(
114 execExpr( (*i).begin() ) // Are they atomic? 114 execExpr( (*i).begin() ) // Are they atomic?
115 ); 115 );
116 } 116 }
117 if( lStack.getSize() != 1 ) 117 if( lStack.getSize() != 1 )
118 { 118 {
119 throw Bu::ExceptionBase( 119 throw Bu::ExceptionBase(
120 "Something went wrong, expression processing " 120 "Something went wrong, expression processing "
121 "left %d elements on stack, should be 1.", 121 "left %d elements on stack, should be 1.",
122 lStack.getSize() ); 122 lStack.getSize() );
123 } 123 }
124 } 124 }
125 break; 125 break;
126 126
127 default: 127 default:
128 sio << "?? branch ???: " 128 sio << "?? branch ???: "
129 << (pBranch)->getType(); 129 << (pBranch)->getType();
130 break; 130 break;
131 } 131 }
132 } 132 }
133 else 133 else
134 { 134 {
135 const AstLeaf *pLeaf = dynamic_cast<const AstLeaf *>( *e ); 135 const AstLeaf *pLeaf = dynamic_cast<const AstLeaf *>( *e );
136 switch( pLeaf->getType() ) 136 switch( pLeaf->getType() )
137 { 137 {
138 case AstNode::typeVariable: 138 case AstNode::typeVariable:
139 try 139 try
140 { 140 {
141 lStack.push( 141 lStack.push(
142 rCont.getVariable( pLeaf->getStrValue() ) 142 rCont.getVariable( pLeaf->getStrValue() )
143 ); 143 );
144 } 144 }
145 catch(...) 145 catch(...)
146 { 146 {
147 lStack.push( Variable() ); 147 lStack.push( Variable() );
148 } 148 }
149 break; 149 break;
150 150
151 case AstNode::typeVariableRef: 151 case AstNode::typeVariableRef:
152 lStack.push( 152 lStack.push(
153 Variable::mkRef( pLeaf->getStrValue() ) 153 Variable::mkRef( pLeaf->getStrValue() )
154 ); 154 );
155 break; 155 break;
156 156
157 case AstNode::typeString: 157 case AstNode::typeString:
158 lStack.push( 158 lStack.push(
159 rCont.expand( pLeaf->getStrValue() ) 159 rCont.expand( pLeaf->getStrValue() )
160 ); 160 );
161 break; 161 break;
162 162
163 case AstNode::typeInt: 163 case AstNode::typeInt:
164 lStack.push( 164 lStack.push(
165 pLeaf->getIntValue() 165 pLeaf->getIntValue()
166 ); 166 );
167 break; 167 break;
168 168
169 case AstNode::typeFloat: 169 case AstNode::typeFloat:
170 lStack.push( 170 lStack.push(
171 pLeaf->getFloatValue() 171 pLeaf->getFloatValue()
172 ); 172 );
173 break; 173 break;
174 174
175 case AstNode::typeBool: 175 case AstNode::typeBool:
176 lStack.push( 176 lStack.push(
177 pLeaf->getBoolValue() 177 pLeaf->getBoolValue()
178 ); 178 );
179 break; 179 break;
180 180
181 case AstNode::typeVersion: 181 case AstNode::typeVersion:
182 break; 182 break;
183 183
184 case AstNode::typeNull: 184 case AstNode::typeNull:
185 lStack.push( 185 lStack.push(
186 Variable() 186 Variable()
187 ); 187 );
188 break; 188 break;
189 189
190 case AstNode::typeCmpEq: 190 case AstNode::typeCmpEq:
191 { 191 {
192 Variable a, b; 192 Variable a, b;
193 a = lStack.peekPop(); 193 a = lStack.peekPop();
194 b = lStack.peekPop(); 194 b = lStack.peekPop();
195 lStack.push( Variable( a == b ) ); 195 lStack.push( Variable( a == b ) );
196 } 196 }
197 break; 197 break;
198 198
199 case AstNode::typeCmpLt: 199 case AstNode::typeCmpLt:
200 { 200 {
201 Variable a, b; 201 Variable a, b;
202 a = lStack.peekPop(); 202 a = lStack.peekPop();
203 b = lStack.peekPop(); 203 b = lStack.peekPop();
204 lStack.push( Variable( b < a ) ); 204 lStack.push( Variable( b < a ) );
205 } 205 }
206 break; 206 break;
207 207
208 case AstNode::typeCmpGt: 208 case AstNode::typeCmpGt:
209 { 209 {
210 Variable a, b; 210 Variable a, b;
211 a = lStack.peekPop(); 211 a = lStack.peekPop();
212 b = lStack.peekPop(); 212 b = lStack.peekPop();
213 lStack.push( Variable( b > a ) ); 213 lStack.push( Variable( b > a ) );
214 } 214 }
215 break; 215 break;
216 216
217 case AstNode::typeCmpNe: 217 case AstNode::typeCmpNe:
218 { 218 {
219 Variable a, b; 219 Variable a, b;
220 a = lStack.peekPop(); 220 a = lStack.peekPop();
221 b = lStack.peekPop(); 221 b = lStack.peekPop();
222 lStack.push( Variable( a != b ) ); 222 lStack.push( Variable( a != b ) );
223 } 223 }
224 break; 224 break;
225 225
226 case AstNode::typeCmpLtEq: 226 case AstNode::typeCmpLtEq:
227 { 227 {
228 Variable a, b; 228 Variable a, b;
229 a = lStack.peekPop(); 229 a = lStack.peekPop();
230 b = lStack.peekPop(); 230 b = lStack.peekPop();
231 lStack.push( Variable( b <= a ) ); 231 lStack.push( Variable( b <= a ) );
232 } 232 }
233 break; 233 break;
234 234
235 case AstNode::typeCmpGtEq: 235 case AstNode::typeCmpGtEq:
236 { 236 {
237 Variable a, b; 237 Variable a, b;
238 a = lStack.peekPop(); 238 a = lStack.peekPop();
239 b = lStack.peekPop(); 239 b = lStack.peekPop();
240 lStack.push( Variable( b >= a ) ); 240 lStack.push( Variable( b >= a ) );
241 } 241 }
242 break; 242 break;
243 243
244 case AstNode::typeOpEq: 244 case AstNode::typeOpEq:
245 { 245 {
246 Variable ref, val; 246 Variable ref, val;
247 val = lStack.peekPop(); 247 val = lStack.peekPop();
248 ref = lStack.peekPop(); 248 ref = lStack.peekPop();
249 rCont.addVariable( ref.getString(), val ); 249 rCont.addVariable( ref.getString(), val );
250 lStack.push( val ); 250 lStack.push( val );
251 } 251 }
252 break; 252 break;
253 253
254 case AstNode::typeOpPlusEq: 254 case AstNode::typeOpPlusEq:
255 { 255 {
256 Variable ref, val; 256 Variable ref, val;
257 val = lStack.peekPop(); 257 val = lStack.peekPop();
258 ref = lStack.peekPop(); 258 ref = lStack.peekPop();
259 try 259 try
260 { 260 {
261 Variable &nVal = rCont.getVariable( 261 Variable &nVal = rCont.getVariable(
262 ref.getString() 262 ref.getString()
263 ); 263 );
264 nVal += val; 264 nVal += val;
265 lStack.push( nVal ); 265 lStack.push( nVal );
266 } catch(...) 266 } catch(...)
267 { 267 {
268 rCont.addVariable( ref.getString(), val ); 268 rCont.addVariable( ref.getString(), val );
269 lStack.push( val ); 269 lStack.push( val );
270 } 270 }
271 } 271 }
272 break; 272 break;
273 273
274 case AstNode::typeOpPlusEqRaw: 274 case AstNode::typeOpPlusEqRaw:
275 { 275 {
276 Variable ref, val; 276 Variable ref, val;
277 val = lStack.peekPop(); 277 val = lStack.peekPop();
278 ref = lStack.peekPop(); 278 ref = lStack.peekPop();
279 try 279 try
280 { 280 {
281 Variable &nVal = rCont.getVariable( 281 Variable &nVal = rCont.getVariable(
282 ref.getString() 282 ref.getString()
283 ); 283 );
284 nVal << val; 284 nVal << val;
285 lStack.push( nVal ); 285 lStack.push( nVal );
286 } catch(...) 286 } catch(...)
287 { 287 {
288 rCont.addVariable( ref.getString(), val ); 288 rCont.addVariable( ref.getString(), val );
289 lStack.push( val ); 289 lStack.push( val );
290 } 290 }
291 } 291 }
292 break; 292 break;
293 293
294 case AstNode::typeOpPlus: 294 case AstNode::typeOpPlus:
295 { 295 {
296 Variable a, b; 296 Variable a, b;
297 a = lStack.peekPop(); 297 a = lStack.peekPop();
298 b = lStack.peekPop(); 298 b = lStack.peekPop();
299 lStack.push( Variable( b + a ) ); 299 lStack.push( Variable( b + a ) );
300 } 300 }
301 break; 301 break;
302 302
303 case AstNode::typeOpMinus: 303 case AstNode::typeOpMinus:
304 { 304 {
305 Variable a, b; 305 Variable a, b;
306 a = lStack.peekPop(); 306 a = lStack.peekPop();
307 b = lStack.peekPop(); 307 b = lStack.peekPop();
308 lStack.push( Variable( b - a ) ); 308 lStack.push( Variable( b - a ) );
309 } 309 }
310 break; 310 break;
311 311
312 case AstNode::typeOpMultiply: 312 case AstNode::typeOpMultiply:
313 { 313 {
314 Variable a, b; 314 Variable a, b;
315 a = lStack.peekPop(); 315 a = lStack.peekPop();
316 b = lStack.peekPop(); 316 b = lStack.peekPop();
317 lStack.push( Variable( b * a ) ); 317 lStack.push( Variable( b * a ) );
318 } 318 }
319 break; 319 break;
320 320
321 case AstNode::typeOpDivide: 321 case AstNode::typeOpDivide:
322 { 322 {
323 Variable a, b; 323 Variable a, b;
324 a = lStack.peekPop(); 324 a = lStack.peekPop();
325 b = lStack.peekPop(); 325 b = lStack.peekPop();
326 lStack.push( Variable( b / a ) ); 326 lStack.push( Variable( b / a ) );
327 } 327 }
328 break; 328 break;
329 329
330 case AstNode::typeOpNegate: 330 case AstNode::typeOpNegate:
331 lStack.peek().doNegate(); 331 lStack.peek().doNegate();
332 break; 332 break;
333 333
334 case AstNode::typeOpNot: 334 case AstNode::typeOpNot:
335 lStack.peek().doNot(); 335 lStack.peek().doNot();
336 break; 336 break;
337 337
338 default: 338 default:
339 sio << "?? leaf ???: " 339 sio << "?? leaf ???: "
340 << (pLeaf)->getType(); 340 << (pLeaf)->getType();
341 break; 341 break;
342 } 342 }
343 } 343 }
344 } 344 }
345 345
346 return lStack.peek(); 346 return lStack.peek();
347} 347}
348 348
349void Runner::run() 349void Runner::run()
350{ 350{
351 run( rAst.getNodeBegin() ); 351 run( rAst.getNodeBegin() );
352 352
353 rCont.buildTargetTree( *this ); 353 rCont.buildTargetTree( *this );
354 354
355 rCont.attachDefaults(); 355 rCont.attachDefaults();
356 rCont.genDefaultActions(); 356 rCont.genDefaultActions();
357 357
358// rCont.writeTargetDot(); 358// rCont.writeTargetDot();
359} 359}
360 360
361Variable Runner::run( AstBranch::NodeList::const_iterator n ) 361Variable Runner::run( AstBranch::NodeList::const_iterator n )
362{ 362{
363 /* Execute the top level code. */ 363 /* Execute the top level code. */
364 364
365 Variable vReturn; 365 Variable vReturn;
366 Bu::List<Ast::NodeList::const_iterator> sI; 366 Bu::List<Ast::NodeList::const_iterator> sI;
367 sI.push( n ); 367 sI.push( n );
368// for( Ast::NodeList::const_iterator i = rAst.getNodeBegin(); i; i++ ) 368// for( Ast::NodeList::const_iterator i = rAst.getNodeBegin(); i; i++ )
369 while( !sI.isEmpty() ) 369 while( !sI.isEmpty() )
370 { 370 {
371 while( !sI.isEmpty() && !(sI.peek()) ) 371 while( !sI.isEmpty() && !(sI.peek()) )
372 { 372 {
373 sI.pop(); 373 sI.pop();
374 } 374 }
375 if( sI.isEmpty() ) 375 if( sI.isEmpty() )
376 break; 376 break;
377 Ast::NodeList::const_iterator &i = sI.peek(); 377 Ast::NodeList::const_iterator &i = sI.peek();
378 if( ((*i)->getType()&AstNode::typeClassMask) == AstNode::typeLeaf ) 378 if( ((*i)->getType()&AstNode::typeClassMask) == AstNode::typeLeaf )
379 { 379 {
380 const AstLeaf *pExpr = dynamic_cast<const AstLeaf *>( *i ); 380 const AstLeaf *pExpr = dynamic_cast<const AstLeaf *>( *i );
381 switch( pExpr->getType() ) 381 switch( pExpr->getType() )
382 { 382 {
383 case AstNode::typeError: 383 case AstNode::typeError:
384 { 384 {
385 Bu::String sMsg = rCont.expand( pExpr->getStrValue() ); 385 Bu::String sMsg = rCont.expand( pExpr->getStrValue() );
386 rCont.getView()->userError( sMsg.getStr() ); 386 rCont.getView()->userError( sMsg.getStr() );
387 throw Bu::ExceptionBase( sMsg.getStr() ); 387 throw Bu::ExceptionBase( sMsg.getStr() );
388 } 388 }
389 break; 389 break;
390 390
391 case AstNode::typeWarning: 391 case AstNode::typeWarning:
392 rCont.getView()->userWarning( 392 rCont.getView()->userWarning(
393 rCont.expand( pExpr->getStrValue() ) 393 rCont.expand( pExpr->getStrValue() )
394 ); 394 );
395 break; 395 break;
396 396
397 case AstNode::typeNotice: 397 case AstNode::typeNotice:
398 rCont.getView()->userNotice( 398 rCont.getView()->userNotice(
399 rCont.expand( pExpr->getStrValue() ) 399 rCont.expand( pExpr->getStrValue() )
400 ); 400 );
401 break; 401 break;
402 402
403 case AstNode::typeCondition: 403 case AstNode::typeCondition:
404 break; 404 break;
405 405
406 case AstNode::typeDisplay: 406 case AstNode::typeDisplay:
407 if( pCurTarget ) 407 if( pCurTarget )
408 { 408 {
409 pCurTarget->setDisplay( 409 pCurTarget->setDisplay(
410 rCont.expand( pExpr->getStrValue() ) 410 rCont.expand( pExpr->getStrValue() )
411 ); 411 );
412 } 412 }
413 else if( pCurRule ) 413 else if( pCurRule )
414 { 414 {
415 pCurRule->setDisplay( 415 pCurRule->setDisplay(
416 rCont.expand( pExpr->getStrValue() ) 416 rCont.expand( pExpr->getStrValue() )
417 ); 417 );
418 } 418 }
419 break; 419 break;
420 420
421 case AstNode::typePushPrefix: 421 case AstNode::typePushPrefix:
422 case AstNode::typePopPrefix: 422 case AstNode::typePopPrefix:
423 break; 423 break;
424/* 424/*
425 case AstNode::typeCondition: 425 case AstNode::typeCondition:
426 if( pCurTarget ) 426 if( pCurTarget )
427 { 427 {
428 if( pExpr->getStrValue() == "filetime" ) 428 if( pExpr->getStrValue() == "filetime" )
429 { 429 {
430 pCurTarget->setCondition( 430 pCurTarget->setCondition(
431 new ConditionFileTime() 431 new ConditionFileTime()
432 ); 432 );
433 } 433 }
434 } 434 }
435 else if( pCurRule ) 435 else if( pCurRule )
436 { 436 {
437 if( pExpr->getStrValue() == "filetime" ) 437 if( pExpr->getStrValue() == "filetime" )
438 { 438 {
439 pCurRule->setCondition( 439 pCurRule->setCondition(
440 new ConditionFileTime() 440 new ConditionFileTime()
441 ); 441 );
442 } 442 }
443 } 443 }
444 else 444 else
445 { 445 {
446 throw Bu::ExceptionBase( 446 throw Bu::ExceptionBase(
447 "You can only set a condition in a target or rule."); 447 "You can only set a condition in a target or rule.");
448 } 448 }
449 break; 449 break;
450*/ 450*/
451 default: 451 default:
452 sio << "Leaf? " << (*i)->getType() << sio.nl; 452 sio << "Leaf? " << (*i)->getType() << sio.nl;
453 break; 453 break;
454 } 454 }
455 } 455 }
456 else 456 else
457 { 457 {
458 const AstBranch *pExpr = dynamic_cast<const AstBranch *>( *i ); 458 const AstBranch *pExpr = dynamic_cast<const AstBranch *>( *i );
459 switch( pExpr->getType() ) 459 switch( pExpr->getType() )
460 { 460 {
461 case AstNode::typeSet: 461 case AstNode::typeSet:
462 { 462 {
463 // This is effectively legacy, if we add the set 463 // This is effectively legacy, if we add the set
464 // keyword back in I want it to work. 464 // keyword back in I want it to work.
465 doSet( pExpr ); 465 doSet( pExpr );
466 } 466 }
467 break; 467 break;
468 468
469 case AstNode::typeUnset: 469 case AstNode::typeUnset:
470 { 470 {
471 AstBranch::NodeList::const_iterator n = 471 AstBranch::NodeList::const_iterator n =
472 (*pExpr->getBranchBegin()).begin(); 472 (*pExpr->getBranchBegin()).begin();
473 Bu::String sVar = dynamic_cast<const AstLeaf *>( 473 Bu::String sVar = dynamic_cast<const AstLeaf *>(
474 *n )->getStrValue(); 474 *n )->getStrValue();
475 rCont.delVariable( sVar ); 475 rCont.delVariable( sVar );
476 } 476 }
477 break; 477 break;
478 478
479 case AstNode::typeIf: 479 case AstNode::typeIf:
480 { 480 {
481 AstBranch::BranchList::const_iterator b = 481 AstBranch::BranchList::const_iterator b =
482 pExpr->getBranchBegin(); 482 pExpr->getBranchBegin();
483 483
484 Variable v = execExpr( (*b).begin() ); 484 Variable v = execExpr( (*b).begin() );
485 if( v.getType() != Variable::typeBool ) 485 if( v.getType() != Variable::typeBool )
486 { 486 {
487 throw Bu::ExceptionBase( 487 throw Bu::ExceptionBase(
488 "If statement evaluated to non-boolean."); 488 "If statement evaluated to non-boolean.");
489 } 489 }
490 b++; 490 b++;
491 if( v.getBool() ) 491 if( v.getBool() )
492 { 492 {
493 i++; 493 i++;
494 sI.push( (*b).begin() ); 494 sI.push( (*b).begin() );
495 continue; 495 continue;
496 } 496 }
497 else 497 else
498 { 498 {
499 b++; 499 b++;
500 if( b ) 500 if( b )
501 { 501 {
502 i++; 502 i++;
503 sI.push( (*b).begin() ); 503 sI.push( (*b).begin() );
504 continue; 504 continue;
505 } 505 }
506 } 506 }
507 } 507 }
508 break; 508 break;
509 509
510 case AstNode::typeFor: 510 case AstNode::typeFor:
511 { 511 {
512 AstBranch::BranchList::const_iterator b = 512 AstBranch::BranchList::const_iterator b =
513 pExpr->getBranchBegin(); 513 pExpr->getBranchBegin();
514 Bu::String sVar = dynamic_cast<const AstLeaf *>( 514 Bu::String sVar = dynamic_cast<const AstLeaf *>(
515 (*b).first() )->getStrValue(); 515 (*b).first() )->getStrValue();
516 b++; 516 b++;
517 Variable v = execExpr( (*b).begin() ); 517 Variable v = execExpr( (*b).begin() );
518 b++; 518 b++;
519 for( VarList::const_iterator vi = v.getList().begin(); 519 for( VarList::const_iterator vi = v.getList().begin();
520 vi; vi++ ) 520 vi; vi++ )
521 { 521 {
522 rCont.addVariable( sVar, *vi ); 522 rCont.addVariable( sVar, *vi );
523 run( (*b).begin() ); 523 run( (*b).begin() );
524 } 524 }
525 } 525 }
526 break; 526 break;
527 527
528 case AstNode::typeFunction: 528 case AstNode::typeFunction:
529 { 529 {
530 Variable vIn; 530 Variable vIn;
531 execFunc( pExpr, vIn ); 531 execFunc( pExpr, vIn );
532 } 532 }
533 break; 533 break;
534 534
535 case AstNode::typeReturn: 535 case AstNode::typeReturn:
536 vReturn = execExpr( (*pExpr->getBranchBegin()).begin() ); 536 vReturn = execExpr( (*pExpr->getBranchBegin()).begin() );
537 return vReturn; 537 return vReturn;
538 break; 538 break;
539 539
540 case AstNode::typeFunctionDef: 540 case AstNode::typeFunctionDef:
541 case AstNode::typeActionDef: 541 case AstNode::typeActionDef:
542 // We ignore these, we already dealt with them 542 // We ignore these, we already dealt with them
543 break; 543 break;
544 544
545 case AstNode::typeTarget: 545 case AstNode::typeTarget:
546 // This actually runs exactly like a for loop, if there's 546 // This actually runs exactly like a for loop, if there's
547 // only one item, then we only go once, if it's a list, go 547 // only one item, then we only go once, if it's a list, go
548 // more than once :-P 548 // more than once :-P
549 if( pCurTarget == NULL ) 549 if( pCurTarget == NULL )
550 { 550 {
551 AstBranch::BranchList::const_iterator b = 551 AstBranch::BranchList::const_iterator b =
552 pExpr->getBranchBegin(); 552 pExpr->getBranchBegin();
553 Variable vLoop = execExpr( (*b).begin() ); 553 Variable vLoop = execExpr( (*b).begin() );
554 b++; 554 b++;
555 if( vLoop.getType() == Variable::typeString ) 555 if( vLoop.getType() == Variable::typeString )
556 { 556 {
557 rCont.addTarget( 557 rCont.addTarget(
558 buildTarget( 558 buildTarget(
559 vLoop.getString(), (*b).begin() 559 vLoop.getString(), (*b).begin()
560 ) 560 )
561 ); 561 );
562 } 562 }
563 else if( vLoop.getType() == Variable::typeList ) 563 else if( vLoop.getType() == Variable::typeList )
564 { 564 {
565 for( VarList::iterator i = vLoop.begin(); i; i++ ) 565 for( VarList::iterator i = vLoop.begin(); i; i++ )
566 { 566 {
567 rCont.addTarget( 567 rCont.addTarget(
568 buildTarget( 568 buildTarget(
569 (*i).getString(), (*b).begin() 569 (*i).getString(), (*b).begin()
570 ) 570 )
571 ); 571 );
572 } 572 }
573 } 573 }
574 } 574 }
575 else 575 else
576 { 576 {
577 throw Bu::ExceptionBase( 577 throw Bu::ExceptionBase(
578 "You cannot declare a target within " 578 "You cannot declare a target within "
579 "a target decleration."); 579 "a target decleration.");
580 } 580 }
581 break; 581 break;
582 582
583 case AstNode::typeRuleDef: 583 case AstNode::typeRuleDef:
584 if( pCurRule == NULL ) 584 if( pCurRule == NULL )
585 { 585 {
586 AstBranch::BranchList::const_iterator b = 586 AstBranch::BranchList::const_iterator b =
587 pExpr->getBranchBegin(); 587 pExpr->getBranchBegin();
588 Bu::String sName = dynamic_cast<const AstLeaf *>( 588 Bu::String sName = dynamic_cast<const AstLeaf *>(
589 (*b).first() 589 (*b).first()
590 )->getStrValue(); 590 )->getStrValue();
591 b++; 591 b++;
592 rCont.addRule( buildRule( sName, (*b).begin() ) ); 592 rCont.addRule( buildRule( sName, (*b).begin() ) );
593 } 593 }
594 else 594 else
595 { 595 {
596 throw Bu::ExceptionBase( 596 throw Bu::ExceptionBase(
597 "You cannot declare a rule within " 597 "You cannot declare a rule within "
598 "a rule decleration."); 598 "a rule decleration.");
599 } 599 }
600 break; 600 break;
601 601
602 case AstNode::typeInput: 602 case AstNode::typeInput:
603 if( pCurTarget != NULL ) 603 if( pCurTarget != NULL )
604 { 604 {
605 Variable vRet = execExpr( 605 Variable vRet = execExpr(
606 (*pExpr->getBranchBegin()).begin() 606 (*pExpr->getBranchBegin()).begin()
607 ); 607 );
608 if( vRet.getType() == Variable::typeString ) 608 if( vRet.getType() == Variable::typeString )
609 { 609 {
610 pCurTarget->addInput( vRet.getString() ); 610 pCurTarget->addInput( vRet.getString() );
611 } 611 }
612 else if( vRet.getType() == Variable::typeList ) 612 else if( vRet.getType() == Variable::typeList )
613 { 613 {
614 for( VarList::iterator i = vRet.begin(); i; i++ ) 614 for( VarList::iterator i = vRet.begin(); i; i++ )
615 { 615 {
616 pCurTarget->addInput( 616 pCurTarget->addInput(
617 (*i).getString() 617 (*i).getString()
618 ); 618 );
619 } 619 }
620 } 620 }
621 } 621 }
622 else if( pCurRule != NULL ) 622 else if( pCurRule != NULL )
623 { 623 {
624 pCurRule->setInput( pExpr ); 624 pCurRule->setInput( pExpr );
625 } 625 }
626 else 626 else
627 { 627 {
628 throw Bu::ExceptionBase( 628 throw Bu::ExceptionBase(
629 "input can only occur within a target or rule."); 629 "input can only occur within a target or rule.");
630 } 630 }
631 break; 631 break;
632 632
633 case AstNode::typeRequires: 633 case AstNode::typeRequires:
634 if( pCurTarget != NULL ) 634 if( pCurTarget != NULL )
635 { 635 {
636 Variable vRet = execExpr( 636 Variable vRet = execExpr(
637 (*pExpr->getBranchBegin()).begin() 637 (*pExpr->getBranchBegin()).begin()
638 ); 638 );
639 if( vRet.getType() == Variable::typeString ) 639 if( vRet.getType() == Variable::typeString )
640 { 640 {
641 pCurTarget->addRequires( vRet.getString() ); 641 pCurTarget->addRequires( vRet.getString() );
642 } 642 }
643 else if( vRet.getType() == Variable::typeList ) 643 else if( vRet.getType() == Variable::typeList )
644 { 644 {
645 for( VarList::iterator i = vRet.begin(); i; i++ ) 645 for( VarList::iterator i = vRet.begin(); i; i++ )
646 { 646 {
647 pCurTarget->addRequires( 647 pCurTarget->addRequires(
648 (*i).getString() 648 (*i).getString()
649 ); 649 );
650 } 650 }
651 } 651 }
652 } 652 }
653 else if( pCurRule != NULL ) 653 else if( pCurRule != NULL )
654 { 654 {
655 pCurRule->addRequires( pExpr ); 655 pCurRule->addRequires( pExpr );
656 } 656 }
657 else 657 else
658 { 658 {
659 throw Bu::ExceptionBase( 659 throw Bu::ExceptionBase(
660 "requires can only occur within a target or rule."); 660 "requires can only occur within a target or rule.");
661 } 661 }
662 break; 662 break;
663 663
664 case AstNode::typeRule: 664 case AstNode::typeRule:
665 if( pCurTarget ) 665 if( pCurTarget )
666 { 666 {
667 pCurTarget->setRule( 667 pCurTarget->setRule(
668 dynamic_cast<const AstLeaf *>( 668 dynamic_cast<const AstLeaf *>(
669 (*pExpr->getBranchBegin()).first() 669 (*pExpr->getBranchBegin()).first()
670 )->getStrValue() 670 )->getStrValue()
671 ); 671 );
672 } 672 }
673 else 673 else
674 { 674 {
675 throw Bu::ExceptionBase( 675 throw Bu::ExceptionBase(
676 "rule can only occur within a target."); 676 "rule can only occur within a target.");
677 } 677 }
678 break; 678 break;
679 679
680 case AstNode::typeProfile: 680 case AstNode::typeProfile:
681 if( pCurTarget ) 681 if( pCurTarget )
682 { 682 {
683 pCurTarget->addProfile( pExpr ); 683 pCurTarget->addProfile( pExpr );
684 } 684 }
685 else if( pCurRule ) 685 else if( pCurRule )
686 { 686 {
687 pCurRule->addProfile( pExpr ); 687 pCurRule->addProfile( pExpr );
688 } 688 }
689 else 689 else
690 { 690 {
691 throw Bu::ExceptionBase( 691 throw Bu::ExceptionBase(
692 "profile can only occur within a target or rule."); 692 "profile can only occur within a target or rule.");
693 } 693 }
694 break; 694 break;
695 695
696 case AstNode::typeOutput: 696 case AstNode::typeOutput:
697 if( pCurRule ) 697 if( pCurRule )
698 { 698 {
699 pCurRule->addOutput( pExpr ); 699 pCurRule->addOutput( pExpr );
700 } 700 }
701 else 701 else
702 { 702 {
703 throw Bu::ExceptionBase( 703 throw Bu::ExceptionBase(
704 "output can only occur within a rule."); 704 "output can only occur within a rule.");
705 } 705 }
706 break; 706 break;
707 707
708 case AstNode::typeProcessTarget: 708 case AstNode::typeProcessTarget:
709 { 709 {
710 AstBranch::BranchList::const_iterator b = 710 AstBranch::BranchList::const_iterator b =
711 pExpr->getBranchBegin(); 711 pExpr->getBranchBegin();
712 Bu::String sProfile = dynamic_cast<const AstLeaf *>( 712 Bu::String sProfile = dynamic_cast<const AstLeaf *>(
713 (*b).first() 713 (*b).first()
714 )->getStrValue(); 714 )->getStrValue();
715 b++; 715 b++;
716 Variable vTargs = execExpr( (*b).begin() ); 716 Variable vTargs = execExpr( (*b).begin() );
717 if( vTargs.getType() == Variable::typeString ) 717 if( vTargs.getType() == Variable::typeString )
718 { 718 {
719 rCont.getTarget( vTargs.getString() )->process( 719 rCont.getTarget( vTargs.getString() )->process(
720 *this, sProfile 720 *this, sProfile
721 ); 721 );
722 } 722 }
723 else if( vTargs.getType() == Variable::typeList ) 723 else if( vTargs.getType() == Variable::typeList )
724 { 724 {
725 for( VarList::iterator v = vTargs.begin(); 725 for( VarList::iterator v = vTargs.begin();
726 v; v++ ) { 726 v; v++ ) {
727 rCont.getTarget( (*v).getString() )->process( 727 rCont.getTarget( (*v).getString() )->process(
728 *this, sProfile 728 *this, sProfile
729 ); 729 );
730 } 730 }
731 } 731 }
732 } 732 }
733 break; 733 break;
734 734
735 case AstNode::typeTag: 735 case AstNode::typeTag:
736 if( pCurTarget ) 736 if( pCurTarget )
737 { 737 {
738 AstBranch::BranchList::const_iterator b = 738 AstBranch::BranchList::const_iterator b =
739 pExpr->getBranchBegin(); 739 pExpr->getBranchBegin();
740 Variable vTags = execExpr( (*b).begin() ); 740 Variable vTags = execExpr( (*b).begin() );
741 if( vTags.getType() == Variable::typeList ) 741 if( vTags.getType() == Variable::typeList )
742 { 742 {
743 for( VarList::iterator i = vTags.begin(); i; i++ ) 743 for( VarList::iterator i = vTags.begin(); i; i++ )
744 { 744 {
745 rCont.addTargetToTag( pCurTarget, (*i).toString() ); 745 rCont.addTargetToTag( pCurTarget, (*i).toString() );
746 } 746 }
747 } 747 }
748 else 748 else
749 { 749 {
750 Bu::String sTag = vTags.toString(); 750 Bu::String sTag = vTags.toString();
751 if( sTag.isSet() ) 751 if( sTag.isSet() )
752 { 752 {
753 rCont.addTargetToTag( pCurTarget, sTag ); 753 rCont.addTargetToTag( pCurTarget, sTag );
754 } 754 }
755 else 755 else
756 { 756 {
757 throw Bu::ExceptionBase( 757 throw Bu::ExceptionBase(
758 "A tag evaluted to empty string." 758 "A tag evaluted to empty string."
759 ); 759 );
760 } 760 }
761 } 761 }
762 } 762 }
763 else if( pCurRule ) 763 else if( pCurRule )
764 { 764 {
765 AstBranch::BranchList::const_iterator b = 765 AstBranch::BranchList::const_iterator b =
766 pExpr->getBranchBegin(); 766 pExpr->getBranchBegin();
767 Variable vTags = execExpr( (*b).begin() ); 767 Variable vTags = execExpr( (*b).begin() );
768 if( vTags.getType() == Variable::typeList ) 768 if( vTags.getType() == Variable::typeList )
769 { 769 {
770 for( VarList::iterator i = vTags.begin(); i; i++ ) 770 for( VarList::iterator i = vTags.begin(); i; i++ )
771 { 771 {
772 pCurRule->addTag( (*i).toString() ); 772 pCurRule->addTag( (*i).toString() );
773 } 773 }
774 } 774 }
775 else 775 else
776 { 776 {
777 Bu::String sTag = vTags.toString(); 777 Bu::String sTag = vTags.toString();
778 if( sTag.isSet() ) 778 if( sTag.isSet() )
779 { 779 {
780 pCurRule->addTag( sTag ); 780 pCurRule->addTag( sTag );
781 } 781 }
782 else 782 else
783 { 783 {
784 throw Bu::ExceptionBase( 784 throw Bu::ExceptionBase(
785 "A tag evaluted to empty string." 785 "A tag evaluted to empty string."
786 ); 786 );
787 } 787 }
788 } 788 }
789 } 789 }
790 else 790 else
791 { 791 {
792 throw Bu::ExceptionBase( 792 throw Bu::ExceptionBase(
793 "tag can only occur within a target or rule."); 793 "tag can only occur within a target or rule.");
794 } 794 }
795 break; 795 break;
796 796
797 case AstNode::typeExpr: 797 case AstNode::typeExpr:
798 execExpr( (*pExpr->getBranchBegin()).begin() ); 798 execExpr( (*pExpr->getBranchBegin()).begin() );
799 break; 799 break;
800 800
801 default: 801 default:
802 sio << "Branch? " << (*i)->getType() << sio.nl; 802 sio << "Branch? " << (*i)->getType() << sio.nl;
803 break; 803 break;
804 } 804 }
805 } 805 }
806 806
807 i++; 807 i++;
808 } 808 }
809 809
810 return vReturn; 810 return vReturn;
811} 811}
812 812
813void Runner::execProfile( Target *pTarget, const Bu::String &sProfile ) 813void Runner::execProfile( Target *pTarget, const Bu::String &sProfile )
814{ 814{
815 rCont.pushScope( pTarget->getVars() ); 815 rCont.pushScope( pTarget->getVars() );
816 run( (*(pTarget->getProfile( sProfile )->getRoot()-> 816 run( (*(pTarget->getProfile( sProfile )->getRoot()->
817 getBranchBegin()+1)).begin() ); 817 getBranchBegin()+1)).begin() );
818 rCont.popScope(); 818 rCont.popScope();
819} 819}
820 820
821void Runner::execAction( const Bu::String &sName ) 821void Runner::execAction( const Bu::String &sName )
822{ 822{
823 try 823 try
824 { 824 {
825 Action *pAct = rCont.getAction( sName ); 825 Action *pAct = rCont.getAction( sName );
826 826
827 pAct->call( this ); 827 pAct->call( this );
828 } 828 }
829 catch( Bu::HashException &e ) 829 catch( Bu::HashException &e )
830 { 830 {
831 Bu::String sError("No such action '" + sName + "' found."); 831 Bu::String sError("No such action '" + sName + "' found.");
832 rCont.getView()->sysError( sError ); 832 rCont.getView()->sysError( sError );
833 } 833 }
834} 834}
835 835
836Context &Runner::getContext() 836Context &Runner::getContext()
837{ 837{
838 return rCont; 838 return rCont;
839} 839}
840 840
841Target *Runner::buildTarget( const Bu::String &sOutput, 841Target *Runner::buildTarget( const Bu::String &sOutput,
842 AstBranch::NodeList::const_iterator n ) 842 AstBranch::NodeList::const_iterator n )
843{ 843{
844 Target *pTrg = NULL; 844 Target *pTrg = NULL;
845 try 845 try
846 { 846 {
847 pTrg = rCont.getTarget( sOutput ); 847 pTrg = rCont.getTarget( sOutput );
848 rCont.pushScope( pTrg->getVars() ); 848 rCont.pushScope( pTrg->getVars() );
849 } 849 }
850 catch( Bu::HashException &e ) 850 catch( Bu::HashException &e )
851 { 851 {
852 pTrg = new Target( sOutput, true ); 852 pTrg = new Target( sOutput, true );
853 rCont.pushScope(); 853 rCont.pushScope();
854 } 854 }
855 855
856 // sio << " (target) \"" << sOutput << "\" explicit." << sio.nl; 856 // sio << " (target) \"" << sOutput << "\" explicit." << sio.nl;
857 857
858 rCont.addVariable("OUTPUT", sOutput ); 858 rCont.addVariable("OUTPUT", sOutput );
859 pCurTarget = pTrg; 859 pCurTarget = pTrg;
860 run( n ); 860 run( n );
861 861
862 rCont.addVariable("INPUT", pTrg->getInputList() ); 862 rCont.addVariable("INPUT", pTrg->getInputList() );
863 pCurTarget = NULL; 863 pCurTarget = NULL;
864 864
865 pTrg->setVars( rCont.getScope() ); 865 pTrg->setVars( rCont.getScope() );
866 rCont.popScope(); 866 rCont.popScope();
867 867
868 return pTrg; 868 return pTrg;
869} 869}
870 870
871Rule *Runner::buildRule( const Bu::String &sName, 871Rule *Runner::buildRule( const Bu::String &sName,
872 AstBranch::NodeList::const_iterator n ) 872 AstBranch::NodeList::const_iterator n )
873{ 873{
874 Rule *pRule = new Rule( sName ); 874 Rule *pRule = new Rule( sName );
875 875
876 rCont.pushScope(); 876 rCont.pushScope();
877 pCurRule = pRule; 877 pCurRule = pRule;
878 run( n ); 878 run( n );
879 rCont.popScope(); 879 rCont.popScope();
880 pCurRule = NULL; 880 pCurRule = NULL;
881 881
882 return pRule; 882 return pRule;
883} 883}
884 884
885Variable Runner::doSet( const AstBranch *pRoot ) 885Variable Runner::doSet( const AstBranch *pRoot )
886{ 886{
887 AstBranch::NodeList::const_iterator n = 887 AstBranch::NodeList::const_iterator n =
888 (*pRoot->getBranchBegin()).begin(); 888 (*pRoot->getBranchBegin()).begin();
889 Bu::String sVar = dynamic_cast<const AstLeaf *>( *n )->getStrValue(); 889 Bu::String sVar = dynamic_cast<const AstLeaf *>( *n )->getStrValue();
890 n++; 890 n++;
891 const AstLeaf *pLeaf = dynamic_cast<const AstLeaf *>( *n ); 891 const AstLeaf *pLeaf = dynamic_cast<const AstLeaf *>( *n );
892 n++; 892 n++;
893 Variable v = execExpr( n ); 893 Variable v = execExpr( n );
894 894
895 switch( pLeaf->getType() ) 895 switch( pLeaf->getType() )
896 { 896 {
897 case AstNode::typeOpEq: 897 case AstNode::typeOpEq:
898 rCont.addVariable( sVar, v ); 898 rCont.addVariable( sVar, v );
899 break; 899 break;
900 900
901 case AstNode::typeOpPlusEq: 901 case AstNode::typeOpPlusEq:
902 try 902 try
903 { 903 {
904 rCont.getVariable( sVar ) += v; 904 rCont.getVariable( sVar ) += v;
905 } catch(...) 905 } catch(...)
906 { 906 {
907 rCont.addVariable( sVar, v ); 907 rCont.addVariable( sVar, v );
908 } 908 }
909 break; 909 break;
910 910
911 case AstNode::typeOpPlusEqRaw: 911 case AstNode::typeOpPlusEqRaw:
912 try 912 try
913 { 913 {
914 rCont.getVariable( sVar ) << v; 914 rCont.getVariable( sVar ) << v;
915 } catch(...) 915 } catch(...)
916 { 916 {
917 rCont.addVariable( sVar, v ); 917 rCont.addVariable( sVar, v );
918 } 918 }
919 break; 919 break;
920 920
921 default: break; 921 default: break;
922 } 922 }
923 923
924 return v; 924 return v;
925} 925}
926 926