simkin
Class Interpreter

java.lang.Object
  |
  +--simkin.ExecutableRoot
        |
        +--simkin.Interpreter
All Implemented Interfaces:
Executable

public class Interpreter
extends ExecutableRoot

This class represents the Simkin interpreter. The interpreter can load, parse and interpret Simkin code.

The Interpreter maintains a list of global variables. This maps names to objects, which are available to all Simkin scripts.

The interpreter itself is a global object with the name "Interpreter".

The Interpreter implements the Executable interface, supports the single field "tracing" which enables/disables tracing of method calls

New from Simkin 1.22: callers are now responsible for creating Interpreter instances. There are no global interpreter variables in the class. Please see the document entitled "Creating Interpreters and Contexts" for more details.


Field Summary
static Null g_Break
          special marker object for break
static java.lang.Boolean g_False
          false object
static Null g_null
          the null object
static java.lang.Boolean g_True
          true object
static java.lang.Integer g_Zero
          zero object
 
Constructor Summary
Interpreter()
          Default constructor - adds a global variable pointing to this interpreter
 
Method Summary
 void addGlobalVariable(java.lang.String name, java.lang.Object r)
          Adds a global variable to the current list
static boolean boolValue(java.lang.Object value)
          This method converts the given value into a boolean value
 boolean checkThrowException(ExecutableContext ctxt, java.lang.Exception e, java.lang.String desc)
          Alerts the current statement stepper (if there is one) that an exception has occurred
 java.lang.Object evaluateExpression(java.lang.String location, java.lang.Object obj, java.lang.String expression, java.util.Hashtable vars, ExecutableContext ctxt)
          this function parses and evaluates an expression within the given context
 java.lang.Object executeParseTree(java.lang.String location, java.lang.Object obj, ParseNode parseNode, java.lang.Object[] args, ExecutableContext ctxt)
          This method executes a piece of Simkin code from a parse tree.
 ExecuteResult executeString(java.lang.String location, java.lang.Object obj, java.lang.String code, java.lang.Object[] args, ExecutableContext ctxt)
          This method executes a piece of Simkin code within a string
 ExecuteResult executeStringExternalParams(java.lang.String location, java.lang.Object obj, java.util.Vector paramNames, java.lang.String code, java.lang.Object[] args, ExecutableContext ctxt)
          This method executes a piece of Simkin code within a string, it assumes that the parameters have been defined outside the statement block.
 java.lang.Object findGlobalVariable(java.lang.String name)
          looks for the given global variable.
static double floatValue(java.lang.Object value)
          This method converts the given value into a double value
 java.util.Hashtable getGlobalVariables()
          This method returns the current global variables for this instance of the Interpreter
 boolean getReflectionEnabled()
          Returns the value of the reflection enabled flag.
 java.lang.Object getValue(java.lang.String field_name, java.lang.String attrib, ExecutableContext ctxt)
          Returns the value of the "tracing" variable - e.g.
 java.lang.Object getValueAt(java.lang.Object index, java.lang.String attrib_name, ExecutableContext ctxt)
          Returns null - this is not a collection
static int intValue(java.lang.Object value)
          This method converts the given value into an integer value
 java.lang.Object method(java.lang.String method_name, java.lang.Object[] arguments, ExecutableContext ctxt)
          The following methods are supported directly by this class:
 ParseNode parse(java.lang.String location, java.lang.String code, ExecutableContext ctxt)
          This method parses a string full of Simkin code and returns the parse tree.
 ParseNode parseExternalParams(java.lang.String location, java.util.Vector paramNames, java.lang.String code, ExecutableContext ctxt)
          This method parses a string of Simkin statements, excluding parameters and enclosing braces.
 java.lang.Object reflectiveGetValue(ExecutableContext ctxt, java.lang.Object owner, java.lang.String field_name)
          This function attempts to retrieve a public Java field using reflection
 java.lang.Object reflectiveMethodCall(ExecutableContext ctxt, java.lang.Object owner, java.lang.String method_name, java.lang.Object[] arguments)
          This function attempts to make a public method call on a Java object by using reflection
 void reflectiveSetValue(ExecutableContext ctxt, java.lang.Object owner, java.lang.String field_name, java.lang.Object value)
          This function attempts to set a public Java field using reflection
 void removeGlobalVariable(java.lang.String name)
          Removes a global variable from the current list
