<section>
<name filename="syntax">Basic Syntax</name>

BeanShell is, foremost, a Java interpreter. So you probably already know 
most of what you need to start scripting with BeanShell.  This 
section describes specifically what portion of the Java language BeanShell 
interprets and how BeanShell extends it or "loosens" it to be more 
scripting-language-like.
<p/>

<h2> Standard Java Syntax </h2>

In a BeanShell script (and on the command line) you can type normal 
Java statements and expressions and display the results.  
Statements and expressions are the kinds of things you normally find 
inside of a Java method: variable assignments, method calls, math 
expressions, for-loops, etc.  

<p/>

Here are some examples:

<example>
/*
    Standard Java syntax
*/

// Use a hashtable
Hashtable hashtable = new Hashtable();
Date date = new Date();
hashtable.put( "today", date );

// Print the current clock value
print( System.currentTimeMillis() );

// Loop
for (int i=0; i&lt;5; i++)
    print(i);

// Pop up a frame with a button in it
JButton button = new JButton( "My Button" );
JFrame frame = new JFrame( "My Frame" );
frame.getContentPane().add( button, "Center" );
frame.pack();
frame.setVisible(true);
</example>

You can also define your own methods and use them just as you would inside a 
Java class.  We'll get to that in a moment.

<h2>Loosely Typed Java Syntax </h2>

In the examples above, all of our variables have declared types. e.g. 
"JButton button".  Beanshell will enforce these types, as you will see if 
you later try to assign something other than a JButton to the variable 
"button" (you will get an error message).
However BeanShell also supports "loose" or dynamically typed variables.
That is, you can refer to 
variables without declaring them first and without specifying any type.
In this case BeanShell will do type checking where appropriate at runtime.  
So, for example, we could have left off the types in the above example and 
written all of the above as:

<example>
/*
    Loosely Typed Java syntax
*/

// Use a hashtable
hashtable = new Hashtable();
date = new Date();
hashtable.put( "today", date );

// Print the current clock value
print( System.currentTimeMillis() );

// Loop
for (i=0; i&lt;5; i++)
    print(i);

// Pop up a frame with a button in it
button = new JButton( "My Button" );
frame = new JFrame( "My Frame" );
frame.getContentPane().add( button, "Center" );
frame.pack();
frame.setVisible(true);
</example>

This may not seem like it has saved us a great deal of work.  But you will
see the difference when you come to rely on scripting as part of your
development and testing process; especially for in interactive use.
<p/>

When a "loose" variable is used you are free to reassign it to another type of 
Java object later.  Untyped BeanShell variables can also freely hold Java 
primitive values like <b>int</b>
and <b>boolean</b>.  Don't worry, BeanShell always knows the real types and 
only lets you use the values where appropriate.  For primitive types this 
includes doing the
correct numeric promotion that the real Java language would do when you use
them in an expression.
<p/>

<h2>Exception Handling</h2>

Exception handling using try/catch blocks works just as it does in Java.  
For example:

<example>
try {
    int i = 1/0;
} catch ( ArithmeticException e ) {
    print( e );
}
</example>

But you can loosely type your catch blocks if you wish:

<example>
try {
    ...
} catch ( e ) { 
    print( "caught exception: "+e );
}
</example>

<h2>Basic Scoping of Variables</h2>

<note>
As of BeanShell version 1.3 the default scoping of loosely typed variables was
changed to be more consistent with Java.  BeanShell still supports an alternate
scoping used in earlier versions.  This mode can be enabled for legacy code by 
setting the system property "localscoping" to true.  
See appendix "Local Scoping".
</note>

Variable scoping in BeanShell behaves, wherever possible, just like that in 
Java.  Ordinary Java, however, does not offer "loose" variables 
(variables that can be used without being declared first).  
So we must define their behavior within BeanShell.
We'll see in the next section that untyped variables - variables that are not 
declared and not assigned a value elsewhere - default to the 
<em>local</em> scope.  
This means that, in general, if you assign a value to a variable without first
declaring it, you are creating a new local variable in the current scope.
<p/>

<h3>Blocks</h3>

Blocks are statements between curly braces {}.  In BeanShell, as in Java, 
blocks define a level of scope for typed variables: typed variables declared
within a block are local to the block.  Other assignments within the block 
occur, as always, wherever the variable was defined.
<p/>

Untyped variables in BeanShell, however, are not constrained by blocks.
Instead they act as if they were declared at the outer (enclosing)
scope's level.  
With this in mind, BeanShell code looks just like Java code.

