Manual of Icwri Script Version 0.361 - A Lightweight Service Oriented Java(TM) Built-in Script

Icwri is a lightweight service oriented Java built-in script. It is a very simple script. It can help Java developers to build some applications interfaces and tools in a service oriented style. It can also help non-technical people to join the development team to write their own application scripts to enforce business rules and decisions. It can also be a good assistant language for Java developers.

Icwri service providers and consumers can be either Icwri scripts or Java classes. Icwri script can run all alone. But my primary purpose to invent Icwri script is to have an assistant language of Java.

Icwri can run on any system (UNIX/Linux, Windows, Mac, …) with JDK/JRE 1.5 or above installed. Icwri does not support Java SE 6 Script Engine because the service oriented design and the requirement to support Java SE 1.5 users.

Following are major resource URL’s of Icwri Script:

Following are major topics in this manual:

 

Why Service Oriented

Most developers know OOP (Object Oriented Programming). OOP is a good development method to write high efficient code. But if the target system is complex, and you just want to use some of its service directly, it is not always the best way to invent objects for the system, and service oriented programming (SOP) becomes a better programming style. It is loose-coupling and easier to change. The obvious characters of SOP are direct business and technical independent.

For example, a store provides a service named "buyBeer". You can write this service as following code in Icwri style:

%service !buyBeer;
%uses
 @brandsToBuy, @moneyPay, @priceLimit, #For inputs
 @brandBought, @moneyReturned; #For outputs
%begin;
 …<<script code>> …
 brandBought:…;
 moneyReturned:…;
%end;

You can also realize the service with java code in the similar style (see following chapters). The service implementation code can be a file on disk, or an URL in the Internet. Service consumers do not care the service implementation.

You can call the service with following Icwri script code:

!buyBeer.@brandsToBuy: `Qingdao, Carlsberg`;
!buyBeer.@moneyPay: 200;
!buyBeer.@priceLimit: 10;
!buyBeer();
#You can get !buyBeer.@brandBought and !buyBeer.@moneyReturned now.

Or:

!buyBeer.@priceLimit: 10;
!buyBeer(`Qingdao, Carlsberg`, 200);
#You can get !buyBeer.@brandBought and !buyBeer.@moneyReturned now.

Or following Java code:

Service svc= icwri.loadService("!buyBeer");
svc.setAttribute("@brandsToBuy", "Qingdao, Carlsberg");
svc.setAttribute("@moneyPay", 200);
svc.setAttribute("@priceLimit", 10);
svc.run();

 

Getting Start

Icwri can run on any system (UNIX/Linux, Windows, MAC, …) with JDK/JRE 1.5 or above installed. The kernel files include icwri.jar and service list files. The service list files can be rewrite by users. Icwri can be installed into any path. Following steps shows how to install Icwri and run some simple demo applications.

1. For Unix/Linux users

1) Extract the package

$ cd /opt
$ gzip -d icwri_0.361.tar.gz
$ tar vxf icwri_0.361.tar

2) Set environment

$ CLASSPATH=/opt/icwri_0.361/icwri.jar
$ export CLASSPATH

3) Run demo script application in style-1 (Service List - Service)

$ java lr.icwri.app.RunService -l /opt/icwri_0.361/config/IcwriApp.lst -s !helloWorld1
Hello World!
Icwri version 0.361

Or in style-2 (Script - Service)

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/HellpWorld2.icw -s !helloWorld2
Hello World!
Icwri version 0.361

Note:
"-s" argument specifies the service name.
"-l" argument specifies the service list (registry) file;
"-f" argument specifies the script file.

Note: Other demo acript applications include (Service "!testBonusPlan3A" requires GUI support):

java lr.icwri.app.RunService -l /opt/icwri_0.361/config/IcwriApp.lst -s !helloWorld1
java lr.icwri.app.RunService -l /opt/icwri_0.361/config/IcwriApp.lst -s !learnObject
java lr.icwri.app.RunService -l /opt/icwri_0.361/config/IcwriApp.lst -s !learnArray
java lr.icwri.app.RunService -l /opt/icwri_0.361/config/IcwriApp.lst -s !learnString
java lr.icwri.app.RunService -l /opt/icwri_0.361/config/IcwriApp.lst -s !testCommands1
java lr.icwri.app.RunService -l /opt/icwri_0.361/config/IcwriApp.lst -s !testCommands2
java lr.icwri.app.RunService -l /opt/icwri_0.361/config/IcwriApp.lst -s !testCommands3

java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/HellpWorld2.icw -s !helloWorld2
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/HellpWorld2.icw -s !testString
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/HellpWorld2.icw -s !writeFile

java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan1
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan2
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan2A
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan3
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan3A

java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray0 < /opt/icwri_0.361/samples/WorldCup.lst
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray1 < /opt/icwri_0.361/samples/WorldCup.lst
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray2 < /opt/icwri_0.361/samples/WorldCup.lst
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray3 < /opt/icwri_0.361/samples/WorldCup.lst
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray4 < /opt/icwri_0.361/samples/WorldCup.lst
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray5 < /opt/icwri_0.361/samples/WorldCup.lst
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray6 < /opt/icwri_0.361/samples/WorldCup.lst
java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !analyzeData1 < /opt/icwri_0.361/samples/TestData

 

2. For Microsoft Windows users

1) Extract the package to directory, for example: c:\icwri_0.361

2) Set environment

SET CLASSPATH=c:/icwri_0.361/icwri.jar

3) Run demo script application in style-1 (Service List - Service)

$ java lr.icwri.app.RunService -l c:/icwri_0.361/config/IcwriApp.lst -s !helloWorld1
Hello World!
Icwri version 0.361

Or in style-2 (Script - Service)

$ java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/HellpWorld2.icw -s !helloWorld2
Hello World!
Icwri version 0.361

Note:
"-s" argument specifies the service name.
"-l" argument specifies the service list (registry) file;
"-f" argument specifies the script file.

