bool handle_args (EnvT* e) { // handle Log options passing via Keywords // note: undocumented keywords [xyz]type still exist and // have priority on [xyz]log ! static int xTypeIx = e->KeywordIx( "XTYPE" ); static int yTypeIx = e->KeywordIx( "YTYPE" ); static int zTypeIx = e->KeywordIx( "ZTYPE" ); static int xLogIx = e->KeywordIx( "XLOG" ); static int yLogIx = e->KeywordIx( "YLOG" ); static int zLogIx = e->KeywordIx( "ZLOG" ); static int xTickunitsIx = e->KeywordIx( "XTICKUNITS" ); static int yTickunitsIx = e->KeywordIx( "YTICKUNITS" ); static int zTickunitsIx = e->KeywordIx( "ZTICKUNITS" ); if ( e->KeywordPresent( xTypeIx ) ) xLog = e->KeywordSet( xTypeIx ); else xLog = e->KeywordSet( xLogIx ); if ( e->KeywordPresent( yTypeIx ) ) yLog = e->KeywordSet( yTypeIx ); else yLog = e->KeywordSet( yLogIx ); if ( e->KeywordPresent( zTypeIx ) ) zLog = e->KeywordSet( zTypeIx ); else zLog = e->KeywordSet( zLogIx ); if ( xLog && e->KeywordSet( xTickunitsIx ) ) { Message( "PLOT: LOG setting ignored for Date/Time TICKUNITS." ); xLog = FALSE; } if ( yLog && e->KeywordSet( yTickunitsIx ) ) { Message( "PLOT: LOG setting ignored for Date/Time TICKUNITS." ); yLog = FALSE; } if ( zLog && e->KeywordSet( zTickunitsIx ) ) { Message( "PLOT: LOG setting ignored for Date/Time TICKUNITS." ); zLog = FALSE; } if ( nParam ( )==1 ) { if ( (e->GetNumericArrayParDefined ( 0 ))->Rank ( )!=2 ) e->Throw ( "Array must have 2 dimensions: " +e->GetParString ( 0 ) ); BaseGDL* p0=e->GetNumericArrayParDefined ( 0 )->Transpose ( NULL ); zVal=static_cast<DDoubleGDL*> ( p0->Convert2 ( GDL_DOUBLE, BaseGDL::COPY ) ); p0_guard.reset ( p0 ); // delete upon exit if ( zVal->Rank ( )!=2 ) e->Throw ( "Array must have 2 dimensions: " +e->GetParString ( 0 ) ); xEl=zVal->Dim ( 1 ); yEl=zVal->Dim ( 0 ); xVal=new DDoubleGDL ( dimension ( xEl ), BaseGDL::INDGEN ); xval_guard.reset ( xVal ); // delete upon exit if (xLog) xVal->Inc(); yVal=new DDoubleGDL ( dimension ( yEl ), BaseGDL::INDGEN ); yval_guard.reset ( yVal ); // delete upon exit if (yLog) yVal->Inc(); } else if ( nParam ( )==2||nParam ( )>3 ) { e->Throw ( "Incorrect number of arguments." ); } else { BaseGDL* p0=e->GetNumericArrayParDefined ( 0 )->Transpose ( NULL ); zVal=static_cast<DDoubleGDL*> ( p0->Convert2 ( GDL_DOUBLE, BaseGDL::COPY ) ); p0_guard.reset ( p0 ); // delete upon exit if ( zVal->Rank ( )!=2 ) e->Throw ( "Array must have 2 dimensions: " +e->GetParString ( 0 ) ); xVal=e->GetParAs< DDoubleGDL>( 1 ); yVal=e->GetParAs< DDoubleGDL>( 2 ); if ( xVal->Rank ( )!=1 ) e->Throw ( "Unable to handle non-vectorial array "+e->GetParString ( 1 )+" (FIXME!)" ); if ( yVal->Rank ( )!=1 ) e->Throw ( "Unable to handle non-vectorial array "+e->GetParString ( 1 )+" (FIXME!)" ); if ( xVal->Rank ( )==1 ) { xEl=xVal->Dim ( 0 ); if ( xEl!=zVal->Dim ( 1 ) ) e->Throw ( "X, Y, or Z array dimensions are incompatible." ); } if ( yVal->Rank ( )==1 ) { yEl=yVal->Dim ( 0 ); if ( yEl!=zVal->Dim ( 0 ) ) e->Throw ( "X, Y, or Z array dimensions are incompatible." ); } } GetMinMaxVal ( xVal, &xStart, &xEnd ); GetMinMaxVal ( yVal, &yStart, &yEnd ); //XRANGE and YRANGE overrides all that, but Start/End should be recomputed accordingly DDouble xAxisStart, xAxisEnd, yAxisStart, yAxisEnd; bool setx=gdlGetDesiredAxisRange(e, "X", xAxisStart, xAxisEnd); bool sety=gdlGetDesiredAxisRange(e, "Y", yAxisStart, yAxisEnd); if(setx && sety) { xStart=xAxisStart; xEnd=xAxisEnd; yStart=yAxisStart; yEnd=yAxisEnd; } else if (sety) { yStart=yAxisStart; yEnd=yAxisEnd; } else if (setx) { xStart=xAxisStart; xEnd=xAxisEnd; //must compute min-max for other axis! { gdlDoRangeExtrema(xVal,yVal,yStart,yEnd,xStart,xEnd); } } #undef UNDEF_RANGE_VALUE // z range datamax=0.0; datamin=0.0; GetMinMaxVal ( zVal, &datamin, &datamax ); zStart=datamin; zEnd=datamax; setZrange = gdlGetDesiredAxisRange(e, "Z", zStart, zEnd); //SHADES: Doing the job will be for nothing since plplot does not give the functionality. static int shadesIx=e->KeywordIx ( "SHADES" ); doShade=false; if ( e->GetKW ( shadesIx )!=NULL ) { shades=e->GetKWAs<DLongGDL>( shadesIx ); doShade=true; } else { // Get COLOR from PLOT system variable static DStructGDL* pStruct=SysVar::P(); shades=new DLongGDL( 1, BaseGDL::NOZERO ); shades_guard.Init ( shades ); // delete upon exit shades=static_cast<DLongGDL*>(pStruct->GetTag(pStruct->Desc()->TagIndex("COLOR"), 0)); doShade=false; } if (doShade) Warning ( "SHADE_SURF: SHADES array ignored, shading with current color table." ); return false; }
// execute one line of code (commands and statements) DInterpreter::CommandCode DInterpreter::ExecuteLine( istream* in, SizeT lineOffset) { string line = (in != NULL) ? ::GetLine(in) : GetLine(); // cout << "ExecuteLine: " << line << endl; string firstChar = line.substr(0,1); // command if( firstChar == ".") { return ExecuteCommand( line.substr(1)); } // online help (if possible, start a browser) if( firstChar == "?") { // later, we will have to check whether we have X11/Display or not // on some computing nodes on supercomputers, this is de-activated. if (line.substr(1).length() > 0) { line=line.substr(1); StrTrim(line); line="online_help, '"+line+"'"; //' } else { line="online_help"; } } // shell command if( firstChar == "#") { if (line.substr(1).length() > 0) { line=line.substr(1); StrTrim(line); line=StrUpCase(line); //cout << "yes ! >>"<<StrUpCase(line)<<"<<" << endl; SizeT nProFun; int nbFound=0; // looking in internal procedures nProFun=libProList.size(); for( SizeT i = 0; i<nProFun; ++i) { if (line.compare(libProList[ i]->Name()) == 0) { cout << "Internal PROCEDURE : " << libProList[ i]->ToString() << endl; nbFound++; break; } } // looking in internal functions nProFun = libFunList.size(); for( SizeT i = 0; i<nProFun; ++i) { if (line.compare(libFunList[ i]->Name()) == 0) { cout << "Internal FUNCTION : " << libFunList[ i]->ToString() << endl; nbFound++; break; } } // looking in compiled functions nProFun = funList.size(); for( SizeT i = 0; i<nProFun; ++i) { if (line.compare(funList[ i]->Name()) == 0) { cout << "Compiled FUNCTION : " << funList[ i]->ToString() << endl; nbFound++; break; } } // looking in compiled procedures nProFun = proList.size(); for( SizeT i = 0; i<nProFun; ++i) { if (line.compare(proList[ i]->Name()) == 0) { cout << "Compiled PROCEDURE : " << proList[ i]->ToString() << endl; nbFound++; break; } } if (nbFound == 0) { cout << "No Procedure/Function, internal or compiled, with name : "<< line << endl; } } else { cout << "Please provide a pro/fun name !" << endl; } return CC_OK; } // shell command if( firstChar == "$") { ExecuteShellCommand( line.substr(1)); return CC_OK; } // include (only when at $MAIN$) // during compilation this is handled by the interpreter if( firstChar == "@" && callStack.size() <= 1) { string fileRaw = line.substr(1); StrTrim( fileRaw); string file = fileRaw; AppendExtension( file); bool found = CompleteFileName( file); if( !found) { file = fileRaw; CompleteFileName( file); } ExecuteFile( file); return CC_OK; } // statement -> execute it executeLine.clear(); // clear EOF (for executeLine) executeLine.str( line + "\n"); // append new line RefDNode theAST; try { Guard<GDLLexer> lexer; // LineContinuation LC // conactenate the strings and insert \n // the resulting string can be fed to the lexer // print if expr parse ok int lCNum = 0; for(;;) { lexer.Reset( new GDLLexer(executeLine, "", callStack.back()->CompileOpt())); try { // works, but ugly -> depends from parser detecting an error // (which it always will due to missing END_U token in case of LC) //lexer->Parser().SetCompileOpt(callStack.back()->CompileOpt()); lexer.Get()->Parser().interactive(); break; // no error -> everything ok } catch( GDLException& e) { int lCNew = lexer.Get()->LineContinuation(); if( lCNew == lCNum) // throw; // no LC -> real error { #ifdef AUTO_PRINT_EXPR #ifndef GDL_DEBUG try { // executeLine.clear(); // clear EOF (for executeLine) // lexer.reset( new GDLLexer(executeLine, "", callStack.back()->CompileOpt())); // lexer->Parser().expr(); executeLine.clear(); // clear EOF (for executeLine) executeLine.str( "print," + executeLine.str()); // append new line lexer.reset( new GDLLexer(executeLine, "", callStack.back()->CompileOpt())); lexer->Parser().interactive(); break; // no error -> everything ok } catch( GDLException& e2) #endif #endif { throw e; } } lCNum = lCNew; // save number to see if next line also has LC } // line continuation -> get next line if( in != NULL && !in->good()) throw GDLException( "End of file encountered during line continuation."); string cLine = (in != NULL) ? ::GetLine(in) : GetLine(); executeLine.clear(); // clear EOF (for executeLine) executeLine.str( executeLine.str() + cLine + "\n"); // append new line } // lexer->Parser().interactive(); theAST = lexer.Get()->Parser().getAST(); } catch( GDLException& e) { ReportCompileError( e); return CC_OK; } catch( ANTLRException& e) { cerr << "Lexer/Parser exception: " << e.getMessage() << endl; return CC_OK; } if( theAST == NULL) return CC_OK; // consider line offset if( lineOffset > 0) AddLineOffset( lineOffset, theAST); #ifdef GDL_DEBUG antlr::print_tree pt; cout << "Parser output:" << endl; pt.pr_tree(static_cast<antlr::RefAST>(theAST)); cout << "ExecuteLine: Parser end." << endl; #endif ProgNodeP progAST = NULL; RefDNode trAST; assert( dynamic_cast<EnvUDT*>(callStack.back()) != NULL); EnvUDT* env = static_cast<EnvUDT*>(callStack.back()); int nForLoopsIn = env->NForLoops(); try { GDLTreeParser treeParser( callStack.back()); treeParser.interactive(theAST); trAST=treeParser.getAST(); if( trAST == NULL) { // normal condition for cmd line procedure calls return CC_OK; } #ifdef GDL_DEBUG cout << "Tree parser output (RefDNode):" << endl; pt.pr_tree(static_cast<antlr::RefAST>(trAST)); cout << "ExecuteLine: Tree parser end." << endl; #endif // ************************************** // this is the call of the ProgNode factory // ************************************** progAST = ProgNode::NewProgNode( trAST); assert( dynamic_cast<EnvUDT*>(callStack.back()) != NULL); EnvUDT* env = static_cast<EnvUDT*>(callStack.back()); int nForLoops = ProgNode::NumberForLoops( progAST, nForLoopsIn); env->ResizeForLoops( nForLoops); } catch( GDLException& e) { env->ResizeForLoops( nForLoopsIn); ReportCompileError( e); return CC_OK; } catch( ANTLRException& e) { env->ResizeForLoops( nForLoopsIn); cerr << "Compiler exception: " << e.getMessage() << endl; return CC_OK; } Guard< ProgNode> progAST_guard( progAST); try { #ifdef GDL_DEBUG cout << "Converted tree (ProgNode):" << endl; pt.pr_tree( progAST); cout << "end." << endl; #endif RetCode retCode = interactive( progAST); env->ResizeForLoops( nForLoopsIn); // write to journal file string actualLine = GetClearActualLine(); if( actualLine != "") lib::write_journal( actualLine); if( retCode == RC_RETURN) return CC_RETURN; return CC_OK; } catch( GDLException& e) { env->ResizeForLoops( nForLoopsIn); cerr << "Unhandled GDL exception: " << e.toString() << endl; return CC_OK; } catch( ANTLRException& e) { env->ResizeForLoops( nForLoopsIn); cerr << "Interpreter exception: " << e.getMessage() << endl; return CC_OK; } return CC_OK; }
bool handle_args (EnvT* e) { xLog=e->KeywordSet ( "XLOG" ); yLog=e->KeywordSet ( "YLOG" ); zLog=e->KeywordSet ( "ZLOG" ); if ( nParam ( )==1 ) { if ( (e->GetNumericArrayParDefined ( 0 ))->Rank ( )!=2 ) e->Throw ( "Array must have 2 dimensions: " +e->GetParString ( 0 ) ); BaseGDL* p0=e->GetNumericArrayParDefined ( 0 )->Transpose ( NULL ); zVal=static_cast<DDoubleGDL*> ( p0->Convert2 ( GDL_DOUBLE, BaseGDL::COPY ) ); p0_guard.reset ( p0 ); // delete upon exit if ( zVal->Rank ( )!=2 ) e->Throw ( "Array must have 2 dimensions: " +e->GetParString ( 0 ) ); xEl=zVal->Dim ( 1 ); yEl=zVal->Dim ( 0 ); xVal=new DDoubleGDL ( dimension ( xEl ), BaseGDL::INDGEN ); xval_guard.reset ( xVal ); // delete upon exit if (xLog) xVal->Inc(); yVal=new DDoubleGDL ( dimension ( yEl ), BaseGDL::INDGEN ); yval_guard.reset ( yVal ); // delete upon exit if (yLog) yVal->Inc(); } else if ( nParam ( )==2||nParam ( )>3 ) { e->Throw ( "Incorrect number of arguments." ); } else { BaseGDL* p0=e->GetNumericArrayParDefined ( 0 )->Transpose ( NULL ); zVal=static_cast<DDoubleGDL*> ( p0->Convert2 ( GDL_DOUBLE, BaseGDL::COPY ) ); p0_guard.reset ( p0 ); // delete upon exit if ( zVal->Rank ( )!=2 ) e->Throw ( "Array must have 2 dimensions: " +e->GetParString ( 0 ) ); xVal=e->GetParAs< DDoubleGDL>( 1 ); yVal=e->GetParAs< DDoubleGDL>( 2 ); if ( xVal->Rank ( )!=1 ) e->Throw ( "Unable to handle non-vectorial array "+e->GetParString ( 1 )+" (FIXME!)" ); if ( yVal->Rank ( )!=1 ) e->Throw ( "Unable to handle non-vectorial array "+e->GetParString ( 1 )+" (FIXME!)" ); if ( xVal->Rank ( )==1 ) { xEl=xVal->Dim ( 0 ); if ( xEl!=zVal->Dim ( 1 ) ) e->Throw ( "X, Y, or Z array dimensions are incompatible." ); } if ( yVal->Rank ( )==1 ) { yEl=yVal->Dim ( 0 ); if ( yEl!=zVal->Dim ( 0 ) ) e->Throw ( "X, Y, or Z array dimensions are incompatible." ); } } GetMinMaxVal ( xVal, &xStart, &xEnd ); GetMinMaxVal ( yVal, &yStart, &yEnd ); //XRANGE and YRANGE overrides all that, but Start/End should be recomputed accordingly DDouble xAxisStart, xAxisEnd, yAxisStart, yAxisEnd; bool setx=gdlGetDesiredAxisRange(e, "X", xAxisStart, xAxisEnd); bool sety=gdlGetDesiredAxisRange(e, "Y", yAxisStart, yAxisEnd); if(setx && sety) { xStart=xAxisStart; xEnd=xAxisEnd; yStart=yAxisStart; yEnd=yAxisEnd; } else if (sety) { yStart=yAxisStart; yEnd=yAxisEnd; } else if (setx) { xStart=xAxisStart; xEnd=xAxisEnd; //must compute min-max for other axis! { gdlDoRangeExtrema(xVal,yVal,yStart,yEnd,xStart,xEnd); } } #undef UNDEF_RANGE_VALUE // z range datamax=0.0; datamin=0.0; GetMinMaxVal ( zVal, &datamin, &datamax ); zStart=datamin; zEnd=datamax; setZrange = gdlGetDesiredAxisRange(e, "Z", zStart, zEnd); return false; }