In BeanShell if you declare a typed variable within a block it is local to the
block.  But if you use an untyped variable (which looks just like an ordinary
assignment in Java) it behaves as an assignment to the enclosing scope.
<p/>

This will make sense with a few examples:
<p/>

<example>
// Arbitrary code block
{
    y = 2;      // Untyped variable assigned
    int x = 1;  // Typed variable assigned
}
print( y ); // 2
print( x ); // Error! x is undefined.

// Same with any block statement: if, while, try/catch, etc.
if ( true ) {
    y = 2;      // Untyped variable assigned
    int x = 1;  // Typed variable assigned
}
print( y ); // 2
print( x ); // Error! x is undefined.
</example>

Variables declared in the for-init area of a for-loop follow the same
rules as part of the block:

<example>
for( int i=0; i&lt;10; i++ ) {  // typed for-init variable
    j=42;
}
print( i ); // Error! 'i' is undefined.
print( j ); // 42

for( z=0; z&lt;10; z++ ) { }   // untyped for-init variable
print( z ); // 10
</example>

<h2>Variable Modifiers</h2>

The standard Java variable modifiers may be used on typed variables:
private / protected / public, final, transient, volatile, static.
Only 'final' is currently implemented.  The others are currently ignored.
<p/>
Modifiers may not be applied to untyped variables.

<h2>Convenience Syntax</h2>

In BeanShell you may access JavaBean properties as if they were fields:

<example>
button = new java.awt.Button();
button.label = "my button";  // Equivalent to: b.setLabel("my button");
print( button.label );       // Equivalent to print( b.getLabel() );
</example>

JavaBean properties are simply pairs of "setter" and "getter" methods that
adhere to a naming convention.  In the above example BeanShell located
a "setter" method with the name "setLabel()" and used it to assign the string
value.  It then found the method named getLabel() to retrieve the value.
<p/>

Boolean properties may optionally use the syntax "is" for their "getter".
e.g.

<example>
Float f = new Float(42f);
print( f.infinite );  // Equivalent to print( f.isInfinite() ); // false
</example>

If there is any ambiguity with an actual Java field name of the object 
(e.g. label in the above example) then the actual field name takes precedence.

If you wish to avoid any ambiguity BeanShell provides an additional, 
uniform syntax for accessing both Java Bean properties and Hashtable or Map 
entries.  You may use the "{}" curly brace construct with a 
String identifier as a qualifier on any variable of the appropriate type:

<example>
b = new java.awt.Button();
b{"label"} = "my button";  // Equivalent to: b.setLabel("my button");

h = new Hashtable();
h{"foo"} = "bar";          // Equivalent to: h.put("foo", "bar");
</example>

Where the java.util.Collections API is available, Maps are also supported.
<p/>

<h3>Enhanced 'for' Loop</h3>

BeanShell supports the Java 1.5 style enhanced for-loop for iterating over
collections and array types.  (Note that you do not have to be running Java 1.5
to use this feature).

<example>
List foo = getSomeList();

for ( untypedElement : foo ) 
	print( untypedElement ); 

for ( Object typedElement: foo ) 
	print( typedElement );

int [] array = new int [] { 1, 2, 3 };

for( i : array ) 
	print(i);

for( char c : "a string" )
	print( c ); 
</example>

Supported iterable types include all the obvious things.  

<ul>
<li>JDK 1.1+ - (no collections): Enumeration, arrays, Vector, String, StringBuffer</li>
<li>JDK 1.2+ - (w/collections): Collections, Iterator</li>
</ul>

See also the BshIterator API which supports the ehanced for-loop and allows
iteration over these types using the dynamically loaded BeanShell Collection 
manager.
<p/>

<h3>Switch Statements</h3>

In BeanShell, the switch statement may be used not only with numeric types
but with objects.  For example, you may switch on Dates and Strings which
are compared for equality with their equals() methods:

<example>
dateobj = new Date();

switch( dateobj ) 
{
	case newYears:
		break;
	case christmas:
		break;
	default:
}
</example>


<h2>Auto Boxing and Unboxing</h2>

"Boxing" and "Unboxing" are the terms used to describe automatically wrapping 
a primitive type in a wrapper class and unwrapping it as necessary.  Boxing
is a feature of Java (SDK1.5) and has been supported in BeanShell for many
years.
<p/>

