JCM Scripting Code Syntax

The essence of the JCM scripting code is to make use of the same names system as used for translatable labels and documentation. It's not necessary to know the references of objects in the low-level java code. See the documentation page on names for more explanation.

The script is intepreted by the java code in jcm/tls/player. This operates in a separate thread, so it can work simultaneously with response to mouse-events.

The original text script is first split into items, dividing at each space, tab, or newline. Thus, everything, even opening and closing brackets, must be separated by such whitespace on both sides,. Multiple spaces are ignored, so the layout on the page is free.

Simple scripts, without loops or variables, can be written without understanding the remainder below. Just use a sequence of instructions: object_name : value_to_set

Note that for future development of JCM, it is anticipated that the java "Beanshell" (www.beanshell.org) will probably be used to replace this scripting code system. Therefore you are not advised to invest time writing scripts using this code

Code sections and flow

Each section 'Sec' of the code ('scriptchunk' in @player) has:
  • a current location 'Loc' (the index of the last item processed),
  • a current value 'Val' (a string that can represent a number, some text, or a name of a variable or an object in JCM),
  • an instruction 'Next', and the previous one 'Prev'.
  • three flags, 'inquote', 'inbracket', 'skip'.

    At the beginning of each step, Loc is incremented by one, and Next is then read from the item at Loc.

    There is a simple recursive system for managing program flow.

  • The first Sec starts with Loc = -1, Val = null, inbracket true, other flags false.
  • After getting and intepreting Next, a Sec will continue to the next step while either inbracket or inquote is true, otherwise it has finished.
  • Each Instruction (as below) starts a new Sec for each of its parameters 'Par', 'Par2', etc., with Loc following from its parent. This starts with with Val null and all flags false. When it has finished, its Val is returned as the Par, and its parent's Loc follows from where it left off
  • Sub also starts a new Sec whose Loc is the first location of its Par, and returns to its parent's Loc when done.
  • Goto sets Loc to the first location of its Par, without starting a new Sec, and never comes back

    Next is processed as follows:

  • If Next is a single quote ', inquote is set to true until the next single quote ' is reached.
  • If Next is an opening bracket '(', inbracket is set to true until the next closing bracket ')'
  • While inquote is true, Next is appended to Val.
  • While skip is true, Next is ignored.
  • Otherwise, Next is checked agaNextt the list of Functions (below).
  • If no instruction is found, set Val = the contents of Next, and record Prev=Next

    Variable and Object Contents

    Note: in the instructions listed below, Val refers to the string itself, whereas ValC refer to its contents. The same applies for parameters Par and ParC.

    The 'contents' is one of the following (sought in this order):

  • If Val starts with $ it's a script variable (if not yet registered, a new one is created - they are all global in scope).
  • A JCM @iob with the name of Val , if one can be found (see @names)
  • Any other public field in JCM with the name of Val, sought using java reflection (see @ref)
  • Failing all the above, the string Val itself (possibly interpreted as a floating point number if appropriate)

    Note: for a JCM object, "setting" its contents calls its doscript(Next) method (see @iob). For @param, that sets the value. In the case of menu parameters, 'next' and 'prev' can be used instead of menu items. For @blankplot there are special functions to set up a new graph. For most other objects, its state is written to debug output.

    For a java field that is an array, its index can be appended using a dot The same notation can be used for writing into arrays, but to make the model recalculate you also have to set the appropriate module changed=true, then add 'go' For an example see emitdeclinescript

    If the script causes a java exception, a message will be reported to debug output, but the script will keep going.

    Instructions:

  • (value of Next What to do )

    Setting values

  • : set Val= Prev and ValC = ParC
  • :+ :- :~ combination of : self +/-/~etc.
  • ; set Val = null
  • _ set Val= Prev and set ValC = Par (use for setting to strings not contents)
  • var set Val = ParC (to make a variable name dynamically)
  • put set ParC = ValC

    Branching

  • if set Val = ParC and if this is true, start another Sec, otherwise skip a Sec
  • else if Val is false start another Sec, otherwise skip a Sec
  • sub start a subroutine whose name is ParC
  • sub jump to name is ParC

    Boolean

  • ! set ValC = not ParC
  • < / > set ValC= ValC less than / greater than ParC
  • & / | set ValC = ValC AND / OR ParC
  • == / != set ValC = ValC equals / notequals ParC (works for both strings and numbers)

    Mathematical

  • rnd set ValC = random number between 0 and 1
  • int set ValC = ParC rounded to an integer
  • exp or log set ValC = exponential or natural logaritm of ParC
  • +, -, /, asterix set ValC = ValC +, -, /, x ParC (using floating point arithmetic)

    Note: the interpreter is very simple, so it doesn't know about arithmetic precedence, so always use brackets!

  • % set ValC = remainder after division by ParC
  • ^ set ValC = ValC to power of ParC

    Strings

  • ~ set ValC = ValC +(append a string) ParC

    Control

  • run run JCM main model loop (only necessary if scriptmode=delay, see @scriptparam)
  • end break out of script

    Timing

  • w wait ParC milliseconds
  • p pause (duration specified by last w)

    Text output

  • ? write ValC to debug output (java console or a @notepad)
  • c write ParC to debug output

    Showing webpages

  • swp show specified webpage (as below)
  • page set page to ParC
  • frame set browser frame to ParC
  • html set htmlinfo to ParC (a webpage may pick up this info using javascript)
  • jvs run ParC as javascript (from page containing main applet)

    Demo:

  • show show popup info for iob with name of Val (duration as for pause)