Easy
Programming Language
Written by Mika Heinonen, 22nd Jan 2010

Easy is intended to be a cross-platform, cross-hardware, cross-language programming language.

It is implemented as a variadic macro header, which can be compiled directly in any language which supports variadic macros. C++ is one language which supports this.

Examples

A simple hello world program:
#include "easy.h"
Begin
       PrintLine( "Hello World!" )
End


A loop:
#include "easy.h"
Begin
       For( Int, i, 1, 10 )
              PrintLine( IntForm, i )
       End
End


Creating, populating and iterating a dynamic array:
#include "easy.h"
Begin
       Array( Int, a )
       Append( a, 5 )
       Append( a, 9 )
       ForEach( a )
              PrintLine( IntForm, Current( a ) )
       End
End


String operations:
#include "easy.h"
Begin
       Define( String, s = "Hello" )
       StringAppend( s, " World!" )
       StringInsert( s, 5, " Easy" )
       PrintTextLine( Text( s ) )
End


Map operations:
#include "easy.h"
Begin
       Map( String, StringKey, m )
       Put( m, "cat", "Churchill" )
       Put( m, "dog", "Hector" )
       PrintLine( StringForm, Text( Get( m, "cat" ) ) )
       PrintLine( StringForm, Text( Get( m, "dog" ) ) )
       ForEach( m )
              PrintLine( StringForm "=" StringForm, Key( m ), Text( Value( m ) ) )
       End
End


Creating a prepopulated dynamic array:
#include "easy.h"
Begin
       Define( Int, z[] = { 1, 3, 5, 8 } )
       ArrayPopulated( Int, a, z )
       ForEach( a )
              PrintLine( IntForm, Current( a ) )
       End
End


Fun with variable declarations:
#include "easy.h"
Begin
Define( Double, k )        Rem( The basic usage of Define )
Set( k, 5.4321 )             Rem( The basic usage of Set )
Set( Double j, 6.7894 )  Rem( A bit dirty way to define variables,
                                               since Define should be used for that )
Define( Double, Set( h, 4.5376 ) )    Rem( Very formal way )
Define( Double, p = 9.5424 )           Rem( Acceptable )
Define( Double, k1, k2, k3 )             Rem( Multiple definitions at once )
PrintLine( FloatForm ", " FloatForm ", " FloatForm ", " FloatForm, k, j, h, p )
End


Creating Functions:
#include "easy.h"

Function( Int, Add, Int a, Int b )
      Return( a + b )
End

Begin
      PrintIntLine( Check( Add, 2, 3 ) )
      PrintIntLine( Add( 2, 3 ) )
End


Creating Classes:
#include "easy.h"

Class( Axe )
      Public
      Function( Void, Sharpen, Int a )
            PrintLine( "Axe Sharpness level is now " IntForm ".", a )
      End
EndClass

Begin

      Define( Axe, axe )
      Use( axe.Sharpen(2) )
      New( Axe, consumableaxe )
      Use( consumableaxe To Sharpen(2) )
      Delete( consumableaxe )
End


Creating Templates:
#include "easy.h"

Template( T, Max, T a, T b )
      Return( a > b ? a : b )
End

Begin

      Define( Int, i = 2, j = 3 )
      Define( Double, m = 5, n = 4 )
      PrintIntLine( Max( i, j ) )
      PrintFloatLine( Max( m, n ) )
End

Source
Easy is free and open-source.
You can view or download it here:

Version 0.0.8.0: easy.h


Reference

General commands

Begin
Marks the starting of the program execution.

End
Marks the ending of any kind of blocks, like Loops, If clauses, and even the main program.

Define( type, variable )
Defines a variable to exist and to be the given type. The scope of the variable is defined by the physical location of the definition. Commands which are terminated with the End statement form blocks of scopes, so definitions inside such blocks are accordingly only existant inside those blocks.

Set( variable, value )
Sets the value of a variable.

Text( Stringvariable )
Converts the Stringvariable into Text, so that it can be used with the Print statement.

