Skip to content

Latest commit

 

History

History
86 lines (63 loc) · 3.7 KB

script.adoc

File metadata and controls

86 lines (63 loc) · 3.7 KB

script

since version 1.0.0

The macro script defines a user-defined macro interpreted as a script. The syntax of the command is

Jamal source
{@script/scripttype id(parameters)=body}

If script is followed by a / character, then the subsequent identifier specifies the type of script. If omitted, JShell is used by default. Any scripting language that supports the Java scripting API and has its interpreter on the classpath can be utilized.

The handling of parameters differs from that of user-defined macros created with the define built-in macro. For user-defined macros, parameter strings are replaced with their actual values during evaluation. In scripts, however, parameters are treated as global variable names, and their actual values are injected into the script’s context before evaluation.

This approach limits the freedom in choosing parameter names. With define, any string can be used as a parameter identifier, provided it does not contain , or ). For scripts, parameter names must be valid identifiers within the scripting language since they are utilized as such.

Value injection transforms the actual parameter values into script values. To facilitate this, Jamal performs several conversions:

  • It first attempts to interpret the parameter as an integer. If successful, the corresponding global variable will store an integer value.

  • If integer conversion fails, it tries to convert the value to a double.

  • If neither numeric conversion is possible, it checks if the value is the lowercase true or false. If so, the variable will hold a Boolean value.

  • Otherwise, the global variable is assigned the actual value as a string.

The actual scripting implementation might not support Integer, Double, or Boolean types, but corresponding script types will be available.

Below is a sample script that demonstrates a looping construct in JShell.

The source Jamal file:

Jamal source
{@script for(loopvar,start,end,text)=
var c = "";
for( var i = start ; i <= end ; i++ ){
c = c + text.replaceAll(loopvar, ""+i);
}
System.out.print(c);
}
{for%xxx%1%3%xxx. iterated
}

The output generated by the Jamal preprocessor:

output
1. iterated
2. iterated
3. iterated

Note that the script code itself contains the macro opening and closing strings. This does not do any harm so long as long these are in pairs. It is a better practice to change the separator characters to something that cannot appear in the body of the script macro.

Starting with version 1.3.0, Jamal supports the JShell built-in scripting engine. You can define JShell as a script type. In this case, the content will be passed to the Java built-in JShell engine. When the script is invoked, the result of the macro will be the string printed by the JShell script. If this is empty, the value of the last Java shell snippet will be used. The argument names have to be valid Java identifiers. When the script is invoked they will be defined as String, long, double or boolean variables. They will get the actual values of the parameters. The type depends on the actual value. If the value string can be interpreted as a long, then it will be converted to long. If the string is not a long, but can be converted to double, then the variable will be double. If the string is either true or false case insensitive, then the variable will be boolean. In any other case the variable will be declared as String.

In short, the arguments to a script macro will be converted to the following types in this order, whichever first succeeds:

  • long

  • double

  • boolean

  • String

For more information and details, see the macro JShell.