Note: Other demo applications include (Service "!testBonusPlan3A" requires GUI support):

java lr.icwri.app.RunService -l c:/icwri_0.361/config/IcwriApp.lst -s !helloWorld1
java lr.icwri.app.RunService -l c:/icwri_0.361/config/IcwriApp.lst -s !learnObject
java lr.icwri.app.RunService -l c:/icwri_0.361/config/IcwriApp.lst -s !learnArray
java lr.icwri.app.RunService -l c:/icwri_0.361/config/IcwriApp.lst -s !learnString
java lr.icwri.app.RunService -l c:/icwri_0.361/config/IcwriApp.lst -s !testCommands1
java lr.icwri.app.RunService -l c:/icwri_0.361/config/IcwriApp.lst -s !testCommands2
java lr.icwri.app.RunService -l c:/icwri_0.361/config/IcwriApp.lst -s !testCommands3

java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/HellpWorld2.icw -s !helloWorld2
java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/HellpWorld2.icw -s !testString
java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/HellpWorld2.icw -s !writeFile

java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan1
java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan2
java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan2A
java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan3
java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan3A

java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/formatter.icw -s !readArray0 < c:\icwri_0.361\samples\WorldCup.lst
java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/formatter.icw -s !readArray1 < c:\icwri_0.361\samples\WorldCup.lst
java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/formatter.icw -s !readArray2 < c:\icwri_0.361\samples\WorldCup.lst
java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/formatter.icw -s !readArray3 < c:\icwri_0.361\samples\WorldCup.lst
java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/formatter.icw -s !readArray4 < c:\icwri_0.361\samples\WorldCup.lst
java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/formatter.icw -s !readArray5 < c:\icwri_0.361\samples\WorldCup.lst
java lr.icwri.app.RunScript -f c:/icwri_0.361/samples/formatter.icw -s !readArray6 < c:\icwri_0.361\samples\WorldCup.lst

You can find that there are 2 service invocation styles:

 

The First Demo Script - Hello World

By convention the first simplest demo application is always named “Hello World”. You can find this demo script in "samples/HellpWorld2.icw". This file has defined 3 services including a very simple service named “!helloWorld2”. You can find that the names of the services in Icwri Script are all prefixed by character “!”. Following is the code:

... ...
################################################################################
#The Icwri service list file
%serviceList `../config/IcwriSystem.lst`;

################################################################################
%service !helloWorld2;
%uses;
%begin;
 !sys_printLine( `Hello World!` );
 !sys_printLine( !aboutIcwri() );
%end;
... ...

Icwri system treats text in a line after "#" as comments. Icwri commands are all prefixed by character “%”, for example: "%service", "%uses", "%begin", and "%end". It is not required to write one Icwri statement in one line, but each statement must be ended by character ";". Constant strings in Icwri script are enclose by back ticks (`) instead of apostrophe () or quotation marks ("). So developers can use apostrophe (') or quotation marks (") in their strings without any escape characters.

The “%serviceList” statement specifies the service list file. Service list file is the service catalog or registry of syetem or user defined services. In this demo, the service list file is "../config/IcwriSystem.lst". The “uses” statement defines attributes used by the service. All lines between “%begin” statement and “%end” statement are the execution statements of the service. “!sys_printLine()” is a system defined service. The default behavior is to write message to a line on the console. “!aboutIcwri()” is another system defined service. It returns the version information of current Icwri Script engine.

Following is the output when running service “!helloWorld2” on UNIX/Linix:

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/HellpWorld2.icw -s !helloWorld2
Hello World!
Icwri version 0.35

Following ss the output when running service “!helloWorld2” on Windows:

C:\> java lr.icwri.app.RunScript -f C:/icwri_0.361/samples/HellpWorld2.icw -s !helloWorld2
Hello World!
Icwri version 0.35

 

Service List (Registry)

Icwri services are dynamically invoked by checking a service registry named Icwri Service List. It is usually a file on a disk or in the Internet. Following is a sample Icwri Service List file (IcwriApp.lst):

# Generic Description
%icwriVersion:0.361
#%baseFilePath:
%include:file,IcwriSystem.lst

# Service list
!bonusPlan1:file,LalaBonus.icw
!testBonusPlan1:file,LalaBonus.icw
!bonusPlan2:file,LalaBonus.icw
!testBonusPlan2:file,LalaBonus.icw
!testBonusPlan2A:file,LalaBonus.icw
!bonusPlan3:file,LalaBonus.icw
!testBonusPlan3:file,LalaBonus.icw
!testBonusPlan3A:file,LalaBonus.icw

!testCommands1:file,test1.icw
!testCommands2:file,test1.icw
!testCommands3:file,test1.icw

Note: Icwri system treats text in a line after "#" as comments.

Following statement means the least required version of Icwri script engine is "0.361".

%icwriVersion:0.361

You can use "%baseFilePath" to specify the default path of Icwri script files and service list files like following:

%baseFilePath: /opt/icwri_0.361/config

If you do not set "%baseFilePath", system takes the current directory as the default path of Icwri script files and service list files.

Following statement means "IcwriSystem.lst" file should be included in this Service List (You can also use a full path of the included file).

%include: file, IcwriSystem.lst

The included service list file can also be in the Internet. Following is a sample:

%include: url, http://www.lrsolution.com/icwri/IcwriSystem.lst

You can also use non-default encoding (character-set ID defined in Java) for the include file. For example:

%include: file, IcwriSystem.lst, GBK
%include: url, http://www.lrsolution.com/icwri/IcwriSystem.lst, UTF-8

The most important content of Icwri Service List is service entries. Each service entry use following format:

<Service Name>:< Service type>,<Service path>

For example, Following statement registers an Icwri Service named "!helloWorld". The service is defined in a script file whose path is "test1.icw":

!helloWorld: file, test1.icw

Following statement registers an Icwri Service named "!bonusPlan1". The service is defined in a script file in "http://www.lrsolution.com/Icwri/LalaBonus.icw":

!helloWorld: url, http://www.lrsolution.com/Icwri/test1.icw

Following statement registers an Icwri Service named "!sys_printLine". The service is defined in a Java class named "lr.icwri.app.api.IOUtil".

!sys_printLine: java, lr.icwri.app.api.IOUtil

You can also use non-default encoding (character-set ID defined in Java) for the Services. For example:

!helloWorld: file, test1.icw, GBK
!helloWorld: url, http://www.lrsolution.com/Icwri/LalaBonus.icw, UTF-8

Under the "config" directory, you can find 2 service list files: "IcwriApp.lst" and "IcwriSystem.lst". "IcwriApp.lst" is a demo user service list. "IcwriSystem.lst" is the list of system provided services. "IcwriSystem.lst" is also included in "IcwriApp.lst". You can write your own service list. The nesting of "include" is not limited.

The"IcwriSystem.hlp" file is the help file to "IcwriSystem.lst". System does not read the ".hlp" files.

You can run the service defined in the service list file directly. For example you can use following command to run service “!helloWorld1” defined in service list file “IcwriApp.lst”:

java lr.icwri.app.RunService -l /opt/icwri_0.361/config/IcwriApp.lst -s !helloWorld1

You can also run the service defined in a script. The script must specify the system service list file. For example, you can use following command to run service “!helloWorld2” defined in script file “HellpWorld2.icw”:

java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/HellpWorld2.icw -s !helloWorld2

In script file “HellpWorld2.icw”, following statement is used to specify the system service list file "IcwriSystem.lst":

%serviceList `../config/IcwriSystem.lst`;

If you want to specify the character encoding of the service list file to be non-default, for example: GBK, you can use following statement:

%serviceList `../config/IcwriSystem.lst, GBK`;

 

Script Syntax 1 – Entities in Icwri Script

There only 3 types of entities used by Icwri:

1) Constant (string or number)
Following are examples of constant:
123, 1.23, 1,23e5  # constant numbers
`abc`, `abc def`   # constant strings

Constant strings in Icwri script are enclose by back ticks (`) instead of apostrophe () or quotation marks ("). So developers can use apostrophe (') or quotation marks (") in their strings without any escape characters. The escape character of Icwri script is tilde (~). Following is a table showing how to use the escape character to express special characters in an Icwri string.