static void runtimeError(ExecutableContext ctxt, java.lang.String buffer)
          this method is called when there is a runtime error and throws a RuntimeException
 void setReflectionEnabled(boolean flag)
          Sets the value of the reflection enabled flag.
 void setStatementStepper(StatementStepper stepper)
          this method sets an object to be called each time a statement is executed.
 void setTraceCallback(TraceCallback cb)
          this method sets an object to receive trace messages.
 void setValue(java.lang.String field_name, java.lang.String attrib, java.lang.Object value, ExecutableContext ctxt)
          Used to set the "tracing" variable - for example in Simkin:
 void setValueAt(java.lang.Object index, java.lang.String attrib_name, java.lang.Object value, ExecutableContext ctxt)
          Does nothing - this is not a collection
 void trace(java.lang.Exception e)
          Sends the text of an exception to the tracer
 void trace(java.lang.String s)
          this method outputs a message to the trace - either the global class Tracer, or the current Trace callback
 
Methods inherited from class simkin.ExecutableRoot
createIterator, createIterator, getAttributes, getInstanceVariables, getSource
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

g_null

public static final Null g_null
the null object


g_True

public static final java.lang.Boolean g_True
true object


g_False

public static final java.lang.Boolean g_False
false object


g_Zero

public static final java.lang.Integer g_Zero
zero object


g_Break

public static final Null g_Break
special marker object for break

Constructor Detail

Interpreter

public Interpreter()
Default constructor - adds a global variable pointing to this interpreter

Method Detail

getReflectionEnabled

public boolean getReflectionEnabled()
Returns the value of the reflection enabled flag. If this is true, the interpreter will use the Java reflection API to look for public methods and fields

Returns:
flag true or false

setReflectionEnabled

public void setReflectionEnabled(boolean flag)
Sets the value of the reflection enabled flag. If this is true, the interpreter will use the Java reflection API to look for public methods and fields

Parameters:
flag - true or false

setValue

public void setValue(java.lang.String field_name,
                     java.lang.String attrib,
                     java.lang.Object value,
                     ExecutableContext ctxt)
              throws java.lang.RuntimeException,
                     FieldNotSupportedException
Used to set the "tracing" variable - for example in Simkin:

Interpreter.tracing=true;

Specified by:
setValue in interface Executable
Overrides:
setValue in class ExecutableRoot
Parameters:
field_name - the name of the field
attrib - the name of the attribute to be set (can be null)
value - the value to be set
ctxt - the context the function is called within
Throws:
java.lang.RuntimeException - - if there was a problem running the script (such as not having permission to access a field)
FieldNotSupportedException - - if the field could not be found

method

public java.lang.Object method(java.lang.String method_name,
                               java.lang.Object[] arguments,
                               ExecutableContext ctxt)
                        throws ParseException,
                               java.lang.RuntimeException,
                               MethodNotSupportedException
The following methods are supported directly by this class:

breakpoint - forces a breakpoint to be signalled to an attached debugger

Specified by:
method in interface Executable
Overrides:
method in class ExecutableRoot
Returns:
true if the method is found
ParseException
java.lang.RuntimeException
MethodNotSupportedException

checkThrowException

public boolean checkThrowException(ExecutableContext ctxt,
                                   java.lang.Exception e,
                                   java.lang.String desc)
Alerts the current statement stepper (if there is one) that an exception has occurred

Parameters:
ctxt - the current ExecutableContext
e - the exception to throw
desc - the exception description without location information
Returns:
true if the exception should be thrown, false if the statement stepper requests the exception is not thrown

boolValue

public static boolean boolValue(java.lang.Object value)
This method converts the given value into a boolean value

If the object is an instance of Boolean, the boolean value is returned, otherwise toString() is called, and compared with "true"

Returns:
the boolean equivalent of the object

intValue

public static int intValue(java.lang.Object value)
This method converts the given value into an integer value

If the object is an instance of Integer, the integer value is returned, otherwise toFloat() is called, and converted to an integer

Returns:
the integer equivalent of the object

floatValue

public static double floatValue(java.lang.Object value)
This method converts the given value into a double value

If the object is an instance of Double, the integer value is returned. If the object is a boolean, true maps to 1.0f and false to 0.0f, otherwise toString() is called, and converted to a double

Returns:
the double equivalent of the object

getValueAt

public java.lang.Object getValueAt(java.lang.Object index,
                                   java.lang.String attrib_name,
                                   ExecutableContext ctxt)
                            throws java.lang.RuntimeException
Returns null - this is not a collection

Specified by:
getValueAt in interface Executable
Overrides:
getValueAt in class ExecutableRoot
Parameters:
index - an object whose value indicates the index of the item in the collection
attrib_name - attribute name (null if no attribute specified)
ctxt - the context the function is called within
Returns:
the value of the object (null if not present)
Throws:
java.lang.RuntimeException - - if there was a problem running the script

setValueAt

public void setValueAt(java.lang.Object index,
                       java.lang.String attrib_name,
                       java.lang.Object value,
                       ExecutableContext ctxt)
                throws java.lang.RuntimeException
Does nothing - this is not a collection

