Category:Elena: Difference between revisions

From Rosetta Code
Content added Content deleted
No edit summary
No edit summary
Line 12: Line 12:
ELENA is a general-purpose, object-oriented, polymorphic language with late binding. It features message dispatching/manipulation, dynamic object mutation, a script engine / interpreter and mix-ins.
ELENA is a general-purpose, object-oriented, polymorphic language with late binding. It features message dispatching/manipulation, dynamic object mutation, a script engine / interpreter and mix-ins.


The simplest program
== The simplest program ==
==


To create a simple console program we have to declare the **program** symbol in the project root namespace:
To create a simple console program we have to declare the **program** symbol in the project root namespace:
Line 58: Line 57:
**Console::write** method is similar to **writeLine** except that it writes to the output screen without a new line character.
**Console::write** method is similar to **writeLine** except that it writes to the output screen without a new line character.


Declaring a variable
== Declaring a variable ==
===


A variable can be declared in an assignment statement starting with **var** attribute:
A variable can be declared in an assignment statement starting with **var** attribute:
Line 131: Line 129:
system'startUp(5)
system'startUp(5)
Basic Types
== Basic Types ==
===


The Boolean Type
=== The Boolean Type ===
=====


Boolean type is used in conditional operations and may accept only two Boolean literals - **true** and **false**.
Boolean type is used in conditional operations and may accept only two Boolean literals - **true** and **false**.
Line 161: Line 157:
false==true is false
false==true is false


### The Numeric types
=== The Numeric types ===


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**):
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**):
Line 184: Line 180:
Real number - 2.3456
Real number - 2.3456


### The string Type
=== The string Type ===


**LiteralValue** is used to store the text encoded in UTF-8. LiteralValus is read-only collection of **CharValue** classes each representing UTF-32 symbol. *Note that one character may be encoded with more than one byte!*.
**LiteralValue** is used to store the text encoded in UTF-8. LiteralValus is read-only collection of **CharValue** classes each representing UTF-32 symbol. *Note that one character may be encoded with more than one byte!*.
Line 263: Line 259:
The last character of Привет is т
The last character of Привет is т


### Array type
=== Array type ===


It is possible to declare a dynamic or static array.
It is possible to declare a dynamic or static array.
Line 286: Line 282:
dynamic array 1,b,2.3
dynamic array 1,b,2.3


## Basic arithmetic operations
== Basic arithmetic operations ==


ELENA supports basic arithmetic operations with integer and floating-point numbers:
ELENA supports basic arithmetic operations with integer and floating-point numbers:
Line 315: Line 311:
12 + 5 * 2.3 = 23.5
12 + 5 * 2.3 = 23.5


## Conditions, Multi-select, Loops
== Conditions, Multi-select, Loops ==


Conditional statement in ELENA are defined as follows:
Conditional statement in ELENA are defined as follows:
Line 390: Line 386:
].
].


## Classes, Fields Methods, Constructors
== Classes, Fields Methods, Constructors ==


Everything in ELENA is a class. So to implement some tasks we will have to declare our own classes.
Everything in ELENA is a class. So to implement some tasks we will have to declare our own classes.


### Declaring a simple class
=== Declaring a simple class ===


Let's create a simple class :
Let's create a simple class :
Line 432: Line 428:
*Note that in ELENA a class is an object itself and can be used by like any other object*
*Note that in ELENA a class is an object itself and can be used by like any other object*


### Class Inheritance
=== Class Inheritance ===


We may inherit our class. When the parent is not explicitly declared - the class inherits *system'Object* super class
We may inherit our class. When the parent is not explicitly declared - the class inherits *system'Object* super class
Line 483: Line 479:
I'm a Child Class.
I'm a Child Class.


### Private methods
=== Private methods ===


It is possible to declare the private methods which cannot be called outside the class.
It is possible to declare the private methods which cannot be called outside the class.
Line 528: Line 524:
system'startUp(5)
system'startUp(5)


### Properties
=== Properties ===


In normal case the class fields cannot be accessed outside the class. That's why we may declare a special method to access it:
In normal case the class fields cannot be accessed outside the class. That's why we may declare a special method to access it:
Line 577: Line 573:
].
].
## Exception Handling
== Exception Handling ==


We may use try-catch statement to handle the possible exceptions:
We may use try-catch statement to handle the possible exceptions:

Revision as of 16:26, 6 February 2018

Language
Elena
This programming language may be used to instruct a computer to perform a task.
Official website
Execution method: Compiled (bytecode)
Garbage collected: Yes
Type safety: Safe
Type strength: Strong
Type expression: Implicit
Type checking: Dynamic
See Also:
Listed below are all of the tasks on Rosetta Code which have been solved using Elena.


