Anonymous user
Category:Elena: Difference between revisions
no edit summary
No edit summary |
|||
Line 14:
== The simplest program ==
To create a simple console program we have to declare the public **program**
public program()
Everything in ELENA is an object. To interact with it we have to send a message. The
The statement should be terminated by a
public program()
console
In our example the action is **writeLine** and the parameter list consists of a single
Several message operations can be done in a single statement
public program()
console
The result will be:
Line 43:
How are you?
We may read a user input by sending **readLine** message without parameters:
public program()
console
The result will be:
Line 55:
Hello Alex
**Console::write** method is similar to **writeLine** except that it writes to the output screen without a new line character.
== Declaring a variable ==
A variable can be declared in an assignment statement starting with **var** attribute:
var myVariable := "A text"
where we declare a variable **myVariable** and initialize it with a
The assigning value can be an expression itself:
public program()
console
var s := console
ELENA is a dynamic language and in
public program()
var s := "Hello"
console
s := 2
console
The output will be:
Line 89:
2
But it is
console
*where system'
We may use a class alias to simplify the code:
console
ELENA does not enforce types in compilation-time, so the following code will be successfully compiled:
s :=
But it will raise an exception in the run-time:
system'IntNumber : Method #cast[0] not found
Call stack:
system'Exception#class.new[1]:exceptions.l(125)
system'MethodNotFoundException#class.new[2]:exceptions.l(236)
system'$inlineC.start[0]:win32_app.l(313)
mytest'program.#invoke[0]:test.l(5)
system'$inlineC.start[0]:win32_app.l(39)
system'#startUp:win32_app.l(52)
As you may see, the compiler injects the typecasting code, so the actual code looks like this:
string s := "Hello";
s := cast string(2);
*where* **cast string(2)** *is a construction to typecast the target expression* - **a numeric constant** - *to the expected type* - **System'String**
As a result if the object supports casting method the operation will work. For example, system'IntNumber can be implicitly converted into system'RealNumber so the following code:
public program()
{
real r := 2;
console.writeLine(r)
}
will be successfully executed with the result:
2.0
== Basic Types ==
Line 130 ⟶ 140:
=== The Boolean Type ===
Boolean type is used in conditional operations and may accept only two Boolean literals - **true** and **false**.
import extensions
public program()
bool b1 := true
bool b2 := false
console
console
console
console
*Note that implicit extension method - **extensions'outputOp.printLine[]** - was used to simplify the output operations.*
The output is:
Line 158 ⟶ 168:
The most used numeric types in ELENA are 32-bit signed integer number (represented by **IntNumber**), 64-bit signed integer number (represented by **LongNumber**) and 64-bit floating-point number (represented by **RealNumber**):
import extensions
public
int n := -234
long l := 1235456765l
real r := 2.3456r
console
console
console
The output is:
Line 177 ⟶ 187:
Real number - 2.3456
=== The
import extensions
public program
var s := "Hello"
console
console
The output is:
Line 198 ⟶ 208:
The same code for example with a Russian text will not work. Because every character is encoded with a two bytes and this should be taken into account.
import extensions
public program
var s := "Привет"
console
console
The output is:
Line 213 ⟶ 223:
An index is out of range
Call stack:
system'Exception#class.new
system'OutOfRangeException#class.new[
system'
system'String.at[1]:memory.l(1243)
mytest'program.#invoke[0]:test.l(8)
system'
system'#
We may use another class representing UTF-16 text (
import extensions
public program
var s := "Привет"w. // UTF-16 string
console
console
The output will be correct this time:
Line 240 ⟶ 250:
But this code will not work with Chinese text or any other requiring more than 2 bytes per symbol. So instead we may use enumerators:
import system'routines
import extensions
public program
var s := "Привет"
console
console
The output will be correct for any UTF-8 text:
Line 256 ⟶ 266:
The last character of Привет is т
=== Array
It is possible to declare a
import extensions
public program
var
var genericArray := Array.allocate(3);
genericArray[0] := 1;
genericArray[1] := "b";
genericArray[2] := 2.3r;
console.printLine("strong-typed array ",strongTypedArray.asEnumerable());
console.printLine("dynamic-typed array ",genericArray.asEnumerable());
}
The output is:
dynamic-typed array 1,b,2.3
== Basic arithmetic operations ==
Line 283 ⟶ 294:
ELENA supports basic arithmetic operations with integer and floating-point numbers:
import extensions
public program
var n1 := 12
var n2 := 5
var n3 := -3
var r1 := 2.3r
console
console
console
console
console
The result is:
Line 307 ⟶ 318:
12 / 5 = 2
12 + 5 * 2.3 = 23.5
== ?? operator ==
Operator ?? is used to deal with nil.
_a ?? b_ - will return _a_ if _a_ is not _nil_ or _b_
See the following code:
import extensions;
public program()
{
var a := nil;
var b := a ?? 0 + 2;
console.printLine(a ?? "nil", " ?? 0 + 2 = ", b);
a := 1;
b := a ?? 0 + 2;
console.printLine(a ?? "nil", " ?? 0 + 2 = ", b);
}
The output is:
nil ?? 0 + 2 = 2
1 ?? 0 + 2 = 3
The operator can be used for typecasting operations as well:
_cast type(a) ?? b_ - will typecast _a_ to _type_ or return _b_ if it is not possible.
See the code:
import extensions;
public program()
{
string s := "a";
var n := 2;
console.printLine("cast int(",s,") ?? 0 = ", cast int(s) ?? 0);
console.printLine("cast int(",n,") ?? 0 = ", cast int(n) ?? 0);
}
The output is:
cast int(a) ?? 0 = 0
cast int(2) ?? 0 = 2
== Conditions, Multi-select, Loops ==
Line 313 ⟶ 372:
if(<Boolean expression>)
{
}
else
{
/*doSomehting if ELSE*/
};
We could omit else part
if(<Boolean expression>)
Usually Boolean expression is a result of a comparison operation:
public program
console
var s := console
if(s == "good")
{
else
{
console.writeLine("What happends?")
}
}
Several conditions can be checked:
public program
console
var s := console
if((s == "good") || (s == "fine"))
{
else
{
console.writeLine("What happends?")
}
}
A switch statement can be implemented using => operator:
public program
console
var s := console
s =>
"good"
"fine"
"bad"
"so so"
We could declare *while* loop which will be repeated until the condition is true:
public program
console
var s := console
while (s != "nothing")
console
s := console
Alternatively *until* loop is executed until the condition is met :
public program
console
var s := console
until (s == "nothing")
console
s := console
ELENA supports C-styled *for* loop as well:
public program()
{
for(int n := 0, n < 5, n += 1)
{
console.write("*")
}
}
The output is:
*****
_Note that comma is used instead of semicolon!_
*doUntil* loop is similar to *for*, but the loop is executed at least once:
var text := new StringWriter();
doUntil(string line, line.isEmpty(), line := console.readLine())
{
text.writeLine(line)
};
== Classes, Fields Methods, Constructors ==
Line 391 ⟶ 489:
Let's create a simple class :
import extensions
class MyClass
{
// a field
//
constructor
myString := s
// an explicit constructor
constructor fromNuber(int n)
{
myString := n.toString();
}
// a method
printString()
console
}
public program
// creating a class instance by sending new message to the class
var myClass := new MyClass
myClass
The output will be:
Line 423 ⟶ 527:
This is printed by my class.
*Note that in ELENA a class is an object itself and can be used by like any other object
=== Class Inheritance ===
We may inherit our class. When the parent is not explicitly declared - the class inherits *system'Object* super class
import extensions
class MyParent
{
constructor new()
console
console
}
class MyChild
{
constructor new()
<= new
console
// calling the parent method
super
console
}
public program
var myClass := MyChild
myClass
The output is:
Line 480 ⟶ 584:
It is possible to declare the private methods which cannot be called outside the class.
import extensions
class MyClass
{
private printPrivate()
console
printPublic()
console
//
self
}
// Note that if the constructor explicitly is not declared
// the system'Object one (without input parameters) is inherited
var myClass :=
myClass
myClass
The output is:
Calling from public print - private print.
mytest'$private'MyClass : Method
Call stack:
system'Exception#class.new
system'MethodNotFoundException#class.new
system'
mytest'program.#invoke[0]:test.l(
system'
system'#
=== Properties ===
In normal case the class fields cannot be accessed outside the class. That's why we may declare
import extensions;
class MyClass
{
int _x
get int x() = _x
set x(int o) // set accessor
_x := o
}
public program
var myClass :=
myClass
console
The output is:
Line 552 ⟶ 655:
MyClass.x=2
We may simplify our code if we will use **prop**
import extensions
class MyClass
{
int
prop int x
{
get() = _x;
set(int val)
{
_x := val;
}
}
}
public program
var myClass :=
myClass
console
Simple accessors can be omitted:
import extensions;
class MyClass
{
prop int x;
}
public program()
{
var myClass := new MyClass();
myClass.x := 2;
console.printLine("MyClass.x=", myClass.x)
}
== Exception Handling ==
Line 574 ⟶ 705:
We may use try-catch statement to handle the possible exceptions:
import extensions
public program
try
{
}
catch(MethodNotFoundException e)
{
console.printLine("Method not found")
}
catch(Exception e)
{
console.printLine("Unknown error")
}
}
The output is :
Method not found
== See also ==
|