Original Character Escaped Sequence
LF (ASCII value=10) ~LF
CR (ASCII value=13) ~CR
` (ASCII value=96) ~BT
~ (ASCII value=126) ~TD
character of any ASCII value ~nn (nn is the ASCII value in hexadecimal)

Icwri script does not distinguish strings and numbers. In Icwri script following expression is true:
`12.3` = 12.3

See following chapters to know how to express a logical value (true or false) in Icwri script.

 

2) Service

You can define an Icwri service with either Icwri script or Java code. Then you should add this service description into the Icwri Service List described in previous chapters. Both Icwri script and Java application can be Icwri service consumers.

Following is snippet of a sample Icwri script (LalaBonus.icw) to define 2 services "!bonusPlan1" and "!testBonusPlan1". Service "!testBonusPlan1" calls service "!bonusPlan1".

%service !bonusPlan1;
%uses
 @bonusRate:0.15, @totalSales, #Input
 @bonus; #Output
%begin;
 @bonus:@totalSales*@bonusRate;
%end;

%service !testBonusPlan1;
%uses;
%begin;
 !bonusPlan1.@totalSales: !sys_inputLine(`Please input the total sales figure:`);
 !bonusPlan1();
 !sys_printLine( `The bonus is $` | !bonusPlan1.@bonus );
%end;

Note:

To implement an Icwri service with Java, you should compose a Java class to implement lr.icwri.app.Serviceable interface.

public interface Serviceable {
/**
 * Get the Uses line of the service.
 *
 * @param serviceName
 * @return The USES line of the service
 * @throws IcwriException
 */
 public String getUses(String serviceName) throws IcwriException;

/**
 * Run the service code
 *
 * @param serviceName
 * @param attrs
 * @throws IcwriException
 */
 public void run(String serviceName, Attributes attrs) throws IcwriException;
}

There are 2 methods in this interface. Use method "getUses" to return the "uses" statement. Use method "run" to implement the service.
Following are the simple implementations of system service "!sys_printLine", "!sys_print", and "!sys_inputLine":

public String getUses(String serviceName) throws IcwriException {
 if (serviceName.equals("!sys_printLine"))
  return "@message($1), @style($2);";
 else if (serviceName.equals("!sys_print"))
  return "@message($1), @style($2);";
 else if (serviceName.equals("!sys_inputLine"))
  return "@message($1), @style($2), @input($?);";
 else
  throw new IcwriException(IcwriException.ET_NO_SUCH_SERVICE, "No such Service - " + serviceName);
}

public void run(String serviceName, Attributes attrs) throws IcwriException {
 String msg = attrs.getAttribute("@message").getStringValue();
 String style = attrs.getAttribute("@style").getStringValue();
 if (serviceName.equals("!sys_printLine")) {
  if (style.equals("SWI")) {
   JOptionPane.showMessageDialog(null, msg, "message", JOptionPane.PLAIN_MESSAGE);
  } else {
   System.out.println(msg);
  }
 } else if (serviceName.equals("!sys_print")) {
  System.out.print(msg);
 } else if (serviceName.equals("!sys_inputLine")) {
  if (style.equals("SWI")) {
   attrs.setAttribute("@input", JOptionPane.showInputDialog(msg));
  } else {
   try {
    System.out.print(msg + "\n>> ");
    attrs.setAttribute("@input", new BufferedReader(new InputStreamReader(System.in)).readLine());
   } catch (IOException e) {
    attrs.setAttribute("@input", "");
   }
  }
 } else {
  throw new IcwriException(IcwriException.ET_NO_SUCH_SERVICE, "No such Service - " + serviceName);
 }
}

 

3) Attribute

Attributes must belong to a service. Attributes can be used as input, output or just internal used for a service. The format to quote an attribute is as following:

<service name>.<attribute name>

If you use following abbreviated format, it means that the service holding the attribute is the current service.

<attribute name>

Using attributes without declaration in the "uses" statement is not permitted. Following "uses" statement declares 3 attributes:

%uses @v1, @v2, @v3;

Sometimes you want to give an initial value to the attributes. Following is a sample:

%uses @v1:15.3, @v2:`good`, @v3;

The constants following a colon is the initial value. The initial value is applied only at the first time of an Icwri context loading a service.

Sometimes you want to use an alias instead of the attribute name. The attribute alias must be declared in the "uses" statement in parentheses following the attribute. Attribute alias must be prefixed with "$". Following are samples:

%uses @v1($num1):15.3, @v2:`good`, @v3($num2);

$num1 is the alias of @v1 and $num2 is the alias of @v3. So you can use either $num1 or @v1 in your application code. So you can use either $num2 or @v3 in your application code.

Why do we need attribute alias?
The traditional format to call a service is as following sample:

service1.attribute1: `value1`;
service1.attribute2: `value2`
service1.attribute3: `value3`
service1();

We may want to use an abbreviated way to call the service. Following is the sample code:

service1(`value1`, `value2`, `value3`);

Service invoked in this style is also called Function. System will always take "$0" as the Service name, "$1" as the first argument of the function, "$2" as the second argument of the function, "$3" as the third argument of the function… So you should declare aliases in the "uses" statement as following:

%uses attribute1($1), attribute2($2), attribute3($3),

 

Script Syntax 2 – Statement

All Icwri statements must begin with a command (prefixed by character "%") and end with a semicolon (;). There are 2 syntaxes:

<command> <expression>;

Or

<command> <attribute>:<expression>;

The default command is "%do", which can be omitted. The "<attribute>" at the left side of colon is also called "Left Value". Following are steps to run a statement:

  1. Calculate the "<expression>".
  2. Assign the value of "<expression>" to the Left Value.
  3. Go to next step according to the command.

Following are samples of valid Left Values:

The "<expression>" can be a simple constant or attribute. It can also be a complex nested expression. Following are samples of valid expressions:

The commands used between “%begin” and “%end” statement are called Application Commands. There are 4 groups of Application Commands. The major usage of the Application Command is to control the execution flow.

1) Command "%do": Evaluate the expression and assignment then go to next step. Command "%do" can be omitted. Following are samples:

2) Commands "%if", "%elseif", "%else", and "%endif" are used to for branch choice. The branch choice can be nested. Following is a sample:

%if @totalSales<=@quota;
 @bonus:0;
 %if @totalSales < (@quota/2);
  !sys_printLine( `Very poor performance!` );
 %endif;
%elseif @totalSales > (@quota*2);
 @bonus: (@totalSales-@quota*2)*(@bonusRate*2) + @quota*@bonusRate;
%else;
 @bonus:(@totalSales-@quota)*@bonusRate;
%endif;

3) Commands "%loop" and "%endloop" are used to for loop execution. It can also be nested. Following is a sample:

%loop @v1<=5;
 !sys_printLine( `loop: @v1=` | @v1 );
%endloop @v1:@v1+1;

4) Command "%break" can be used to jump out of the end of blocks labeled by the "%endloop" and "%endif" statements. You can also use an expression following command "%break". For example, if you want to jump out of 2 blocks, you can use "%break 2".

Following is a sample showing how to break out of "%endif" and "%endloop".

%service !testCommands3;
%uses @v1;
%begin;
 @v1:1;
 %loop @v1<=5;
  !sys_printLine( `loop: @v1=` | @v1 );
  %if @v1=3;
   %break 2;
  %endif;
 %endloop @v1:@v1+1;
 !sys_printLine( `out: @v1=` | @v1 );
%end;

If there are no more blocks to break out, the "%break" command will end the service. It is like a "return" command in other languages. See following example:

%service !testCommands3A;
%uses @v1;
%begin;
 @v1:1;
 %loop @v1<=5;
  !sys_printLine( `loop: @v1=` | @v1 );
  %if @v1=3;
   %break 3;
  %endif;
 %endloop @v1:@v1+1;
 !sys_printLine( `out: @v1=` | @v1 );
%end;

4) Command "%return" will end the service and set the result value to "$?". See following example:

%service !add;
%uses @v1($1), @v2($2), @v($?);
%begin;
 %return @v1+@v2;
%end;

It is similar to following code:

%service !add;
%uses @v1($1), @v2($2), @v($?);
%begin;
 @v: @v1+@v2;
%end;

If you want to quit the whole script process, you can call the "!sys_exit" service.

 

Script Syntax 3 – Operator

There are many types of operators which can be used in the Icwri expression in a statement. The priorities of operators are different. For example, the multiplication operator "*" take precedence of addition operator "+". You can use parentheses () to change the priority. Following is table to describe all operators in the sequence of priority:

Operators Description
"\\" not (logical operator)
"**" power
"*", "/" multiplication, division
"+", "-" addition, subtraction
"|" concatenation (for 2 strings)
"=", ">", "<", ">=", "<=", "<>"
"==", "/="
comparison operators for digits
comparison operators for strings
"&&", "||", "^^" and, or, xor (logical operators)

Logical operators require logical values. Logical values include TRUE and FALSE. In Icwri, any number can be converted to logical value, and logical value can also be converted to a number. The conversion rule is as following:

For example "1+(2>3)" is a valid expression in Icwri script. The result is 0.

 

Demo Scripts - Bonus Plans

You can find this demo in "samples/LalaBonus.icw". It shows how to involve people with a little software programming knowledge to write business rules for an application system.

In the following “%serviceList” statement, “../config/IcwriSystem.lst” is specified as the service list.

%serviceList `../config/IcwriSystem.lst`;

The author of the script is Lucy, who is the CFO of a small company named "Lala". She wants to write the bonus plan for the company by herself. She chose Icwri script, which will be invoked by the financial software application system of her company.

The first plan is very simple. Any sales employees will get 15% of his/her total sales figure as the bonus. The code is as following:

%service !bonusPlan1;
%uses
 @bonusRate:0.15, @totalSales, #Input
 @bonus; #Output
%begin;
 @bonus:@totalSales*@bonusRate;
%end;

%service !testBonusPlan1;
%uses;
%begin;
 !bonusPlan1.@totalSales: !sys_inputLine(`Please input the total sales figure:`);
 !bonusPlan1();
 !sys_printLine( `The bonus is $` | !bonusPlan1.@bonus );
%end;

Following shows how to invoke the sample service:

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan1
Please input the total sales figure:
>> 10000
The bonus is $1500.00
$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan1
Please input the total sales figure:
>> 10000
The bonus is $1500.00

Then Lucy wanted to simplify the application. She rewrote the code with attribute alias. Following is the code:

%service !bonusPlan2;
%uses
 @bonusRate:0.15, @totalSales($1), #Input
 @bonus($?); #Output
%begin;
 @bonus:@totalSales*@bonusRate;
%end;

%service !testBonusPlan2;
%uses @n;
%begin;
 @n: !sys_inputLine(`Please input the total sales figure:`);
 !sys_printLine( `The bonus is $` | !bonusPlan2(@n) );
%end;

%service !testBonusPlan2A;
%uses @n;
%begin;
 @n: !sys_inputLine(`Please input the total sales figure:`);
 !bonusPlan2.@bonusRate: 0.2;
 !sys_printLine( `The bonus is $` | !bonusPlan2(@n) );
%end;

Service "!testBonusPlan2" uses the default bonus rate (15%). Service "!testBonusPlan2A" sets new bonus rate (20%). Following shows how to invoke the sample service:

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan2
Please input the total sales figure:
>> 10000
The bonus is $1500.00

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan2A
Please input the total sales figure:
>> 10000
The bonus is $2000.0

Then Lucy changed the bonus plan to a more reasonable one. If the total sales figure is less than his/her quota, he/she will not get any bonus. On the contrary, if his/her total sales figure doubles his quota, he/she will get double bonus. Following is the code.

%service !bonusPlan3;
%uses
 @bonusRate:0.15, @totalSales($1), @quota($2):10000, #Input
 @bonus($?); #Output
%begin;
 %if @totalSales<=@quota;
  @bonus:0;
  %if @totalSales < (@quota/2);
   !sys_printLine( `Very poor performance!` );
  %endif;
 %elseif @totalSales > (@quota*2);
  @bonus: (@totalSales-@quota*2)*(@bonusRate*2) + @quota*@bonusRate;
 %else;
  @bonus:(@totalSales-@quota)*@bonusRate;
 %endif;
%end;

%service !testBonusPlan3;
%uses @n;
%begin;
 @n: !sys_inputLine(`Please input the total sales figure:`);
 !sys_printLine( `The bonus is $` | !bonusPlan3(@n) );
%end;

%service !testBonusPlan3A;
%uses @n;
%begin;
 @n: !sys_inputLine( `Please input the total sales figure:`, `SWI` );
 !sys_printLine( `The bonus is $` | !bonusPlan3(@n), `SWI` );
%end;

Service "!testBonusPlan3" uses command line for input/output. Service "!testBonusPlan3A" uses GUI for input/output. Following shows how to invoke the sample service:

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan3
Please input the total sales figure:
>> 10000
The bonus is $0
$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan3
Please input the total sales figure:
>> 20000
The bonus is $1500.00
$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/LalaBonus.icw -s !testBonusPlan3
Please input the total sales figure:
>> 30000
The bonus is $4500.00

 

Run Icwri script From Java

If you want to call Icwri services in Java applications, the first step is to create an "IcwriContext" class with a specified Icwri Service List. Following is the sample code:

IcwriContext icwri = new IcwriContext();
icwri.builtFromFile("C:/Icwri/config/ShopApp.lst", null); //Service List is a file on disk

or

IcwriContext icwri = new IcwriContext();
icwri.builtFromUrl("http://www.lrsolution.com/icwri/ShopApp.lst", null); //Service List is from Internet

The second parameter of method "builtFromFile" and "builtFromUrl" is the encoding (character-set ID defined in Java).

Then you can load the target Icwri Service from the Icwri context, set attributes if required, then call the "run" method. The returned data is stored in an attribute with alias "$?" and other attributes used by the service.

Service svc= icwri.loadService("!buyBeer");
svc.setAttribute("@brandsToBuy", "Qingdao, Carlsberg");
svc.setAttribute("@moneyPay", 200);
svc.setAttribute("@priceLimit", 10);
svc.run();

Now it seems that all services should be defined in a file on disk or in a data stream from internet. If you want to call your dynamic script code directly in Java, you can define your service directly into the context. For example:

String serviceName= "!testSvc";
String code= "%service !testSvc; %uses; %begin; !sys_printLine( `Hello World!` ); %end;";
icwri= new IcwriContext();
icwri.builtFromFile("D:/Icwri/config/IcwriApp.lst", null);
icwri.defineDynamicService(serviceName, code);
icwri.loadService(serviceName).run();

If you want to run a service defined in a script file directly, use following code:

icwri= new IcwriContext();
icwri.builtFromScriptFile(scriptFile, encoding);
icwri.loadService(serviceName).run();

 

String, Object and Array Support

Icwri has similar services for strings as other programming languages. Please read "config/IcwriSystem.hlp" file to understand the services prefixed with “string_”. Following is the service list for string manipulations:

!string_length: @string($1), @result($?);
!string_snippet: @string($1), @startPosition($2), @length($3), @result($?);
!string_changeCase: @string($1), @toLower, @toUpper, @result($?);
!string_trim: @string($1), @result($?);
!string_compare: @string1($1), @string2($2), @ignoreCase, @result($?);
!string_find: @string($1), @find($2), @ifBackward, @ifStartWith, @ifEndWith, @position($?);
!string_match: @string($1), @match($2), @result($?);
!string_replace: @string($1), @replacePattern($2), @replacement($3), @result($?);
!string_getColumn: @string($1), @delimiter($2), @colNo($3), @colData($?), @beginPos, @len;

There is a demo service named "!learnString" to test system provided string services:

%service !learnString;
%uses @str1:`South Africa World Cup 2010`,
          @str2:` Cup `,
          @pattern:`.*\d\d\d\d`,
          @tmp;
%begin;
 !sys_printLine( `str1= '` | @str1 | `'` );
 !sys_printLine( `Length of str1=` | !string_length(@str1) );
 !sys_printLine( `Get a snippet of str1= '` | !string_snippet(@str1, 14, 9) | `'` );
 !string_changeCase.@toUpper =1;
 !sys_printLine( `toUpper of str1= '` | !string_changeCase(@str1) | `'` );

 @str2: !string_trim(@str2);
 !sys_printLine( `Test Trim, str2= '` | @str2 | `'` );

 @tmp: !string_compare(@str1, @str2);
 %if @tmp<0;
  !sys_printLine( `str1 < str2` );
 %elseif @tmp>0;
  !sys_printLine( `str1 > str2` );
 %else;
  !sys_printLine( `str1 = str2` );
 %endif;

 !sys_printLine( `Test Find, str2 position in str1= ` | !string_find(@str1, @str2) );

 @tmp: !string_compare(@str1, @pattern);
 %if @tmp>0;
  !sys_printLine( `str1 matches the pattern - ` | @pattern );
 %else;
  !sys_printLine( `str1 does not match the pattern - ` | @pattern );
 %endif;

 !sys_printLine( `Replace the year number in str1 to null - ` | !string_replace(@str1, `\d\d\d\d`, ``) );
%end;

Following shows how to invoke the service "!learnString":

# java lr.icwri.app.RunService -l /opt/icwri_0.361/config/IcwriApp.lst -s !learnString
str1= 'South Africa World Cup 2010'
Length of str1=27
Get a snippet of str1= 'World Cup'
toUpper of str1= 'South Africa World Cup 2010'
Test Trim, str2= 'Cup'
str1 > str2
Test Find, str2 position in str1= 20
str1 matches the pattern - .*\d\d\d\d
Replace the year number in str1 to null - South Africa World Cup

Icwri script has limited Object and Array support with system provided services. Developer can create an Object or Array in the system which means to register an Object or Array in the Icwri context. Developer can use this Object or Array until he/she deletes the Object or Array.

Developer can read/write properties of the Object. Object can be cloned. Icwri service list file "IcwriSystem.lst" and help file "IcwriSystem.hlp" show more details.

Following is a demo application using Object. It clones an object and adds/changes its properties.

%service !learnObject;
%uses @person1:`Person1`, @user1:`User1`;
%begin;
 !object_create(@person1);
 !object_setProperty(@person1, `name`, `Liu Rui`);
 !object_setProperty(@person1, `age`, 40);
 !object_setProperty(@person1, `job`, `engineer`);
 !object_clone(@person1, @user1);
 !object_setProperty(@user1, `job`, `developer`);
 !object_setProperty(@user1, `userID`, `liurui`);
 !sys_printLine( `Person1 name= ` | !object_getProperty(@person1, `name` ) );
 !sys_printLine( `Person1 age=  ` | !object_getProperty(@person1,  `age` ) );
 !sys_printLine( `Person1 job=  ` | !object_getProperty(@person1,  `job` ) );
 !sys_printLine( `User1 name=   ` | !object_getProperty(@user1,   `name` ) );
 !sys_printLine( `User1 age=    ` | !object_getProperty(@user1,    `age` ) );
 !sys_printLine( `User1 job=    ` | !object_getProperty(@user1,    `job` ) );
 !sys_printLine( `User1 userID= ` | !object_getProperty(@user1, `userID` ) );
%end;

Run this demo service "!learnObject" with following command:

$ java lr.icwri.app.RunService -l /opt/icwri_0.361/config/IcwriApp.lst -s !learnObject
Person1 name= Liu Rui
Person1 age=  40
Person1 job=  engineer
User1 name=   Liu Rui
User1 age=    40
User1 job=    developer
User1 userID= liurui

Developer can manipulate items in the Array. Icwri service list file "IcwriSystem.lst" and help file "IcwriSystem.hlp" show more details.

Following is a demo application using Array:

%service !learnArray;
%uses @array1:`array1`, @item, @size;
%begin;
 !array_create(@array1, 5);
 !array_setProperty(@array1, `owner`, `Liu Rui`);
 @size: !array_getQuantity(@array1);

 @item:1;
 %loop @item <= @size;
  !array_setItem(@array1, @item, `Item` | @item);
 %endloop @item: @item+1;

 !sys_printLine( `array1 owner= ` | !array_getProperty(@array1, `owner` ) );

 @item:1;
 %loop @item <= @size;
  !sys_printLine( `No.` | @item | `= ` | !array_getItem(@array1, @item ) );
 %endloop @item: @item+1;
%end;

Run this demo service "!learnArray" with following command:

$ java lr.icwri.app.RunService -l /opt/icwri_0.361 /config/IcwriApp.lst -s !learnArray
array1 owner= Liu Rui
No.1= Item1
No.2= Item2
No.3= Item3
No.4= Item4
No.5= Item5

 

Demo Scripts - Formatter Tools

You can find this demo in "samples/formatter.icw". It shows how to use Icwri as a text formatter tool.

Now we have a file (/opt/icwri_0.361/samples/WorldCup.lst) which is the list of countries which have hold the FIFA Football World Cup Games:

No.01 Uruguay 1930
No.02 Italy 1934
No.03 France 1938
No.04 Brazil 1950
No.05 Switzerland 1954
No.06 Sweden 1958
No.07 Chile 1962
No.08 England 1966
No.09 Mexico 1970
No.10 Germany 1974
No.11 Argentina 1978
No.12 Spain 1982
No.13 Mexico 1986
No.14 Italy 1990
No.15 United States 1994
No.16 France 1998
No.17 Korea & Japan 2002
No.18 Germany 2006
No.19 South Africa 2010

We want to manipulate this list to get our expected results.

Service “!readArray0” reads and writes the list without any change. Following is the code:

%service !readArray0;
%uses;
%begin;
 !array_read(`Array1`);
 !array_write(`Array1`);
%end;

Run service “!readArray0” with following command:

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray0 < /opt/icwri_0.361/samples/WorldCup.lst
No.01 Uruguay 1930
No.02 Italy 1934
No.03 France 1938
No.04 Brazil 1950
No.05 Switzerland 1954
No.06 Sweden 1958
No.07 Chile 1962
No.08 England 1966
No.09 Mexico 1970
No.10 Germany 1974
No.11 Argentina 1978
No.12 Spain 1982
No.13 Mexico 1986
No.14 Italy 1990
No.15 United States 1994
No.16 France 1998
No.17 Korea & Japan 2002
No.18 Germany 2006
No.19 South Africa 2010

Service “!readArray1” reads the list and writes the list without the first 2 lines and the last 1 line. Following is the code:

%service !readArray1;
%uses;
%begin;
 !array_read.@skipFirstLines:2;
 !array_read.@skipLastLines:1;
 !array_read(`Array1`);
 !array_write(`Array1`);
%end;

Run service “!readArray1” with following command:

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray1 < /opt/icwri_0.361/samples/WorldCup.lst
No.03 France 1938
No.04 Brazil 1950
No.05 Switzerland 1954
No.06 Sweden 1958
No.07 Chile 1962
No.08 England 1966
No.09 Mexico 1970
No.10 Germany 1974
No.11 Argentina 1978
No.12 Spain 1982
No.13 Mexico 1986
No.14 Italy 1990
No.15 United States 1994
No.16 France 1998
No.17 Korea & Japan 2002
No.18 Germany 2006

Service “!readArray2” reads the list and writes only the lines including Italy. Following is the code:

%service !readArray2;
%uses;
%begin;
 !array_read.@find:`Italy`;
 !array_read(`Array1`);
 !array_write(`Array1`);
%end;

Run service “!readArray2” with following command:

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray2 < /opt/icwri_0.361/samples/WorldCup.lst
No.02 Italy 1934
No.14 Italy 1990

Service “!readArray3” reads the list and writes the lines matching a regular expression “.*S.*n.*”. Following is the code:

%service !readArray3;
%uses;
%begin;
 !array_read.@match:`.*S.*n.*`;
 !array_read(`Array1`);
 !array_write(`Array1`);
%end;

Run service “!readArray3” with following command:

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray3 < /opt/icwri_0.361/samples/WorldCup.lst
No.05 Switzerland 1954
No.06 Sweden 1958
No.12 Spain 1982

Service “!readArray4” reads the list and writes the list without the first “No.nn” columns. Following is the code:

%service !readArray4;
%uses;
%begin;
 !array_read.@replacePattern:`^No\.\d\d`;
 !array_read.@replacement:``;
 !array_read(`Array1`);
 !array_write(`Array1`);
%end;

Run service “!readArray4” with following command:

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray4 < /opt/icwri_0.361/samples/WorldCup.lst
Uruguay 1930
Italy 1934
France 1938
Brazil 1950
Switzerland 1954
Sweden 1958
Chile 1962
England 1966
Mexico 1970
Germany 1974
Argentina 1978
Spain 1982
Mexico 1986
Italy 1990
United States 1994
France 1998
Korea & Japan 2002
Germany 2006
South Africa 2010

Service “!readArray5” reads and writes the list with only the country names in alphabetical order without duplication. Following is the code:

%service !readArray5;
%uses;
%begin;
 !array_read.@replacePattern:`^No\.\d\d`;
 !array_read.@replacement:``;
 !array_read(`Array1`);

 !array_read.@fromArray:`Array1`;
 !array_read.@replacePattern:`\d\d\d\d`;
 !array_read.@replacement:``;
 !array_read.@ifTrim:1;
 !array_read.@ifRemoveDuplication:1;
 !array_read.@sortMode:3;
 !array_read(`Array2`);

 !array_write(`Array2`);
%end;

Run service “!readArray5” with following command:

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray5 < /opt/icwri_0.361/samples/WorldCup.lst
Argentina
Brazil
Chile
England
France
Germany
Italy
Korea & Japan
Mexico
South Africa
Spain
Sweden
Switzerland
United States
Uruguay

Service “!readArray6” reads and writes the list with the country names moved at the first column in alphabetical order. Following is the code:

%service !readArray6;
%uses @num, @row, @rowData, @pos, @seq;
%begin;
 !array_read.@delimiter:` `;
 !array_read.@column:2;
 !array_read.@sortMode:3;
 !array_read(`Array1`);

 @num: !array_getSize(`Array1`);
 @row: 1;
 %loop @row<=@num;
  @rowData: !array_getItem(`Array1`, @row);
  @seq: !string_snippet(@rowData, 1, 5);
  !sys_printLine( !string_snippet(@rowData, 7, 999) | ` - ` | @seq );
 %endloop @row:@row+1;
%end;

Run service “!readArray6” with following command:

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !readArray6 < /opt/icwri_0.361/samples/WorldCup.lst
Argentina 1978 - No.11
Brazil 1950 - No.04
Chile 1962 - No.07
England 1966 - No.08
France 1938 - No.03
France 1998 - No.16
Germany 1974 - No.10
Germany 2006 - No.18
Italy 1934 - No.02
Italy 1990 - No.14
Korea & Japan 2002 - No.17
Mexico 1970 - No.09
Mexico 1986 - No.13
South Africa 2010 - No.19
Spain 1982 - No.12
Sweden 1958 - No.06
Switzerland 1954 - No.05
United States 1994 - No.15
Uruguay 1930 - No.01

The next sample is an advanced one. It is for a real case. I have just completed a stress test for IBM CICS applications. I got following raw test data:

SAPSIREG,65
MCOM01,134
SAPS2001,136
MCOM01,95
SAPS2001,96
MCOM01,151
MCOM01,82
SAPS2001,83
SAPS2001,175
MCOM01,168
MCOM01,149
SAPS2001,169
SAPS2001,150
MCOM01,199
MCOM01,210
SAPS2001,201
SAPS2001,212
MCOM01,253
SAPS2001,255
MCOM01,239
MCOM01,225
SAPS2001,240
SAPS2001,226
MCOM01,240
SAPS2001,241
... ...
... ...

The first column is the CICS program name, and the second column is the time used (in milliseconds) to run this CICS program. Now I want to make a report for all tested programs to show numbers of running, average running time, maximum running time, and minimum running time.

The UNIX tool “awk” is a wonderful to do this calculation. However I can also write an Icwri script to do this. Icwri script can run on any operating systems. Following shows the test result. You can study the code by yourself.

$ java lr.icwri.app.RunScript -f /opt/icwri_0.361/samples/formatter.icw -s !analyzeData1 < /opt/icwri_0.361/samples/TestData
ProgramNumAverageMinMax
MCOM012511224.21822729
SAPSIREG1656565
SAPS20012491227.41832730

 

References

Generic considerations of Icwri script:

 

Exception Types of lr.icwri.app.IcwriException:

ID Definition Description
0 ET_UNKNOWN

 

1 ET_ENVIRONMENT  
2 ET_COMMANDLINE Command syntax error. The syntax of command line is:\njava lr.icwri.app.Main [-t {file|url}] -l <Service list file/url> -s <Service> [-v <log level>]
3 ET_CANNOT_ACCESS_FILE

File not found or access security problem

4 ET_CANNOT_ACCESS_URL Invalid URL
5 ET_CANNOT_ACCESS_INPUT_STREAM  
6 ET_INVALID_ENCODING Invalid encoding (character-set ID defined in Java)
1000 ET_INVALID_SERVICE_LIST  
1001 ET_INVALID_SERVICE_NAME Service name must be prefixed with character "!"
1002 ET_INVALID_ATTR_NAME Attribute name must be prefixed with character "@"
1003 ET_INVALID_ALIAS_NAME Alias name must be prefixed with character "$"
1004 ET_INVALID_LINE_IN_SERVICE_LIST The syntax of service registry line is:
<Service name>, {file|url|java}, path
1005 ET_INVALID_SERVICE_TYPE

Service types in the service list can only be "file", "url", or "java"

1006 ET_INVALID_CLASSPATH The "classpath" defined in the service list is invalid
1007 ET_INVALID_USES

The format of "%uses" statement is invalid

1008 ET_NO_SUCH_SERVICE

The service is not defined in service list

1009 ET_SERVICE_NO_SUCH_ATTR

The attribute is not defined in the "%uses" statement of the service

1010 ET_SERVICE_NO_SUCH_ALIAS

The alias of the attribute is not defined in the "%uses" statement of the service

1011 ET_DEF_SERVICE_LIST_FIRST The script file should define "service list" before any services
2000 ET_SCRIPT_FORMAT_INVILID  
2001 ET_SCRIPT_FORMAT_INVILID1 Lack of "%endif" or "%endloop", or invalid "%break" statement
2002 ET_SCRIPT_FORMAT_INVILID2 Lack of "%endif" or "%endloop", or invalid "%break" statement
2003 ET_SCRIPT_FORMAT_INVILID3 Lack of "%endif" or "%endloop", or invalid "%break" statement
2010 ET_STATEMENT_NOT_MATCH The "%if" and "%endif" are not matched. Or the "%loop" and "%endloop" are not matched
2011 ET_SERVICE_NOT_DEFINED_CORRECTLY The commands sequence should be "%service", "%uses", "%begin", "%end"
3000 ET_COMMAND_INVILID Invalid command
3001 ET_BREAK_LEVEL_INVILID The level of the "%break" command is invalid
3002 ET_NO_MATCH_BRACKETS There is no matched brackets
3003 ET_LEFT_VALUE_INVILID The left value should be an attribute
3004 ET_STRING_INVILID

The string in Icwri script should be enclosed with backticks (`)