ELENA is a general-purpose, object-oriented, polymorphic language with late binding. It features message dispatching/manipulation, dynamic object mutation, a script engine / interpreter and mix-ins.

The simplest program

To create a simple console program we have to declare the **program** symbol in the project root namespace:

   program =
   [
   ].

Everything in ELENA is an object. To interact with it we have to send a message. The simplest (*generic*, i.e. without an explicit signature) message consists of *an action* and a *parameter list*.

The statement should be terminated by a dot (*ELENA is inspired by Smalltalk and uses its syntax notations*).

   program =
   [
       console writeLine("Hello!").
   ].

In our example the action is **writeLine** and the parameter list consists of a single literal constant. The message target is **console** object (implementing input / output operations with a program console).

Several message operations can be done in a single statement separated by a semicolon:

   program =
   [
       console writeLine("Hello!"); writeLine("How are you?").
   ].

The result will be:

    Hello!
    How are you?

We may read a user input by sending **readLine** message without parameters:

   program =
   [
       console write("What is your name:"); writeLine("Hello " + console readLine).
   ].

The result will be:

   What is your name:Alex
   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 literal constant value.

The assigning value can be an expression itself:

   program =
   [
       console writeLine("Hello!"); writeLine("How are you?").
       var s := console readLine.
   ].

ELENA is a dynamic language and in normal case we may not specify the variable type:

   program =
   [
       var s := "Hello".
       console writeLine(s).
       s := 2. 
       console writeLine(s).
   ].

The output will be:

   Hello
   2

But it is still possible to specify the variable expected type:

   type<LiteralValue> s := "Hello".
   console writeLine(s).
  • where system'LiteralValue is a class representing text as a sequence of UTF-8 characters.*

We may use a class alias to simplify the code:

   literal s := "Hello".  // literal is a LiteralValue alias
   console writeLine(s).

Note that despite it we may still assign the objects of different types without a compile-time error:

   literal s := "Hello".
   s := 2. 

Why? ELENA is a dynamic language and in most cases resolves the types in run-time. So our code will be actually compiled as follow:

   literal s := "Hello".  
   s := 2 literal. 

It is guaranteed that the result of **literal** message is an instance of LiteralValue, so if the object supports the message the conversion will be done quietly. In fact this code will work because **IntNumber** supports this conversion. But the following code will be broken in run-time:

   int n := 3.
   n := 3.4r.

The output will be:

   system'RealNumber : Method $system'IntNumber not found
   Call stack:
   system'Exception#class.new$system'LiteralValue[1]:exceptions.l(125)
   system'MethodNotFoundException#class.new$system'Object$system'Message[2]:exceptions.l(213)
   system'#inline1BF.start[1]:win32_app.l(252)
   mytest'program.#invoke[0]:test.l(5)
   system'BaseFunction.eval[0]:control.l(172)
   system'#inline1BF.start[1]:win32_app.l(37)
   system'startUp(5)
  

Basic Types

The Boolean Type

Boolean type is used in conditional operations and may accept only two Boolean literals - **true** and **false**.

   import extensions.
   
   program =
   [
       bool b1 := true.
       bool b2 := false.
       
       console printLine(b1,"==",b1," is ",b1==b1).
       console printLine(b2,"==",b2," is ",b2==b2).
       console printLine(b1,"==",b2," is ",b1==b2).
       console printLine(b2,"==",b1," is ",b1==b2).
   ].
  • Note that implicit extension method - **extensions'outputOp.printLine[]** - was used to simplify the output operations.*

The output is:

   true==true is true
   false==false is true
   true==false is false
   false==true is false

The Numeric types

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.
   
   program =
   [
       int  n := -234.
       long l := 1235456765l.
       real r := 2.3456r.
       
       console printLine("Integer number - ",n).
       console printLine("Long integer number - ",l).
       console printLine("Real number - ",r).
   ].

The output is:

   Integer number - -234
   Long integer number - 1235456765
   Real number - 2.3456

The string Type

    • LiteralValue** is used to store the text encoded in UTF-8. LiteralValus is read-only collection of **CharValue** classes each representing UTF-32 symbol. *Note that one character may be encoded with more than one byte!*.
   import extensions.
   
   program =
   [
       var s := "Hello".
       
       console printLine("The first character of ",s," is ", s[0]).
       console printLine("The last character of ",s," is ", s[s length - 1]).
   ].

