1 33 34 package bsh; 35 36 import java.util.Vector ; 37 import java.io.*; 38 import java.lang.reflect.Method ; 39 import java.lang.reflect.InvocationTargetException ; 40 41 93 public class Interpreter 94 implements Runnable , ConsoleInterface,Serializable 95 { 96 97 98 public static final String VERSION = "2.0b4-jedit"; 99 107 public static boolean DEBUG, TRACE, LOCALSCOPING; 108 109 transient static PrintStream debug; 111 static String systemLineSeparator = "\n"; 113 static { 114 staticInit(); 115 } 116 117 118 static This sharedObject; 119 120 124 private boolean strictJava = false; 125 126 127 128 129 130 transient Parser parser; 131 NameSpace globalNameSpace; 132 transient Reader in; 133 transient PrintStream out; 134 transient PrintStream err; 135 ConsoleInterface console; 136 137 138 Interpreter parent; 139 140 141 String sourceFileInfo; 142 143 144 private boolean exitOnEOF = true; 145 146 protected boolean 147 evalOnly, interactive; 150 151 private boolean showResults; 152 153 154 155 169 public Interpreter( 170 Reader in, PrintStream out, PrintStream err, 171 boolean interactive, NameSpace namespace, 172 Interpreter parent, String sourceFileInfo ) 173 { 174 parser = new Parser( in ); 176 long t1=System.currentTimeMillis(); 177 this.in = in; 178 this.out = out; 179 this.err = err; 180 this.interactive = interactive; 181 debug = err; 182 this.parent = parent; 183 if ( parent != null ) 184 setStrictJava( parent.getStrictJava() ); 185 this.sourceFileInfo = sourceFileInfo; 186 187 BshClassManager bcm = BshClassManager.createClassManager( this ); 188 if ( namespace == null ) 189 this.globalNameSpace = new NameSpace( bcm, "global"); 190 else 191 this.globalNameSpace = namespace; 192 193 197 200 if ( ! ( getu("bsh") instanceof bsh.This ) ) 201 initRootSystemObject(); 202 203 if ( interactive ) 204 loadRCFiles(); 205 206 long t2=System.currentTimeMillis(); 207 if ( Interpreter.DEBUG ) 208 Interpreter.debug("Time to initialize interpreter: "+(t2-t1)); 209 } 210 211 public Interpreter( 212 Reader in, PrintStream out, PrintStream err, 213 boolean interactive, NameSpace namespace) 214 { 215 this( in, out, err, interactive, namespace, null, null ); 216 } 217 218 public Interpreter( 219 Reader in, PrintStream out, PrintStream err, boolean interactive) 220 { 221 this(in, out, err, interactive, null); 222 } 223 224 228 public Interpreter(ConsoleInterface console, NameSpace globalNameSpace) { 229 230 this( console.getIn(), console.getOut(), console.getErr(), 231 true, globalNameSpace ); 232 233 setConsole( console ); 234 } 235 236 240 public Interpreter(ConsoleInterface console) { 241 this(console, null); 242 } 243 244 247 public Interpreter() 248 { 249 this( new StringReader(""), 250 System.out, System.err, false, null ); 251 evalOnly = true; 252 setu( "bsh.evalOnly", new Primitive(true) ); 253 } 254 255 257 261 public void setConsole( ConsoleInterface console ) { 262 this.console = console; 263 setu( "bsh.console", console ); 264 setOut( console.getOut() ); 266 setErr( console.getErr() ); 267 } 269 270 private void initRootSystemObject() 271 { 272 BshClassManager bcm = getClassManager(); 273 setu("bsh", new NameSpace( bcm, "Bsh Object" ).getThis( this ) ); 275 276 if ( sharedObject == null ) 278 sharedObject = new NameSpace( 279 bcm, "Bsh Shared System Object" ).getThis( this ); 280 setu( "bsh.system", sharedObject ); 282 setu( "bsh.shared", sharedObject ); 284 This helpText = new NameSpace( 286 bcm, "Bsh Command Help Text" ).getThis( this ); 287 setu( "bsh.help", helpText ); 288 289 try { 291 setu( "bsh.cwd", System.getProperty("user.dir") ); 292 } catch ( SecurityException e ) { 293 setu( "bsh.cwd", "." ); 295 } 296 297 setu( "bsh.interactive", new Primitive(interactive) ); 299 setu( "bsh.evalOnly", new Primitive(evalOnly) ); 301 } 302 303 318 public void setNameSpace( NameSpace globalNameSpace ) { 319 this.globalNameSpace = globalNameSpace; 320 } 321 322 337 public NameSpace getNameSpace() { 338 return globalNameSpace; 339 } 340 341 344 public static void main( String [] args ) 345 { 346 if ( args.length > 0 ) { 347 String filename = args[0]; 348 349 String [] bshArgs; 350 if ( args.length > 1 ) { 351 bshArgs = new String [ args.length -1 ]; 352 System.arraycopy( args, 1, bshArgs, 0, args.length-1 ); 353 } else 354 bshArgs = new String [0]; 355 356 Interpreter interpreter = new Interpreter(); 357 interpreter.setu( "bsh.args", bshArgs ); 359 try { 360 Object result = 361 interpreter.source( filename, interpreter.globalNameSpace ); 362 if ( result instanceof Class ) 363 try { 364 invokeMain( (Class )result, bshArgs ); 365 } catch ( Exception e ) 366 { 367 Object o = e; 368 if ( e instanceof InvocationTargetException ) 369 o = ((InvocationTargetException )e) 370 .getTargetException(); 371 System.err.println( 372 "Class: "+result+" main method threw exception:"+o); 373 } 374 } catch ( FileNotFoundException e ) { 375 System.out.println("File not found: "+e); 376 } catch ( TargetError e ) { 377 System.out.println("Script threw exception: "+e); 378 if ( e.inNativeCode() ) 379 e.printStackTrace( DEBUG, System.err ); 380 } catch ( EvalError e ) { 381 System.out.println("Evaluation Error: "+e); 382 } catch ( IOException e ) { 383 System.out.println("I/O Error: "+e); 384 } 385 } else 386 { 387 InputStream src; 390 if ( System.getProperty("os.name").startsWith("Windows") 391 && System.getProperty("java.version").startsWith("1.1.")) 392 { 393 src = new FilterInputStream(System.in) { 394 public int available() throws IOException { 395 return 0; 396 } 397 }; 398 } 399 else 400 src = System.in; 401 402 Reader in = new CommandLineReader( new InputStreamReader(src)); 403 Interpreter interpreter = 404 new Interpreter( in, System.out, System.err, true ); 405 interpreter.run(); 406 } 407 } 408 409 public static void invokeMain( Class clas, String [] args ) 410 throws Exception 411 { 412 Method main = Reflect.resolveJavaMethod( 413 null, clas, "main", 414 new Class [] { String [].class }, true ); 415 if ( main != null ) 416 main.invoke( null, new Object [] { args } ); 417 } 418 419 422 public void run() 423 { 424 if(evalOnly) 425 throw new RuntimeException ("bsh Interpreter: No stream"); 426 427 432 if ( interactive ) 433 try { 434 eval("printBanner();"); 435 } catch ( EvalError e ) { 436 println( 437 "BeanShell "+VERSION+" - by Pat Niemeyer (pat@pat.net)"); 438 } 439 440 CallStack callstack = new CallStack( globalNameSpace ); 442 443 boolean eof = false; 444 while( !eof ) 445 { 446 try 447 { 448 System.out.flush(); 450 System.err.flush(); 451 Thread.yield(); 453 if ( interactive ) 454 print( getBshPrompt() ); 455 456 eof = Line(); 457 458 if( get_jjtree().nodeArity() > 0 ) { 460 SimpleNode node = (SimpleNode)(get_jjtree().rootNode()); 461 462 if(DEBUG) 463 node.dump(">"); 464 465 Object ret = node.eval( callstack, this ); 466 467 if ( callstack.depth() > 1 ) 469 throw new InterpreterError( 470 "Callstack growing: "+callstack); 471 472 if(ret instanceof ReturnControl) 473 ret = ((ReturnControl)ret).value; 474 475 if( ret != Primitive.VOID ) 476 { 477 setu("$_", ret); 478 if ( showResults ) 479 println("<" + ret + ">"); 480 } 481 } 482 } 483 catch(ParseException e) 484 { 485 error("Parser Error: " + e.getMessage(DEBUG)); 486 if ( DEBUG ) 487 e.printStackTrace(); 488 if(!interactive) 489 eof = true; 490 491 parser.reInitInput(in); 492 } 493 catch(InterpreterError e) 494 { 495 error("Internal Error: " + e.getMessage()); 496 e.printStackTrace(); 497 if(!interactive) 498 eof = true; 499 } 500 catch(TargetError e) 501 { 502 error("// Uncaught Exception: " + e ); 503 if ( e.inNativeCode() ) 504 e.printStackTrace( DEBUG, err ); 505 if(!interactive) 506 eof = true; 507 setu("$_e", e.getTarget()); 508 } 509 catch (EvalError e) 510 { 511 if ( interactive ) 512 error( "EvalError: "+e.toString() ); 513 else 514 error( "EvalError: "+e.getMessage() ); 515 516 if(DEBUG) 517 e.printStackTrace(); 518 519 if(!interactive) 520 eof = true; 521 } 522 catch(Exception e) 523 { 524 error("Unknown error: " + e); 525 if ( DEBUG ) 526 e.printStackTrace(); 527 if(!interactive) 528 eof = true; 529 } 530 catch(TokenMgrError e) 531 { 532 error("Error parsing input: " + e); 533 534 539 parser.reInitTokenInput( in ); 540 541 if(!interactive) 542 eof = true; 543 } 544 finally 545 { 546 get_jjtree().reset(); 547 if ( callstack.depth() > 1 ) { 549 callstack.clear(); 550 callstack.push( globalNameSpace ); 551 } 552 } 553 } 554 555 if ( interactive && exitOnEOF ) 556 System.exit(0); 557 } 558 559 561 564 public Object source( String filename, NameSpace nameSpace ) 565 throws FileNotFoundException, IOException, EvalError 566 { 567 File file = pathToFile( filename ); 568 if ( Interpreter.DEBUG ) debug("Sourcing file: "+file); 569 Reader sourceIn = new BufferedReader( new FileReader(file) ); 570 try { 571 return eval( sourceIn, nameSpace, filename ); 572 } finally { 573 sourceIn.close(); 574 } 575 } 576 577 581 public Object source( String filename ) 582 throws FileNotFoundException, IOException, EvalError 583 { 584 return source( filename, globalNameSpace ); 585 } 586 587 600 603 609 610 public Object eval( 611 Reader in, NameSpace nameSpace, String sourceFileInfo 612 ) 613 throws EvalError 614 { 615 Object retVal = null; 616 if ( Interpreter.DEBUG ) debug("eval: nameSpace = "+nameSpace); 617 618 623 Interpreter localInterpreter = 624 new Interpreter( 625 in, out, err, false, nameSpace, this, sourceFileInfo ); 626 627 CallStack callstack = new CallStack( nameSpace ); 628 629 boolean eof = false; 630 while(!eof) 631 { 632 SimpleNode node = null; 633 try 634 { 635 eof = localInterpreter.Line(); 636 if (localInterpreter.get_jjtree().nodeArity() > 0) 637 { 638 node = (SimpleNode)localInterpreter.get_jjtree().rootNode(); 639 node.setSourceFile( sourceFileInfo ); 641 642 if ( TRACE ) 643 println( "// " +node.getText() ); 644 645 retVal = node.eval( callstack, localInterpreter ); 646 647 if ( callstack.depth() > 1 ) 649 throw new InterpreterError( 650 "Callstack growing: "+callstack); 651 652 if ( retVal instanceof ReturnControl ) { 653 retVal = ((ReturnControl)retVal).value; 654 break; } 656 657 if ( localInterpreter.showResults 658 && retVal != Primitive.VOID ) 659 println("<" + retVal + ">"); 660 } 661 } catch(ParseException e) { 662 667 if ( DEBUG ) 668 error( e.getMessage(DEBUG) ); 670 671 e.setErrorSourceFile( sourceFileInfo ); 673 throw e; 674 675 } catch ( InterpreterError e ) { 676 e.printStackTrace(); 677 throw new EvalError( 678 "Sourced file: "+sourceFileInfo+" internal Error: " 679 + e.getMessage(), node, callstack); 680 } catch ( TargetError e ) { 681 if ( e.getNode()==null ) 683 e.setNode( node ); 684 e.reThrow("Sourced file: "+sourceFileInfo); 685 } catch ( EvalError e) { 686 if ( DEBUG) 687 e.printStackTrace(); 688 if ( e.getNode()==null ) 690 e.setNode( node ); 691 e.reThrow( "Sourced file: "+sourceFileInfo ); 692 } catch ( Exception e) { 693 if ( DEBUG) 694 e.printStackTrace(); 695 throw new EvalError( 696 "Sourced file: "+sourceFileInfo+" unknown error: " 697 + e.getMessage(), node, callstack); 698 } catch(TokenMgrError e) { 699 throw new EvalError( 700 "Sourced file: "+sourceFileInfo+" Token Parsing Error: " 701 + e.getMessage(), node, callstack ); 702 } finally { 703 localInterpreter.get_jjtree().reset(); 704 705 if ( callstack.depth() > 1 ) { 707 callstack.clear(); 708 callstack.push( nameSpace ); 709 } 710 } 711 } 712 return Primitive.unwrap( retVal ); 713 } 714 715 718 public Object eval( Reader in ) throws EvalError 719 { 720 return eval( in, globalNameSpace, "eval stream" ); 721 } 722 723 726 public Object eval( String statements ) throws EvalError { 727 if ( Interpreter.DEBUG ) debug("eval(String): "+statements); 728 return eval(statements, globalNameSpace); 729 } 730 731 734 public Object eval( String statements, NameSpace nameSpace ) 735 throws EvalError 736 { 737 738 String s = ( statements.endsWith(";") ? statements : statements+";" ); 739 return eval( 740 new StringReader(s), nameSpace, 741 "inline evaluation of: ``"+ showEvalString(s)+"''" ); 742 } 743 744 private String showEvalString( String s ) { 745 s = s.replace('\n', ' '); 746 s = s.replace('\r', ' '); 747 if ( s.length() > 80 ) 748 s = s.substring( 0, 80 ) + " . . . "; 749 return s; 750 } 751 752 754 759 public final void error( Object o ) { 760 if ( console != null ) 761 console.error( "// Error: " + o +"\n" ); 762 else { 763 err.println("// Error: " + o ); 764 err.flush(); 765 } 766 } 767 768 773 777 public Reader getIn() { return in; } 778 779 783 public PrintStream getOut() { return out; } 784 785 789 public PrintStream getErr() { return err; } 790 791 public final void println( Object o ) 792 { 793 print( String.valueOf(o) + systemLineSeparator ); 794 } 795 796 public final void print( Object o ) 797 { 798 if (console != null) { 799 console.print(o); 800 } else { 801 out.print(o); 802 out.flush(); 803 } 804 } 805 806 808 812 public final static void debug(String s) 813 { 814 if ( DEBUG ) 815 debug.println("// Debug: " + s); 816 } 817 818 822 823 827 public Object get( String name ) throws EvalError { 828 try { 829 Object ret = globalNameSpace.get( name, this ); 830 return Primitive.unwrap( ret ); 831 } catch ( UtilEvalError e ) { 832 throw e.toEvalError( SimpleNode.JAVACODE, new CallStack() ); 833 } 834 } 835 836 839 Object getu( String name ) { 840 try { 841 return get( name ); 842 } catch ( EvalError e ) { 843 throw new InterpreterError("set: "+e); 844 } 845 } 846 847 851 public void set( String name, Object value ) 852 throws EvalError 853 { 854 if ( value == null ) 856 value = Primitive.NULL; 857 858 CallStack callstack = new CallStack(); 859 try { 860 if ( Name.isCompound( name ) ) 861 { 862 LHS lhs = globalNameSpace.getNameResolver( name ).toLHS( 863 callstack, this ); 864 lhs.assign( value, false ); 865 } else globalNameSpace.setVariable( name, value, false ); 867 } catch ( UtilEvalError e ) { 868 throw e.toEvalError( SimpleNode.JAVACODE, callstack ); 869 } 870 } 871 872 875 void setu(String name, Object value) { 876 try { 877 set(name, value); 878 } catch ( EvalError e ) { 879 throw new InterpreterError("set: "+e); 880 } 881 } 882 883 public void set(String name, long value) throws EvalError { 884 set(name, new Primitive(value)); 885 } 886 public void set(String name, int value) throws EvalError { 887 set(name, new Primitive(value)); 888 } 889 public void set(String name, double value) throws EvalError { 890 set(name, new Primitive(value)); 891 } 892 public void set(String name, float value) throws EvalError { 893 set(name, new Primitive(value)); 894 } 895 public void set(String name, boolean value) throws EvalError { 896 set(name, new Primitive(value)); 897 } 898 899 903 public void unset( String name ) 904 throws EvalError 905 { 906 910 CallStack callstack = new CallStack(); 911 try { 912 LHS lhs = globalNameSpace.getNameResolver( name ).toLHS( 913 callstack, this ); 914 915 if ( lhs.type != LHS.VARIABLE ) 916 throw new EvalError("Can't unset, not a variable: "+name, 917 SimpleNode.JAVACODE, new CallStack() ); 918 919 lhs.nameSpace.unsetVariable( name ); 921 } catch ( UtilEvalError e ) { 922 throw new EvalError( e.getMessage(), 923 SimpleNode.JAVACODE, new CallStack() ); 924 } 925 } 926 927 929 979 public Object getInterface( Class interf ) throws EvalError 980 { 981 try { 982 return globalNameSpace.getThis( this ).getInterface( interf ); 983 } catch ( UtilEvalError e ) { 984 throw e.toEvalError( SimpleNode.JAVACODE, new CallStack() ); 985 } 986 } 987 988 989 990 private JJTParserState get_jjtree() { 991 return parser.jjtree; 992 } 993 994 private JavaCharStream get_jj_input_stream() { 995 return parser.jj_input_stream; 996 } 997 998 private boolean Line() throws ParseException { 999 return parser.Line(); 1000 } 1001 1002 1003 1004 void loadRCFiles() { 1005 try { 1006 String rcfile = 1007 System.getProperty("user.home") + File.separator + ".bshrc"; 1009 source( rcfile, globalNameSpace ); 1010 } catch ( Exception e ) { 1011 if ( Interpreter.DEBUG ) debug("Could not find rc file: "+e); 1013 } 1014 } 1015 1016 1020 public File pathToFile( String fileName ) 1021 throws IOException 1022 { 1023 File file = new File( fileName ); 1024 1025 if ( !file.isAbsolute() ) { 1027 String cwd = (String )getu("bsh.cwd"); 1028 file = new File( cwd + File.separator + fileName ); 1029 } 1030 1031 return new File( file.getCanonicalPath() ); 1034 } 1035 1036 public static void redirectOutputToFile( String filename ) 1037 { 1038 try { 1039 PrintStream pout = new PrintStream( 1040 new FileOutputStream( filename ) ); 1041 System.setOut( pout ); 1042 System.setErr( pout ); 1043 } catch ( IOException e ) { 1044 System.err.println("Can't redirect output to file: "+filename ); 1045 } 1046 } 1047 1048 1070 public void setClassLoader( ClassLoader externalCL ) { 1071 getClassManager().setClassLoader( externalCL ); 1072 } 1073 1074 1079 public BshClassManager getClassManager() 1080 { 1081 return getNameSpace().getClassManager(); 1082 } 1083 1084 1096 public void setStrictJava( boolean b ) { 1097 this.strictJava = b; 1098 } 1099 1100 1103 public boolean getStrictJava() { 1104 return this.strictJava; 1105 } 1106 1107 static void staticInit() 1108 { 1109 1114 try { 1115 systemLineSeparator = System.getProperty("line.separator"); 1116 debug = System.err; 1117 DEBUG = Boolean.getBoolean("debug"); 1118 TRACE = Boolean.getBoolean("trace"); 1119 LOCALSCOPING = Boolean.getBoolean("localscoping"); 1120 String outfilename = System.getProperty("outfile"); 1121 if ( outfilename != null ) 1122 redirectOutputToFile( outfilename ); 1123 } catch ( SecurityException e ) { 1124 System.err.println("Could not init static:"+e); 1125 } catch ( Exception e ) { 1126 System.err.println("Could not init static(2):"+e); 1127 } catch ( Throwable e ) { 1128 System.err.println("Could not init static(3):"+e); 1129 } 1130 } 1131 1132 1140 public String getSourceFileInfo() { 1141 if ( sourceFileInfo != null ) 1142 return sourceFileInfo; 1143 else 1144 return "<unknown source>"; 1145 } 1146 1147 1156 public Interpreter getParent() { 1157 return parent; 1158 } 1159 1160 public void setOut( PrintStream out ) { 1161 this.out = out; 1162 } 1163 public void setErr( PrintStream err ) { 1164 this.err = err; 1165 } 1166 1167 1171 private void readObject(ObjectInputStream stream) 1172 throws java.io.IOException , ClassNotFoundException 1173 { 1174 stream.defaultReadObject(); 1175 1176 if ( console != null ) { 1178 setOut( console.getOut() ); 1179 setErr( console.getErr() ); 1180 } else { 1181 setOut( System.out ); 1182 setErr( System.err ); 1183 } 1184 } 1185 1186 1192 private String getBshPrompt() 1193 { 1194 try { 1195 return (String )eval("getBshPrompt()"); 1196 } catch ( Exception e ) { 1197 return "bsh % "; 1198 } 1199 } 1200 1201 1212 public void setExitOnEOF( boolean value ) { 1213 exitOnEOF = value; } 1215 1216 1222 public void setShowResults( boolean showResults ) { 1223 this.showResults = showResults; 1224 } 1225 1230 public boolean getShowResults() { 1231 return showResults; 1232 } 1233} 1234 1235 | Popular Tags |