3005 ET_EXPRESSION_INVILID The expression is invalid. For example there is invalid operator
3006 ET_OPERATOR_INVILID The operator is invalid
3007 ET_CONSTANT_INVILID The format of the constant (number or string) is invalid
3008 ET_MULTIPLE_SERVICE_LINE There are more than 1 "%service" statement. Or service is not ended by "%end" statement properly
3009 ET_MULTIPLE_USES_LINE There are more than 1 "%uses" statement. Or service is not ended by "%end" statement properly
3010 ET_MULTIPLE_BEGIN_LINE There are more than 1 "%begin" statement. Or service is not ended by "%end" statement properly
9000 ET_VT_ARRAY_OUTOF_BOUNDS Array item must larger or equal to 0
10000 ET_APP  
10001 ET_NO_SUCH_OBJECT Object not found
10002 ET_ARRAY_QUANTITY_INVALID  
10003 ET_ARRAY_ITEM_OUTOF_RANGE  
10004 ET_CANNOT_READ_FROM_SYSIN  
10005 ET_CANNOT_WRITE_TO_SYSOUT  
10006 ET_INDEX_OUTOF_RANGE  

 

Thanks for Your Interest in Icwri

Coding, testing, helping to answer questions and making documents are all appreciated. Welcome to contact liurui@lrsolution.com to report defects and tell your suggestions.

-- Liu Rui