Specified by:
setValueAt in interface Executable
Overrides:
setValueAt in class ExecutableRoot
Parameters:
index - an object whose value indicates the index of the item in the collection
attrib_name - the name of the attribute to be set (can be null)
value - the value to be set
ctxt - the context the function is called within
Throws:
java.lang.RuntimeException - - if there was a problem running the script

getValue

public java.lang.Object getValue(java.lang.String field_name,
                                 java.lang.String attrib,
                                 ExecutableContext ctxt)
                          throws java.lang.RuntimeException,
                                 FieldNotSupportedException
Returns the value of the "tracing" variable - e.g. in Simkin:

tracing=Interpreter.tracing;

Specified by:
getValue in interface Executable
Overrides:
getValue in class ExecutableRoot
Parameters:
field_name - the name of the field
attrib - attribute name (null if no attribute specified)
ctxt - the context the function is called within
Returns:
the value of the field (or null, if the field is not supported)
Throws:
java.lang.RuntimeException - - if there was a problem running the script (such as not having permission to access a field)
FieldNotSupportedException - - if the field could not be found

findGlobalVariable

public java.lang.Object findGlobalVariable(java.lang.String name)
looks for the given global variable.

Parameters:
name - - the name of the global variable
Returns:
the object found, or null if the global variable is undefined

addGlobalVariable

public void addGlobalVariable(java.lang.String name,
                              java.lang.Object r)
Adds a global variable to the current list

Parameters:
name - - the name of the global variable, if one already exists it is replaced
r - - the object to be added to the list

removeGlobalVariable

public void removeGlobalVariable(java.lang.String name)
Removes a global variable from the current list

Parameters:
name - - the name of the global variable to be removed

parse

public ParseNode parse(java.lang.String location,
                       java.lang.String code,
                       ExecutableContext ctxt)
                throws ParseException
This method parses a string full of Simkin code and returns the parse tree. If a parse error occurs, a ParseException is thrown

For example the following string could be passed:

(a,b){
     a=b+1;
     return a;
     }
     

Parameters:
location - used to help identify the code in error messages
code - a string containing the Simkin code
ctxt - the owning ExecutableContext
Returns:
a ParseNode representing the parse tree for the code
ParseException

parseExternalParams

public ParseNode parseExternalParams(java.lang.String location,
                                     java.util.Vector paramNames,
                                     java.lang.String code,
                                     ExecutableContext ctxt)
                              throws ParseException
This method parses a string of Simkin statements, excluding parameters and enclosing braces. The method returns a parse tree. If a parse error occurs, a ParseException is thrown

For example the following string could be passed (note the absence of enclosing braces around the statement list):

     a=b+1;
     return a;
     

Parameters:
location - used to help identify the code in error messages
paramNames - a vector of names for the parameters
code - a string containing the Simkin code
ctxt - the owning ExecutableContext
Returns:
a ParseNode representing the parse tree for the code
ParseException

executeString

public ExecuteResult executeString(java.lang.String location,
                                   java.lang.Object obj,
                                   java.lang.String code,
                                   java.lang.Object[] args,
                                   ExecutableContext ctxt)
                            throws java.lang.RuntimeException,
                                   ParseException
This method executes a piece of Simkin code within a string

For example the following string could be passed:

(a,b){
     a=b+1;
     return a;
     }
     

Parameters:
location - a name used to identify the code in error messages
obj - the object within whose context the code will execute
code - a string containing some Simkin code
args - and array of RValue arguments to the code
ctxt - the owning ExecutableContext
Returns:
returns an object containing the result of the method and the parse tree for the method, which can be safely cached
Throws:
ParseException - this is thrown if there is a syntax error in the code
java.lang.RuntimeException - this is thrown if there is an error during the execution of the code (such as method or field not found)

executeStringExternalParams

public ExecuteResult executeStringExternalParams(java.lang.String location,
                                                 java.lang.Object obj,
                                                 java.util.Vector paramNames,
                                                 java.lang.String code,
                                                 java.lang.Object[] args,
                                                 ExecutableContext ctxt)
                                          throws java.lang.RuntimeException,
                                                 ParseException
This method executes a piece of Simkin code within a string, it assumes that the parameters have been defined outside the statement block.

For example the following string could be passed (note the absence of enclosing braces around the statement list):

     a=b+1;
     return a;
     

Parameters:
location - a name used to identify the code in error messages
obj - the object within whose context the code will execute
paramNames - a vector of names for the parameters
code - a string containing some Simkin code
args - and array of RValue arguments to the code
ctxt - the owning ExecutableContext
Returns:
returns an object containing the result of the method and the parse tree for the method, which can be safely cached
Throws:
ParseException - this is thrown if there is a syntax error in the code
java.lang.RuntimeException - this is thrown if there is an error during the execution of the code (such as method or field not found)

