Expressions and Data References

From HEWIKI
Revision as of 15:39, 30 August 2012 by HE-ALEX (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

Overview

Expressions in HeroScript are similar to most other programming languages. They can be anything from a simple number to a complex mathematical formula involving calls to other functions. They are only valid as parts of statements.

There are also various different kinds of data references in HeroScript. For example, how to access the data in a timer field, a subfield, and an array, all warrant some additional explanation, which is included on this page.

Literals

These are the ways of referencing different types of data.

String tokens

There are also various string tokens such as the following:

System Variables

Please see the section on System Variables.


Node/Class Field References

Given that myVar is a variable of a type with a class that has field1, and field1 is of a class type that has field2, subfields are accessed as follows:

  myVar.field1.field2

Timer field references

Given that n is a reference to a node, and that node has a class with the field exampleTimer of any timer type, the following fields may be retrieved:

n.exampleTimer.firstEnabled Date Time
n.exampleTimer.lastEnabled Date Time
n.exampleTimer.lastFired Date Time
n.exampleTimer.fireCount Integer
n.exampleTimer.enabled Boolean
n.exampleTimer.elapsed Time Interval
n.exampleTimer.remaining Time Interval



 
WallClockTimers have a fireTime field which can be read or set. It is a combination DateTime such as SYSTEM.TIME.NOW. Other timers have an interval field which can be read or set to a TimeInterval.

The remaining field can be set to a Time Interval but only applies until the timer fires (does not change interval).

List References

Given that myVar is a variable of a list type, the following gives the first element of the list:

  myvar[1]

Operators

Operator Name Operand data type(s)
+ add integer, float, string
- subtract integer, float
* multiply integer, float
/ divide integer, float
+= add and assign integer, float, string
-= subtract and assign integer, float
*= multiply and assign integer, float
/= divide and assign integer, float
not logical inverse boolean
and logical and boolean
or logical or boolean
is exactly test class on node node - produces boolean
is kindof test class on node node - produces boolean
= or == equal integer, float, string, node, class, boolean - produces boolean
> greater than integer, float, string - produces boolean
>= greater than or equal integer, float, string - produces boolean
< less than integer, float, string - produces boolean
<= less than or equal integer, float, string - produces boolean
 != or <> not equal produces boolean
mod produce remainder modulus operator: returns the integer remainder
& | ^ ~ << >> bitwise operations Same as C. See http://en.wikipedia.org/wiki/Bitwise_operation


Operator Precedence

Expressions are processed from left to right, except in specific precedence cases.

Level Operator Name
highest . dot
IS KINDOF
IS EXACTLY
not
~
-
boolean "not"
bitwise "not"
unary negation
mod
*
/
mod
multiplication
division
+
-
addition
subtraction
<<
>>
bit shift left
bit shift right
has
<
>
<=
>=
has
less than
greater than
less than or equals
greater than or equals
==
!=
equals
not equal to
& bitwise "and"
^ bitwise "exclusive or"
| bitwise "or"
and boolean "and"
or boolean "or"
lowest = += -= *= /= assignment






It is worth noting that in some cases, evaluation will stop before the entire expression is processed. For example, if there are multiple AND operators in an expression, which would all need to be TRUE simultaneously, then if any single one of them results as FALSE, the Here's Journey engine won't bother evaluating the others.

For example, suppose that trying to check the value of a field on a noderef will result in a script error if the NodeRef is None. So it is desirable to check that the node exists:

function demo (n as noderef of class x)
  if n != None then
    if n.name = "Bob"
      kill(n)
    .
  .
.

A faster way to do this would be:

  if n != None and n.name = "Bob"
    kill(n)
  .

So, even though checking n.name would generate an error if n was None, the engine won't get that far. However, writing the above statement as:

  if n.name="Bob" and n!=None

then it *would* generate an error, since the engine would be evaluating the n.name part first.

The same principle (processing stops when it becomes unnecessary) is true for the OR operator, except that it is reversed. For example, if there are multiple expressions being compared with OR, then the first one that returns a value of TRUE means that the rest can be skipped.

Examples

if i mod 7 
.
if x == 2 
.
if y <= 27 
.
if n is kindof ExampleClassName
.


println("runLimit = "+SYSTEM.EXEC.RUNLIMIT.timeString)
runLimit = 0:0:0.5
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox