A list is a consecutive sequence of elements having a dynamic capacity.
variable
List[elementType] list_name; // new empty list of "elementType"
List list_name := [value, ...]; // new list with type inferrence
# full type declarations
variable
List[Integer] n_list;
List[Object ] o_list;
List[String ] s_list;
list literals
Literals can be used for initialization of variables:
# initialized list with type inference
variable
List c_list = ['a', 'b', 'c'];
List n_list = [1, 2, 3];
Literals can be used in assign expressions:
# Defer initialization
routine main:
** define empty list if native types
List[Integer] c_list;
process
** initialize list using ":=" assign
c_list := [1,2,3];
return;
In mathematics a set is an abstract data structure that can store certain values, without any particular order, and no repeated values. Sets are fast to search, add or remove elements from. However, you have to know the element value in order to search for it or to remove it from the set.
declaration
variable
Set[type] set_name = {}; //empty Set but not Null
Empty set
An empty set is represented like this: {} and can be assigned to a set if you wish to remove all elements of the set. A set that is not initialized is Null. Empty set allocated but not Null. It is a difference.
Set restrictions
Mutability
A set can be modified during run-time using operators.
#using a set
routine main:
Set[Integer] my_set = {0,2,3}; //initialized set of integers
process
** append element 1
my_set <+ 1;
expect my_set == {0,1,2,3};
** modify all elements
my_set[*] := 0;
expect my_set == {0,0,0,0};
** remove all elements
my_set := {};
expect my_set == {};
return;
Use union operator | combine two sets.
# combine two sets using "|" = (or)
routine main:
Set first = {0,1,2,3,4,5,6,7,8,9};
Set[Integer] second; // Null set
process
store second := first | {0,1,2,10}; // create set
expect second == {0,1,2,3,4,5,6,7,8,9,10};
return;
Intersect operator & find common elements:
# Create intersection using &=(and)
routine main:
Set test; // Null set
process
store test := {1,2,3,4} & {3,4,5};
print test; // {3,4}
return;
Note: Operators "|" and "&" are overloaded betwise operators
It is also called "hash-map" due to similar letter H representing a connection between two columns: the key column and value column. Collections are ordered by key. This helps to find elements fast using a binary search. That's the idea, so in Python these collections are called Dictionaries.
# define some hash-map variables
variable
Map[String:String] mapName; // define map with string:key and value
Map m = {(key:value), ...}; // use type inference to create a map
routine main:
Map[String,Integer] table; // Null table (require initialization)
process
table := {('one':1), ('two':2)}; //initialize table
return;
In EVE There are two types of strings. Single quoted and double quoted strings. They are using different internal representation: Single quoted strings are ASCII strings while double quoted string is called "Text" and has UTF8 internal encoding. Single quoted strings has a limited capacity. Double quoted strings can store multiple lines of text and it has unlimited capacity.
String can be initialized with a constant literal using single quotes or double quotes. It is an error to deglare string and initialize with the double quotes and also is wrong to declare Text and initialize with single quotes.
# define some hash-map variables
variable
String strName; // define Null string with default capacity
String(capacity) lmString; // define a limited capacity string
Text text_name; // define Null text with unrestricted capacity
# examples of strings
variable
String(100) short_string = ''; //this string can hold 100 symbols
String string_name = ''; //default capacity 256 ASCII symbols
Text text_name = ""; //variable capacity Unicode string
In EVE strings are mutable. If you use ":=" the string object is replaced. If you use a modifiers:"<+" the double quoted string resized automatically. For single quoted strings, if the capacity is over the limit you will get an error: "capacity overflow".
# working with strings
routine test_string():
String str = 'First value'; //mutable string
String ref = 'First value'; //mutable string
process
expect (str == ref); // same value
expect (str is not ref); // different locations
** assign := work by reference not by value
ref := str; // reset ref
expect (str == ref); // same value
expect (str is ref); // same reference
** if we modify "str" then "ref" will appear modified
str <+ ":"; // mutate string "str"
expect str == 'First value:'; // modified
expect ref == "First value:"; // also modified
expect str is ref; // the reference is holding
** if we recreate str, reference is reset
str := 'First value:'; // new string location
expect str == ref; // same value
expect str is not ref; // different location
** ref is pointing to a different location
ref := 'New value:'
print ref; // New value: (modified)
print str; // First value: (initial value)
return;
Note:
# compare strings
expect('this' == 'this'); // true (same value)
expect("this" == 'this'); // true (same value)
expect(' this' != 'this'); // true (not same value)
expect("this " != "this"); // true (not same value)
We can test if a string is Null using "is Null" expression.
routine main:
String str; //Null string (not initialized)
String btr = ''; //Not Null (default capacity)
process
** null string
expect (str == Null);
expect (str != '');
expect (str != "");
** initialized string
expect (btr is not Null);
expect (btr == "");
expect (btr == '');
return;
Text can contain multiple lines separated with end of line character. A text use Unicode symbols and is optimized for faster search of internal words and symbols. Text is iterable collection, each item is a smaller Text. Default separation is the end of line.
Literal
A text literal can be defined on multiple lines and will preserve the end of line but will cut the indentation. Text literal is enclosed in double quotes. "..." and it may contain symbol "'" without escape. Double quoted Symbol (") must be escaped using notation (\").
# declaration of a text literal
routine main:
Text my_text;
process
my_text:=
"Opportunity is missed by most people
because it is dressed in overalls
and looks like work.";
print (my_text);
return;
Output:
Oportunity is missed by most people because it is dressed in overalls and looks like work.
Unicode
The Unicode is a standard for representation of writing for all human languages. An Unicode string is a set of code points using symbols from universal character set (UCS). Unicode is more difficult to represent then ASCII. There are many encoding techniques available. Java uses UTF-16. We will probably use UTF-8 to be more efficient.
See also: wikipedia ucs, unicode characters
routine main:
Text us = "I can write Greek: \αβγδ\.";
process
print (us);
return;
I can write Greek: "αβγδ".
To edit source code containing Unicode literals one must use a specific font and UTF-8 source files. The preferred font for EVE programming is "DejaVu Sans Mono".
Exception is interrupting the current logical flow and jump to the recover region in current section or parent section. In EVE all exceptions are considered errors.
The exception is a variable of type Object that is created when exception is raised and is available in the recover block. System variable @error contains several members that are fill-in by the EVE program when exception is created:
** system exception type
type .Exception = {
Integer code
,String message
,String routine_name
,String module_name
,String line_number
} <: Object;
** system variables for last error is predefined
variable
Exception: @error;
Exceptions can be system exceptions or user defined exceptions.
system exception System exceptions are predefined and created during the program execution when there is a "run-time error" and program can not continue.
There are two alternative statements to create user defined exceptions.
** raise exception
when condition do
raise (code,"message");
done;
** conditional
raise (code,"message") if condition;
Recover: region define an "exception handling region" for a routine.
In this region developer can use control statements like "switch","case" to analyze the #Error. Developer can decide to stop the program, print a message and resume the program using resume keyword.
routine main:
Double a = 0.00;
process
a := 1/0;
recover
print (#error.message);
return;
error: numeric division by zero.
The expect statement check a condition and raise an error if condition is false. Error message is default: "Unexpected error in line: N".
** precondition
expect condition;
** equivalent
raise ("Unexpected error in line \n" ? @error.line_number ) if condition;
** example of collection iteration
routine test():
List this = ['a','b','c','d','e'];
Integer i = 0;
Symbol e;
process
while i & this.length() loop
e := this[i];
i := i + 1;
if e >= 'c' then
write e;
if e is not this.tail then write ',';
end if;
else
print ('i = #s' ? i);
end loop;
return;
Read next: Control Flow