Now let's try to write a simple script.
First of all let's discuss what is ELENAVM script. Any ELENA source code is compiled into bytes codes (ecodes) and interpreted by a virtual machine (ELENAVM). It is the case even for a stand-alone application. So ecodes could be considered as a low level code and objects written in ELENA as a high level one. But above them there is another layer - ELENAVM inline script. It is in fact set of instructions how to assemble the objects in the virtual machine memory. With it help we could interact with ELENAVM directly. And finally we could add another layer which we could call ELENA script - it is a grammar rules how to generate ELENAVM inline script basing on a user defined syntax (DSA rules).
+++++++++++++++ + ELENA + + script + +++++++++++++++ + ELENAVM + + inline + + script + +++++++++++++++ + ELENA + + source code + +++++++++++++++ + ecodes + +++++++++++++++ + native code + +++++++++++++++
The simplest way to work with ELENAVM is to call a VM terminal - ELT.
First of all let's start VM:
-Ninline @config win32_vm_console2 @start
(command "-Ninline" executes ELENAVM inline script directly without using any grammar; @config loads the project template; @start starts VM)
Now we could directly print the welcome message:
-Ninline &nil 'program'output "Hello World" ^write
Let's try to understand how it works. To print the message we have to load 'program'output symbol and a string constant into the stack and then send a message (the similar we did in the previous tutorial). A symbol call expects a parameter in the stack (or nil if it is not required), that's why we put &nil symbol first (note: "&" symbol indicates a constant and therefore it is not a call but writing into the stack). Then the literal constant follows (writing into the stack as well). Now we have a two objects in VM stack - 'program'output (actually sys'io'consoleoutput) and std'basic'wideliteral - and can invoke a message (the message is sent to the previous stack item with the current one as a parameter) with a command ^ write. After the message is executed the parameter is removed from the stack.
Alternatively we could provide a grammar rules to parse a user defined script (ELENA script). Let's start with defining a simple context free grammar rules (only aA, a, A, AB and $eps rules are allowed).
-mcf start ::= "?" print; print ::= $literal;
(Note: $literal is a terminal mask accepting any literal constant)
Then we need a DSA rule to build proper inline script.
print => &nil 'program'output $terminal $body ^write;
(Note: $body is place holder where appropriate rule content is inserted - in our case it is a literal constant, $terminal defines the place where the parsed value should be inserted ).
Now let's end the CF grammar definition mode
Now try simple expression:
? "Hello World!!"
To see how script is translated into the VM instructions let's turn on tracking mode
And repeat the command:
? "Hello World!!"
We will see the code similar to our previous one:
@push $elena'nil @call 'program'output @push "Hello World!!" @send write
Let's turn the tracking off
The script engine can be used to execute programs as well.
First let's provide the path to our module:
-Ninline @use "..\examples\helloworld"
And now let's execute it:
-Ninline &nil helloworld'program &nil ^eval
(Note: the program should be already compiled)
Our inline script is the same as a previous one except that we do not need a parameter that's why nil is used second time as well.