BeanShell supports boxing and unboxing of primitive types.  For example:

<example>
int i=5;
Integer iw = new Integer(5);
print( i * iw );  // 25

Vector v = new Vector();
v.put(1); 
int x = v.getFirstElement();
</example>

<h2>Importing Classes and Packages</h2>

In BeanShell as in Java, you can either refer to classes by their fully
qualified names, or you can <strong>import</strong> one or more classes 
from a Java package.
<p/>

<example>
// Standard Java
import javax.xml.parsers.*;
import mypackage.MyClass;
</example>
<p/>

In BeanShell import statements may appear anywhere, even inside a method, 
not just at the top of a file.  In the event of a conflict, later imports take
precedence over earlier ones.
<p/>

A somewhat experimental feature is the "super import".  With it you may 
automatically import the entire classpath, like so:

<example>
import *;
</example>

The first time you do this BeanShell will map out your entire classpath;
so this is primarily intended for interactive use.  Note that importing every
class in your classpath can be time consuming.  It can also result in a lot 
of ambiguities.  Currently BeanShell will report an error when resolving an 
an ambiguous import from mapping the entire classpath.  You may disambiguate 
it by importing the class you intend.
<p/>

<tip>
The BeanShell which() command will use the classpath mapping capability to
tell you where exactly in your classpath a specified class is located:
<pre>
bsh % which( java.lang.String );
Jar: file:/usr/java/j2sdk1.4.0/jre/lib/rt.jar
</pre>
</tip>

See "Class Path Management" for information about modifying the BeanShell
classpath at run-time with the addClassPath() or setClassPath() commands.
<p/>
Also see "BeanShell Commands" for information about importing new BeanShell
commands from the classpath.
<p/>

<h3>Default Imports</h3>

By default, common Java core and extension packages are imported for 
you.  They are, in the order in which they are imported:

<ul>
<li>javax.swing.event</li>
<li>javax.swing</li>
<li>java.awt.event</li>
<li>java.awt</li>
<li>java.net</li>
<li>java.util</li>
<li>java.io</li>
<li>java.lang</li>
</ul>
<p/>

Two BeanShell package classes are also imported by default:
<p/>

<ul>
<li>bsh.EvalError</li>
<li>bsh.Interpreter</li>
</ul>
<p/>

Finally, we should mention that BeanShell commands may be imported from the 
classpath.  The default commands are imported in the following way:

<example>
importCommands("/bsh/commands");
</example>

We will discuss how to import your own commands in a later section.

<tip>
The classes java.awt.List and java.util.List are both imported by default.  
Because java.util.List is imported later, as part of the java.util package,
it takes precedence.  To access java.awt.List simply import it in, or the
java.awt package again your script.  Later imports take precedence.
</tip>

<h2>Document Friendly Entities</h2>

BeanShell supports special overloaded text forms of all common operators
to make it easier to embed BeanShell scripts inside other kinds of documents
(e.g XML).
<p/>

<table border="1" cellpadding="5">
<tr><td><strong>@gt</strong></td><td>&gt;</td></tr>
<tr><td><strong>@lt</strong></td><td>&lt;</td></tr>
<tr><td><strong>@lteq</strong></td><td>&lt;=</td></tr>
<tr><td><strong>@gteq</strong></td><td>&gt;=</td></tr>
<tr><td><strong>@or</strong></td><td>||</td></tr>
<tr><td><strong>@and</strong></td><td>&amp;&amp;</td></tr>
<tr><td><strong>@bitwise_and</strong></td><td>&amp;</td></tr>
<tr><td><strong>@bitwise_or</strong></td><td>|</td></tr>
<tr><td><strong>@left_shift</strong></td><td>&lt;&lt;</td></tr>
<tr><td><strong>@right_shift</strong></td><td>&gt;&gt;</td></tr>
<tr><td><strong>@right_unsigned_shift</strong></td><td>&gt;&gt;&gt;</td></tr>
<tr><td><strong>@and_assign</strong></td><td>&amp;=</td></tr>
<tr><td><strong>@or_assign</strong></td><td>|=</td></tr>
<tr><td><strong>@left_shift_assign</strong></td><td>&lt;&lt;=</td></tr>
<tr><td><strong>@right_shift_assign</strong></td><td>&gt;&gt;=</td></tr>
<tr><td><strong>@right_unsigned_shift_assign</strong></td><td>&gt;&gt;&gt;=</td></tr>
</table>

</section>
