In this article you will learn about:
#hello world
driver hello:
import
con := $lib.console;
process
con.print ("Hello World!");
return;
Next code fragment represents a very symple program written in EVE language. Let's identify the main syntaxtic elements and pubctuation using this example:
# Progra example written in EVE
+-----------------------------------------
| a driver can receive parameters |
+----------------------------------------+
driver syntax_elements(Integer p1, p2):
** start declaration region
globals
Integer @v1, @v2;
** use a system library
import
con := $lib.console;
** define two driver functions
functions
Integer add(Integer p1, p2) => (p1+p2);
Integer sub(Integer p1, p2) => (p1-p2);
** define executable region
process
con.print ("param1:#p1, #p2");
@v1 := add(p1, p2);
@v2 := sub(p1, p2);
con.print ("result: @v1");
con.print ("result: @v2");
return;
# comments in EVE language
+-------------------------------
| New style boxed comments |
+------------------------------+
driver comment_demo:
global Integer a = 0;
*******************************
** old style boxed comments **
*******************************
process
** Next we use expression comments:
a := a + 1 /* *(a - 1) */ -1;
/* expression comments are similar to C++
comments. we use expression comments
for commenting out code for debug */
return; // end of line comment
The name of identifiers in EVE can have a length of 30 characters. A name starts with lowercase letters (a..z) or capital letters (A..Z) followed by one or more characters or numbers. No special characters or spaces are permitted in the name except underscore ("_"). An identifier can contain underscore and can start with underscore but it can not end with underscore and can not use two consecutive underscores.
These are valid identifiers
x, y, z a1,a2,a3 thisIsOK this_is_ok _this_is_valid
These are invalid identifiers
1st not_valid_ _not_valid_
A sigil is a special character prefix that is used to define an identifier. We use sigil to improve code readability but also to add extra functionality to specific identifiers that are not regular. EVE is using following sigils to define special kind of variables or identifiers:
in scope variable | |
* | variable arguments |
$ | global constants |
@ | global variables |
. | public variables |
_ | static variables |
variable | Description |
---|---|
@object | current instance of a class, current object |
@result | default result of a routine when a name is not specified |
@error | current exception object of type Exception |
In EVE you can define global variables. These are primitive values or references to objects. A global variable is represented by an identifier, and is pair-up with a data type that must pe specified before the identifier name, like in Java.
Global variables can have an initial value that is establish using initial value operator "=" and then can be modified during the program execution using modifiers like: { :=, ::, +=, -= ... } in assignment statements.
A syntax pattern is a pseudo-code example, not a valid EVE program. We use EVE patterns in this document to explain the syntax, but then we also create one or more examples.
# design pattern
** define a type using definition symbol ":"
type Type_name: super_type {parameters};
** establish several variables
globals
** use type to define a variable without initialization
Type_name @var_name;
** declare variable with specific value and type
Type_name @var_name = value;
** define multiple variables with same initial value
Type_name @var_name1 = @var_name2 ...= value;
** multiple variables with diverse initial values
Type_name @var_name1 =value1, @var_name2 = value2;
Usually the exemples are complette programs but sometimes just a fragment. Most of the examples that can be executed are stored also in GitHub document. However it is possible the one in GitHub to be a bit different then the one in documentation.
** define global variables
globals
** two integer variables
Integer @a = 0;
Integer @b = 0;
** one double variable
Double @d = 0.5;
** multiple Double numbers
Double @x, @y, @z;
The initial value can be establish using the initializer that is "=". This symbol can use only literals and no expressions. It is not able to execute the right operator. That is the initial value can be a constant literal. When used in this way the right side literal value must match the type of the declaration.
When a variable is specified, and the initializer "=" is missing the variable takes default zero value. This value is different for each data type. For example zero value for Integers = 0 for Double = 0.0 and for String = "" (empty string). Compozite data types are initialized to "empty", that is a reserved value equivalent to "∅" used in set theory.
Operator "=" is used to create an expression. That means you can initialize multiple variables using a single declaration. This is different than assignment ":=" or clone "::" that create a statement and not an expression.
# define global variables
globals
** two integer numbers
Integer a = b = 0;
Double x = y = z = 0.5;
An expression is a syntax element that can be evaluated using mathematical rules and principles. Expressions are created using identifiers, operators, functions and constant literals.
** simple expressions in print statement
driver expression_demo:
import console.(*)
process:
print 10;
write "this is a test";
** complex expressions can use ()
print (10 + 10 + 15); // numeric expression
print (10 > 5) or (2 < 3); // logical expression
** list of expressions are enclosed in ()
print (1, 2, 3); // expect: 1 2 3
print (10, 11, 12); // expect: 10 11 12
** using write to: avoid new line and print
write (1,2);
write (3,4);
** now create a new line and output the text
print; // 1234
return;
To assign result of an expression to a variable you can use assign operator: ":=". This operator has a strange behavior that you must understand to avoid unintended side-effects. When a single variable is used as an expression, the operator transfer a value "by sharing" a reference, so it does not "copy" the value but the reference to that value.
#pseudo-code fragment
identifier := variable_name; // share a reference to global
identifier := function_name; // share a reference to function
identifier := literal; // mutate value / initialize
identifier := expression; // mutate value / initialize
identifier := function_name(); // mutate value / reset value
by value:
To make a clone/copy of an object value you must use clone operator that is (::) instead of (:=). This will transfer a value not a reference. After clonning, we can modify one value without affecting the other.
// making a clone
variable_name :: reference_name;
A ternary operator is the "if" keyword. This keyword has actually two roles in EVE. It can be used to create a conditional statement or an expression. It can be used to return a value or other depending on one or several logical expressions.
variable_name := (value1 if condition else value2); variable_name := (value1 if condition1 else value 2 if condition2 else value3);
global test = True; ... expect(True if test else False); // will pass ...
One statement can be declarative or imperative.
The most simple statements are definitly the declaration statements:
driver assign_demo:
locals
** initialization statements
Integer a = 2;
Double b:= a + 0.5;
process
** verification statements
expect a == 2;
expect b == 2.5;
return;
One expression can span multiple lines.
# multiple line demo
driver multi_line:
locals
Integer x;
Hash a;
process
** multi-row expression
x := 1 +
2 +
(3 + 4)
+ 5;
** multi-row literal
a := {
(1:2),
(3:4),
(5:6)
};
return;
Computer was invented in England during WW2 so, we prefer English words even though a computer language could be created using keywords from other spoken languages. EVE is using about 50 English reserved words. You can not use these words as identifiers.
abort | alias | alter | analyze |
append | apply | ascending | augment |
begin | type | break | by |
case | class | clone | close |
commit | constant | create | cursor |
defer | delete | descendin | discard |
else | end | error | exit |
expect | fail | feature | fetch |
for | from | function | group |
halt | if | import | inherit |
insert | into | item | join |
limit | loop | method | object |
offset | open | order | orif |
over | package | pass | |
process | raise | read | record |
recover | release | remove | repeat |
reset | rest | result | resume |
retry | return | rollback | routine |
solve | select | resolve | skip |
step | store | switch | task |
then | trial | try | type |
update | use | global | view |
where | while | with | write |
Keyword | Description |
---|---|
imports | define import region |
types | define data-type or sub-type |
globals | declare module variables (start with "." if is public) |
functions | start a declaration region for named expression |
locals | start a declaration region for local variables |
Keyword | Description |
---|---|
module | define a program file (module-name = file-name) |
class | define a composite data type for object oriented programming |
create | begin constructor region for a classes |
remove | define object disposal region, executed when object is out of scope |
feature | define a design pattern that can be enabled by a class |
augment | define an augment for an existing class |
routine | define a named block of code belonging to a module |
method | define a named block of code belonging to a class |
process | begin executable region for a routine and constructor for a class |
recover | define a recover region for methods |
release | define a finalization region for routines |
return | terminate a routine/function or a class declaration |
Keyword | Description |
---|---|
locals | create a local block scope for next block of code |
if | conditional operator |
else | alternative path for { when, case, while } statements |
switch | multi-path case (variable) selector |
case | define a pathway in multi-case methods |
loop | unconditional repetitive block |
while | conditional repetition block |
for | visitor iteration loop |
end | block finalization keyword |
with | define local scope/ establish qualifier suppression block for records |
Keyword | Description |
---|---|
is | check data type | reference identity |
in | check element is belonging to a list/set |
not | logical NOT operator |
and | logical AND operator |
or | logical OR operator |
xor | logical XOR operator |
Keyword | Description |
---|---|
exit | silent stop a routine and return control to the caller |
abort | stop current process and return control to the caller |
halt | stop current program and create unrecoverable error (panic) |
over | stop current process and then execute: release & report |
raise | create exception with error code > 0 (recoverable) |
break | early terminate execution of a repetitive block |
repeat | jump over all other statements to the end of block |
fail | create standard work-flow error if condition is true |
pass | create standard unexpected error if condition is true |
retry | work-flow jump backwards to specified step |
apply | start subroutine execution in syncrhonous mode |
begin | start subroutine execution in asyncrhonous mode |
solve | execute one aspect in synchronous mode |
defer | start execution for one aspect in asynchronous mode |
yield | interrupt current execution and wait for deferred processes |
resume | used in work-flow handlers to continue with next step |
In the syntax description "..." represent content and "_,_,_," represents a sequence of elements. In descriptions vertical bar "|" represents second alternative. Some operators can have multiple purposes depending on the context and data types.
Symbol | Description |
---|---|
**...** | Single line separator |
/*...*/ | Outline comments | Expression comments |
#(....) | String interpolation (placeholder) for operator "?" |
Symbol | Description | (_,_,_) | Expression | Tuple literal |
---|---|
[_,_,_] | Range | Index | List literals |
{_,_,_} | Ordinal type | Set of values | Hash type | Generic types |
Symbol | Description | '...' | Limited capacity ASCII string |
---|---|
"..." | Variable capacity Unicode: UTF8 |
EVE us ASCII symbols for operators. One operator can be single character or two characters with no space between tem. Sometimes we use the same character twice for example "==" or ">>". This technique is known in many other computer languages.
Single symbol:
# , : . ; = ~ ? % ^ * - + / < > ~ & | ^ ! @ $
Two symbols:
** // == != =+ <> << >> => >= <= <: .. .! !. !!
Modifiers:
++ -- :: := += -= *= /= %= ^= &= |= <+ +>
Delimiters:
"_" '_' `_` (...) [...] {...} #(...)
EVE use al single simbols usually found on your keyboward.
Symbol | Description |
---|---|
! | Negation symbol |
? | String template find & replace |
# | Title at beggining of line | Digit in string pattern |
$ | Environment variable sigil |
@ | System variable sigil |
; | Statement separator | End of statement |
: | Define type, routine, class or block | Pair-up/binding operator (a:b) |
= | Setup initial value for variables or parameters |
~ | Check if two variables have same type |
. | Decimal separator | Prefix public member | Member qualifier |
, | Enumeration for elements | complex expression |
* | Variable arguments | Multiplication |
| | Used in set builders | Set union "∪" |
& | String concatenation | Set intersection "∩" |
Eve use two symbols to create supplementary operators.
Symbol | Description |
---|---|
** | Single line comment |
// | End of line comment |
.. | Slice [n..m] | Domain [n..m] or Range (n..m) |
.! | Domain/Range: exclude upper limit |
!. | Domain/Range: exclude lower limit |
!! | Domain/Range: exclude both limits |
=+ | Outer join operator used in data "select" statement |
<: | Define sub-type for a class or super-type |
:> | Numeric data conversion or convert a subtype into a supertipe. |
<+ | Append to the end of a collection |
+> | Append to the beginning of a collection |
<< | Shift ordered collection to left with n: X := C << n |
>> | Shift ordered collection to right with n: Y := C >> n |
:= | Assign value of expression to a variable. |
Symbol | Description |
---|---|
+ | Concatenate two strings as they are without trim |
- | Concatenate two strings after trimming to one space |
/ | Concatenate two strings with "/" separator and de-duplicate "//" |
\ | Concatenate two strings with "\" separator and de-duplicate "\\" |
. | Concatenate path or URL strings with a symbol and de-duplicate "//" |
Symbol | Description |
---|---|
* | Numeric multiplication | Scalar operator |
/ | Numeric division |
% | Reminder operator | Scalar operator |
+ | Numeric addition | String concatenation | Set union |
- | Numeric subtraction | String concatenation | Set difference |
EVE use two symbols to create a additional operators.
Symbol | Description |
---|---|
== | Equal | deep comparison |
!= | Different value | (deep comparison) |
> | Greater than value |
< | Less than value |
>= | Greater than or equal to values |
<= | Less than or equal to values |
Each modifier is created with pattern "x=" where x is a single symbol:
symbol | meaning |
---|---|
:= | Assign by reference | shallow assignment |
:: | Assign by copy | clone assignment |
+= | Increment value |
-= | Decrement value |
*= | Multiplication modifier |
/= | Real division modifier |
%= | Modulo modifier |
In following table: A, B, C are collections and x is a member:
Operator | Result | Description |
---|---|---|
A + B | list | Simple concatenation, use like L := A + B |
A - B | set/list | Simple difference, use like L := A - B |
A || B | set | Union A with B: "∪" use like C : = A | B |
A && B | set | Intersect A with B: "∩" use like C := A & B |
A -- B | list/set | Symmetric difference, use like C := A -- B |
A ++ B | list/set | Concatenate two lists use like L := A ++ B |
A <= B | logic | verify if A is subset of B: In math: ⊂ |
A >= B | logic | verify if B is subset of A: In math: ⊃ |
C <+ x | list | append element x to C at the end |
C +> x | list | append element x to C at the beginning |
S += x | set | append element x to S |
S -= x | set | remove element x from set S |
These operators are expected logical values T = True, F = False
Symbol | Description |
---|---|
if | conditional operator |
is | check element is of Type or same reference (object) |
is not | check element is not of Type or different references (objects) |
in | logic belong to: instead of "∈" |
not in | logic not belong to: instead of "!∈" |
not | logic NOT (negation) |
and | logic AND (intersection) |
or | logic OR (union) |
xor | logic Exclusive OR |
Table of truth for logical operators:
A | B | A and B | A or B | A xor B |
---|---|---|---|---|
True | True | True | True | False |
True | False | False | True | True |
False | True | False | True | True |
False | False | False | False | False |
These operators are working for natural numbers ≥ 0
symbol | description |
---|---|
~ | bitwise NOT (unary) |
& | bitwise AND |
| | bitwise OR |
^ | bitwise XOR |
<< | shift bits to left |
>> | shift bits to right |
Binary operators
A | B | A & B | A | B | A ^ B |
---|---|---|---|---|
00 | 00 | 00 | 00 | 00 |
01 | 00 | 00 | 01 | 01 |
11 | 01 | 01 | 11 | 10 |
10 | 11 | 10 | 11 | 01 |
11 | 11 | 11 | 11 | 00 |
Unary operators
A | ~A | A << 1 | A >> 1 |
---|---|---|---|
0000 | 1111 | 0000 | 0000 |
1111 | 0000 | 1110 | 0111 |
0111 | 1000 | 1110 | 0011 |
0110 | 1001 | 1100 | 0011 |
For printing output using a format we use operator as that is the "quick format" operator. We can use system constant templlated that are available for making different formats for different data types. This operator is a bit smarter than the "?" operator that we can use for "string templates".
Constant | Value |
---|---|
YDM | YYYY/DD/MM |
DMY | DD/MM/YYYY |
MDY | MM/DD/YYYY |
Constant | Value |
---|---|
T24 | HH:MM:SS,MS |
T12 | HH:MM:SSpm,MS | HH:MM:SSam,MS |
Constant | Value |
---|---|
EUR | ,. |
USA | ., |
Read next: Structure