1. Easy Language
1.1. What is the Easy Language ?
The EZ (Easy) language is a simple yet powerful language close to C++. The source code of the language
is translated to C++ and then compiled by a C++ compiler. The aim of the language is to simplify the
writing of algorithms and the annoyances of C++.
1.2. Language definition
1.2.1. Types of the Language ?
- bool for boolean values
- int for (C int)
- nat for (C unsigned int)
- int16 for (C int16_t)
- int32 for (C int or int32_t)
- int64 for (C int64_t)
- nat16 for (C uint16_t)
- nat32 for (C unsigned int or uint32_t)
- nat64 for (C uint64_t)
- real (float or double depending on compilation options)
- char
- string
- class for used-defined structures
- array<T> [ x1 .. y1 ] for 1D array of fixed size
- grid<T>[ x1 .. y1 ][ x2 .. y2 ] for 2D array of fixed size
- mesh<T> [ x1 .. y1 ][ x2 .. y2 ][ x3 .. y3 ] for 3D array of fixed size
- vector<T> for vector of variable size
- matrix<T> for 2D array of variable size
- volume<T> for 3D array of variable size
- stack<T>
- set<T>
- queue<T>
- map<T1,T2>
- text_file
- binary_file
Each type has built-in methods, for exemple in the case of integers :
- is_even()
- is_odd()
- is_multiple_of(x)
- has_divisor(x)
- sqrt() for square root to nearest integer
- min_value() smallest value that can represent an integer
- max_value() biggest value that can represent an integer
- to_boolean()
- to_character()
- to_real()
- to_string()
for strings :
- to_boolean()
- to_character()
- to_integer()
- to_real()
- substring( pbegin is integer, pend is integer)
- size()
- starts_with(s is string)
- ends_with(s is string)
- contains(s is string)
for vectors :
- first()
- last()
- reverse()
- fill(value)
- size()
- sort()
- sort(field)
- contains(value)
1.2.1.a Variables definition
We use the keyword var to introduce a list of variables
// definition of a simple variable
var int n
// initialization
var int x = 1, y, z = 2
var string s = "hello"
// ------------------------------------------------------------------
// containers
// ------------------------------------------------------------------
// definition of a vector
var vector<int> v
// definition of a vector of size 10 with first three elements
// defined
var vector<int> v(10) = { 1, 2, 3 }
// definition of two arrays that range from -3 to +3
var array<int>[ -3 : 3 ] tab1, tab2
1.2.2. Instructions
For the sake of simplicity, the following rules must be respected:
- there is one instruction per line and the new line marks the end of the instruction
- every variable/type/constant/subprogram used must be defined first
The main instructions are the following:
if
if x < 1 then
println "x < 1"
elsif x < 10 then
println "1 <= x < 10"
else
println "x >= 10"
end if
on do
// on <condition> do <simple-instruction>
on x < 1 do return false
while
var int i = 1, sum = 0
// compute sum of the integers from 1 to 10
while i <= 10 do
sum += i // or sum = sum + i
++i // or i = i + 1
end while
repeat until
var int i = 1, sum = 0
// compute sum of the integers from 1 to 10
repeat
sum += i // or sum = sum + i
++i // or i = i + 1
until i > 10
for
// i is defined as an integer by default
// if i already exists a warning will be issued
var int sum = 0
// compute sum of the integers from 1 to 10
for i in range(1,10) do
sum += i
end for
loop
var int i = 1, sum = 0
// compute sum of the integers from 1 to 10
loop 10
sum += i // or sum = sum + i
++i // or i = i + 1
end loop
switch
switch x
case 1
println "x = 1"
end case
case 2
println "x = 2"
end case
default case
println "x is not equal to 1 or 2"
end case
end switch
print, read, ask, dump
var int i = 3
var string name = "John"
// print different data
print "a string ", 10, 'c', 3.1415, " ", name
// read from standard input
ask name
// print variable type and value
dump name, i
Examples
The Hello World ! program in EZ
- a program will generate a binary
- the starter procedure is the entry point of the executable, while for modules it is the initialization procedure
- use the print, println instructions to output string, expressions, variables
prog hello_world
// -----------------------------------------
// a procedure that has the same name as the
// program is the entry point
// -----------------------------------------
proc hello_world()
println( "Hello World !" )
end proc
First 20 Prime numbers and their average
The following program computes the first 20 prime numbers using the user defined function 'is_prime'. Once these numbers are found we can compute their average.
prog prime_numbers
(
var int max_primes = 20 parse as "mp"
)
var vector<int> v
/* =====================================
* function that determines if 'x' is
* a prime number or not
* =====================================
*/
func bool is_prime( int x )
on n <= 1 do return false
on n <= 3 do return true
on (n % 2) = 0 do return false
// no need to declare variable i it will be declared
// in C++ by "for (int i = 3; i <= x.sqrt(); i += 2)"
for i in [3 : x.sqrt() : 2]
on (x % i) = 0 do return false
end for
return true
end func
// =====================================
// start program here
// =====================================
proc prime_numbers()
var int n = 1
while (v.size() != max_primes) and (n <= 1000) do
on is_prime(n) do v.insert_last(n)
++n
end while
println "the first ", MAX_PRIMES, " numbers are ", v
println "their average is ", v.average()
end proc
This program will be translated in C++ as the following:
#include <iostream>
#include <vector>
using namespace std;
#include "ez.h"
const int MAX_PRIMES = 20;
int n;
bool is_prime(int x) {
int i;
if (n <= 1) return false;
if (n <= 3) return true;
for (i = 2; i <= x/2; ++i) {
if ((x % i) == 0) return false;
}
return true;
}
int main() {
ez::vector<int> v;
n = 1
while (v.size() < MAX_PRIMES) {
if (is_prime(n)) v.push_back(n);
n += 1;
}
cout << "the first " << MAX_PRIMES << " numbers are " << v << endl;
cout << "their average is " << v.average() << endl;
return EXIT_SUCCESS;
}
User-defined data structure
The following program creates a vector of persons and sort them by name, by age and computes maximum of ages
prog prog_person
import math
/**
* definition of a person,
* default methods will be created for this class
* - a constructor with no arguments that initializes all data members
* - a constructor with arguments for each data members except containers
* - a print method to display all data members
*/
class Person
var string name
var int age
end class
// =====================================
// start program here
// =====================================
proc prog_person()
var Person p
var vector<Person> v
var int i, max
for i in range(1,10) do
p.name = "p" + i
p.age = math.rand( 1, 100 )
v.insert(p)
end for
// sort by name
v.sort( name );
println v
// store to file and restore from file
v.store( "persons.txt" )
v.empty()
v.restore( "persons.txt" )
// sort by age
v.sort( age )
// compute maximum of ages (detailed version)
max = 0
for i in v.range()
on v[i].age > max do max = v[i].age
end for
// or use built-in function
max = v.max(age)
println "oldest person is ", max, " years old"
end proc
This program will be translated in C++ as the following:
#include <iostream>
#include <vector>
using namespace std;
#include "ez.h"
class Person {
public:
string name;
int age;
Person() {
name = "";
age = 0;
}
ostream& print(ostream& out) {
out << name << ", " << age;
}
ostream& _export(ostream& out) {
out << name << ", " << age;
}
ostream& operator<<(ostream& out, Person& obj) {
return obj.print(out);
}
};
int main() {
Person p;
ez::vector<Person> v;
int i, max;
for (i = 1; i <= 10; ++i) {
p.name = "p" + i;
p.age = 1 + rand() % 100;
v.push_back(p);
}
// sort by name
sort(v.begin(), v.end(), [](const Person& lhs, const Person& rhs) {
return lhs.name > rhs.name;
});
cout << v;
v.store("persons.txt")
v.clear()
v.restore("persons.txt")
// sort by age
sort(v.begin(), v.end(), [](const Person& lhs, const Person& rhs) {
return lhs.age > rhs.age;
});
// compute maximum of ages (detailed version)
max = 0
for (i = 1; i <= v.size(); ++i) do
if (v[i].age > max) max = v[i].age;
}
// or use built-in function
max = v.max(age)
cout << "maximum of ages = " << max << endl;
end
Input and Output parameters
prog parameters
(
int x = 1 parse as "x" required
int y = 1 parse as "y" required
)
/* ------------------------------------------------------------------
* by default any parameter declared is considered as 'input'
* which means non modifiable.
* Here z is an output parameter
* ------------------------------------------------------------------
*/
proc add( int x, y; exist int z )
z = a + b
end proc
/* ------------------------------------------------------------------
* It all starts here !
* ------------------------------------------------------------------
*/
proc parameters()
var int z
add(x, y, z)
dump z
end proc
This program will be translated in C++ as the following:
Warning: file_get_contents(ez/parameters.cpp): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
Merge sort
prog merge_sort_program
/*
* Command line argument of the program which must be provided as
* -s <integer-constant>
* or
* --array-size=<integer-constant>
*/
(
int array_size = 10 parse as 's' or "array-size"
)
/* ------------------------------------------------------------------
*
* SUBPROGRAM
*
* proc merge( exist array<int> t; int l, m, h )
*
* WHAT
*
* Merge two parts consecutive parts of the array @param(t)
*
* PARAMETERS
*
* @paramdef(t) array of integers
* @paramdef(l) lowest index of array to merge
* @paramdef(m) middle index of array to merge
* @paramdef(h) highest index of array to merge
*
* ------------------------------------------------------------------
*/
proc merge( exist array<int> t; int l, m, h )
var int i = l, j = m, k = l
var array<int> temp;
while (i < m) and (j <= h) do
if t[ i ] < t[ j ] then
temp[ k ] = t[ i ]
++k
++i
elsif t[ j ] < t[ i ] then
temp[ k ] = t[ j ]
++k
++j
else
temp[ k ] = t[ j ]
temp[ k ] = t[ i ]
++i
++j
k += 2
end while
while i < m do
temp[ k ] = t[ i ]
++k
++i
end while
while j <= h do
temp[ k ] = t[ j ]
++k
++j
end while
t = temp
end proc
/* ------------------------------------------------------------------
*
* SUBPROGRAM
*
* proc split( exist array<int> t, int l, h )
*
* WHAT
*
* Split array @param(t) in two parts based on middle index
* defined by @formula( (l+h) / 2 ).
*
* PARAMETERS
*
* @paramdef(t) array of integers
* @paramdef(l) lowest index of array to split
* @paramdef(h) highest index of array to split
*
* ------------------------------------------------------------------
*/
proc split( exist array<int> t, int l, h )
// number of elements of the
var int size = h - l + 1
on size = 1 do return
if size = 2 then
on t[l] > t[h] do t.swap(l, h)
else
var int m = (l + h) / 2
split( t, l, m-1 )
split( t, m, h )
merge( t, l, m, h )
end if
end proc
/* ------------------------------------------------------------------
*
* SUBPROGRAM
*
* proc merge_sort( exist array<int> t )
*
* WHAT
*
* Perform merge-sort on array @param(t)
*
* PARAMETERS
*
* @paramdef(t) array of integers
*
* ------------------------------------------------------------------
*/
proc merge_sort( exist array<int> t )
split( t, t.min_index(), t.max_index() )
end proc
/* ------------------------------------------------------------------
*
* SUBPROGRAM
*
* proc merge_sort_program()
*
* WHAT
*
* Main method
*
* NOTE
*
* @var(array_size) is a parameter of the program provided
* as a command line argument (@see arguments section).
*
* ------------------------------------------------------------------
*/
proc merge_sort_program()
// check condition, if false then raise exception
assume array_size > 1
// create array
var array<int> t[ 1:array_size ]
t.random_fill( 20, 1500 )
merge_sort( t )
print t
end proc
1.3. Compilation process
The EZ language source file must have the .ezl extension.
The compiler is called ezc and uses some compilation flags :
- --cpp will generate the C++ source file and stop
- --run will generate executable and run the program
- --real-precision=[simple|double]
- --optimize
- --debug
- --profile
- --technology=[sse|cuda]
By default the compiler will try to generate the C++ file, compile it into and executable and
run it.