1 /***************************************************************************
2 prognodeexpr.cpp - GDL's AST is made of DNodes
3 -------------------
4 begin : July 22 2002
5 copyright : (C) 2002 by Marc Schellens
6 email : m_schellens@users.sf.net
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "includefirst.hpp"
19
20 #include <memory>
21 #include <cassert>
22
23 #include <antlr/ASTFactory.hpp>
24
25 #include "dinterpreter.hpp"
26 #include "prognodeexpr.hpp"
27 #include "basegdl.hpp"
28 #include "arrayindexlistt.hpp"
29 #include "envt.hpp"
30 #include "gdlexception.hpp"
31 #include "nullgdl.hpp"
32 #include "basic_fun.hpp"
33 #include "basic_fun_jmg.hpp"
34
35 #include "initsysvar.hpp"
36
37 using namespace std;
38
39
BinaryExpr(const RefDNode & refNode)40 BinaryExpr::BinaryExpr( const RefDNode& refNode): DefaultNode( refNode)
41 {
42 op1 = GetFirstChild();
43 op2 = GetFirstChild()->GetNextSibling();
44 setType( GDLTokenTypes::EXPR);
45 }
46
BinaryExprNC(const RefDNode & refNode)47 BinaryExprNC::BinaryExprNC( const RefDNode& refNode): BinaryExpr( refNode)
48 {
49 op1NC = NonCopyNode( op1->getType());
50 op2NC = NonCopyNode( op2->getType());
51 }
52
ProgNode()53 ProgNode::ProgNode(): // for NULLProgNode
54 ttype( antlr::Token::NULL_TREE_LOOKAHEAD),
55 text( "NULLProgNode"),
56 keepRight( false),
57 keepDown( false),
58 breakTarget( NULL),
59 down( NULL),
60 right( NULL),
61 cData( NULL),
62 var( NULL),
63 libFun( NULL),
64 libPro( NULL),
65 lineNumber( 0),
66 labelStart( 0),
67 labelEnd( 0)
68 {}
69
EvalNC()70 BaseGDL* ProgNode::EvalNC()
71 {
72 throw GDLException( this,
73 "Internal error. ProgNode::EvalNC() called.",true,false);
74 }
EvalNCNull()75 BaseGDL* ProgNode::EvalNCNull()
76 {
77 return this->EvalNC();
78 }
79
LEval()80 BaseGDL** ProgNode::LEval()
81 {
82 throw GDLException( this,
83 "Internal error. ProgNode::LEval() called.",true,false);
84 }
EvalRefCheck(BaseGDL * & rEval)85 BaseGDL** ProgNode::EvalRefCheck( BaseGDL*& rEval) // default like Eval()
86 {
87 rEval = this->Eval();
88 return NULL;
89 }
90
Run()91 RetCode ProgNode::Run()
92 {
93 throw GDLException( this,
94 "Internal error. ProgNode::Run() called.",true,false);
95 return RC_OK; // silence compiler
96 }
97
SetRightDown(const ProgNodeP r,const ProgNodeP d)98 void ProgNode::SetRightDown( const ProgNodeP r, const ProgNodeP d)
99 {
100 right = r;
101 down = d;
102 }
103
Eval()104 BaseGDL* ProgNode::Eval()
105 {
106 throw GDLException( this,
107 "Internal error. ProgNode::Eval() called.",true,false);
108 // return ProgNode::interpreter->expr( this);
109 }
110
111
112
113 // converts inferior type to superior type
114 // for not (yet) overloaded operators
AdjustTypes(Guard<BaseGDL> & a,Guard<BaseGDL> & b)115 void ProgNode::AdjustTypes(Guard<BaseGDL>& a, Guard<BaseGDL>& b)
116 {
117 DType aTy=a->Type();
118 DType bTy=b->Type();
119 if( aTy == bTy) return;
120
121 // Will be checked by Convert2() function
122 // if( DTypeOrder[aTy] > 100 || DTypeOrder[bTy] > 100) // GDL_STRUCT, GDL_PTR, OBJ
123 // {
124 // //exception
125 // throw GDLException( "Expressions of this type cannot be converted.");
126 // }
127
128 // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
129 DType cxTy = PromoteComplexOperand( aTy, bTy);
130 if( cxTy != GDL_UNDEF)
131 {
132 a.reset( a.release()->Convert2( cxTy));
133 b.reset( b.release()->Convert2( cxTy));
134 return;
135 }
136
137 // Change > to >= JMG
138 if( DTypeOrder[aTy] >= DTypeOrder[bTy])
139 {
140 // convert b to a
141 b.reset( b.release()->Convert2( aTy));
142 }
143 else
144 {
145 // convert a to b
146 a.reset( a.release()->Convert2( bTy));
147 }
148 }
149 // converts inferior type to superior type
150 // handles overloaded operators
AdjustTypesObj(Guard<BaseGDL> & a,Guard<BaseGDL> & b)151 void ProgNode::AdjustTypesObj(Guard<BaseGDL>& a, Guard<BaseGDL>& b)
152 {
153 DType aTy=a->Type();
154 DType bTy=b->Type();
155 if( aTy == bTy) return;
156
157 // Will be checked by Convert2() function
158 // if( DTypeOrder[aTy] > 100 || DTypeOrder[bTy] > 100) // GDL_STRUCT, GDL_PTR, OBJ
159 // {
160 // //exception
161 // throw GDLException( "Expressions of this type cannot be converted.");
162 // }
163
164 // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
165 DType cxTy = PromoteComplexOperand( aTy, bTy);
166 if( cxTy != GDL_UNDEF)
167 {
168 a.reset( a.release()->Convert2( cxTy));
169 b.reset( b.release()->Convert2( cxTy));
170 return;
171 }
172
173 // Change > to >= JMG
174 if( DTypeOrder[aTy] >= DTypeOrder[bTy])
175 {
176 // convert b to a
177 if( aTy == GDL_OBJ) // only check for aTy is ok because GDL_OBJ has highest order
178 return; // for operator overloading, do not convert other type then
179 b.reset( b.release()->Convert2( aTy));
180 }
181 else
182 {
183 // convert a to b
184 if( bTy == GDL_OBJ) // only check for bTy is ok because GDL_OBJ has highest order
185 return; // for operator overloading, do not convert other type then
186 a.reset( a.release()->Convert2( bTy));
187 }
188 }
189
190 // for not (yet) overloaded operators
AdjustTypesNC(Guard<BaseGDL> & g1,BaseGDL * & e1,Guard<BaseGDL> & g2,BaseGDL * & e2)191 void BinaryExprNC::AdjustTypesNC(Guard<BaseGDL>& g1, BaseGDL*& e1,
192 Guard<BaseGDL>& g2, BaseGDL*& e2)
193 {
194 if( op1NC)
195 {
196 e1 = op1->EvalNC();
197 }
198 else
199 {
200 e1 = op1->Eval();
201 g1.reset( e1);
202 }
203 if( op2NC)
204 {
205 e2 = op2->EvalNC();
206 }
207 else
208 {
209 e2 = op2->Eval();
210 g2.reset( e2);
211 }
212
213 DType aTy=e1->Type();
214 DType bTy=e2->Type();
215 if( aTy == bTy) return;
216
217 // Will be checked by Convert2() function
218 // if( DTypeOrder[aTy] > 100 || DTypeOrder[bTy] > 100) // GDL_STRUCT, GDL_PTR, OBJ
219 // {
220 // throw GDLException( "Expressions of this type cannot be converted.");
221 // }
222 DType cxTy = PromoteComplexOperand( aTy, bTy);
223 if( cxTy != GDL_UNDEF)
224 {
225 e2 = e2->Convert2( cxTy, BaseGDL::COPY);
226 g2.reset( e2); // delete former e2
227 e1 = e1->Convert2( cxTy, BaseGDL::COPY);
228 g1.reset( e1); // delete former e1
229 return;
230 }
231
232 // Change > to >= JMG
233 if( DTypeOrder[aTy] >= DTypeOrder[bTy])
234 {
235 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
236 // if( (aTy == GDL_COMPLEX && bTy == GDL_DOUBLE))
237 // {
238 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
239 // g2.reset( e2); // delete former e2
240 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
241 // g1.reset( e1); // delete former e1
242 // return;
243 // }
244
245 // convert e2 to e1
246 e2 = e2->Convert2( aTy, BaseGDL::COPY);
247 g2.reset( e2); // delete former e2
248 }
249 else
250 {
251 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
252 // if( (bTy == GDL_COMPLEX && aTy == GDL_DOUBLE))
253 // {
254 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
255 // g2.reset( e2); // delete former e2
256 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
257 // g1.reset( e1); // delete former e1
258 // return;
259 // }
260
261 // convert e1 to e2
262 e1 = e1->Convert2( bTy, BaseGDL::COPY);
263 g1.reset( e1); // delete former e1
264 }
265 }
266
267 // handles overloaded operators
SetupGuards(Guard<BaseGDL> & g1,BaseGDL * & e1,Guard<BaseGDL> & g2,BaseGDL * & e2)268 void BinaryExprNC::SetupGuards(Guard<BaseGDL>& g1, BaseGDL*& e1,
269 Guard<BaseGDL>& g2, BaseGDL*& e2)
270 {
271 if( op1NC)
272 {
273 e1 = op1->EvalNC();
274 }
275 else
276 {
277 e1 = op1->Eval();
278 g1.Init( e1);
279 }
280 if( op2NC)
281 {
282 e2 = op2->EvalNC();
283 }
284 else
285 {
286 e2 = op2->Eval();
287 g2.Init( e2);
288 }
289 }
290
291
292 // only called from EqOp and NeOp
293 // also handles overloaded operators
AdjustTypesNCNull(Guard<BaseGDL> & g1,BaseGDL * & e1,Guard<BaseGDL> & g2,BaseGDL * & e2)294 void BinaryExprNC::AdjustTypesNCNull(Guard<BaseGDL>& g1, BaseGDL*& e1,
295 Guard<BaseGDL>& g2, BaseGDL*& e2)
296 {
297 if( op1NC)
298 {
299 e1 = op1->EvalNCNull();
300 }
301 else
302 {
303 e1 = op1->Eval();
304 g1.Init( e1);
305 }
306 if( op2NC)
307 {
308 e2 = op2->EvalNCNull();
309 }
310 else
311 {
312 e2 = op2->Eval();
313 g2.Init( e2);
314 }
315
316 // if at least one is !NULL make sure this is e1
317 if( e1 == NullGDL::GetSingleInstance())
318 return;
319 if( e2 == NullGDL::GetSingleInstance())
320 {
321 // e1 is not !NULL (but might be NULL)
322 // BaseGDL* tmp = e1;
323 // e1 = e2;
324 // e2 = tmp;
325 e2 = e1;
326 e1 = NullGDL::GetSingleInstance();
327 return;
328 }
329
330 if( e1 == NULL)
331 {
332 // provoke error
333 e1 = op1->EvalNC();
334 assert( false); // code should never reach here
335 }
336 else if( e2 == NULL)
337 {
338 // provoke error
339 e2 = op2->EvalNC();
340 assert( false); // code should never reach here
341 }
342
343 DType aTy=e1->Type();
344 DType bTy=e2->Type();
345 if( aTy == bTy) return;
346
347 // Will be checked by Convert2() function
348 // if( DTypeOrder[aTy] > 100 || DTypeOrder[bTy] > 100) // GDL_STRUCT, GDL_PTR, OBJ
349 // {
350 // throw GDLException( "Expressions of this type cannot be converted.");
351 // }
352
353 // Change > to >= JMG
354 DType cxTy = PromoteComplexOperand( aTy, bTy);
355 if( cxTy != GDL_UNDEF)
356 {
357 e2 = e2->Convert2( cxTy, BaseGDL::COPY);
358 g2.Reset( e2); // delete former e2
359 e1 = e1->Convert2( cxTy, BaseGDL::COPY);
360 g1.Reset( e1); // delete former e1
361 return;
362 }
363
364 if( DTypeOrder[aTy] >= DTypeOrder[bTy])
365 {
366 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
367 // if( (aTy == GDL_COMPLEX && bTy == GDL_DOUBLE))
368 // {
369 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
370 // g2.Reset( e2); // delete former e2
371 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
372 // g1.Reset( e1); // delete former e1
373 // return;
374 // }
375
376 // no conversion because of operator overloads
377 if( aTy == GDL_OBJ) // only check for aTy is ok because GDL_OBJ has highest order
378 return;
379
380 // convert e2 to e1
381 e2 = e2->Convert2( aTy, BaseGDL::COPY);
382 g2.Reset( e2); // delete former e2
383 }
384 else
385 {
386 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
387 // if( (bTy == GDL_COMPLEX && aTy == GDL_DOUBLE))
388 // {
389 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
390 // g2.Reset( e2); // delete former e2
391 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
392 // g1.Reset( e1); // delete former e1
393 // return;
394 // }
395
396 // no conversion because of operator overloads
397 if( bTy == GDL_OBJ) // only check for bTy is ok because GDL_OBJ has highest order
398 return;
399
400 // convert e1 to e2
401 e1 = e1->Convert2( bTy, BaseGDL::COPY);
402 g1.Reset( e1); // delete former e1
403 }
404 }
405
Eval()406 BaseGDL* VARNode::Eval()
407 {
408 BaseGDL* vData = this->EvalNC();
409 if( vData == NULL)
410 {
411 throw GDLException( this, "Variable is undefined: "+this->getText(),true,false);
412 }
413 return vData->Dup();
414 }
Eval()415 BaseGDL* VARPTRNode::Eval()
416 {
417 BaseGDL* vData = this->EvalNC();
418 if( vData == NULL)
419 {
420 throw GDLException( this, "Common block variable is undefined.",true,false);
421 }
422 return vData->Dup();
423 }
Eval()424 BaseGDL* SYSVARNode::Eval()
425 {
426 return this->EvalNC()->Dup();
427 }
428
EvalNC()429 BaseGDL* VARNode::EvalNC()
430 {
431 EnvStackT& callStack=interpreter->CallStack();
432 BaseGDL* res=static_cast<EnvUDT*> ( callStack.back() )->GetKW ( this->varIx );
433 if ( res == NULL )
434 throw GDLException ( this, "Variable is undefined: "+
435 callStack.back()->GetString ( this->varIx ),true,false );
436 return res;
437 }
EvalNCNull()438 BaseGDL* VARNode::EvalNCNull()
439 {
440 EnvStackT& callStack=interpreter->CallStack();
441 BaseGDL* res=static_cast<EnvUDT*> ( callStack.back() )->GetKW ( this->varIx );
442 // if ( res == NULL )
443 // res = NullGDL::GetSingleInstance();
444 return res;
445 }
446
EvalNC()447 BaseGDL* VARPTRNode::EvalNC()
448 {
449 BaseGDL* res=this->var->Data();
450 if( res == NULL)
451 {
452 EnvStackT& callStack=interpreter->CallStack();
453 throw GDLException( this, "Variable is undefined: "+
454 callStack.back()->GetString( res),true,false);
455 }
456 return res;
457 }
EvalNCNull()458 BaseGDL* VARPTRNode::EvalNCNull()
459 {
460 BaseGDL* res=this->var->Data();
461 // if( res == NULL)
462 // res = NullGDL::GetSingleInstance();
463 return res;
464 }
465
EvalNC()466 BaseGDL* CONSTANTNode::EvalNC()
467 {
468 return this->cData;
469 }
Eval()470 BaseGDL* CONSTANTNode::Eval()
471 {
472 return this->cData->Dup();
473 }
474
EvalNC()475 BaseGDL* SYSVARNode::EvalNC()
476 {
477 //GD: explore also obsoleteSysVarList (costs nothing)
478 if( this->var == NULL)
479 {
480 this->var=FindInVarList(sysVarList,this->getText());
481 if( this->var == NULL) {
482 this->var=FindInVarList(obsoleteSysVarList,this->getText());
483 if( this->var == NULL) throw GDLException( this, "Not a legal system variable: !"+this->getText(),true,false);
484 }
485 }
486
487 // we have these two variables which need to be updated before returning
488 if( SysVar::STime() == this->var->Data()) SysVar::UpdateSTime();
489 // if( SysVar::D() == this->var->Data()) SysVar::UpdateD();
490
491 // system variables are always defined
492 return this->var->Data();
493 }
494
EvalRefCheck(BaseGDL * & rEval)495 BaseGDL** SYSVARNode::EvalRefCheck( BaseGDL*& rEval)
496 {
497 return this->LEval();
498 }
499
LEval()500 BaseGDL** SYSVARNode::LEval()
501 {
502 const ProgNodeP& sysVar = this;
503 //match(antlr::RefAST(_t),SYSVAR);
504 if( sysVar->var == NULL)
505 {
506 sysVar->var=FindInVarList(sysVarList,sysVar->getText());
507 if( sysVar->var == NULL) {
508 sysVar->var = FindInVarList(obsoleteSysVarList, sysVar->getText());
509 if (sysVar->var == NULL) {
510 throw GDLException( sysVar, "Not a legal system variable: !"+sysVar->getText(),true,false);
511 }
512 }
513
514 // note: this works, because system variables are never
515 // passed by reference
516 SizeT rdOnlySize = sysVarRdOnlyList.size();
517 for( SizeT i=0; i<rdOnlySize; ++i)
518 if( sysVarRdOnlyList[ i] == sysVar->var)
519 throw GDLException( this,
520 "Attempt to write to a readonly variable: !"+
521 sysVar->getText(),true,false);
522 }
523 // interpreter->SetRetTree( sysVar->getNextSibling());
524 // system variables are always defined
525 return &sysVar->var->Data();
526 }
527
528
Eval()529 BaseGDL* DEREFNode::Eval()
530 {
531 Guard<BaseGDL> e1_guard;
532 BaseGDL* e1;
533 ProgNodeP evalExpr = this->getFirstChild();
534 if( NonCopyNode( evalExpr->getType()))
535 {
536 e1 = evalExpr->EvalNC();
537 }
538 else
539 {
540 BaseGDL** ref = evalExpr->EvalRefCheck(e1);
541 if( ref == NULL)
542 // here a guard is ok here as we return a copy
543 e1_guard.Init( e1);
544 else
545 e1 = *ref;
546 }
547
548 if( e1 == NULL || e1->Type() != GDL_PTR)
549 throw GDLException( evalExpr, "Pointer type required"
550 " in this context: "+interpreter->Name(e1),true,false);
551
552 DPtrGDL* ptr=static_cast<DPtrGDL*>(e1);
553
554 DPtr sc;
555 if( !ptr->StrictScalar(sc))
556 throw GDLException( this, "Expression must be a scalar in this context: "+
557 interpreter->Name(e1),true,false);
558 if( sc == 0)
559 throw GDLException( this, "Unable to dereference NULL pointer: "+
560 interpreter->Name(e1),true,false);
561
562 BaseGDL** res;
563 try{
564 res = &interpreter->GetHeap(sc);
565 }
566 catch( DInterpreter::HeapException)
567 {
568 throw GDLException( this, "Invalid pointer: "+interpreter->Name(e1),true,false);
569 }
570
571 if( *res == NULL)
572 throw GDLException( this, "Variable is undefined: "+
573 interpreter->Name(res),true,false);
574 return (*res)->Dup();
575 }
576
EvalNC()577 BaseGDL* DEREFNode::EvalNC()
578 {
579 BaseGDL* e1;
580 ProgNodeP evalExpr = this->getFirstChild();
581 if( NonCopyNode( evalExpr->getType()))
582 {
583 e1 = evalExpr->EvalNC();
584 }
585 else
586 {
587 BaseGDL** ref = evalExpr->EvalRefCheck(e1);
588 if( ref == NULL)
589 {
590 // use new env if set (during parameter parsing)
591 EnvBaseT* actEnv = DInterpreter::CallStackBack()->GetNewEnv();
592 if( actEnv == NULL) actEnv = DInterpreter::CallStackBack();
593 assert( actEnv != NULL);
594 // this is crucial, a guard does not work here as a temporary
595 // ptr will be cleaned up at return from this function
596 actEnv->DeleteAtExit( e1);
597 }
598 else
599 e1 = *ref;
600 }
601
602 if( e1 == NULL || e1->Type() != GDL_PTR)
603 throw GDLException( this, "Pointer type required"
604 " in this context: "+interpreter->Name(e1),true,false);
605 DPtrGDL* ptr=static_cast<DPtrGDL*>(e1);
606 DPtr sc;
607 if( !ptr->Scalar(sc))
608 throw GDLException( this, "Expression must be a "
609 "scalar in this context: "+interpreter->Name(e1),true,false);
610 if( sc == 0)
611 throw GDLException( this, "Unable to dereference"
612 " NULL pointer: "+interpreter->Name(e1),true,false);
613
614 try{
615 return interpreter->GetHeap(sc);
616 }
617 catch( GDLInterpreter::HeapException)
618 {
619 throw GDLException( this, "Invalid pointer: "+interpreter->Name(e1),true,false);
620 }
621 }
622
EvalRefCheck(BaseGDL * & rEval)623 BaseGDL** DEREFNode::EvalRefCheck( BaseGDL*& rEval)
624 {
625 return this->LEval();
626 }
627
LEval()628 BaseGDL** DEREFNode::LEval()
629 {
630 BaseGDL* e1;
631 ProgNodeP evalExpr = this->getFirstChild();
632 if( NonCopyNode( evalExpr->getType()))
633 {
634 e1 = evalExpr->EvalNC();
635 }
636 else
637 {
638 BaseGDL** ref = evalExpr->EvalRefCheck(e1);
639 if( ref == NULL)
640 {
641 // use new env if set (during parameter parsing)
642 EnvBaseT* actEnv = DInterpreter::CallStackBack()->GetNewEnv();
643 if( actEnv == NULL) actEnv = DInterpreter::CallStackBack();
644 assert( actEnv != NULL);
645 // this is crucial, a guard does not work here as a temporary
646 // ptr will be cleaned up at return from this function
647 actEnv->DeleteAtExit( e1);
648 }
649 else
650 e1 = *ref;
651 }
652
653 if( e1 == NULL || e1->Type() != GDL_PTR)
654 throw GDLException( evalExpr, "Pointer type required in this context: "+
655 interpreter->Name(e1),true,false);
656
657 DPtrGDL* ptr=static_cast<DPtrGDL*>(e1);
658
659 DPtr sc;
660 if( !ptr->StrictScalar(sc))
661 throw GDLException( this, "Expression must be a scalar in this context: "+
662 interpreter->Name(e1),true,false);
663 if( sc == 0)
664 throw GDLException( this, "Unable to dereference NULL pointer: "+
665 interpreter->Name(e1),true,false);
666
667 BaseGDL** res;
668 try{
669 res = &interpreter->GetHeap(sc);
670 }
671 catch( DInterpreter::HeapException)
672 {
673 throw GDLException( this, "Invalid pointer: "+interpreter->Name(e1),true,false);
674 }
675
676 return res;
677 }
678
679
680
681
682
683 // trinary operator
EvalRefCheck(BaseGDL * & rEval)684 BaseGDL** QUESTIONNode::EvalRefCheck( BaseGDL*& rEval)
685 {
686 ProgNodeP branch = this->GetThisBranch();
687 return branch->EvalRefCheck( rEval);
688 }
689
LEval()690 BaseGDL** QUESTIONNode::LEval()
691 {
692 ProgNodeP branch = this->GetThisBranch();
693 return branch->LEval();
694 }
695
Eval()696 BaseGDL* QUESTIONNode::Eval()
697 {
698 ProgNodeP branch = this->GetThisBranch();
699 return branch->Eval();
700
701 // Guard<BaseGDL> e1_guard;
702 // BaseGDL* e1;
703 // if( NonCopyNode( op1->getType()))
704 // {
705 // e1 = op1->EvalNC();
706 // }
707 // else
708 // {
709 // // e1 = op1->Eval();
710 // // e1_guard.Init(e1);
711 // BaseGDL** ref = op1->EvalRefCheck(e1);
712 // if( ref == NULL)
713 // e1_guard.Init(e1);
714 // else
715 // e1 = *ref;
716 // }
717 // // Guard<BaseGDL> e1( op1->Eval());
718 // if( e1->True())
719 // {
720 // return op2->Eval(); // right->down
721 // }
722 // return op3->Eval(); // right->right
723 }
724
GetThisBranch()725 ProgNodeP QUESTIONNode::GetThisBranch()
726 {
727 Guard<BaseGDL> e1_guard;
728 BaseGDL* e1;
729 if( NonCopyNode( op1->getType()))
730 {
731 e1 = op1->EvalNC();
732 }
733 else
734 {
735 // e1 = op1->Eval();
736 // e1_guard.Init(e1);
737 BaseGDL** ref = op1->EvalRefCheck(e1);
738 if( ref == NULL)
739 e1_guard.Init(e1);
740 else
741 e1 = *ref;
742 }
743 // Guard<BaseGDL> e1( op1->Eval());
744 if( e1->True())
745 {
746 return op2;
747 }
748 return op3;
749 }
750
751 // unary operators
Eval()752 BaseGDL* UMINUSNode::Eval()
753 {
754 BaseGDL* e1 = down->Eval();
755 return e1->UMinus(); // might delete e1 (GDL_STRING)
756 }
Eval()757 BaseGDL* NOT_OPNode::Eval()
758 {
759 BaseGDL* e1 = down->Eval();
760 return e1->NotOp();
761 }
Eval()762 BaseGDL* LOG_NEGNode::Eval()
763 {
764 Guard<BaseGDL> e1( down->Eval());
765 return e1->LogNeg();
766 }
767
768 // binary operators
Eval()769 BaseGDL* AND_OPNode::Eval()
770 { BaseGDL* res;
771 Guard<BaseGDL> e1( op1->Eval());
772 Guard<BaseGDL> e2( op2->Eval());
773 AdjustTypes(e1,e2);
774 if( e1->StrictScalar())
775 {
776 res= e2->AndOpS(e1.get()); // scalar+scalar or array+scalar
777 e2.release();
778 }
779 else
780 if( e2->StrictScalar())
781 {
782 res= e1->AndOpInvS(e2.get()); // array+scalar
783 e1.release();
784 }
785 else
786 if( e1->N_Elements() <= e2->N_Elements())
787 {
788 res = e1->AndOpInv(e2.get()); // smaller_array + larger_array or same size
789 e1.release();
790 }
791 else
792 {
793 res = e2->AndOp(e1.get()); // smaller + larger
794 e2.release();
795 }
796 return res;
797 }
Eval()798 BaseGDL* OR_OPNode::Eval()
799 { BaseGDL* res;
800 Guard<BaseGDL> e1( op1->Eval());
801 Guard<BaseGDL> e2( op2->Eval());
802 AdjustTypes(e1,e2);
803 if( e1->StrictScalar())
804 {
805 res= e2->OrOpS(e1.get()); // scalar+scalar or array+scalar
806 e2.release();
807 }
808 else
809 if( e2->StrictScalar())
810 {
811 res= e1->OrOpInvS(e2.get()); // array+scalar
812 e1.release();
813 }
814 else
815 if( e1->N_Elements() <= e2->N_Elements())
816 {
817 res= e1->OrOpInv(e2.get()); // smaller_array + larger_array or same size
818 e1.release();
819 }
820 else
821 {
822 res= e2->OrOp(e1.get()); // smaller + larger
823 e2.release();
824 }
825 return res;
826 }
Eval()827 BaseGDL* XOR_OPNode::Eval()
828 { BaseGDL* res;
829 Guard<BaseGDL> e1( op1->Eval());
830 Guard<BaseGDL> e2( op2->Eval());
831 AdjustTypes(e1,e2);
832 if( e1->N_Elements() <= e2->N_Elements())
833 {
834 res= e1->XorOp(e2.get()); // smaller_array + larger_array or same size
835 e1.release();
836 }
837 else
838 {
839 res= e2->XorOp(e1.get()); // smaller + larger
840 e2.release();
841 }
842 return res;
843 }
Eval()844 BaseGDL* LOG_ANDNode::Eval()
845 { BaseGDL* res;
846 Guard<BaseGDL> e1( op1->Eval());
847 if( !e1->LogTrue()) return new DByteGDL( 0);
848 Guard<BaseGDL> e2( op2->Eval());
849 if( !e2->LogTrue()) return new DByteGDL( 0);
850 return new DByteGDL( 1);
851 }
Eval()852 BaseGDL* LOG_ORNode::Eval()
853 { BaseGDL* res;
854 Guard<BaseGDL> e1( op1->Eval());
855 if( e1->LogTrue()) return new DByteGDL( 1);
856 Guard<BaseGDL> e2( op2->Eval());
857 if( e2->LogTrue()) return new DByteGDL( 1);
858 return new DByteGDL( 0);
859 }
860
Eval()861 BaseGDL* EQ_OPNode::Eval()
862 {
863 Guard<BaseGDL> e1( op1->Eval());
864 Guard<BaseGDL> e2( op2->Eval());
865 AdjustTypesObj(e1,e2);
866 if( e2->Type() == GDL_OBJ)
867 {
868 if( e1->Type() != GDL_OBJ)
869 {
870 // order is critical: overload might just be defined for one of the object types
871 // use e2 only if e1 is no object
872 BaseGDL* res=e2->EqOp(e1.get());
873 if( e1.Get() == NullGDL::GetSingleInstance())
874 e1.Release();
875 return res;
876 }
877 }
878 BaseGDL* res=e1->EqOp(e2.get());
879 if( e1.Get() == NullGDL::GetSingleInstance())
880 e1.Release();
881 if( e2.Get() == NullGDL::GetSingleInstance())
882 e2.Release();
883 return res;
884 }
Eval()885 BaseGDL* NE_OPNode::Eval()
886 {
887 Guard<BaseGDL> e1( op1->Eval());
888 Guard<BaseGDL> e2( op2->Eval());
889 AdjustTypesObj(e1,e2);
890 if( e2->Type() == GDL_OBJ)
891 {
892 if( e1->Type() != GDL_OBJ)
893 {
894 // order is critical: overload might just be defined for one of the object types
895 // use e2 only if e1 is no object
896 BaseGDL* res=e2->NeOp(e1.get());
897 if( e1.Get() == NullGDL::GetSingleInstance())
898 e1.Release();
899 return res;
900 }
901 }
902 BaseGDL* res=e1->NeOp(e2.get());
903 if( e1.Get() == NullGDL::GetSingleInstance())
904 e1.Release();
905 if( e2.Get() == NullGDL::GetSingleInstance())
906 e2.Release();
907 return res;
908 }
Eval()909 BaseGDL* LE_OPNode::Eval()
910 { BaseGDL* res;
911 Guard<BaseGDL> e1( op1->Eval());
912 Guard<BaseGDL> e2( op2->Eval());
913 AdjustTypes(e1,e2);
914 res=e1->LeOp(e2.get());
915 return res;
916 }
Eval()917 BaseGDL* LT_OPNode::Eval()
918 { BaseGDL* res;
919 Guard<BaseGDL> e1( op1->Eval());
920 Guard<BaseGDL> e2( op2->Eval());
921 AdjustTypes(e1,e2);
922 res=e1->LtOp(e2.get());
923 return res;
924 }
Eval()925 BaseGDL* GE_OPNode::Eval()
926 { BaseGDL* res;
927 Guard<BaseGDL> e1( op1->Eval());
928 Guard<BaseGDL> e2( op2->Eval());
929 AdjustTypes(e1,e2);
930 res=e1->GeOp(e2.get());
931 return res;
932 }
Eval()933 BaseGDL* GT_OPNode::Eval()
934 { BaseGDL* res;
935 Guard<BaseGDL> e1( op1->Eval());
936 Guard<BaseGDL> e2( op2->Eval());
937 AdjustTypes(e1,e2);
938 res=e1->GtOp(e2.get());
939 return res;
940 }
Eval()941 BaseGDL* PLUSNode::Eval()
942 {
943 BaseGDL* res;
944 Guard<BaseGDL> e1 ( op1->Eval() );
945 Guard<BaseGDL> e2 ( op2->Eval() );
946
947 DType aTy=e1->Type();
948 DType bTy=e2->Type();
949 if( aTy == bTy)
950 {
951 if( aTy == GDL_OBJ) // we MUST do this here (correct guard handling)
952 return e1->Add( e2.get());; // operator overloading
953
954 }
955 // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
956 else
957 {
958 DType cxTy = PromoteComplexOperand( aTy, bTy);
959 if( cxTy != GDL_UNDEF)
960 {
961 e1.reset( e1.release()->Convert2( cxTy));
962 e2.reset( e2.release()->Convert2( cxTy));
963 }
964 // Change > to >= JMG
965 else if( DTypeOrder[aTy] >= DTypeOrder[bTy])
966 {
967 // convert b to a
968 if( aTy == GDL_OBJ) // only check for aTy is ok because GDL_OBJ has highest order
969 return e1->Add( e2.get());; // for operator overloading, do not convert other type then
970 e2.reset( e2.release()->Convert2( aTy));
971 }
972 else
973 {
974 // convert a to b
975 if( bTy == GDL_OBJ) // only check for bTy is ok because GDL_OBJ has highest order
976 return e2->AddInv( e1.get());; // for operator overloading, do not convert other type then
977 e1.reset( e1.release()->Convert2( bTy));
978 }
979 }
980
981 if ( e1->StrictScalar() )
982 {
983 res= e2->AddInvS ( e1.get() ); // scalar+scalar or array+scalar
984 e2.release();
985 }
986 else
987 if ( e2->StrictScalar() )
988 {
989 res= e1->AddS ( e2.get() ); // array+scalar
990 e1.release();
991 }
992 else
993 if ( e1->N_Elements() <= e2->N_Elements() )
994 {
995 res= e1->Add ( e2.get() ); // smaller_array + larger_array or same size
996 e1.release();
997 }
998 else
999 {
1000 res= e2->AddInv ( e1.get() ); // smaller + larger
1001 e2.release();
1002 }
1003 return res;
1004 }
1005
Eval()1006 BaseGDL* MINUSNode::Eval()
1007 {
1008 BaseGDL* res;
1009 Guard<BaseGDL> e1( op1->Eval());
1010 Guard<BaseGDL> e2( op2->Eval());
1011 // AdjustTypes(e1,e2);
1012
1013 DType aTy=e1->Type();
1014 DType bTy=e2->Type();
1015 if( aTy == bTy)
1016 {
1017 if( aTy == GDL_OBJ) // we MUST do this here (correct guard handling)
1018 return e1->Sub( e2.get());; // operator overloading
1019
1020 }
1021 // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
1022 else
1023 {
1024 DType cxTy = PromoteComplexOperand( aTy, bTy);
1025 if( cxTy != GDL_UNDEF)
1026 {
1027 e1.reset( e1.release()->Convert2( cxTy));
1028 e2.reset( e2.release()->Convert2( cxTy));
1029 }
1030 // Change > to >= JMG
1031 else if( DTypeOrder[aTy] >= DTypeOrder[bTy])
1032 {
1033 // convert b to a
1034 if( aTy == GDL_OBJ) // only check for aTy is ok because GDL_OBJ has highest order
1035 return e1->Sub( e2.get());; // for operator overloading, do not convert other type then
1036 e2.reset( e2.release()->Convert2( aTy));
1037 }
1038 else
1039 {
1040 // convert a to b
1041 if( bTy == GDL_OBJ) // only check for bTy is ok because GDL_OBJ has highest order
1042 return e2->SubInv( e1.get());; // for operator overloading, do not convert other type then
1043 e1.reset( e1.release()->Convert2( bTy));
1044 }
1045 }
1046 if( e1->StrictScalar())
1047 {
1048 res= e2->SubInvS(e1.get()); // scalar+scalar or array+scalar
1049 e2.release();
1050 }
1051 else
1052 if( e2->StrictScalar())
1053 {
1054 res= e1->SubS(e2.get()); // array+scalar
1055 e1.release();
1056 }
1057 else
1058 if( e1->N_Elements() <= e2->N_Elements())
1059 {
1060 res= e1->Sub(e2.get()); // smaller_array + larger_array or same size
1061 e1.release();
1062 }
1063 else
1064 {
1065 res= e2->SubInv(e1.get()); // smaller + larger
1066 e2.release();
1067 }
1068
1069 return res;
1070 }
Eval()1071 BaseGDL* LTMARKNode::Eval()
1072 { BaseGDL* res;
1073 Guard<BaseGDL> e1( op1->Eval());
1074 Guard<BaseGDL> e2( op2->Eval());
1075 AdjustTypes(e1,e2);
1076 if( e1->StrictScalar())
1077 {
1078 res= e2->LtMarkS(e1.get()); // scalar+scalar or array+scalar
1079 e2.release();
1080 }
1081 else
1082 if( e2->StrictScalar())
1083 {
1084 res= e1->LtMarkS(e2.get()); // array+scalar
1085 e1.release();
1086 }
1087 else
1088 if( e1->N_Elements() <= e2->N_Elements())
1089 {
1090 res= e1->LtMark(e2.get()); // smaller_array + larger_array or same size
1091 e1.release();
1092 }
1093 else
1094 {
1095 res= e2->LtMark(e1.get()); // smaller + larger
1096 e2.release();
1097 }
1098 return res;
1099 }
Eval()1100 BaseGDL* GTMARKNode::Eval()
1101 { BaseGDL* res;
1102 Guard<BaseGDL> e1( op1->Eval());
1103 Guard<BaseGDL> e2( op2->Eval());
1104 AdjustTypes(e1,e2);
1105 if( e1->StrictScalar())
1106 {
1107 res= e2->GtMarkS(e1.get()); // scalar+scalar or array+scalar
1108 e2.release();
1109 }
1110 else
1111 if( e2->StrictScalar())
1112 {
1113 res= e1->GtMarkS(e2.get()); // array+scalar
1114 e1.release();
1115 }
1116 else
1117 if( e1->N_Elements() <= e2->N_Elements())
1118 {
1119 res= e1->GtMark(e2.get()); // smaller_array + larger_array or same size
1120 e1.release();
1121 }
1122 else
1123 {
1124 res= e2->GtMark(e1.get()); // smaller + larger
1125 e2.release();
1126 }
1127 return res;
1128 }
Eval()1129 BaseGDL* ASTERIXNode::Eval()
1130 {
1131 BaseGDL* res;
1132 Guard<BaseGDL> e1 ( op1->Eval() );
1133 Guard<BaseGDL> e2 ( op2->Eval() );
1134 AdjustTypes ( e1,e2 );
1135 if ( e1->StrictScalar() )
1136 {
1137 res= e2->MultS ( e1.get() ); // scalar+scalar or array+scalar
1138 e2.release();
1139 }
1140 else if ( e2->StrictScalar() )
1141 {
1142 res= e1->MultS ( e2.get() ); // array+scalar
1143 e1.release();
1144 }
1145 else
1146 if ( e1->N_Elements() <= e2->N_Elements() )
1147 {
1148 res= e1->Mult ( e2.get() ); // smaller_array + larger_array or same size
1149 e1.release();
1150 }
1151 else
1152 {
1153 res= e2->Mult ( e1.get() ); // smaller + larger
1154 e2.release();
1155 }
1156 return res;
1157 }
1158
Eval()1159 BaseGDL* MATRIX_OP1Node::Eval()
1160 { BaseGDL* res;
1161 Guard<BaseGDL> e1( op1->Eval());
1162 Guard<BaseGDL> e2( op2->Eval());
1163 DType aTy=e1->Type();
1164 DType bTy=e2->Type();
1165
1166 // DType maxTy=(DTypeOrder[aTy] >= DTypeOrder[bTy])? aTy: bTy;
1167 // DType cTy=maxTy;
1168 // if( maxTy == GDL_BYTE || maxTy == GDL_INT)
1169 // cTy=GDL_LONG;
1170 // else if( maxTy == GDL_UINT)
1171 // cTy=GDL_ULONG;
1172
1173 DType cTy = PromoteMatrixOperands( aTy, bTy);
1174
1175 if( aTy != cTy)
1176 e1.reset( e1.release()->Convert2( cTy));
1177
1178 AdjustTypes(e1,e2);
1179 res=e1->MatrixOp(e2.get());
1180 return res;
1181 }
Eval()1182 BaseGDL* MATRIX_OP2Node::Eval()
1183 { BaseGDL* res;
1184 Guard<BaseGDL> e1( op1->Eval());
1185 Guard<BaseGDL> e2( op2->Eval());
1186 DType aTy=e1->Type();
1187 DType bTy=e2->Type();
1188
1189 // DType maxTy=(DTypeOrder[aTy] >= DTypeOrder[bTy])? aTy: bTy;
1190 // DType cTy=maxTy;
1191 // if( maxTy == GDL_BYTE || maxTy == GDL_INT)
1192 // cTy=GDL_LONG;
1193 // else if( maxTy == GDL_UINT)
1194 // cTy=GDL_ULONG;
1195
1196 DType cTy = PromoteMatrixOperands( aTy, bTy);
1197
1198 if( aTy != cTy)
1199 e1.reset( e1.release()->Convert2( cTy));
1200
1201 AdjustTypes(e1,e2);
1202 res=e2->MatrixOp(e1.get());
1203 return res;
1204 }
Eval()1205 BaseGDL* SLASHNode::Eval()
1206 { BaseGDL* res;
1207 Guard<BaseGDL> e1( op1->Eval());
1208 Guard<BaseGDL> e2( op2->Eval());
1209 AdjustTypes(e1,e2);
1210 if( e1->StrictScalar())
1211 {
1212 res= e2->DivInvS(e1.get()); // scalar+scalar or array+scalar
1213 e2.release();
1214 }
1215 else
1216 if( e2->StrictScalar())
1217 {
1218 res= e1->DivS(e2.get()); // array+scalar
1219 e1.release();
1220 }
1221 else
1222 if( e1->N_Elements() <= e2->N_Elements())
1223 {
1224 res= e1->Div(e2.get()); // smaller_array + larger_array or same size
1225 e1.release();
1226 }
1227 else
1228 {
1229 res= e2->DivInv(e1.get()); // smaller + larger
1230 e2.release();
1231 }
1232
1233 return res;
1234 }
Eval()1235 BaseGDL* MOD_OPNode::Eval()
1236 { BaseGDL* res;
1237 Guard<BaseGDL> e1( op1->Eval());
1238 Guard<BaseGDL> e2( op2->Eval());
1239 AdjustTypes(e1,e2);
1240 if( e1->StrictScalar())
1241 {
1242 res= e2->ModInvS(e1.get()); // scalar+scalar or array+scalar
1243 e2.release();
1244 }
1245 else
1246 if( e2->StrictScalar())
1247 {
1248 res= e1->ModS(e2.get()); // array+scalar
1249 e1.release();
1250 }
1251 else
1252 if( e1->N_Elements() <= e2->N_Elements())
1253 {
1254 res= e1->Mod(e2.get()); // smaller_array + larger_array or same size
1255 e1.release();
1256 }
1257 else
1258 {
1259 res= e2->ModInv(e1.get()); // smaller + larger
1260 e2.release();
1261 }
1262 return res;
1263 }
1264
1265
Eval()1266 BaseGDL* POWNode::Eval()
1267 { BaseGDL* res;
1268 Guard<BaseGDL> e1( op1->Eval());
1269 Guard<BaseGDL> e2( op2->Eval());
1270 // special handling for aTy == complex && bTy != complex
1271 DType aTy=e1->Type();
1272 DType bTy=e2->Type();
1273 if( aTy == GDL_STRING)
1274 {
1275 e1.reset( e1->Convert2( GDL_FLOAT, BaseGDL::COPY));
1276 aTy = GDL_FLOAT;
1277 }
1278 if( bTy == GDL_STRING)
1279 {
1280 e2.reset( e2->Convert2( GDL_FLOAT, BaseGDL::COPY));
1281 bTy = GDL_FLOAT;
1282 }
1283 if( ComplexType( aTy))
1284 {
1285 if( IntType( bTy))
1286 {
1287 e2.reset( e2.release()->Convert2( GDL_LONG));
1288 res = e1->Pow( e2.get());
1289 if( res == e1.get())
1290 e1.release();
1291 return res;
1292 }
1293 if( aTy == GDL_COMPLEX)
1294 {
1295 if( bTy == GDL_DOUBLE)
1296 {
1297 e1.reset( e1.release()->Convert2( GDL_COMPLEXDBL));
1298 aTy = GDL_COMPLEXDBL;
1299 }
1300 else if( bTy == GDL_FLOAT)
1301 {
1302 res = e1->Pow( e2.get());
1303 if( res == e1.get())
1304 e1.release();
1305 return res;
1306 }
1307 }
1308 if( aTy == GDL_COMPLEXDBL)
1309 {
1310 if( bTy == GDL_FLOAT)
1311 {
1312 e2.reset( e2.release()->Convert2( GDL_DOUBLE));
1313 bTy = GDL_DOUBLE;
1314 }
1315 if( bTy == GDL_DOUBLE)
1316 {
1317 res = e1->Pow( e2.get());
1318 if( res == e1.get())
1319 e1.release();
1320 return res;
1321 }
1322 }
1323 }
1324
1325 if( IntType( bTy) && FloatType( aTy))
1326 {
1327 e2.reset( e2.release()->Convert2( GDL_LONG));
1328
1329 res = e1->PowInt( e2.get());
1330 if( res == e1.get())
1331 e1.release();
1332
1333 return res;
1334 }
1335
1336 DType convertBackT;
1337
1338 // convert back
1339 if( IntType( bTy) && (DTypeOrder[ bTy] > DTypeOrder[ aTy]))
1340 // if( IntType( bTy) && (DTypeOrder[ bTy] > DTypeOrder[ aTy]))
1341 convertBackT = aTy;
1342 else
1343 convertBackT = GDL_UNDEF;
1344
1345 // first operand determines type JMG
1346 // AdjustTypes(e2,e1); // order crucial here (for converting back)
1347 AdjustTypes(e1,e2); // order crucial here (for converting back)
1348
1349 if( e1->StrictScalar())
1350 {
1351 res= e2->PowInvS(e1.get()); // scalar+scalar or array+scalar
1352 e2.release();
1353 }
1354 else
1355 if( e2->StrictScalar())
1356 {
1357 res= e1->PowS(e2.get()); // array+scalar
1358 e1.release();
1359 }
1360 else
1361 if( e1->N_Elements() <= e2->N_Elements())
1362 {
1363 res= e1->Pow(e2.get()); // smaller_array + larger_array or same size
1364 e1.release();
1365 }
1366 else
1367 {
1368 res= e2->PowInv(e1.get()); // smaller + larger
1369 e2.release();
1370 }
1371 if( convertBackT != GDL_UNDEF)
1372 {
1373 res = res->Convert2( convertBackT, BaseGDL::CONVERT);
1374 }
1375 endPOW:
1376 return res;
1377 }
1378 // BaseGDL* DECNode::Eval()
1379 // { BaseGDL* res;
1380 // return new DECNode( refNode);
1381 // }
1382 // BaseGDL* INCNode::Eval()
1383 // { BaseGDL* res;
1384 // return new INCNode( refNode);
1385 // }
1386 // BaseGDL* POSTDECNode::Eval()
1387 // { BaseGDL* res;
1388 // return new POSTDECNode( refNode);
1389 // }
1390 // BaseGDL* POSTINCNode::Eval()
1391 // { BaseGDL* res;
1392 // return new POSTINCNode( refNode);
1393 // }
1394
1395 // ***********************
1396 // **** nonCopy nodes ****
1397 // ***********************
Eval()1398 BaseGDL* AND_OPNCNode::Eval()
1399 { BaseGDL* res;
1400 Guard<BaseGDL> g1;
1401 Guard<BaseGDL> g2;
1402 BaseGDL *e1, *e2; AdjustTypesNC( g1, e1, g2, e2);
1403
1404 if( e1->StrictScalar())
1405 {
1406 if( g2.get() == NULL) return e2->AndOpSNew( e1); else g2.release();
1407 res= e2->AndOpS(e1); // scalar+scalar or array+scalar
1408
1409 }
1410 else
1411 if( e2->StrictScalar())
1412 {
1413 if( g1.get() == NULL) return e1->AndOpInvSNew( e2); else g1.release();
1414 res= e1->AndOpInvS(e2); // array+scalar
1415
1416 }
1417 else
1418 if( e1->N_Elements() == e2->N_Elements())
1419 {
1420 if( g1.get() != NULL)
1421 {
1422 g1.release();
1423 return e1->AndOpInv(e2);
1424 }
1425 if( g2.get() != NULL)
1426 {
1427 g2.release();
1428 res = e2->AndOp(e1);
1429 res->SetDim( e1->Dim());
1430 return res;
1431 }
1432 else
1433 {
1434 return e1->AndOpInvNew(e2);
1435 }
1436 }
1437 else if( e1->N_Elements() < e2->N_Elements())
1438 {
1439 if( g1.get() == NULL) return e1->AndOpInvNew( e2); else g1.release();
1440 res = e1->AndOpInv(e2); // smaller_array + larger_array or same size
1441
1442 }
1443 else
1444 {
1445 if( g2.get() == NULL) return e2->AndOpNew( e1); else g2.release();
1446 res = e2->AndOp(e1); // smaller + larger
1447
1448 }
1449
1450 return res;
1451 }
Eval()1452 BaseGDL* OR_OPNCNode::Eval()
1453 { BaseGDL* res;
1454 Guard<BaseGDL> g1;
1455 Guard<BaseGDL> g2;
1456 BaseGDL *e1, *e2; AdjustTypesNC( g1, e1, g2, e2);
1457
1458 if( e1->StrictScalar())
1459 {
1460 if( g2.get() == NULL) return e2->OrOpSNew( e1); else g2.release();
1461 res= e2->OrOpS(e1); // scalar+scalar or array+scalar
1462
1463 }
1464 else
1465 if( e2->StrictScalar())
1466 {
1467 if( g1.get() == NULL) return e1->OrOpInvSNew( e2); else g1.release();
1468 res= e1->OrOpInvS(e2); // array+scalar
1469
1470 }
1471 else
1472 if( e1->N_Elements() == e2->N_Elements())
1473 {
1474 if( g1.get() != NULL)
1475 {
1476 g1.release();
1477 return e1->OrOpInv(e2);
1478 }
1479 if( g2.get() != NULL)
1480 {
1481 g2.release();
1482 res = e2->OrOp(e1);
1483 res->SetDim( e1->Dim());
1484 return res;
1485 }
1486 else
1487 {
1488 return e1->OrOpInvNew(e2);
1489 }
1490 }
1491 else if( e1->N_Elements() < e2->N_Elements())
1492 {
1493 if( g1.get() == NULL) return e1->OrOpInvNew( e2); else g1.release();
1494 res= e1->OrOpInv(e2); // smaller_array + larger_array or same size
1495
1496 }
1497 else
1498 {
1499 if( g2.get() == NULL) return e2->OrOpNew( e1); else g2.release();
1500 res= e2->OrOp(e1); // smaller + larger
1501
1502 }
1503 return res;
1504 }
Eval()1505 BaseGDL* XOR_OPNCNode::Eval()
1506 { BaseGDL* res;
1507 Guard<BaseGDL> g1;
1508 Guard<BaseGDL> g2;
1509 BaseGDL *e1, *e2; AdjustTypesNC( g1, e1, g2, e2);
1510
1511 if( e1->StrictScalar())
1512 {
1513 if( g2.get() == NULL) return e2->XorOpSNew( e1); else g2.release();
1514 res= e2->XorOpS(e1); // scalar+scalar or array+scalar
1515
1516 }
1517 else if( e2->StrictScalar())
1518 {
1519 if( g1.get() == NULL) return e1->XorOpSNew( e2); else g1.release();
1520 res= e1->XorOpS(e2); // array+scalar
1521
1522 }
1523 else if( e1->N_Elements() == e2->N_Elements())
1524 {
1525 if( g1.get() != NULL)
1526 {
1527 g1.release();
1528 return e1->XorOp(e2);
1529 }
1530 if( g2.get() != NULL)
1531 {
1532 g2.release();
1533 res = e2->XorOp(e1);
1534 res->SetDim( e1->Dim());
1535 return res;
1536 }
1537 else
1538 {
1539 return e1->XorOpNew(e2);
1540 }
1541 }
1542 else if( e1->N_Elements() < e2->N_Elements())
1543 {
1544 if( g1.get() == NULL) return e1->XorOpNew( e2); else g1.release();
1545 res= e1->XorOp(e2); // smaller_array + larger_array or same size
1546
1547 }
1548 else
1549 {
1550 if( g2.get() == NULL) return e2->XorOpNew( e1); else g2.release();
1551 res= e2->XorOp(e1); // smaller + larger
1552
1553 }
1554 return res;
1555 }
Eval()1556 BaseGDL* LOG_ANDNCNode::Eval()
1557 { BaseGDL* res;
1558 Guard<BaseGDL> g1;
1559 Guard<BaseGDL> g2;
1560 BaseGDL *e1, *e2;
1561 if( op1NC)
1562 {
1563 e1 = op1->EvalNC();
1564 }
1565 else
1566 {
1567 e1 = op1->Eval();
1568 g1.reset( e1);
1569 }
1570 if( !e1->LogTrue()) return new DByteGDL( 0);
1571
1572 if( op2NC)
1573 {
1574 e2 = op2->EvalNC();
1575 }
1576 else
1577 {
1578 e2 = op2->Eval();
1579 g2.reset( e2);
1580 }
1581 if( !e2->LogTrue()) return new DByteGDL( 0);
1582 return new DByteGDL( 1);
1583 }
Eval()1584 BaseGDL* LOG_ORNCNode::Eval()
1585 { BaseGDL* res;
1586 Guard<BaseGDL> g1;
1587 Guard<BaseGDL> g2;
1588 BaseGDL *e1, *e2;
1589 if( op1NC)
1590 {
1591 e1 = op1->EvalNC();
1592 }
1593 else
1594 {
1595 e1 = op1->Eval();
1596 g1.reset( e1);
1597 }
1598 if( e1->LogTrue()) return new DByteGDL( 1);
1599 if( op2NC)
1600 {
1601 e2 = op2->EvalNC();
1602 }
1603 else
1604 {
1605 e2 = op2->Eval();
1606 g2.reset( e2);
1607 }
1608 if( e2->LogTrue()) return new DByteGDL( 1);
1609 return new DByteGDL( 0);
1610 }
1611
1612
Eval()1613 BaseGDL* EQ_OPNCNode::Eval()
1614 { BaseGDL* res;
1615 Guard<BaseGDL> g1;
1616 Guard<BaseGDL> g2;
1617 BaseGDL *e1, *e2;
1618 AdjustTypesNCNull( g1, e1, g2, e2);
1619 if( e2 != NULL && e2->Type() == GDL_OBJ)
1620 {
1621 if( e1->Type() != GDL_OBJ)
1622 {
1623 // order is critical: overload might just be defined for one of the object types
1624 // use e2 only if e1 is no object
1625 BaseGDL* res=e2->EqOp(e1);
1626 return res;
1627 }
1628 }
1629 res=e1->EqOp(e2);
1630 return res;
1631 }
Eval()1632 BaseGDL* NE_OPNCNode::Eval()
1633 { BaseGDL* res;
1634 Guard<BaseGDL> g1;
1635 Guard<BaseGDL> g2;
1636 BaseGDL *e1, *e2;
1637 AdjustTypesNCNull( g1, e1, g2, e2);
1638 if( e2 != NULL && e2->Type() == GDL_OBJ)
1639 {
1640 if( e1->Type() != GDL_OBJ)
1641 {
1642 // order is critical: overload might just be defined for one of the object types
1643 // use e2 only if e1 is no object
1644 BaseGDL* res=e2->NeOp(e1);
1645 return res;
1646 }
1647 }
1648 res=e1->NeOp(e2);
1649 return res;
1650 }
Eval()1651 BaseGDL* LE_OPNCNode::Eval()
1652 { BaseGDL* res;
1653 Guard<BaseGDL> g1;
1654 Guard<BaseGDL> g2;
1655 BaseGDL *e1, *e2;
1656 AdjustTypesNC( g1, e1, g2, e2);
1657 res=e1->LeOp(e2);
1658 return res;
1659 }
Eval()1660 BaseGDL* LT_OPNCNode::Eval()
1661 { BaseGDL* res;
1662 Guard<BaseGDL> g1;
1663 Guard<BaseGDL> g2;
1664 BaseGDL *e1, *e2;
1665 AdjustTypesNC( g1, e1, g2, e2);
1666 res=e1->LtOp(e2);
1667 return res;
1668 }
Eval()1669 BaseGDL* GE_OPNCNode::Eval()
1670 { BaseGDL* res;
1671 Guard<BaseGDL> g1;
1672 Guard<BaseGDL> g2;
1673 BaseGDL *e1, *e2;
1674 AdjustTypesNC( g1, e1, g2, e2);
1675 res=e1->GeOp(e2);
1676 return res;
1677 }
Eval()1678 BaseGDL* GT_OPNCNode::Eval()
1679 { BaseGDL* res;
1680 Guard<BaseGDL> g1;
1681 Guard<BaseGDL> g2;
1682 BaseGDL *e1, *e2;
1683 AdjustTypesNC( g1, e1, g2, e2);
1684 res=e1->GtOp(e2);
1685 return res;
1686 }
Eval()1687 BaseGDL* PLUSNC12Node::Eval()
1688 {
1689 BaseGDL *e1 = op1->EvalNC();
1690 BaseGDL *e2 = op2->EvalNC();
1691 DType aTy=e1->Type();
1692 DType bTy=e2->Type();
1693 if( aTy == bTy)
1694 {
1695 // as all Add...New() functions are implemented for GDL_OBJ, we can save the if(...) here
1696 // (as there are no guards up to here)
1697 // if( aTy == GDL_OBJ) // this saves us to implement all Add...New() functions
1698 // return e1->Add( e2);
1699
1700 if ( e1->StrictScalar() )
1701 {
1702 return e2->AddInvSNew( e1 ); // scalar+scalar or array+scalar
1703 }
1704 else if ( e2->StrictScalar() )
1705 {
1706 return e1->AddSNew( e2); // array+scalar
1707 }
1708 else if ( e1->N_Elements() <= e2->N_Elements() )
1709 {
1710 return e1->AddNew ( e2 );
1711 }
1712 else // e1->N_Elements() > e2->N_Elements() )
1713 {
1714 return e2->AddInvNew( e1); // smaller + larger
1715 }
1716 }
1717 Guard<BaseGDL> g1;
1718 Guard<BaseGDL> g2;
1719 DType cxTy = PromoteComplexOperand( aTy, bTy);
1720 if( cxTy != GDL_UNDEF)
1721 {
1722 e2 = e2->Convert2( cxTy, BaseGDL::COPY);
1723 g2.reset( e2);
1724 e1 = e1->Convert2( cxTy, BaseGDL::COPY);
1725 g1.reset( e1);
1726 }
1727 else if( DTypeOrder[aTy] >= DTypeOrder[bTy])
1728 {
1729 if( aTy == GDL_OBJ)
1730 return e1->Add( e2);
1731
1732 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
1733 // if(aTy == GDL_COMPLEX && bTy == GDL_DOUBLE)
1734 // {
1735 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
1736 // g2.reset( e2);
1737 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
1738 // g1.reset( e1);
1739 // }
1740 // else
1741 {
1742 // convert e2 to e1
1743 e2 = e2->Convert2( aTy, BaseGDL::COPY);
1744 g2.reset( e2);
1745 }
1746 }
1747 else
1748 {
1749 if( bTy == GDL_OBJ)
1750 return e2->AddInv( e1);
1751
1752 // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
1753 // if( (bTy == GDL_COMPLEX && aTy == GDL_DOUBLE))
1754 // {
1755 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
1756 // g2.reset( e2);
1757 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
1758 // g1.reset( e1);
1759 // }
1760 // else
1761 {// convert e1 to e2
1762 e1 = e1->Convert2( bTy, BaseGDL::COPY);
1763 g1.reset( e1);
1764 }
1765 }
1766
1767 // 'classic handling from here
1768 BaseGDL* res;
1769 if ( e1->StrictScalar() )
1770 {
1771 if ( g2.get() == NULL )
1772 {
1773 res= e2->AddInvSNew( e1 ); // scalar+scalar or array+scalar
1774 }
1775 else
1776 {
1777 g2.release();
1778 res= e2->AddInvS( e1 ); // scalar+scalar or array+scalar
1779 }
1780 }
1781 else if ( e2->StrictScalar() )
1782 {
1783 if ( g1.get() == NULL )
1784 res= e1->AddSNew( e2); // array+scalar
1785 else
1786 {
1787 g1.release();
1788 res= e1->AddS( e2); // array+scalar
1789 }
1790 }
1791 else if ( e1->N_Elements() == e2->N_Elements() )
1792 {
1793 if ( g1.get() != NULL )
1794 {
1795 g1.release();
1796 return e1->Add ( e2 );
1797 }
1798 if ( g2.get() != NULL )
1799 {
1800 g2.release();
1801 res = e2->AddInv ( e1 );
1802 res->SetDim ( e1->Dim() );
1803 return res;
1804 }
1805 else
1806 {
1807 return e1->AddNew ( e2 );
1808 }
1809 }
1810 else if ( e1->N_Elements() < e2->N_Elements() )
1811 {
1812 if ( g1.get() == NULL )
1813 res= e1->AddNew ( e2 ); // smaller_array + larger_array or same size
1814 else
1815 {
1816 g1.release();
1817 res= e1->Add ( e2 ); // smaller_array + larger_array or same size
1818 }
1819 }
1820 else // e1->N_Elements() > e2->N_Elements() )
1821 {
1822 if ( g2.get() == NULL )
1823 res= e2->AddInvNew( e1); // smaller + larger
1824 else
1825 {
1826 g2.release();
1827 res= e2->AddInv( e1); // smaller + larger
1828 }
1829 }
1830 return res;
1831 }
Eval()1832 BaseGDL* PLUSNCNode::Eval()
1833 {
1834 BaseGDL* res;
1835 Guard<BaseGDL> g1;
1836 Guard<BaseGDL> g2;
1837 BaseGDL *e1, *e2;
1838 SetupGuards( g1, e1, g2, e2 );
1839
1840 DType aTy=e1->Type();
1841 DType bTy=e2->Type();
1842 if( aTy == bTy)
1843 {
1844 if( aTy == GDL_OBJ) // we MUST do this here (correct guard handling)
1845 return e1->Add( e2);
1846
1847 // otherwise continue below
1848 }
1849 else // aTy != bTy
1850 {
1851 DType cxTy = PromoteComplexOperand( aTy, bTy);
1852 if( cxTy != GDL_UNDEF)
1853 {
1854 e2 = e2->Convert2( cxTy, BaseGDL::COPY);
1855 g2.Reset( e2); // delete former e2
1856 e1 = e1->Convert2( cxTy, BaseGDL::COPY);
1857 g1.Reset( e1); // delete former e1
1858 }
1859 // Change > to >= JMG
1860 else if( DTypeOrder[aTy] >= DTypeOrder[bTy])
1861 {
1862 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
1863 // if( (aTy == GDL_COMPLEX && bTy == GDL_DOUBLE))
1864 // {
1865 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
1866 // g2.Reset( e2); // delete former e2
1867 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
1868 // g1.Reset( e1); // delete former e1
1869 // }
1870 // else
1871 if( aTy == GDL_OBJ) // only check for aTy is ok because GDL_OBJ has highest order
1872 return e1->Add(e2); // for operator overloading, do not convert other type then
1873 else
1874 {
1875 // convert e2 to e1
1876 e2 = e2->Convert2( aTy, BaseGDL::COPY);
1877 g2.Reset( e2); // delete former e2
1878 }
1879 }
1880 else
1881 {
1882 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
1883 // if( (bTy == GDL_COMPLEX && aTy == GDL_DOUBLE))
1884 // {
1885 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
1886 // g2.Reset( e2); // delete former e2
1887 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
1888 // g1.Reset( e1); // delete former e1
1889 // }
1890 // else
1891 if( bTy == GDL_OBJ) // only check for bTy is ok because GDL_OBJ has highest order
1892 return e2->AddInv( e1); // for operator overloading, do not convert other type then
1893 else
1894 {
1895 // convert e1 to e2
1896 e1 = e1->Convert2( bTy, BaseGDL::COPY);
1897 g1.Reset( e1); // delete former e1
1898 }
1899 }
1900 } // aTy != bTy
1901
1902 if ( e1->StrictScalar() )
1903 {
1904 if ( g2.IsNull() )
1905 {
1906 res= e2->AddInvSNew( e1 ); // scalar+scalar or array+scalar
1907 }
1908 else
1909 {
1910 g2.Release();
1911 res= e2->AddInvS( e1 ); // scalar+scalar or array+scalar
1912 }
1913 }
1914 else if ( e2->StrictScalar() )
1915 {
1916 if ( g1.IsNull() )
1917 res= e1->AddSNew( e2); // array+scalar
1918 else
1919 {
1920 g1.Release();
1921 res= e1->AddS( e2); // array+scalar
1922 }
1923 }
1924 else if ( e1->N_Elements() == e2->N_Elements() )
1925 {
1926 if ( !g1.IsNull() )
1927 {
1928 g1.Release();
1929 return e1->Add ( e2 );
1930 }
1931 if ( !g2.IsNull() )
1932 {
1933 g2.Release();
1934 res = e2->AddInv ( e1 );
1935 res->SetDim ( e1->Dim() );
1936 return res;
1937 }
1938 else
1939 {
1940 return e1->AddNew ( e2 );
1941 }
1942 }
1943 else if ( e1->N_Elements() < e2->N_Elements() )
1944 {
1945 if ( g1.IsNull() )
1946 res= e1->AddNew ( e2 ); // smaller_array + larger_array or same size
1947 else
1948 {
1949 g1.Release();
1950 res= e1->Add ( e2 ); // smaller_array + larger_array or same size
1951 }
1952 }
1953 else // e1->N_Elements() > e2->N_Elements() )
1954 {
1955 if ( g2.IsNull() )
1956 res= e2->AddInvNew( e1); // smaller + larger
1957 else
1958 {
1959 g2.Release();
1960 res= e2->AddInv( e1); // smaller + larger
1961 }
1962 }
1963 return res;
1964 }
1965
1966
Eval()1967 BaseGDL* MINUSNC12Node::Eval()
1968 {
1969 BaseGDL *e1 = op1->EvalNC();
1970 BaseGDL *e2 = op2->EvalNC();
1971 DType aTy=e1->Type();
1972 DType bTy=e2->Type();
1973 if( aTy == bTy)
1974 {
1975 // as all Sub...New() functions are implemented for GDL_OBJ, we can save the if(...) here
1976 // (as there are no guards up to here)
1977 // if( aTy == GDL_OBJ) // this saves us to implement all Add...New() functions
1978 // return e1->Add( e2);
1979
1980 if ( e1->StrictScalar() )
1981 {
1982 return e2->SubInvSNew( e1 ); // scalar+scalar or array+scalar
1983 }
1984 else if ( e2->StrictScalar() )
1985 {
1986 return e1->SubSNew( e2); // array+scalar
1987 }
1988 else if ( e1->N_Elements() <= e2->N_Elements() )
1989 {
1990 return e1->SubNew ( e2 );
1991 }
1992 else // e1->N_Elements() > e2->N_Elements() )
1993 {
1994 return e2->SubInvNew( e1); // smaller + larger
1995 }
1996 }
1997
1998 Guard<BaseGDL> g1;
1999 Guard<BaseGDL> g2;
2000
2001 DType cxTy = PromoteComplexOperand( aTy, bTy);
2002 if( cxTy != GDL_UNDEF)
2003 {
2004 e2 = e2->Convert2( cxTy, BaseGDL::COPY);
2005 g2.reset( e2);
2006 e1 = e1->Convert2( cxTy, BaseGDL::COPY);
2007 g1.reset( e1);
2008 }
2009 else if( DTypeOrder[aTy] >= DTypeOrder[bTy])
2010 {
2011 if( aTy == GDL_OBJ)
2012 return e1->Sub( e2);
2013
2014 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
2015 // if( aTy == GDL_COMPLEX && bTy == GDL_DOUBLE)
2016 // {
2017 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2018 // g2.reset( e2);
2019 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2020 // g1.reset( e1);
2021 // }
2022 // else
2023 {
2024 // convert e2 to e1
2025 e2 = e2->Convert2( aTy, BaseGDL::COPY);
2026 g2.reset( e2);
2027 }
2028 }
2029 else
2030 {
2031 if( bTy == GDL_OBJ)
2032 return e2->SubInv( e1);
2033
2034 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
2035 // if( (bTy == GDL_COMPLEX && aTy == GDL_DOUBLE))
2036 // {
2037 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2038 // g2.reset( e2);
2039 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2040 // g1.reset( e1);
2041 // }
2042 // else
2043 {// convert e1 to e2
2044 e1 = e1->Convert2( bTy, BaseGDL::COPY);
2045 g1.reset( e1);
2046 }
2047 }
2048
2049 // 'classic handling from here
2050 BaseGDL* res;
2051 if( e1->StrictScalar())
2052 {
2053 if( g2.get() == NULL) return e2->SubInvSNew( e1); else g2.release();
2054 res= e2->SubInvS(e1); // scalar+scalar or array+scalar
2055
2056 }
2057 else
2058 if( e2->StrictScalar())
2059 {
2060 if( g1.get() == NULL) return e1->SubSNew( e2); else g1.release();
2061 res= e1->SubS(e2); // array+scalar
2062
2063 }
2064 else if( e1->N_Elements() == e2->N_Elements())
2065 {
2066 if( g1.get() != NULL)
2067 {
2068 g1.release();
2069 return e1->Sub(e2);
2070 }
2071 if( g2.get() != NULL)
2072 {
2073 g2.release();
2074 res = e2->SubInv(e1);
2075 res->SetDim( e1->Dim());
2076 return res;
2077 }
2078 else
2079 {
2080 return e1->SubNew(e2);
2081 }
2082 }
2083 else if( e1->N_Elements() < e2->N_Elements())
2084 {
2085 if( g1.get() == NULL) return e1->SubNew( e2); else g1.release();
2086 res= e1->Sub(e2); // smaller_array + larger_array or same size
2087
2088 }
2089 else
2090 {
2091 if( g2.get() == NULL) return e2->SubInvNew( e1); else g2.release();
2092 res= e2->SubInv(e1); // smaller + larger
2093
2094 }
2095 return res;
2096 }
Eval()2097 BaseGDL* MINUSNCNode::Eval()
2098 {
2099 BaseGDL* res;
2100 Guard<BaseGDL> g1;
2101 Guard<BaseGDL> g2;
2102 BaseGDL *e1, *e2;
2103 // AdjustTypesNC( g1, e1, g2, e2);
2104
2105 SetupGuards( g1, e1, g2, e2 );
2106
2107 DType aTy=e1->Type();
2108 DType bTy=e2->Type();
2109 if( aTy == bTy)
2110 {
2111 if( aTy == GDL_OBJ) // we MUST do this here (correct guard handling)
2112 return e1->Sub( e2);
2113
2114 // otherwise continue below
2115 }
2116 else // aTy != bTy
2117 {
2118 DType cxTy = PromoteComplexOperand( aTy, bTy);
2119 if( cxTy != GDL_UNDEF)
2120 {
2121 e2 = e2->Convert2( cxTy, BaseGDL::COPY);
2122 g2.Reset( e2); // delete former e2
2123 e1 = e1->Convert2( cxTy, BaseGDL::COPY);
2124 g1.Reset( e1); // delete former e1
2125
2126 } // Change > to >= JMG
2127 else if( DTypeOrder[aTy] >= DTypeOrder[bTy])
2128 {
2129 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
2130 // if( (aTy == GDL_COMPLEX && bTy == GDL_DOUBLE))
2131 // {
2132 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2133 // g2.Reset( e2); // delete former e2
2134 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2135 // g1.Reset( e1); // delete former e1
2136 // }
2137 // else
2138 if( aTy == GDL_OBJ) // only check for aTy is ok because GDL_OBJ has highest order
2139 return e1->Sub(e2); // for operator overloading, do not convert other type then
2140 else
2141 {
2142 // convert e2 to e1
2143 e2 = e2->Convert2( aTy, BaseGDL::COPY);
2144 g2.Reset( e2); // delete former e2
2145 }
2146 }
2147 else
2148 {
2149 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
2150 // if( (bTy == GDL_COMPLEX && aTy == GDL_DOUBLE))
2151 // {
2152 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2153 // g2.Reset( e2); // delete former e2
2154 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2155 // g1.Reset( e1); // delete former e1
2156 // }
2157 // else
2158 if( bTy == GDL_OBJ) // only check for bTy is ok because GDL_OBJ has highest order
2159 return e2->SubInv( e1); // for operator overloading, do not convert other type then
2160 else
2161 {
2162 // convert e1 to e2
2163 e1 = e1->Convert2( bTy, BaseGDL::COPY);
2164 g1.Reset( e1); // delete former e1
2165 }
2166 }
2167 } // aTy != bTy
2168
2169 if( e1->StrictScalar())
2170 {
2171 if( g2.Get() == NULL) return e2->SubInvSNew( e1); else g2.Release();
2172 res= e2->SubInvS(e1); // scalar+scalar or array+scalar
2173
2174 }
2175 else
2176 if( e2->StrictScalar())
2177 {
2178 if( g1.Get() == NULL) return e1->SubSNew( e2); else g1.Release();
2179 res= e1->SubS(e2); // array+scalar
2180
2181 }
2182 else if( e1->N_Elements() == e2->N_Elements())
2183 {
2184 if( g1.Get() != NULL)
2185 {
2186 g1.Release();
2187 return e1->Sub(e2);
2188 }
2189 if( g2.Get() != NULL)
2190 {
2191 g2.Release();
2192 res = e2->SubInv(e1);
2193 res->SetDim( e1->Dim());
2194 return res;
2195 }
2196 else
2197 {
2198 return e1->SubNew(e2);
2199 }
2200 }
2201 else if( e1->N_Elements() < e2->N_Elements())
2202 {
2203 if( g1.Get() == NULL) return e1->SubNew( e2); else g1.Release();
2204 res= e1->Sub(e2); // smaller_array + larger_array or same size
2205
2206 }
2207 else
2208 {
2209 if( g2.Get() == NULL) return e2->SubInvNew( e1); else g2.Release();
2210 res= e2->SubInv(e1); // smaller + larger
2211
2212 }
2213 return res;
2214 }
Eval()2215 BaseGDL* LTMARKNCNode::Eval()
2216 { BaseGDL* res;
2217 Guard<BaseGDL> g1;
2218 Guard<BaseGDL> g2;
2219 BaseGDL *e1, *e2; AdjustTypesNC( g1, e1, g2, e2);
2220
2221 if( e1->StrictScalar())
2222 {
2223 if( g2.get() == NULL) return e2->LtMarkSNew( e1); else g2.release();
2224 res= e2->LtMarkS(e1); // scalar+scalar or array+scalar
2225
2226 }
2227 else
2228 if( e2->StrictScalar())
2229 {
2230 if( g1.get() == NULL) return e1->LtMarkSNew( e2); else g1.release();
2231 res= e1->LtMarkS(e2); // array+scalar
2232
2233 }
2234 else if( e1->N_Elements() == e2->N_Elements())
2235 {
2236 if( g1.get() != NULL)
2237 {
2238 g1.release();
2239 return e1->LtMark(e2);
2240 }
2241 if( g2.get() != NULL)
2242 {
2243 g2.release();
2244 res = e2->LtMark(e1);
2245 res->SetDim( e1->Dim());
2246 return res;
2247 }
2248 else
2249 {
2250 return e1->LtMarkNew(e2);
2251 }
2252 }
2253 else if( e1->N_Elements() < e2->N_Elements())
2254 {
2255 if( g1.get() == NULL) return e1->LtMarkNew( e2); else g1.release();
2256 res= e1->LtMark(e2); // smaller_array + larger_array or same size
2257
2258 }
2259 else
2260 {
2261 if( g2.get() == NULL) return e2->LtMarkNew( e1); else g2.release();
2262 res= e2->LtMark(e1); // smaller + larger
2263
2264 }
2265 return res;
2266 }
Eval()2267 BaseGDL* GTMARKNCNode::Eval()
2268 { BaseGDL* res;
2269 Guard<BaseGDL> g1;
2270 Guard<BaseGDL> g2;
2271 BaseGDL *e1, *e2; AdjustTypesNC( g1, e1, g2, e2);
2272
2273 if( e1->StrictScalar())
2274 {
2275 if( g2.get() == NULL) return e2->GtMarkSNew( e1); else g2.release();
2276 res= e2->GtMarkS(e1); // scalar+scalar or array+scalar
2277
2278 }
2279 else
2280 if( e2->StrictScalar())
2281 {
2282 if( g1.get() == NULL) return e1->GtMarkSNew( e2); else g1.release();
2283 res= e1->GtMarkS(e2); // array+scalar
2284
2285 }
2286 else if( e1->N_Elements() == e2->N_Elements())
2287 {
2288 if( g1.get() != NULL)
2289 {
2290 g1.release();
2291 return e1->GtMark(e2);
2292 }
2293 if( g2.get() != NULL)
2294 {
2295 g2.release();
2296 res = e2->GtMark(e1);
2297 res->SetDim( e1->Dim());
2298 return res;
2299 }
2300 else
2301 {
2302 return e1->GtMarkNew(e2);
2303 }
2304 }
2305 else if( e1->N_Elements() < e2->N_Elements())
2306 {
2307 if( g1.get() == NULL) return e1->GtMarkNew( e2); else g1.release();
2308 res= e1->GtMark(e2); // smaller_array + larger_array or same size
2309
2310 }
2311 else
2312 {
2313 if( g2.get() == NULL) return e2->GtMarkNew( e1); else g2.release();
2314 res= e2->GtMark(e1); // smaller + larger
2315
2316 }
2317 return res;
2318 }
2319
Eval()2320 BaseGDL* ASTERIXNC12Node::Eval()
2321 {
2322 BaseGDL *e1 = op1->EvalNC();
2323 BaseGDL *e2 = op2->EvalNC();
2324 DType aTy=e1->Type();
2325 DType bTy=e2->Type();
2326 if( aTy == bTy)
2327 {
2328 if ( e1->StrictScalar() )
2329 {
2330 return e2->MultSNew( e1 ); // scalar+scalar or array+scalar
2331 }
2332 else if ( e2->StrictScalar() )
2333 {
2334 return e1->MultSNew( e2); // array+scalar
2335 }
2336 else if ( e1->N_Elements() <= e2->N_Elements() )
2337 {
2338 return e1->MultNew ( e2 );
2339 }
2340 else // e1->N_Elements() > e2->N_Elements() )
2341 {
2342 return e2->MultNew( e1); // smaller + larger
2343 }
2344 }
2345
2346 Guard<BaseGDL> g1;
2347 Guard<BaseGDL> g2;
2348
2349 DType cxTy = PromoteComplexOperand( aTy, bTy);
2350 if( cxTy != GDL_UNDEF)
2351 {
2352 e2 = e2->Convert2( cxTy, BaseGDL::COPY);
2353 g2.reset( e2);
2354 e1 = e1->Convert2( cxTy, BaseGDL::COPY);
2355 g1.reset( e1);
2356 }
2357 else if( DTypeOrder[aTy] >= DTypeOrder[bTy])
2358 {
2359 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
2360 // if( aTy == GDL_COMPLEX && bTy == GDL_DOUBLE)
2361 // {
2362 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2363 // g2.reset( e2);
2364 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2365 // g1.reset( e1);
2366 // }
2367 // else
2368 {
2369 // convert e2 to e1
2370 e2 = e2->Convert2( aTy, BaseGDL::COPY);
2371 g2.reset( e2);
2372 }
2373 }
2374 else
2375 {
2376 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
2377 // if( (bTy == GDL_COMPLEX && aTy == GDL_DOUBLE))
2378 // {
2379 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2380 // g2.reset( e2);
2381 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2382 // g1.reset( e1);
2383 // }
2384 // else
2385 {// convert e1 to e2
2386 e1 = e1->Convert2( bTy, BaseGDL::COPY);
2387 g1.reset( e1);
2388 }
2389 }
2390
2391 // 'classic handling from here
2392 BaseGDL* res;
2393 if ( e1->StrictScalar() )
2394 {
2395 if ( g2.get() == NULL )
2396 {
2397 res= e2->MultSNew( e1); // scalar+scalar or array+scalar
2398 }
2399 else
2400 {
2401 g2.release();
2402 res= e2->MultS( e1); // scalar+scalar or array+scalar
2403 }
2404 }
2405 else if ( e2->StrictScalar() )
2406 {
2407 if ( g1.get() == NULL )
2408 {
2409 // return e1->New( e2);
2410 res= e1->MultSNew( e2); // array+scalar
2411 }
2412 else
2413 {
2414 g1.release();
2415 res= e1->MultS( e2); // array+scalar
2416 }
2417 }
2418 else if ( e1->N_Elements() == e2->N_Elements() )
2419 {
2420 if ( g1.get() != NULL )
2421 {
2422 g1.release();
2423 return e1->Mult( e2);
2424 }
2425 else if ( g2.get() != NULL )
2426 {
2427 g2.release();
2428 res = e2->Mult( e1);
2429 res->SetDim( e1->Dim());
2430 return res;
2431 }
2432 else
2433 {
2434 return e1->MultNew( e2);
2435 // return e1->Dup()->Mult ( e2 );
2436 }
2437 }
2438 else if ( e1->N_Elements() < e2->N_Elements() )
2439 {
2440 if ( g1.get() == NULL )
2441 {
2442 // return e1->New( e2);
2443 res= e1->MultNew( e2); // smaller_array + larger_array or same size
2444 }
2445 else
2446 {
2447 g1.release();
2448 res= e1->Mult( e2); // smaller_array + larger_array or same size
2449 }
2450 }
2451 else
2452 {
2453 if ( g2.get() == NULL )
2454 {
2455 res = e2->MultNew( e1); // smaller + larger
2456 }
2457 else
2458 {
2459 g2.release();
2460 res= e2->Mult( e1); // smaller + larger
2461 }
2462 }
2463 return res;
2464 }
Eval()2465 BaseGDL* ASTERIXNCNode::Eval()
2466 {
2467 BaseGDL* res;
2468 Guard<BaseGDL> g1;
2469 Guard<BaseGDL> g2;
2470 BaseGDL *e1, *e2; AdjustTypesNC ( g1, e1, g2, e2 );
2471
2472 if ( e1->StrictScalar() )
2473 {
2474 if ( g2.get() == NULL )
2475 {
2476 res= e2->MultSNew( e1); // scalar+scalar or array+scalar
2477 }
2478 else
2479 {
2480 g2.release();
2481 res= e2->MultS( e1); // scalar+scalar or array+scalar
2482 }
2483 }
2484 else if ( e2->StrictScalar() )
2485 {
2486 if ( g1.get() == NULL )
2487 {
2488 // return e1->New( e2);
2489 res= e1->MultSNew( e2); // array+scalar
2490 }
2491 else
2492 {
2493 g1.release();
2494 res= e1->MultS( e2); // array+scalar
2495 }
2496 }
2497 else if ( e1->N_Elements() == e2->N_Elements() )
2498 {
2499 if ( g1.get() != NULL )
2500 {
2501 g1.release();
2502 return e1->Mult( e2);
2503 }
2504 else if ( g2.get() != NULL )
2505 {
2506 g2.release();
2507 res = e2->Mult( e1);
2508 res->SetDim( e1->Dim());
2509 return res;
2510 }
2511 else
2512 {
2513 return e1->MultNew( e2);
2514 // return e1->Dup()->Mult ( e2 );
2515 }
2516 }
2517 else if ( e1->N_Elements() < e2->N_Elements() )
2518 {
2519 if ( g1.get() == NULL )
2520 {
2521 // return e1->New( e2);
2522 res= e1->MultNew( e2); // smaller_array + larger_array or same size
2523 }
2524 else
2525 {
2526 g1.release();
2527 res= e1->Mult( e2); // smaller_array + larger_array or same size
2528 }
2529 }
2530 else
2531 {
2532 if ( g2.get() == NULL )
2533 {
2534 res = e2->MultNew( e1); // smaller + larger
2535 }
2536 else
2537 {
2538 g2.release();
2539 res= e2->Mult( e1); // smaller + larger
2540 }
2541 }
2542 return res;
2543 }
2544
Eval()2545 BaseGDL* MATRIX_OP1NCNode::Eval()
2546 { BaseGDL* res;
2547 Guard<BaseGDL> g1;
2548 Guard<BaseGDL> g2;
2549 BaseGDL *e1, *e2;
2550 if( op1NC)
2551 {
2552 e1 = op1->EvalNC();
2553 }
2554 else
2555 {
2556 e1 = op1->Eval();
2557 g1.reset( e1);
2558 }
2559 if( op2NC)
2560 {
2561 e2 = op2->EvalNC();
2562 }
2563 else
2564 {
2565 e2 = op2->Eval();
2566 g2.reset( e2);
2567 }
2568 DType aTy=e1->Type();
2569 DType bTy=e2->Type();
2570 // DType maxTy=(DTypeOrder[aTy] >= DTypeOrder[bTy])? aTy: bTy;
2571 // if( maxTy > 100)
2572 // {
2573 // throw GDLException( "Expressions of this type cannot be converted.");
2574 // }
2575 // DType cTy=maxTy;
2576 // if( maxTy == GDL_BYTE || maxTy == GDL_INT)
2577 // cTy=GDL_LONG;
2578 // else if( maxTy == GDL_UINT)
2579 // cTy=GDL_ULONG;
2580 DType cTy = PromoteMatrixOperands( aTy, bTy);
2581
2582 if( aTy != cTy)
2583 {
2584 e1 = e1->Convert2( cTy, BaseGDL::COPY);
2585 g1.reset( e1);
2586 }
2587 if( bTy != cTy)
2588 {
2589 e2 = e2->Convert2( cTy, BaseGDL::COPY);
2590 g2.reset( e2);
2591 }
2592
2593 res=e1->MatrixOp(e2);
2594 return res;
2595 }
Eval()2596 BaseGDL* MATRIX_OP2NCNode::Eval()
2597 {
2598 BaseGDL* res;
2599 Guard<BaseGDL> g1;
2600 Guard<BaseGDL> g2;
2601 BaseGDL *e1, *e2;
2602 if( op1NC)
2603 {
2604 e1 = op1->EvalNC();
2605 }
2606 else
2607 {
2608 e1 = op1->Eval();
2609 g1.reset( e1);
2610 }
2611 if( op2NC)
2612 {
2613 e2 = op2->EvalNC();
2614 }
2615 else
2616 {
2617 e2 = op2->Eval();
2618 g2.reset( e2);
2619 }
2620 DType aTy=e1->Type();
2621 DType bTy=e2->Type();
2622 // DType maxTy=(DTypeOrder[aTy] >= DTypeOrder[bTy])? aTy: bTy;
2623 // if( maxTy > 100)
2624 // {
2625 // throw GDLException( "Expressions of this type cannot be converted.");
2626 // }
2627 // DType cTy=maxTy;
2628 // if( maxTy == GDL_BYTE || maxTy == GDL_INT)
2629 // cTy=GDL_LONG;
2630 // else if( maxTy == GDL_UINT)
2631 // cTy=GDL_ULONG;
2632
2633 DType cTy = PromoteMatrixOperands( aTy, bTy);
2634
2635 if( aTy != cTy)
2636 {
2637 e1 = e1->Convert2( cTy, BaseGDL::COPY);
2638 g1.reset( e1);
2639 }
2640 if( bTy != cTy)
2641 {
2642 e2 = e2->Convert2( cTy, BaseGDL::COPY);
2643 g2.reset( e2);
2644 }
2645
2646 res=e2->MatrixOp(e1);
2647 return res;
2648 }
2649
Eval()2650 BaseGDL* SLASHNC12Node::Eval()
2651 {
2652 BaseGDL *e1 = op1->EvalNC();
2653 BaseGDL *e2 = op2->EvalNC();
2654 DType aTy=e1->Type();
2655 DType bTy=e2->Type();
2656 if( aTy == bTy)
2657 {
2658 if ( e1->StrictScalar() )
2659 {
2660 return e2->DivInvSNew( e1 ); // scalar+scalar or array+scalar
2661 }
2662 else if ( e2->StrictScalar() )
2663 {
2664 return e1->DivSNew( e2); // array+scalar
2665 }
2666 else if ( e1->N_Elements() <= e2->N_Elements() )
2667 {
2668 return e1->DivNew ( e2 );
2669 }
2670 else // e1->N_Elements() > e2->N_Elements() )
2671 {
2672 return e2->DivInvNew( e1); // smaller + larger
2673 }
2674 }
2675 Guard<BaseGDL> g1;
2676 Guard<BaseGDL> g2;
2677
2678 DType cxTy = PromoteComplexOperand( aTy, bTy);
2679 if( cxTy != GDL_UNDEF)
2680 {
2681 e2 = e2->Convert2( cxTy, BaseGDL::COPY);
2682 g2.reset( e2);
2683 e1 = e1->Convert2( cxTy, BaseGDL::COPY);
2684 g1.reset( e1);
2685 }
2686 else if( DTypeOrder[aTy] >= DTypeOrder[bTy])
2687 {
2688 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
2689 // if( aTy == GDL_COMPLEX && bTy == GDL_DOUBLE)
2690 // {
2691 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2692 // g2.reset( e2);
2693 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2694 // g1.reset( e1);
2695 // }
2696 // else
2697 {
2698 // convert e2 to e1
2699 e2 = e2->Convert2( aTy, BaseGDL::COPY);
2700 g2.reset( e2);
2701 }
2702 }
2703 else
2704 {
2705 // // GDL_COMPLEX op GDL_DOUBLE = GDL_COMPLEXDBL
2706 // if( (bTy == GDL_COMPLEX && aTy == GDL_DOUBLE))
2707 // {
2708 // e2 = e2->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2709 // g2.reset( e2);
2710 // e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2711 // g1.reset( e1);
2712 // }
2713 // else
2714 {// convert e1 to e2
2715 e1 = e1->Convert2( bTy, BaseGDL::COPY);
2716 g1.reset( e1);
2717 }
2718 }
2719
2720 // 'classic handling from here
2721 BaseGDL* res;
2722 if( e1->StrictScalar())
2723 {
2724 if( g2.get() == NULL) return e2->DivInvSNew( e1); else g2.release();
2725 res= e2->DivInvS(e1); // scalar+scalar or array+scalar
2726
2727 }
2728 else
2729 if( e2->StrictScalar())
2730 {
2731 if( g1.get() == NULL) return e1->DivSNew( e2); else g1.release();
2732 res= e1->DivS(e2); // array+scalar
2733
2734 }
2735 else if( e1->N_Elements() == e2->N_Elements())
2736 {
2737 if( g1.get() != NULL)
2738 {
2739 g1.release();
2740 return e1->Div(e2);
2741 }
2742 if( g2.get() != NULL)
2743 {
2744 g2.release();
2745 res = e2->DivInv(e1);
2746 res->SetDim( e1->Dim());
2747 return res;
2748 }
2749 else
2750 {
2751 return e1->DivNew(e2);
2752 }
2753 }
2754 else if( e1->N_Elements() < e2->N_Elements())
2755 {
2756 if( g1.get() == NULL) return e1->DivNew( e2); else g1.release();
2757 res= e1->Div(e2); // smaller_array + larger_array or same size
2758
2759 }
2760 else
2761 {
2762 if( g2.get() == NULL) return e2->DivInvNew( e1); else g2.release();
2763 res= e2->DivInv(e1); // smaller + larger
2764
2765 }
2766
2767 return res;
2768 }
Eval()2769 BaseGDL* SLASHNCNode::Eval()
2770 { BaseGDL* res;
2771 Guard<BaseGDL> g1;
2772 Guard<BaseGDL> g2;
2773 BaseGDL *e1, *e2; AdjustTypesNC( g1, e1, g2, e2);
2774
2775 if( e1->StrictScalar())
2776 {
2777 if( g2.get() == NULL) return e2->DivInvSNew( e1); else g2.release();
2778 res= e2->DivInvS(e1); // scalar+scalar or array+scalar
2779
2780 }
2781 else
2782 if( e2->StrictScalar())
2783 {
2784 if( g1.get() == NULL) return e1->DivSNew( e2); else g1.release();
2785 res= e1->DivS(e2); // array+scalar
2786
2787 }
2788 else if( e1->N_Elements() == e2->N_Elements())
2789 {
2790 if( g1.get() != NULL)
2791 {
2792 g1.release();
2793 return e1->Div(e2);
2794 }
2795 if( g2.get() != NULL)
2796 {
2797 g2.release();
2798 res = e2->DivInv(e1);
2799 res->SetDim( e1->Dim());
2800 return res;
2801 }
2802 else
2803 {
2804 return e1->DivNew(e2);
2805 }
2806 }
2807 else if( e1->N_Elements() < e2->N_Elements())
2808 {
2809 if( g1.get() == NULL) return e1->DivNew( e2); else g1.release();
2810 res= e1->Div(e2); // smaller_array + larger_array or same size
2811
2812 }
2813 else
2814 {
2815 if( g2.get() == NULL) return e2->DivInvNew( e1); else g2.release();
2816 res= e2->DivInv(e1); // smaller + larger
2817
2818 }
2819
2820 return res;
2821 }
Eval()2822 BaseGDL* MOD_OPNCNode::Eval()
2823 { BaseGDL* res;
2824 Guard<BaseGDL> g1;
2825 Guard<BaseGDL> g2;
2826 BaseGDL *e1, *e2; AdjustTypesNC( g1, e1, g2, e2);
2827
2828 if( e1->StrictScalar())
2829 {
2830 if( g2.get() == NULL) return e2->ModInvSNew( e1); else g2.release();
2831 res= e2->ModInvS(e1); // scalar+scalar or array+scalar
2832
2833 }
2834 else if( e2->StrictScalar())
2835 {
2836 if( g1.get() == NULL) return e1->ModSNew( e2); else g1.release();
2837 res= e1->ModS(e2); // array+scalar
2838
2839 }
2840 else if( e1->N_Elements() == e2->N_Elements())
2841 {
2842 if( g1.get() != NULL)
2843 {
2844 g1.release();
2845 return e1->Mod(e2);
2846 }
2847 if( g2.get() != NULL)
2848 {
2849 g2.release();
2850 res = e2->ModInv(e1);
2851 res->SetDim( e1->Dim());
2852 return res;
2853 }
2854 else
2855 {
2856 return e1->ModNew(e2);
2857 }
2858 }
2859 else if( e1->N_Elements() < e2->N_Elements())
2860 {
2861 if( g1.get() == NULL) return e1->ModNew( e2); else g1.release();
2862 res= e1->Mod(e2); // smaller_array + larger_array or same size
2863
2864 }
2865 else
2866 {
2867 if( g2.get() == NULL) return e2->ModInvNew( e1); else g2.release();
2868 res= e2->ModInv(e1); // smaller + larger
2869
2870 }
2871 return res;
2872 }
2873
2874
Eval()2875 BaseGDL* POWNCNode::Eval()
2876 {
2877 BaseGDL* res;
2878 Guard<BaseGDL> g1;
2879 Guard<BaseGDL> g2;
2880 BaseGDL *e1, *e2;
2881 if( op1NC)
2882 {
2883 e1 = op1->EvalNC();
2884 }
2885 else
2886 {
2887 e1 = op1->Eval();
2888 g1.reset( e1);
2889 }
2890 if( op2NC)
2891 {
2892 e2 = op2->EvalNC();
2893 }
2894 else
2895 {
2896 e2 = op2->Eval();
2897 g2.reset( e2);
2898 }
2899
2900 DType aTy=e1->Type();
2901 DType bTy=e2->Type();
2902
2903 if( aTy == GDL_STRING)
2904 {
2905 e1 = e1->Convert2( GDL_FLOAT, BaseGDL::COPY);
2906 g1.reset( e1); // deletes old e1
2907 aTy = GDL_FLOAT;
2908 }
2909 if( bTy == GDL_STRING)
2910 {
2911 e2 = e2->Convert2( GDL_FLOAT, BaseGDL::COPY);
2912 g2.reset( e2); // deletes old e2
2913 bTy = GDL_FLOAT;
2914 }
2915
2916 if( ComplexType(aTy))
2917 {
2918 if( IntType( bTy))
2919 {
2920 if( bTy != GDL_LONG)
2921 {
2922 e2 = e2->Convert2( GDL_LONG, BaseGDL::COPY);
2923 g2.reset( e2);
2924 }
2925 if( g1.get() == NULL)
2926 {
2927 return e1->PowNew( e2);
2928 }
2929 else
2930 {
2931 res = g1->Pow( e2);
2932 if( res == g1.get())
2933 g1.release();
2934 return res;
2935 }
2936 }
2937 if( aTy == GDL_COMPLEX)
2938 {
2939 if( bTy == GDL_DOUBLE)
2940 {
2941 e1 = e1->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY);
2942 g1.reset( e1);
2943 aTy = GDL_COMPLEXDBL;
2944 }
2945 else if( bTy == GDL_FLOAT)
2946 {
2947 if( g1.get() == NULL)
2948 {
2949 return e1->PowNew( e2);
2950 }
2951 else
2952 {
2953 res = g1->Pow( e2);
2954 if( res == g1.get())
2955 g1.release();
2956 return res;
2957 }
2958 }
2959 }
2960 if( aTy == GDL_COMPLEXDBL)
2961 {
2962 if( bTy == GDL_FLOAT)
2963 {
2964 e2 = e2->Convert2( GDL_DOUBLE, BaseGDL::COPY);
2965 g2.reset( e2);
2966 bTy = GDL_DOUBLE;
2967 }
2968 if( bTy == GDL_DOUBLE)
2969 {
2970 if( g1.get() == NULL)
2971 {
2972 return e1->PowNew( e2);
2973 }
2974 else
2975 {
2976 res = g1->Pow( e2);
2977 if( res == g1.get())
2978 g1.release();
2979 return res;
2980 }
2981 }
2982 }
2983 }
2984
2985 if( IntType( bTy) && FloatType( aTy))
2986 {
2987 if( bTy != GDL_LONG)
2988 {
2989 e2 = e2->Convert2( GDL_LONG, BaseGDL::COPY);
2990 g2.reset( e2);
2991 }
2992 if( g1.get() == NULL)
2993 res = e1->PowIntNew( e2);
2994 else
2995 {
2996 res = g1->PowInt( e2);
2997 if( res == g1.get())
2998 g1.release();
2999 }
3000 return res;
3001 }
3002
3003 DType convertBackT;
3004
3005 bool aTyGEbTy = DTypeOrder[aTy] >= DTypeOrder[bTy];
3006 // convert back
3007 if( IntType( bTy) && !aTyGEbTy)
3008 convertBackT = aTy;
3009 else
3010 convertBackT = GDL_UNDEF;
3011
3012 if( aTy != bTy)
3013 {
3014 if( aTyGEbTy) // crucial: '>' -> '>='
3015 {
3016 if( DTypeOrder[aTy] > 100)
3017 {
3018 throw GDLException( "Expressions of this type cannot be converted.");
3019 }
3020
3021 // convert e2 to e1
3022 e2 = e2->Convert2( aTy, BaseGDL::COPY);
3023 g2.reset( e2); // delete former e2
3024 }
3025 else // bTy > aTy (order)
3026 {
3027 if( DTypeOrder[bTy] > 100)
3028 {
3029 throw GDLException( "Expressions of this type cannot be converted.");
3030 }
3031
3032 // convert e1 to e2
3033 e1 = e1->Convert2( bTy, BaseGDL::COPY);
3034 g1.reset( e1); // delete former e1
3035 }
3036 }
3037
3038 // AdjustTypes(e2,e1); // order crucial here (for converting back)
3039 if( e1->StrictScalar())
3040 {
3041 if( g2.get() == NULL)
3042 res = e2->PowInvSNew( e1);
3043 else
3044 {
3045 g2.release();
3046 res = e2->PowInvS(e1); // scalar+scalar or array+scalar
3047 }
3048 }
3049 else if( e2->StrictScalar())
3050 {
3051 if( g1.get() == NULL)
3052 {
3053 res = e1->PowSNew( e2);
3054 // res = e1->PowS(e2); // array+scalar
3055 }
3056 else
3057 {
3058 g1.release();
3059 res= e1->PowS(e2); // array+scalar
3060 }
3061 }
3062 else if( e1->N_Elements() == e2->N_Elements())
3063 {
3064 if( g1.get() != NULL)
3065 {
3066 g1.release();
3067 res = e1->Pow(e2);
3068 }
3069 else if( g2.get() != NULL)
3070 {
3071 g2.release();
3072 res = e2->PowInv(e1);
3073 res->SetDim( e1->Dim());
3074 }
3075 else
3076 {
3077 res = e1->PowNew( e2);
3078 // res = e1->Pow(e2);
3079 }
3080 }
3081 else if( e1->N_Elements() < e2->N_Elements())
3082 {
3083 if( g1.get() == NULL)
3084 {
3085 res = e1->PowNew( e2);
3086 // res= e1->Pow(e2); // smaller_array + larger_array or same size
3087 }
3088 else
3089 {
3090 g1.release();
3091 res= e1->Pow(e2); // smaller_array + larger_array or same size
3092 }
3093 }
3094 else
3095 {
3096 if( g2.get() == NULL)
3097 res = e2->PowInvNew( e1);
3098 else
3099 {
3100 g2.release();
3101 res= e2->PowInv(e1); // smaller + larger
3102 }
3103 }
3104 if( convertBackT != GDL_UNDEF)
3105 {
3106 res = res->Convert2( convertBackT, BaseGDL::CONVERT);
3107 }
3108 return res;
3109 }
3110
LEval()3111 BaseGDL** FCALL_LIB_N_ELEMENTSNode::LEval()
3112 {
3113 // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack
3114 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3115 throw GDLException(this,"Internal error: N_ELEMENTS called as left expr.");
3116 }
3117
Eval()3118 BaseGDL* FCALL_LIB_N_ELEMENTSNode::Eval()
3119 {
3120 if( this->getFirstChild()->getNextSibling() != 0)
3121 throw GDLException(this,"Keyword parameters not allowed in call.");
3122 try
3123 {
3124 BaseGDL* param=NULL;
3125 bool isReference =
3126 static_cast<ParameterNode*>(this->getFirstChild())->ParameterDirect( param);
3127 Guard<BaseGDL> guard;
3128 if( !isReference)
3129 guard.Reset( param);
3130
3131 if( param == NULL)
3132 return new DLongGDL( 0);
3133
3134 if( param->IsAssoc())
3135 return new DLongGDL( 1);
3136 if(param->Type() == GDL_OBJ and param->Scalar())
3137 {
3138 DObj ID = (*static_cast<DObjGDL*>( param))[0];
3139
3140 DStructGDL* s = NULL;
3141 Guard<BaseGDL> guard(s);
3142 try {
3143 s= BaseGDL::interpreter->GetObjHeap( ID);
3144 }
3145 catch( GDLInterpreter::HeapException& hEx)
3146 {
3147 throw GDLException(this, "Object ID <"+i2s(ID)+"> not found.");
3148 }
3149 if( s->Desc()->IsParent("LIST"))
3150 return new DLongGDL( lib::LIST_count(s));
3151 else
3152 if( s->Desc()->IsParent("HASH"))
3153 return new DLongGDL( lib::HASH_count(s));
3154 }
3155 if (param->N_Elements() > 2147483647UL)
3156 return new DLong64GDL( param->N_Elements());
3157 else
3158 return new DLongGDL( param->N_Elements());
3159 }
3160 catch( GDLException& e)
3161 {
3162 // an error occured -> parameter is undefined
3163 return new DLongGDL( 0);
3164 }
3165 }
3166
LEval()3167 BaseGDL** FCALL_LIB_RETNEWNode::LEval()
3168 {
3169 throw GDLException(this,"Internal error: FCALL_LIB_RETNEW as left expr.");
3170 }
3171
Eval()3172 BaseGDL* FCALL_LIB_RETNEWNode::Eval()
3173 {
3174 // match(antlr::RefAST(_t),FCALL_LIB_RETNEW);
3175 EnvT* newEnv=new EnvT( this, this->libFun);
3176
3177 ProgNode::interpreter->parameter_def_nocheck(this->getFirstChild(), newEnv);
3178
3179 Guard<EnvT> guardEnv( newEnv);
3180
3181 BaseGDL* res = this->libFunFun(newEnv);
3182 //*** MUST always return a defined expression
3183 assert( res != NULL);
3184 return res;
3185 }
3186
LEval()3187 BaseGDL** FCALL_LIB_DIRECTNode::LEval()
3188 {
3189 throw GDLException(this,"Internal error: FCALL_LIB_DIRECTNode as left expr.");
3190 }
3191
Eval()3192 BaseGDL* FCALL_LIB_DIRECTNode::Eval()
3193 {
3194 BaseGDL* param;
3195 bool isReference =
3196 static_cast<ParameterNode*>(this->getFirstChild())->ParameterDirect( param);
3197 Guard<BaseGDL> guard;
3198 if( !isReference)
3199 guard.Init( param);
3200 // check already here to keep functions leaner
3201 if( param == NULL)
3202 {
3203 assert( isReference);
3204 // unfortunately we cannot retrieve the variable's name here without some effort
3205 throw GDLException(this,
3206 this->libFun->ObjectName()+": Variable is undefined.",
3207 false,false);
3208 }
3209 try {
3210 BaseGDL* res = this->libFunDirectFun(param, isReference);
3211 // static_cast<DLibFunDirect*>(this->libFun)->FunDirect()(param, isReference);
3212 assert( res != NULL); //*** MUST always return a defined expression
3213 if( res == param)
3214 guard.release();
3215 return res;
3216 }
3217 catch( GDLException& ex)
3218 {
3219 // annotate exception
3220 throw GDLException(this, this->libFun->ObjectName()+": "+ ex.getMessage(),false,false);
3221 }
3222 }
3223
EvalRefCheck(BaseGDL * & rEval)3224 BaseGDL** FCALL_LIBNode::EvalRefCheck( BaseGDL*& rEval)
3225 {
3226 EnvT* newEnv=new EnvT( this, this->libFun);//libFunList[fl->funIx]);
3227
3228 ProgNode::interpreter->parameter_def_nocheck(this->getFirstChild(), newEnv);
3229 Guard<EnvT> guardEnv( newEnv);
3230
3231 // make the call
3232 static DSub* scopeVarfetchPro = libFunList[ LibFunIx("SCOPE_VARFETCH")];
3233 static DSub* routine_namesPro = libFunList[ LibFunIx("ROUTINE_NAMES")];
3234 if( scopeVarfetchPro == this->libFun)//newEnv->GetPro())
3235 {
3236 BaseGDL** sV = lib::scope_varfetch_reference( newEnv);
3237 if( sV == NULL)
3238 {
3239 rEval = lib::scope_varfetch_value( newEnv);
3240 return NULL;
3241 }
3242 rEval = *sV;
3243 if( newEnv->InLoc(sV))
3244 {
3245 *sV = NULL; // steal local value
3246 return NULL; // return as not global
3247 }
3248 return sV;
3249 }
3250 if( routine_namesPro == this->libFun)// newEnv->GetPro())
3251 {
3252 BaseGDL** sV = lib::routine_names_reference( newEnv);
3253 if( sV == NULL)
3254 {
3255 rEval = lib::routine_names_value( newEnv);
3256 return NULL;
3257 }
3258 rEval = *sV;
3259 if( newEnv->InLoc(sV))
3260 {
3261 *sV = NULL; // steal local value
3262 return NULL; // return as not global
3263 }
3264 return sV;
3265 }
3266
3267 // make the call
3268 // rEval = static_cast<DLibFun*>(newEnv->GetPro())->Fun()(newEnv);
3269 rEval = this->libFunFun(newEnv);
3270 // BaseGDL** res = ProgNode::interpreter->CallStackBack()->GetPtrTo( rEval);
3271 BaseGDL** res = newEnv->GetPtrToReturnValue();
3272 return res; // NULL ok, rEval set properly
3273
3274 }
3275
LEval()3276 BaseGDL** FCALL_LIBNode::LEval()
3277 {
3278 EnvT* newEnv=new EnvT( this, this->libFun);//libFunList[fl->funIx]);
3279
3280 ProgNode::interpreter->parameter_def_nocheck(this->getFirstChild(), newEnv);
3281 Guard<EnvT> guardEnv( newEnv);
3282
3283 // make the call
3284 static DSub* scopeVarfetchPro = libFunList[ LibFunIx("SCOPE_VARFETCH")];
3285 if( scopeVarfetchPro == this->libFun)//newEnv->GetPro())
3286 {
3287 BaseGDL** sV = lib::scope_varfetch_reference( newEnv);
3288 if( sV != NULL)
3289 return sV;
3290 // should never happen
3291 throw GDLException( this, "Internal error: SCOPE_VARFETCH returned no left-value: "+this->getText());
3292 }
3293 static DSub* routine_namesPro = libFunList[ LibFunIx("ROUTINE_NAMES")];
3294 if( routine_namesPro == this->libFun)// newEnv->GetPro())
3295 {
3296 BaseGDL** sV = lib::routine_names_reference( newEnv);
3297 if( sV != NULL)
3298 return sV;
3299 // should never happen
3300 throw GDLException( this, "Internal error: ROUTINE_NAMES returned no left-value: "+this->getText());
3301 }
3302 // BaseGDL* libRes = static_cast<DLibFun*>(newEnv->GetPro())->Fun()(newEnv);
3303 BaseGDL* libRes = this->libFunFun(newEnv);
3304 BaseGDL** res = newEnv->GetPtrToReturnValue();
3305 if( res == NULL)
3306 {
3307 GDLDelete( libRes);
3308
3309 throw GDLException( this, "Library function must return a "
3310 "left-value in this context: "+this->getText());
3311 }
3312 return res;
3313 }
3314
3315 // returns new or existing variable
EvalFCALL_LIB(BaseGDL ** & retValPtr)3316 BaseGDL* FCALL_LIBNode::EvalFCALL_LIB(BaseGDL**& retValPtr)
3317 {
3318
3319 EnvT* newEnv=new EnvT( this, this->libFun);//libFunList[fl->funIx]);
3320
3321 ProgNode::interpreter->parameter_def_nocheck(this->getFirstChild(), newEnv);
3322
3323 Guard<EnvT> guardEnv( newEnv);
3324
3325 // assert( dynamic_cast<EnvUDT*>(ProgNode::interpreter->CallStackBack()) != NULL);
3326 // EnvUDT* callStackBack = static_cast<EnvUDT*>(ProgNode::interpreter->CallStackBack());
3327
3328 // BaseGDL* res=static_cast<DLibFun*>(newEnv->GetPro())->Fun()(newEnv);
3329 BaseGDL* res=this->libFunFun(newEnv);
3330 // *** MUST always return a defined expression or !NULL
3331 assert( res != NULL);
3332
3333 // ProgNode::interpreter->CallStackBack()->SetPtrToReturnValue( newEnv->GetPtrToReturnValueNull());
3334 retValPtr = newEnv->GetPtrToReturnValue();
3335 return res;
3336 }
3337
3338 // returns always a new variable - see EvalFCALL_LIB
Eval()3339 BaseGDL* FCALL_LIBNode::Eval()
3340 {
3341 // match(antlr::RefAST(_t),FCALL_LIB);
3342 EnvT* newEnv=new EnvT( this, this->libFun);//libFunList[fl->funIx]);
3343
3344 ProgNode::interpreter->parameter_def_nocheck(this->getFirstChild(), newEnv);
3345
3346 Guard<EnvT> guardEnv( newEnv);
3347
3348 // // push id.pro onto call stack
3349 // ProgNode::interpreter->CallStack().push_back(newEnv);
3350 // make the call
3351 BaseGDL* res=this->libFunFun(newEnv);
3352 // *** MUST always return a defined expression
3353 assert( res != NULL);
3354 // throw GDLException( _t, "");
3355
3356 if( newEnv->GetPtrToReturnValue() != NULL)
3357 return res->Dup();
3358
3359 return res;
3360 }
3361
EvalRefCheck(BaseGDL * & rEval)3362 BaseGDL** MFCALLNode::EvalRefCheck( BaseGDL*& rEval)
3363 {
3364 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3365
3366 ProgNodeP _t = this->getFirstChild();
3367
3368 BaseGDL* self=_t->Eval(); //ProgNode::interpreter->expr(_t);
3369 Guard<BaseGDL> self_guard(self);
3370
3371 _t = _t->getNextSibling();
3372 //match(antlr::RefAST(_t),IDENTIFIER);
3373
3374 EnvUDT* newEnv=new EnvUDT( self, _t, "", EnvUDT::LRFUNCTION);
3375
3376 self_guard.release();
3377
3378 _t = _t->getNextSibling();
3379
3380 ProgNode::interpreter->parameter_def(_t, newEnv); // temporary owns newEnv (-> no guard necessary)
3381
3382 // push environment onto call stack
3383 ProgNode::interpreter->CallStack().push_back(newEnv); // now guarded by "guard"
3384
3385 // make the call
3386 rEval=ProgNode::interpreter->call_fun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
3387
3388 BaseGDL** res = newEnv->GetPtrToGlobalReturnValue();
3389 return res; // NULL ok, rEval set properly
3390 }
3391
LEval()3392 BaseGDL** MFCALLNode::LEval()
3393 {
3394 // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack
3395 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3396
3397 // match(antlr::RefAST(_t),MFCALL);
3398 ProgNodeP _t = this->getFirstChild();
3399 BaseGDL* self=_t->Eval(); //ProgNode::interpreter->expr(_t);
3400 Guard<BaseGDL> self_guard(self);
3401
3402 ProgNodeP mp = _t->getNextSibling();
3403 // match(antlr::RefAST(_t),IDENTIFIER);
3404 _t = mp->getNextSibling();
3405
3406 EnvUDT* newEnv=new EnvUDT( self, mp, "", EnvUDT::LFUNCTION);
3407
3408 self_guard.release();
3409
3410 ProgNode::interpreter->parameter_def(_t, newEnv);
3411
3412 // push environment onto call stack
3413 ProgNode::interpreter->CallStack().push_back(newEnv);
3414
3415 // make the call
3416 BaseGDL** res=ProgNode::interpreter->
3417 call_lfun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
3418
3419 //ProgNode::interpreter->SetRetTree( this->getNextSibling());
3420 return res;
3421 }
3422
Eval()3423 BaseGDL* MFCALLNode::Eval()
3424 {
3425 // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack
3426 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3427
3428 ProgNodeP _t = this->getFirstChild();
3429
3430 BaseGDL* self=_t->Eval(); //ProgNode::interpreter->expr(_t);
3431 Guard<BaseGDL> self_guard(self);
3432
3433 _t = _t->getNextSibling();
3434 //match(antlr::RefAST(_t),IDENTIFIER);
3435
3436 EnvUDT* newEnv=new EnvUDT( self, _t);
3437
3438 self_guard.release();
3439
3440 _t = _t->getNextSibling();
3441
3442 ProgNode::interpreter->parameter_def(_t, newEnv);
3443
3444 // push environment onto call stack
3445 ProgNode::interpreter->CallStack().push_back(newEnv);
3446
3447 // make the call
3448 BaseGDL* res=ProgNode::interpreter->call_fun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
3449
3450 //ProgNode::interpreter->SetRetTree( this->getNextSibling());
3451 return res;
3452 }
3453
EvalRefCheck(BaseGDL * & rEval)3454 BaseGDL** MFCALL_PARENTNode::EvalRefCheck( BaseGDL*& rEval)
3455 {
3456 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3457 // match(antlr::RefAST(_t),MFCALL_PARENT);
3458 ProgNodeP _t = this->getFirstChild();
3459 BaseGDL* self=_t->Eval(); //ProgNode::interpreter->expr(_t);
3460 Guard<BaseGDL> self_guard(self);
3461
3462 _t = _t->getNextSibling();
3463 ProgNodeP parent = _t;
3464 // match(antlr::RefAST(_t),IDENTIFIER);
3465 _t = _t->getNextSibling();
3466 ProgNodeP p = _t;
3467 // match(antlr::RefAST(_t),IDENTIFIER);
3468 _t = _t->getNextSibling();
3469
3470 EnvUDT* newEnv=new EnvUDT( self, p, parent->getText(), EnvUDT::LRFUNCTION);
3471
3472 self_guard.release();
3473
3474 ProgNode::interpreter->parameter_def(_t, newEnv);
3475
3476 // push environment onto call stack
3477 ProgNode::interpreter->CallStack().push_back(newEnv);
3478
3479 // make the call
3480 rEval=ProgNode::interpreter->call_fun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
3481 BaseGDL** res = newEnv->GetPtrToGlobalReturnValue();
3482 return res; // NULL ok, rEval set properly
3483 }
3484
LEval()3485 BaseGDL** MFCALL_PARENTNode::LEval()
3486 {
3487 // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack
3488 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3489 // match(antlr::RefAST(_t),MFCALL_PARENT);
3490 ProgNodeP _t = this->getFirstChild();
3491 BaseGDL* self=_t->Eval(); //ProgNode::interpreter->expr(_t);
3492 Guard<BaseGDL> self_guard(self);
3493
3494 _t = _t->getNextSibling();
3495 ProgNodeP parent = _t;
3496 // match(antlr::RefAST(_t),IDENTIFIER);
3497 _t = _t->getNextSibling();
3498 ProgNodeP p = _t;
3499 // match(antlr::RefAST(_t),IDENTIFIER);
3500 _t = _t->getNextSibling();
3501
3502 EnvUDT* newEnv=new EnvUDT( self, p, parent->getText(), EnvUDT::LFUNCTION);
3503
3504 self_guard.release();
3505
3506 ProgNode::interpreter->parameter_def(_t, newEnv);
3507
3508 // push environment onto call stack
3509 ProgNode::interpreter->CallStack().push_back(newEnv);
3510
3511 // make the call
3512 BaseGDL** res=ProgNode::interpreter->
3513 call_lfun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
3514
3515 //ProgNode::interpreter->SetRetTree( this->getNextSibling());
3516 return res;
3517 }
3518
Eval()3519 BaseGDL* MFCALL_PARENTNode::Eval()
3520 {
3521 // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack
3522 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3523 // match(antlr::RefAST(_t),MFCALL_PARENT);
3524 ProgNodeP _t = this->getFirstChild();
3525 BaseGDL* self=_t->Eval(); //ProgNode::interpreter->expr(_t);
3526 Guard<BaseGDL> self_guard(self);
3527
3528 _t = _t->getNextSibling();
3529 ProgNodeP parent = _t;
3530 // match(antlr::RefAST(_t),IDENTIFIER);
3531 _t = _t->getNextSibling();
3532 ProgNodeP p = _t;
3533 // match(antlr::RefAST(_t),IDENTIFIER);
3534 _t = _t->getNextSibling();
3535
3536 EnvUDT* newEnv=new EnvUDT( self, p, parent->getText());
3537
3538 self_guard.release();
3539
3540 ProgNode::interpreter->parameter_def(_t, newEnv);
3541
3542 // push environment onto call stack
3543 ProgNode::interpreter->CallStack().push_back(newEnv);
3544
3545 // make the call
3546 BaseGDL* res=ProgNode::interpreter->call_fun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
3547
3548 //ProgNode::interpreter->SetRetTree( this->getNextSibling());
3549 return res;
3550 }
3551
EvalRefCheck(BaseGDL * & rEval)3552 BaseGDL** FCALLNode::EvalRefCheck( BaseGDL*& rEval)
3553 {
3554 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3555 ProgNode::interpreter->SetFunIx( this);
3556 if( this->funIx < -1) throw GDLException(this," FCALLNode::EvalRefcheck - AutoObj",true,false);
3557 EnvUDT* newEnv=new EnvUDT( this, funList[this->funIx], EnvUDT::LRFUNCTION);
3558
3559 ProgNode::interpreter->parameter_def(this->getFirstChild(), newEnv);
3560
3561 // push environment onto call stack
3562 ProgNode::interpreter->CallStack().push_back(newEnv);
3563
3564 // make the call
3565 rEval=ProgNode::interpreter->call_fun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
3566 BaseGDL** res = newEnv->GetPtrToGlobalReturnValue();
3567 return res; // NULL ok, rEval set properly
3568 }
3569
EvalRefCheck(BaseGDL * & rEval)3570 BaseGDL** ARRAYEXPR_FCALLNode::EvalRefCheck( BaseGDL*& rEval)
3571 {
3572 if( fcallNodeFunIx >= 0)
3573 return fcallNode->FCALLNode::EvalRefCheck( rEval);
3574 else if( fcallNodeFunIx == -2)
3575 {
3576 rEval = arrayExprNode->ARRAYEXPRNode::Eval();
3577 return NULL;
3578 }
3579
3580 assert( fcallNodeFunIx == -1);
3581 // 1st try arrayexpr
3582 try {
3583 rEval = arrayExprNode->ARRAYEXPRNode::Eval();
3584 assert( rEval != NULL);
3585 fcallNodeFunIx = -2; // mark as ARRAYEXPR succeeded
3586 return NULL;
3587 }
3588 catch( GDLException& ex)
3589 {
3590 if( !ex.GetArrayexprIndexeeFailed())
3591 {
3592 fcallNodeFunIx = -2; // mark as ARRAYEXPR succeeded
3593 throw ex;
3594 }
3595 // then try fcall
3596 try {
3597 BaseGDL** res = fcallNode->FCALLNode::EvalRefCheck( rEval);
3598 fcallNodeFunIx = fcallNode->funIx;
3599 return res;
3600 }
3601 catch( GDLException& innerEx)
3602 {
3603 // keep FCALL if already compiled (but runtime error)
3604 if(fcallNode->funIx >= 0)
3605 {
3606 fcallNodeFunIx = fcallNode->funIx;
3607 throw innerEx;
3608 }
3609 string msg = "Ambiguous: " + ex.ANTLRException::toString() +
3610 " or: " + innerEx.ANTLRException::toString();
3611 throw GDLException(this,msg,true,false);
3612 }
3613 }
3614 }
3615
LEval()3616 BaseGDL** FCALLNode::LEval()
3617 {
3618 // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack
3619 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3620 // match(antlr::RefAST(_t),FCALL);
3621 ProgNodeP _t = this->getFirstChild();
3622
3623 ProgNode::interpreter->SetFunIx( this);
3624 if( this->funIx < -1) throw GDLException(this," FCALLNode::LEval- AutoObj",true,false);
3625 EnvUDT* newEnv=new EnvUDT( this, funList[this->funIx], EnvUDT::LFUNCTION);
3626
3627 ProgNode::interpreter->parameter_def(_t, newEnv);
3628
3629 // push environment onto call stack
3630 ProgNode::interpreter->CallStack().push_back(newEnv);
3631
3632 // make the call
3633 BaseGDL** res=
3634 ProgNode::interpreter->call_lfun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
3635
3636 //ProgNode::interpreter->SetRetTree( this->getNextSibling());
3637 return res;
3638 }
3639
LEval()3640 BaseGDL** ARRAYEXPR_FCALLNode::LEval()
3641 {
3642 // already succeeded
3643 if( fcallNodeFunIx >= 0)
3644 return fcallNode->FCALLNode::LEval();
3645 else if( fcallNodeFunIx == -2)
3646 {
3647 return arrayExprNode->ARRAYEXPRNode::LEval();
3648 }
3649
3650 // both possible
3651 assert( fcallNodeFunIx == -1);
3652 // 1st try arrayexpr
3653 try {
3654 BaseGDL** res = arrayExprNode->ARRAYEXPRNode::LEval();
3655 fcallNodeFunIx = -2; // mark as ARRAYEXPR succeeded
3656 return res;
3657 }
3658 catch( GDLException& ex)
3659 {
3660 if( !ex.GetArrayexprIndexeeFailed())
3661 {
3662 fcallNodeFunIx = -2; // mark as ARRAYEXPR succeeded
3663 throw ex;
3664 }
3665 // then try fcall
3666 try {
3667 BaseGDL** res = fcallNode->FCALLNode::LEval();
3668 fcallNodeFunIx = fcallNode->funIx;
3669 return res;
3670 }
3671 catch( GDLException& innerEx)
3672 {
3673 // keep FCALL if already compiled (but runtime error)
3674 if(fcallNode->funIx >= 0)
3675 {
3676 fcallNodeFunIx = fcallNode->funIx;
3677 throw innerEx;
3678 }
3679 string msg = "Ambiguous: " + ex.ANTLRException::toString() +
3680 " or: " + innerEx.ANTLRException::toString();
3681 throw GDLException(this,msg,true,false);
3682 }
3683 }
3684 }
3685
Eval()3686 BaseGDL* FCALLNode::Eval()
3687 {
3688 // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack
3689 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3690 ProgNode::interpreter->SetFunIx( this);
3691 if( this->funIx < -1) throw GDLException(this," FCALLNode::Eval - AutoObj",true,false);
3692 EnvUDT* newEnv=new EnvUDT( this, funList[this->funIx]);
3693
3694 ProgNode::interpreter->parameter_def(this->getFirstChild(), newEnv);
3695
3696 // push environment onto call stack
3697 ProgNode::interpreter->CallStack().push_back(newEnv);
3698
3699 // make the call
3700 BaseGDL*
3701 res=ProgNode::interpreter->call_fun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
3702
3703 //ProgNode::interpreter->SetRetTree( this->getNextSibling());
3704 return res;
3705 }
3706
Eval()3707 BaseGDL* ARRAYEXPR_FCALLNode::Eval()
3708 {
3709 if( fcallNodeFunIx >= 0)
3710 return fcallNode->FCALLNode::Eval();
3711 else if( fcallNodeFunIx == -2)
3712 {
3713 return arrayExprNode->ARRAYEXPRNode::Eval();
3714 }
3715
3716 assert( fcallNodeFunIx == -1);
3717
3718 // 1st try arrayexpr
3719 try {
3720 BaseGDL* res = arrayExprNode->ARRAYEXPRNode::Eval();
3721 fcallNodeFunIx = -2; // mark as ARRAYEXPR succeeded
3722 return res;
3723 }
3724 catch( GDLException& ex)
3725 {
3726 // then try fcall
3727 // Problem here: we don't know, why arrayexpr failed
3728 // if it is just because of the index, we should not
3729 // try the function here
3730 if( !ex.GetArrayexprIndexeeFailed())
3731 {
3732 fcallNodeFunIx = -2; // mark as ARRAYEXPR succeeded
3733 throw ex;
3734 }
3735 try {
3736 BaseGDL* res = fcallNode->FCALLNode::Eval();
3737 fcallNodeFunIx = fcallNode->funIx;
3738 return res;
3739 }
3740 catch( GDLException& innerEx)
3741 {
3742 // keep FCALL if already compiled (but runtime error)
3743 if(fcallNode->funIx >= 0)
3744 {
3745 fcallNodeFunIx = fcallNode->funIx;
3746 throw innerEx;
3747 }
3748 string msg = "Ambiguous: " + ex.ANTLRException::toString() +
3749 " or: " + innerEx.ANTLRException::toString();
3750 throw GDLException(this,msg,true,false);
3751 }
3752 }
3753 }
3754
3755
EvalRefCheck(BaseGDL * & rEval)3756 BaseGDL** ARRAYEXPR_MFCALLNode::EvalRefCheck( BaseGDL*& rEval)
3757 {
3758 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3759 // match(antlr::RefAST(_t),ARRAYEXPR_MFCALL);
3760 ProgNodeP mark = this->getFirstChild();
3761
3762 ProgNodeP _t = mark->getNextSibling(); // skip DOT
3763
3764 BaseGDL* self=_t->Eval(); //ProgNode::interpreter->expr(_t);
3765 Guard<BaseGDL> self_guard(self);
3766
3767 ProgNodeP mp2 = _t->getNextSibling();
3768 //match(antlr::RefAST(_t),IDENTIFIER);
3769
3770 _t = mp2->getNextSibling();
3771
3772 BaseGDL** res;
3773
3774 EnvUDT* newEnv;
3775 try {
3776 newEnv=new EnvUDT( self, mp2, "", EnvUDT::LRFUNCTION);
3777 self_guard.release();
3778 }
3779 catch( GDLException& ex)
3780 {
3781 goto tryARRAYEXPR;
3782 }
3783
3784 ProgNode::interpreter->parameter_def(_t, newEnv);
3785
3786 // push environment onto call stack
3787 ProgNode::interpreter->CallStack().push_back(newEnv);
3788
3789 // make the call
3790 rEval= ProgNode::interpreter->
3791 call_fun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
3792 res = newEnv->GetPtrToGlobalReturnValue();
3793 return res; // NULL ok, rEval set properly
3794
3795 tryARRAYEXPR:
3796 ;
3797 //_t = mark;
3798
3799 ProgNodeP dot = mark;
3800 // match(antlr::RefAST(_t),DOT);
3801 _t = mark->getFirstChild();
3802
3803 SizeT nDot=dot->nDot;
3804 Guard<DotAccessDescT> aD( new DotAccessDescT(nDot+1));
3805
3806 ProgNode::interpreter->r_dot_array_expr(_t, aD.get());
3807 _t = _t->getNextSibling();
3808 for (; _t != NULL;) {
3809 ProgNode::interpreter->tag_array_expr(_t, aD.get());
3810 _t = _t->getNextSibling();
3811 }
3812 rEval= aD->ADResolve();
3813 return NULL; // always r-value
3814 }
3815
3816 // from l_arrayexpr_mfcall_as_mfcall
LEval()3817 BaseGDL** ARRAYEXPR_MFCALLNode::LEval()
3818 {
3819 // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack
3820 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3821 BaseGDL *self;
3822 EnvUDT* newEnv;
3823
3824 ProgNodeP _t = this->getFirstChild();
3825 _t = _t->getNextSibling(); // skip DOT
3826
3827 self= _t->Eval(); //interpreter->expr(_t);
3828 ProgNodeP mp2 = _t->getNextSibling(); // interpreter->GetRetTree();
3829 //match(antlr::RefAST(_t),IDENTIFIER);
3830
3831 Guard<BaseGDL> self_guard(self);
3832
3833 newEnv=new EnvUDT( self, mp2, "", EnvUDT::LFUNCTION);
3834
3835 self_guard.release();
3836
3837 ProgNode::interpreter->parameter_def( mp2->getNextSibling(), newEnv);
3838
3839 // push environment onto call stack
3840 ProgNode::interpreter->CallStack().push_back(newEnv);
3841
3842 // make the call
3843 return ProgNode::interpreter->call_lfun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
3844 }
3845
3846
3847
Eval()3848 BaseGDL* ARRAYEXPR_MFCALLNode::Eval()
3849 {
3850 // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack
3851 StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3852 // match(antlr::RefAST(_t),ARRAYEXPR_MFCALL);
3853 ProgNodeP mark = this->getFirstChild();
3854
3855 ProgNodeP _t = mark->getNextSibling(); // skip DOT
3856
3857 BaseGDL* self=_t->Eval(); //ProgNode::interpreter->expr(_t);
3858 Guard<BaseGDL> self_guard(self);
3859
3860 ProgNodeP mp2 = _t->getNextSibling();
3861 //match(antlr::RefAST(_t),IDENTIFIER);
3862
3863 _t = mp2->getNextSibling();
3864
3865 BaseGDL* res;
3866
3867 EnvUDT* newEnv;
3868 try {
3869 newEnv=new EnvUDT( self, mp2);
3870 self_guard.release();
3871 }
3872 catch( GDLException& ex)
3873 {
3874 goto tryARRAYEXPR;
3875 }
3876
3877 ProgNode::interpreter->parameter_def(_t, newEnv);
3878
3879 // push environment onto call stack
3880 ProgNode::interpreter->CallStack().push_back(newEnv);
3881
3882 // make the call
3883 res=
3884 ProgNode::interpreter->
3885 call_fun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
3886
3887 //ProgNode::interpreter->SetRetTree( this->getNextSibling());
3888 return res;
3889
3890 tryARRAYEXPR:
3891 ;
3892 //_t = mark;
3893
3894 ProgNodeP dot = mark;
3895 // match(antlr::RefAST(_t),DOT);
3896 _t = mark->getFirstChild();
3897
3898 SizeT nDot=dot->nDot;
3899 Guard<DotAccessDescT> aD( new DotAccessDescT(nDot+1));
3900
3901 ProgNode::interpreter->r_dot_array_expr(_t, aD.get());
3902 _t = _t->getNextSibling();
3903 for (; _t != NULL;) {
3904 ProgNode::interpreter->tag_array_expr(_t, aD.get());
3905 _t = _t->getNextSibling();
3906 }
3907 res= aD->ADResolve();
3908
3909 //ProgNode::interpreter->SetRetTree( this->getNextSibling());
3910 return res;
3911 }
3912
3913 // BaseGDL** ARRAYEXPR_MFCALLNode::LEval()
3914 // {
3915 // // better than auto_ptr: auto_ptr wouldn't remove newEnv from the stack
3916 // StackGuard<EnvStackT> guard(ProgNode::interpreter->CallStack());
3917 // }
3918
EvalRefCheck(BaseGDL * & rEval)3919 BaseGDL** VARNode::EvalRefCheck( BaseGDL*& rEval)
3920 {
3921 BaseGDL** res = this->LEval();
3922 return res;
3923 }
LEval()3924 BaseGDL** VARNode::LEval()
3925 {
3926 // ProgNode::interpreter->SetRetTree( this->getNextSibling());
3927 // BaseGDL* v = ProgNode::interpreter->CallStackBack()->GetKW(this->varIx);
3928 // BaseGDL** vv = &(ProgNode::interpreter->CallStackBack()->GetKW(this->varIx));
3929 // cout << "vv = " << vv << " *vv = " << *vv << " v = " << v << endl;
3930 return &(ProgNode::interpreter->CallStackBack()->GetKW(this->varIx));
3931 }
EvalRefCheck(BaseGDL * & rEval)3932 BaseGDL** VARPTRNode::EvalRefCheck( BaseGDL*& rEval)
3933 {
3934 return this->LEval();
3935 }
LEval()3936 BaseGDL** VARPTRNode::LEval()
3937 {
3938 // ProgNode::interpreter->SetRetTree( this->getNextSibling());
3939 return &this->var->Data();
3940 }
3941
3942
EvalRefCheck(BaseGDL * & rEval)3943 BaseGDL** EXPRNode::EvalRefCheck( BaseGDL*& rEval)
3944 {
3945 return this->LEval();
3946 }
LEval()3947 BaseGDL** EXPRNode::LEval()
3948 {
3949 return this->getFirstChild()->LExpr( NULL); //interpreter->l_expr( this->getFirstChild(), NULL);
3950 }
3951
Eval()3952 BaseGDL* DOTNode::Eval()
3953 {
3954 BaseGDL* r;
3955 // clears aL when destroyed
3956 ArrayIndexListGuard guard;
3957
3958 DotAccessDescT aD( nDot+1);
3959
3960 ProgNodeP _t = this->getFirstChild();
3961 if( _t->getType() == GDLTokenTypes::ARRAYEXPR)
3962 {
3963 _t = _t->getFirstChild();
3964
3965 // r = interpreter->r_dot_indexable_expr(_t, &aD);
3966 // _t = interpreter->GetRetTree();
3967 if( _t->getType() == GDLTokenTypes::EXPR)
3968 {
3969 r = _t->getFirstChild()->Eval();
3970 aD.SetOwner( true);
3971 _t = _t->getNextSibling();
3972 }
3973 else if( _t->getType() == GDLTokenTypes::SYSVAR)
3974 {
3975 r = _t->EvalNC();
3976 _t = _t->getNextSibling();
3977 }
3978 else
3979 {
3980 assert( _t->getType() == GDLTokenTypes::VAR
3981 || _t->getType() == GDLTokenTypes::VARPTR);
3982 BaseGDL** e = _t->LEval();
3983 if( *e == NULL)
3984 {
3985 if( _t->getType() == GDLTokenTypes::VAR)
3986 throw GDLException( _t, "Variable is undefined: "+
3987 interpreter->CallStackBack()->GetString(_t->GetVarIx()),true,false);
3988 else
3989 throw GDLException( _t, "Common block variable is undefined: "+
3990 interpreter->CallStackBack()->GetString( /* reference! */ *e),true,false);
3991 }
3992 r = *e;
3993 _t = _t->getNextSibling();
3994 }
3995
3996
3997 bool handled = false;
3998 if( !r->IsAssoc() && r->Type() == GDL_OBJ && r->StrictScalar())
3999 {
4000 // check for _overloadBracketsRightSide
4001 DObj s = (*static_cast<DObjGDL*>(r))[0]; // is StrictScalar()
4002 // if( s != 0) // no overloads for null object
4003 // {
4004 // DStructGDL* oStructGDL= GDLInterpreter::GetObjHeapNoThrow( s);
4005 // if( oStructGDL != NULL) // if object not valid -> default behaviour
4006 // {
4007 // DStructDesc* desc = oStructGDL->Desc();
4008 //
4009 // DFun* bracketsRightSideOverload = static_cast<DFun*>(desc->GetOperator( OOBracketsRightSide));
4010 DSubUD* bracketsRightSideOverload = static_cast<DSubUD*>(GDLInterpreter::GetObjHeapOperator( s, OOBracketsRightSide));
4011 if( bracketsRightSideOverload != NULL)
4012 {
4013 // _overloadBracketsRightSide
4014 bool internalDSubUD = bracketsRightSideOverload->GetTree()->IsWrappedNode();
4015
4016 DObjGDL* self = static_cast<DObjGDL*>(r);
4017 Guard<BaseGDL> selfGuard;
4018 if( aD.IsOwner())
4019 {
4020 aD.SetOwner( false);
4021 // WE are now the proud owner of 'self'
4022 selfGuard.Init( self);
4023 // so it might be overwritten
4024 }
4025 else
4026 {
4027 if( !internalDSubUD) // internal beahve well
4028 {
4029 self = self->Dup(); // res should be not changeable via SELF
4030 selfGuard.Init( self);
4031 }
4032 }
4033
4034
4035 IxExprListT indexList;
4036 // uses arrIxListNoAssoc
4037 interpreter->arrayindex_list_overload( _t, indexList);
4038 ArrayIndexListGuard guard(_t->arrIxListNoAssoc);
4039
4040 // hidden SELF is counted as well
4041 int nParSub = bracketsRightSideOverload->NPar();
4042 assert( nParSub >= 1); // SELF
4043 // indexList.size() > regular paramters w/o SELF
4044 if( indexList.size() > nParSub - 1)
4045 {
4046 indexList.Cleanup();
4047 throw GDLException( this, bracketsRightSideOverload->ObjectName() +
4048 ": Incorrect number of arguments.",
4049 false, false);
4050 }
4051
4052 // adds already SELF parameter
4053 EnvUDT* newEnv= new EnvUDT( this, bracketsRightSideOverload, &self);
4054 // no guarding of newEnv here (no exceptions until push_back())
4055
4056 // parameters
4057 for( SizeT p=0; p<indexList.size(); ++p)
4058 newEnv->SetNextParUnchecked( indexList[p]); // takes ownership
4059
4060 StackGuard<EnvStackT> stackGuard(interpreter->CallStack());
4061 interpreter->CallStack().push_back( newEnv);
4062
4063 // make the call, return the result
4064 BaseGDL* res = interpreter->call_fun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
4065
4066 if( selfGuard.Get() != NULL && self != selfGuard.Get())
4067 {
4068 // always put out warning first, in case of a later crash
4069 Warning( "WARNING: " + bracketsRightSideOverload->ObjectName() +
4070 ": Assignment to SELF detected (GDL session still ok).");
4071 // assignment to SELF -> self was deleted and points to new variable
4072 // which it owns
4073 selfGuard.Release();
4074 if( static_cast<BaseGDL*>(self) != NullGDL::GetSingleInstance())
4075 selfGuard.Reset(self);
4076 }
4077
4078 aD.SetOwner( true); // aD owns res here
4079 interpreter->SetRootR( this, &aD, res, NULL);
4080 handled = true;
4081 }
4082 }
4083 if( !handled)
4084 {
4085 // regular (non-object) case
4086 ArrayIndexListT* aL = interpreter->arrayindex_list(_t,!r->IsAssoc());
4087
4088 guard.reset(aL);
4089
4090 // check here for object and get struct
4091 //structR=dynamic_cast<DStructGDL*>(r);
4092 // this is much faster than a dynamic_cast
4093 interpreter->SetRootR( this, &aD, r, aL);
4094 }
4095 _t = this->getFirstChild()->getNextSibling();
4096 }
4097 else // ! ARRAYEXPR
4098 // case EXPR:
4099 // case SYSVAR:
4100 // case VAR:
4101 // case VARPTR:
4102 {
4103 // r=interpreter->r_dot_indexable_expr(_t, &aD);
4104 // _t = interpreter->GetRetTree();
4105 if( _t->getType() == GDLTokenTypes::EXPR)
4106 {
4107 r = _t->getFirstChild()->Eval();
4108 aD.SetOwner( true);
4109 _t = _t->getNextSibling();
4110 }
4111 else if( _t->getType() == GDLTokenTypes::SYSVAR)
4112 {
4113 r = _t->EvalNC();
4114 _t = _t->getNextSibling();
4115 }
4116 else
4117 {
4118 assert( _t->getType() == GDLTokenTypes::VAR || _t->getType() == GDLTokenTypes::VARPTR);
4119 BaseGDL** e = _t->LEval();
4120 if( *e == NULL)
4121 {
4122 if( _t->getType() == GDLTokenTypes::VAR)
4123 throw GDLException( _t, "Variable is undefined: "+
4124 interpreter->CallStackBack()->GetString(_t->GetVarIx()),true,false);
4125 else
4126 throw GDLException( _t, "Common block variable is undefined: "+
4127 interpreter->CallStackBack()->GetString( /* reference */ *e),true,false);
4128 }
4129 r = *e;
4130 _t = _t->getNextSibling();
4131 }
4132
4133 interpreter->SetRootR( this, &aD, r, NULL);
4134 }
4135
4136 for (; _t != NULL;) {
4137 interpreter->tag_array_expr(_t, &aD); // nDot times
4138 _t = interpreter->GetRetTree();
4139 }
4140 return aD.ADResolve();
4141 } // DOTNode::Eval
4142
Eval()4143 BaseGDL* ARRAYEXPRNode::Eval()
4144 {
4145 BaseGDL* res;
4146
4147 ExprListT exprList; // for cleanup
4148 IxExprListT ixExprList;
4149 SizeT nExpr;
4150 BaseGDL* s;
4151
4152 // match(antlr::RefAST(_t),ARRAYEXPR);
4153 ProgNodeP _t = this->getFirstChild();
4154
4155 BaseGDL* r;
4156 Guard<BaseGDL> rGuard;
4157 try {
4158 if( NonCopyNode(_t->getType()))
4159 {
4160 r=_t->EvalNC();
4161 }
4162 else
4163 {
4164 BaseGDL** ref =_t->EvalRefCheck(r);
4165 if( ref == NULL)
4166 rGuard.Init( r);
4167 else
4168 r = *ref;
4169 }
4170 }
4171 catch( GDLException& ex)
4172 {
4173 ex.SetArrayexprIndexeeFailed( true);
4174 throw ex;
4175 }
4176
4177 ProgNodeP ixListNode = _t->getNextSibling();
4178
4179 if( r->Type() == GDL_OBJ && r->StrictScalar())
4180 {
4181 // check for _overloadBracketsRightSide
4182
4183 DObj s = (*static_cast<DObjGDL*>(r))[0]; // is StrictScalar()
4184 // if( s != 0) // no overloads for null object
4185 // {
4186 // DStructGDL* oStructGDL= GDLInterpreter::GetObjHeapNoThrow( s);
4187 // if( oStructGDL != NULL) // if object not valid -> default behaviour
4188 // {
4189 // DStructDesc* desc = oStructGDL->Desc();
4190 //
4191 // DFun* bracketsRightSideOverload = static_cast<DFun*>(desc->GetOperator( OOBracketsRightSide));
4192 DSubUD* bracketsRightSideOverload =
4193 static_cast<DSubUD*>(GDLInterpreter::GetObjHeapOperator( s, OOBracketsRightSide));
4194 if( bracketsRightSideOverload != NULL)
4195 {
4196 // _overloadBracketsRightSide
4197 DObjGDL* self = static_cast<DObjGDL*>(rGuard.Get());
4198 if( self == NULL)
4199 {
4200 self = static_cast<DObjGDL*>(r->Dup()); // not set -> not owner
4201 rGuard.Reset( self);
4202 }
4203 // we are now the proud owner of 'self'
4204
4205 IxExprListT indexList;
4206 // uses arrIxListNoAssoc
4207 interpreter->arrayindex_list_overload( ixListNode, indexList);
4208 ArrayIndexListGuard guard(ixListNode->arrIxListNoAssoc);
4209
4210 // hidden SELF is counted as well
4211 int nParSub = bracketsRightSideOverload->NPar();
4212 assert( nParSub >= 1); // SELF
4213 // indexList.size() > regular paramters w/o SELF
4214 if( indexList.size() > nParSub - 1)
4215 {
4216 indexList.Cleanup();
4217 throw GDLException( this, bracketsRightSideOverload->ObjectName() +
4218 ": Incorrect number of arguments.",
4219 false, false);
4220 }
4221
4222 // adds already SELF parameter
4223 EnvUDT* newEnv= new EnvUDT( this, bracketsRightSideOverload, &self);
4224 // no guarding of newEnv here (no exceptions until push_back())
4225
4226 // parameters
4227 for( SizeT p=0; p<indexList.size(); ++p)
4228 newEnv->SetNextParUnchecked( indexList[p]); // takes ownership
4229
4230 StackGuard<EnvStackT> stackGuard(interpreter->CallStack());
4231 interpreter->CallStack().push_back( newEnv);
4232
4233 // make the call, return the result
4234 BaseGDL* res = interpreter->call_fun(static_cast<DSubUD*>(newEnv->GetPro())->GetTree());
4235
4236 if( self != rGuard.Get())
4237 {
4238 // always put out warning first, in case of a later crash
4239 Warning( "WARNING: " + bracketsRightSideOverload->ObjectName() +
4240 ": Assignment to SELF detected (GDL session still ok).");
4241 // assignment to SELF -> self was deleted and points to new variable
4242 // which it owns
4243 rGuard.Release();
4244 if( static_cast<BaseGDL*>(self) != NullGDL::GetSingleInstance())
4245 rGuard.Reset(self);
4246 }
4247
4248 return res;
4249 }
4250 }
4251
4252 // first use NoAssoc case (just to get nExpr)
4253 ArrayIndexListT* aL = ixListNode->arrIxListNoAssoc;
4254 assert( aL != NULL);
4255 nExpr = aL->NParam();
4256
4257 _t = ixListNode->getFirstChild();
4258
4259 if( nExpr == 0)
4260 {
4261 goto empty;
4262 }
4263
4264 while( true)
4265 {
4266 if( NonCopyNode(_t->getType()))
4267 {
4268 s=_t->EvalNC();//indexable_expr(_t);
4269 assert(s != NULL);
4270 assert( s->Type() != GDL_UNDEF);
4271 }
4272 else
4273 {
4274 BaseGDL** ref =_t->EvalRefCheck(s); //ProgNode::interpreter->indexable_tmp_expr(_t);
4275 if( ref == NULL)
4276 exprList.push_back( s);
4277 else
4278 s = *ref;
4279 assert(s != NULL);
4280 assert( s->Type() != GDL_UNDEF);
4281 }
4282
4283
4284 ixExprList.push_back( s); // already owned (s. a.)
4285 if( ixExprList.size() == nExpr)
4286 break; // while( true) -> finish
4287
4288 _t = _t->getNextSibling(); // set to next index
4289 } // while( true)
4290
4291 empty:
4292
4293 if( r->IsAssoc())
4294 {
4295 ArrayIndexListT* aLAssoc = ixListNode->arrIxList;
4296 assert( aLAssoc != NULL);
4297 ArrayIndexListGuard guardAssoc(aLAssoc);
4298 return aLAssoc->Index( r, ixExprList);
4299 }
4300 else
4301 {
4302 ArrayIndexListGuard guard(aL);
4303 return aL->Index( r, ixExprList);
4304 }
4305 assert( false);
4306 return NULL;
4307 }
4308