The output is:

   The first character of Hello is H
   The last character of Hello is o

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.
   program =
   [
       var s := "Привет".
       
       console printLine("The first character of ",s," is ", s[0]).
       console printLine("The last character of ",s," is ", s[s length - 1]).
   ].

The output is:

   The first character of Привет is П
   An index is out of range
   Call stack:
   system'Exception#class.new$system'LiteralValue[1]:exceptions.l(125)
   system'OutOfRangeException#class.new[0]:exceptions.l(149)
   system'LiteralValue.getAt$system'IntNumber[1]:memory.l(1191)
   mytest'program.#invoke[0]:test.l(8)
   system'BaseFunction.eval[0]:control.l(172)
   system'#inline1BF.start[1]:win32_app.l(37)
   system'startUp(5)

We may use another class representing UTF-16 text (**WideLiteralValue**) to solve this problem:

   import extensions.
   
   program =
   [
       var s := "Привет"w. // UTF-16 string
       
       console printLine("The first character of ",s," is ", s[0]).
       console printLine("The last character of ",s," is ", s[s length - 1]).
   ].

The output will be correct this time:

   The first character of Привет is П
   The last character of Привет is т

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.
   
   program =
   [
       var s := "Привет".
       
       console printLine("The first character of ",s," is ", s enumerator; firstMember).
       console printLine("The last character of ",s," is ", s enumerator; lastMember).
   ].

The output will be correct for any UTF-8 text:

   The first character of Привет is П
   The last character of Привет is т

Array type

It is possible to declare a dynamic or static array.

   import extensions.
   
   program =
   [
       var staticArray := (1,2,3).
       var dynamicArray := Array new(3).
       dynamicArray[0] := 1.
       dynamicArray[1] := "b".
       dynamicArray[2] := 2.3r.
       
       console printLine("static array ",staticArray).
       console printLine("dynamic array ",dynamicArray).
   ].

The output is:

   static array 1,2,3
   dynamic array 1,b,2.3

Basic arithmetic operations

ELENA supports basic arithmetic operations with integer and floating-point numbers:

   import extensions.
   program =
   [
       var n1 := 12.
       var n2 := 5.
       var n3 := -3.
       var r1 := 2.3r.
    
       console printLine(n1, " + ", n2, " = ", n1 + n2).
       console printLine(n1, " - ", n2, " = ", n1 - n2).
       console printLine(n1, " * ", n3, " = ", n1 * n3).
       console printLine(n1, " / ", n2, " = ", n1 / n2). 
       console printLine(n1, " + ", n2, " * ", r1 ," = ", n1 + n2 * r1).
   ].

The result is:

   12 + 5 = 17
   12 - 5 = 7
   12 * -3 = -36
   12 / 5 = 2
   12 + 5 * 2.3 = 23.5

Conditions, Multi-select, Loops

Conditional statement in ELENA are defined as follows:

   if(<Boolean expression>)
      [ /* doSomething if TRUE*/ ];
      [ /*doSomehting if ELSE*/ ].

We could omit else part

   if(<Boolean expression>)
      [ /*doSomehting if TRUE*/ ].

Usually Boolean expression is a result of a comparison operation:

   program =
   [
       console writeLine("Hello!"); writeLine("How are you?").
       var s := console readLine.
       if(s == "good")
          [ console writeLine("Me too") ];
          [ console writeLine("What happends?") ]
   ].   

Several conditions can be checked:

   program =
   [
       console writeLine("Hello!"); writeLine("How are you?").
       var s := console readLine.
       if((s == "good") || (s == "fine"))
          [ console writeLine("Me too") ];
          [ console writeLine("What happens?") ]
   ].   

A switch statement can be implemented using => operator:

   program =
   [
       console writeLine("Hello!"); writeLine("How are you?").
       var s := console readLine.
       s =>
         "good" [ console writeLine("Me too") ];
         "fine" [ console writeLine("Glad to hear") ];
         "bad"  [ console writeLine("What's wrong?") ];
         "so so" [ console writeLine("It happens") ];
         ! [ console writeLine("What happens?") ].
   ].   

We could declare *while* loop which will be repeated until the condition is true:

   program =
   [
       console writeLine("Hello!"); writeLine("Guess what?"). 
       var s := console readLine.
       while (s != "nothing")
       [
           console writeLine("Guess what?"). 
           s := console readLine
       ]
   ].   

Alternatively *until* loop is executed until the condition is met :

   program =
   [
       console writeLine("Hello!"); writeLine("Guess what?"). 
       var s := console readLine.
       until (s == "nothing")
       [
           console writeLine("Guess what?"). 
           s := console readLine
       ]
   ].   

Classes, Fields Methods, Constructors