Print( format|text, variables... )
Prints text to the console. Text can be printed directly, but numbers need to be formatted as text using the IntForm or FloatForm words. Multiple values can be given as parameters, which requires that the format parameters also matches the variables. Multiple format parameters are seperated by space.

PrintLine( format|text, variables... )
Same as Print, but adds a linefeed to the output.

For( type, variablename, startvalue, endvalue )
Iterates a variable through the given values.
Type can be left as blank, but then the variable must be defined before the loop.

Rem( text )
Inserts a remark into the source code. Doesn't do anything at code level.

Call( functionname )
Calls a function which does not return a value.

Check( functionname )
Checks the result of a function which returns a value.


Array commands

Array( type, variablename )
Defines a dynamic array with elements of the given type.

ArrayFilled( type, variablename, amount, value )
Defines a dynamic array with elements of the given type and fills it with an amount of values.

ArrayPopulated( type, variablename, valuesarray )
Defines a dynamic array with elements of the given type and populates it with an given array of values.

Append( variablename, value )
Appends a new array item at the end of the array.

Insert( variablename, value )
Inserts a new array item at the current position of the array iterator. A newly defined array initializes the array iterator to the beginning of the array.

Rewind( variablename )
Sets the array iterator to the beginning of the array.

ForEach( variablename )
Iterates through all elements of an array or map.

Current( variablename )
Returns the value of the current item of an array which is being iterated with the ForEach command.

Swap( variablename1, variablename2 )
Swaps the whole content of an array with another array.


Map commands

Map( type, indextype, variablename )
Defines a dynamic map with elements of the given type, and a index of the given indextype.

Put( variablename, keyvalue, itemvalue )
Puts an item into the map, and associates it with the keyvalue.

Get( variablename, keyvalue )
Gets an itemvalue from a map. If an item with the given keyvalue is not found, the function returns an empty string. Director's note: it should return a NULL pointer when an item is not found, so that it works for all types.

ForEach( variablename )
Iterates through all elements of an array or map.

Key( variablename )
Gets the value of the current key when using the ForEach command.

Value( variablename )
Gets the value of the current item when using the ForEach command.


Constructs

Function( returntype, name, parameters )
Defines a function or class member.

Procedure( name, parameters )
Defines a procedure or class member.

Template( returntype, name, parameters )
Defines a template function. Template functions are like functions, but they work with any kind of parameter types, so you don't have to write a seperate function for parameters of type Int, Double, etc.... Director's note: should be expanded to work with template classes also.

Class( name )
Defines a class.

EndClass
Ends the class definition.

New( type, variable )
Creates a dynamic instance of a class.

Use( method )
Calls a class method.

To
Accesses a member of a dynamic class instance.

Delete( name )
Deletes a dynamic instance of a class.

Scope( name )
Defines a scope. Scopes are useful for defining things without their names conflicting with other scopes, including the global scope.

Merge( name )
Merges a named scope to the global scope.

Name( oldname, newname )
Renames a named scope.


Constants

LineFeed
This is a constant which is used with the Print command to append a line feed to the text.

IntForm
This constant is used with the Print statement to convert a Int value into Text.

FloatForm
This constant is used with the Print statement to convert a Float or Double value into Text.

StringForm
This constant is used with the Print statement to convert a String value into Text. Additionally the String value must be converted using the Text() function, because Strings are internally not Text, but more complex classes.

IntKey
This constant is used with the Map statement to define that the lookup value is a Int type.

StringKey
This constant is used with the Map statement to define that the lookup key is a String type.


Types

Int
Integer number type.

Float
32-bit floating point number type.

Double
64-bit floating point number type. Double is about 5 times faster than Float in performance, and should be always preferred instead of Float.

String
String type. A String is a class, and needs to be converted to Text using the Text() function before it can be used with the Print() function.

Register
The Register keyword is used before the actual type to attempt a compile-time storing of the variable into a CPU register. However, in many compilers this will have no effect, since the compiler optimizes the usage of CPU register variables, and does not let the user to interfere with its optimizations.