executeParseTree

public java.lang.Object executeParseTree(java.lang.String location,
                                         java.lang.Object obj,
                                         ParseNode parseNode,
                                         java.lang.Object[] args,
                                         ExecutableContext ctxt)
                                  throws java.lang.RuntimeException,
                                         ParseException
This method executes a piece of Simkin code from a parse tree.

You can call this with a parse tree produced by parse, parseExternalParams,executeString or executeStringExternalParams. This can be useful for caching parse trees to improve performance.

Parameters:
location - a name used to identify the code in error messages
obj - the object within whose context the code will execute
parseNode - a pre-parsed tree of Simkin code
args - and array of RValue arguments to the code
ctxt - the owning ExecutableContext
Throws:
ParseException - this is thrown if there is a syntax error in the code
java.lang.RuntimeException - this is thrown if there is an error during the execution of the code (such as method or field not found)

evaluateExpression

public java.lang.Object evaluateExpression(java.lang.String location,
                                           java.lang.Object obj,
                                           java.lang.String expression,
                                           java.util.Hashtable vars,
                                           ExecutableContext ctxt)
                                    throws java.lang.RuntimeException,
                                           ParseException
this function parses and evaluates an expression within the given context

Parameters:
location - - a textual description of the location of the expression (this appears in error messages)
obj - - the executable object which "owns" the expression
vars - - a table of local variables defined for the expression
expression - - a single Simkin expression which must begin with "=" for example "=a+b"
Returns:
the result of the expression
Throws:
ParseException - - if a syntax error is encountered
java.lang.RuntimeException - - if an error occurs while the expression is evaluated

runtimeError

public static void runtimeError(ExecutableContext ctxt,
                                java.lang.String buffer)
                         throws java.lang.RuntimeException
this method is called when there is a runtime error and throws a RuntimeException

Parameters:
ctxt - the owning ExecutableContext
buffer - the text of the error
java.lang.RuntimeException

trace

public void trace(java.lang.String s)
this method outputs a message to the trace - either the global class Tracer, or the current Trace callback

Parameters:
s - the message to be sent to the tracer

trace

public void trace(java.lang.Exception e)
Sends the text of an exception to the tracer

Parameters:
e - the exception to be sent to the tracer

setTraceCallback

public void setTraceCallback(TraceCallback cb)
this method sets an object to receive trace messages. Pass 0 to fall back to standard mechanism (using Tracer)

Parameters:
cb - the new tracer to use for trace commands (or null to fall back to Tracer)

setStatementStepper

public void setStatementStepper(StatementStepper stepper)
this method sets an object to be called each time a statement is executed.

Parameters:
stepper - the new statement stepper

reflectiveMethodCall

public java.lang.Object reflectiveMethodCall(ExecutableContext ctxt,
                                             java.lang.Object owner,
                                             java.lang.String method_name,
                                             java.lang.Object[] arguments)
                                      throws java.lang.RuntimeException,
                                             MethodNotSupportedException
This function attempts to make a public method call on a Java object by using reflection

Parameters:
ctxt - the owning ExecutableContext
owner - - the object to call a method on
method_name - - the name of the method to call
arguments - - the method arguments - types Integer, Double, Boolean and Character are converted to their primitive types
Returns:
the result of the method call
Throws:
java.lang.RuntimeException - - if the method could not be called
MethodNotSupportedException - - if the method could not be found

reflectiveSetValue

public void reflectiveSetValue(ExecutableContext ctxt,
                               java.lang.Object owner,
                               java.lang.String field_name,
                               java.lang.Object value)
                        throws java.lang.RuntimeException,
                               FieldNotSupportedException
This function attempts to set a public Java field using reflection

Parameters:
ctxt - the owning ExecutableContext
owner - - the object owning the field
field_name - - the name of the field
value - - the value to assign to the field
Throws:
java.lang.RuntimeException - - if the field could not be set (e.g. if it was private)
FieldNotSupportedException - - if the field could not be found

reflectiveGetValue

public java.lang.Object reflectiveGetValue(ExecutableContext ctxt,
                                           java.lang.Object owner,
                                           java.lang.String field_name)
                                    throws java.lang.RuntimeException,
                                           FieldNotSupportedException
This function attempts to retrieve a public Java field using reflection

Parameters:
ctxt - the owning ExecutableContext
owner - - the object owning the field
field_name - - the name of the field
Returns:
the value of the field
Throws:
java.lang.RuntimeException - - if the field could not be retrieved (e.g. if it was private)
FieldNotSupportedException - - if the field could not be found

getGlobalVariables

public java.util.Hashtable getGlobalVariables()
This method returns the current global variables for this instance of the Interpreter

Returns:
a hashtable containing the current global variables