Everything in ELENA is a class. So to implement some tasks we will have to declare our own classes.

Declaring a simple class

Let's create a simple class :

   import extensions.
   
   class MyClass
   {
       // a field
       literal myString.
   
       // a constructor
       constructor new(literal s)
       [
           myString := s.
       ]
       
       // a method
       printString
       [
           console printLine(myString).
       ]
   }
   
   program =
   [
       // creating a class instance by sending new message to the class
       var myClass := MyClass new("This is printed by my class.").
       
       myClass printString.
   ].

The output will be:

   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 printLine("Parent Constructor.")
       ]
   
       print
       [
           console printLine("I'm a Parent Class.")
       ]    
   }
   
   class MyChild :: MyParent
   {
       
       constructor new
           <= new; // calling the parent constructor
       [
           console printLine("Child Constructor.")
       ]
       
       print
       [
           // calling the parent method
           $super print.
           
           console printLine("I'm a Child Class.")
       ]
   }
   
   program =
   [
       var myClass := MyChild new.
       
       myClass print.
   ].

The output is:

   Parent Constructor.
   Child Constructor.
   I'm a Parent Class.
   I'm a Child Class.

Private methods

It is possible to declare the private methods which cannot be called outside the class.

   import extensions.
   
   class MyClass
   {
       sealed $printPrivate
       [
           console printLine("private print.")
       ]
       
       printPublic
       [
           console print("Calling from public print - ").
           // $self is a reference to the current object
           $self $printPrivate.
       ]
   }
   
   program =
   [
       // Note that if the constructor explicitly is not declared 
       // the system'Object one (without input parameters) is inherited
       var myClass := MyClass new.
       
       myClass printPublic.
       myClass $printPrivate.
   ].

The output is:
   Calling from public print - private print.
   mytest'MyClass : Method mytest#printPrivate not found
   Call stack:
   system'Exception#class.new$system'LiteralValue[1]:exceptions.l(125)
   system'MethodNotFoundException#class.new$system'Object$system'Message[2]:exceptions.l(213)
   system'#inline1BF.start[1]:win32_app.l(252)
   mytest'program.#invoke[0]:test.l(24)
   system'BaseFunction.eval[0]:control.l(172)
   system'#inline1BF.start[1]:win32_app.l(37)
   system'startUp(5)

Properties

In normal case the class fields cannot be accessed outside the class. That's why we may declare a special method to access it:

   import extensions.
   
   class MyClass
   {
       int _x.
   
       int x = _x.  // get accessor
   
       set x(int o) // set accessor 
       [
          _x := o.
       ]
   }
   
   program =
   [
       var myClass := MyClass new.
   
       myClass x := 2.
   
       console printLine("MyClass.x=", myClass x).    
   ].

The output is:

   MyClass.x=2

We may simplify our code if we will use **prop** attribute:

   import extensions.
   
   class MyClass
   {
       int prop x :: _x.
   }
   
   program =
   [
       var myClass := MyClass new.
   
       myClass x := 2.
   
       console printLine("MyClass.x=", myClass x).    
   ].

Exception Handling

We may use try-catch statement to handle the possible exceptions:

   import extensions.
   import system'io.
   
   program =
   [
       try(console printLine(File new("notexistingfile.txt"); content))
       {
           on(Exception ex)
           [
               console printLine("Unknown error - ",ex).
           ]
           
           on(IOException ex)
           [
               console printLine("I/O error - ",ex).
           ]            
       }
   ].

The output is :

   I/O error - Cannot open the file
   Call stack:
   system'Exception#class.new$system'LiteralValue[1]:exceptions.l(125)
   system'io'IOException#class.new$system'LiteralValue[1]:io\ioexceptions.l(10)system'io'FileStream#class.new$system'WideLiteralValue$system'IntNumber$system'IntNumber$system'IntNumber$system'IntNmber[5]:io\win32_files.l(52)
   system'io'FileStream#class.openForRead[1]:io\win32_files.l(29)
   system'io'StreamReader#class.new[1]:io\win32_files.l(207)
   system'io'fileControl.reader[1]:io\win32_files.l(269)
   system'io'File.read$system'text'TextBuilder[1]:io\files.l(59)
   system'io'File.content[0]:io\files.l(33)
   mytest'program.#invoke[0]:test.l(6)
   system'BaseFunction.eval[0]:control.l(172)
   system'#inline1BF.start[1]:win32_app.l(37)
   system'startUp(5)

See also

Subcategories

This category has the following 3 subcategories, out of 3 total.

Pages in category "Elena"

The following 200 pages are in this category, out of 240 total.

(previous page) (next page)
(previous page) (next page)