Difference between revisions of "A Recital Primer"

From Recital Documentation Wiki
Jump to: navigation, search
(Arithmetic operators)
(Constants)
Line 370: Line 370:
  
 
===Constants===
 
===Constants===
 +
 +
Variables each have a type determined by the data they contain. You initialize variables by assigning constants into them. Constants each have a primitive type and are the building blocks for all data in Recital
  
 
====String constants====
 
====String constants====
  
====Date constants====
+
The '''string''' type is used for textual characters. There is no type for representing just one character. A string is a series of zero or more characters. You delimit string constants using either a double-quote " or a single-quote '.
 +
 
 +
<code lang="recital">
 +
myvar = "This is a string"
 +
myvar = 'so is this'
 +
</code>
  
 
====Numeric constants====
 
====Numeric constants====
 +
 +
Numeric types in Recital are all stored as floating point numbers with zero or more decimal places.
 +
 +
<code lang="recital">
 +
myvar = 10
 +
myvar = 10.5678
 +
</code>
 +
 +
You can also define hexadecimal numeric constants.
 +
 +
<code lang="recital">
 +
myvar = 0x0a
 +
</code>
 +
 +
====Date constants====
 +
 +
Date constants are delimited by curly braces.
 +
 +
<code lang="recital">
 +
// set myvar to 10th of october 2009
 +
myvar = {10/10/2009}
 +
</code>
  
 
====Logical constants====
 
====Logical constants====
 +
 +
Logical (boolean) constants have one of two values, '''true''' or '''false'''. The result of any logical comparison expression results in a logical type. (Note: You can also use the older style .t. and .f. to denote true and false respectively.
 +
 +
<code lang="recital">
 +
myvar = true
 +
myvar2 = false
 +
if myvar or myvar2
 +
    /// this will be executed as myvar is true
 +
endif
 +
</code>
  
 
====Currency constants====
 
====Currency constants====
 +
 +
Currency constants are preceeded by a $.
 +
 +
<code lang="recital">
 +
// set myvar to 1000 dollars
 +
myvar = $1000
 +
</code>
  
 
====Datetime constants====
 
====Datetime constants====
 +
 +
Datetime constants are delimited by curly braces.
 +
 +
<code lang="recital">
 +
// set myvar to 10th of october 2009 at 8.30am
 +
myvar = {10/10/2009 08:30}
 +
</code>
  
 
===Expressions===
 
===Expressions===

Revision as of 00:50, 30 October 2009

A Recital Primer

Keywords

There are no reserved words in Recital. Command names can be used as variables names. At first glance these seems strange, but provides for greater flexibility when declaring and referencing memory variables and database field variables, as you do not need to concern yourself about names that may already be used as commands.

As an extreme example, the following code will compile and run. It will output "hello"

procedure if(if)
return if
 
if = "hello"
if if = "hello"
    echo if( if )
endif

Lines and Indentation

Tabs and spaces have no significance in Recital. Recital commands can begin on any column of a line. A newline ends the command. If you have particularly long commands, you can them extend over multiple lines by placing the line continuation character ; (semicolon) at the end of each line that is to be continued.

echo "This is a one line command"
echo "This is a ;
multi line ;
command"

For better code readability it is recommended that you indent code blocks such as if statements, for loops etc.

// indented code if much more readable and easier to maintain
for i=1 to 10
    name = "hello world"
    if name = "hello world"
        // indent like this
    endif
endfor

Comments

Single line comments

// allows comment lines to be inserted in programs to enhance their readability and maintainability. The // command allows all characters following it on a line, to be treated as a comment and to be ignored by Recital. The // command can be placed anywhere on a line, even following an executable command.

// declare variables
private x,y,z

Multi line comments

/* and */ denote block comments. These can be inserted in programs to enhance their readability and maintainability.

The /* denotes the start of the comment block, the */ the end of the comment block.

All characters between the two comment block delimiters are treated as comments and ignored by Recital.

/* the following lines
     are multi
     line comments */
private x,y,z

Variables

Variables in Recital do not need to be explicitly declared, although they should be for better code readability and maintainability. When an expression is assigned to a variable, if the variable does not already exist then it will be created implicitly unless SET STRICT ON is in effect.

private x
x = 10    // x already exists
y = 10    // y does not yet exist so it is created
 
set strict on
z = 10   // error is thrown as z does not exist and STRICT is ON

Simple Variables

Variable names must begin with a letter (A-Z, a-z) or an underscore (-), followed by any combination of letters, digits or underscores. The variable name can be of any length, but only the first 32 characters are significant, so these must be unique. Recital ignores the case of letters, so m_var, M_VAR, and m_VaR would all be treated as the same memory variable name. The name given to a variable has no bearing on the type of data that is, or can be, stored in it. In fact, the type of data stored in a particular variable can be changed at any time unless SET STRICT is ON, in which case Recital will type check variables on assigment to them.

m_var = 1234
m_var = 'a character value'
? m_var + 100

Variables can be declared and optionally initialized before used.

private m_var = 1234
m_var = 'a character value'
? m_var + 100

Variables can optionally be declared as specific datatype.

private m_var as numeric = 1234
m_var = 'a character value'    /// throws an error

Static Arrays

A static array is an ordered list of elements (variables) that is of a fixed size (number of elements). You declare a static array by specifying the number of elements when you declare a variable.

private tab[ 20 ]    // declare a static array of 20 elements all initialized to False
 
// iterate through the array (note the use of the alen( ) function to find the length of the array
for i=1 to alen( tab )
    // change each array element to hold a numeric value
    tab[ i ] = i
endfor

You can initialize a static array with one statement.

// declare the array and init all elements to false
declare tab[10, 10]
 
// init all elements to zero
tab = 0

You can create and initialize static arrays using static array initializers.

// simple one dimensional array with 2 elements
private tab = { "Hello", "world" }
 
// two-dimensional array of two rows with three columns in each row
private tab2 = { { "Hello", 10, date() ], { "world", 20, date()+1 } }
 
// create an array on the fly
mytab = { 10, 20, 30, 40, 50, 60 }

You can view the contents of a static array using the echo or ? commands.

? tab

Associative Arrays

An associative array (also known as a dynamic array) is a collection of key/value pairs where the key can be used to retrieve the value. Associative arrays are dynamic, meaning that elements can be added and removed dynamically.

private tab[]    // note the use of [] to denote a dynamic array
 
tab["name"] = "bill"
tab["age"] = 25
tab["dob"] = date()

Associative arrays can be created and initialized in one statement using the array( ) function.

tab = array("name" => "bill", "age" => 25, ""dob" => date())

You can view the contents of an associative array using the echo or ? commands.

? tab

Objects and Classes

Operators

Arithmetic operators

Operator Type Description
+ addition returns the first value added to the second
- subtraction returns the second value subtracted from the first
* multiplication returns the first value multiplied by the second
* division returns the first value divided by the second
 % modulus returns the remainder of the first value divided by the second
^ exponential returns the first value to the power of the second
** exponential returns the first value to the power of the second
+= shorthand addition adds the first value to the second
-= shorthand subtraction subtracts the second value from the first
*= shorthand multiplication multiplies the first value by the second
/= shorthand division divides the first value by the second
 %= shorthand modulus divides the first value by the second and returns the remainder

Assignment operator

Operator Type Description
= assigment evaluates the expression on the right hand side and stores in the target variable on the left hand side

String operators

Operator Type Description
+ concatenate concatenates the second value to the first
- concatenate trimmed concatenates the second value to the first after trimming spaces from the end of the first
|| concatenate concatenates the second value to the first after converting to character

Comparison operators

Operator Type Description
 = equals returns true if the first value is equal to the second.
 == equals returns true if the first value is exactly equal to the second or matches the pattern specified in the second value.
 != not equals returns true if the first value is not equal to the second
 # not equals returns true if the first value is not equal to the second
 <> not equals returns true if the first value is not equal to the second
 < less than returns true if the first value is less than the second
 > greater than returns true if the first value is greater than the second
 <= less than or equal returns true if the first value is less than or equal to the second
 >= less than returns true if the first value is greater than or equals to the second
 $ contained in returns true if the left hand side is contained in the right hand side
 | contains returns true if the right hand side is contained in the left hand side
 ? sounds like returns true if the second value sounds like the first

Logical operators

Operator Type Description
and logical and returns true if first and second values are both true
or logical or returns true if either first or second values are true
xor logical xor returns true if either first or second values are true but not both
not logical not returns the inverse if the right hand side value
 ! logical not returns the inverse if the right hand side value

Increment and Decrement operators

Operator Type Description
++var pre-increment returns value after incrementing the variable
var++ pre-increment returns current value before incrementing the variable
--var pre-decrement returns value after decrementing the variable
var-- post-decrement returns current value before decrementing the variable

Constants

Variables each have a type determined by the data they contain. You initialize variables by assigning constants into them. Constants each have a primitive type and are the building blocks for all data in Recital

String constants

The string type is used for textual characters. There is no type for representing just one character. A string is a series of zero or more characters. You delimit string constants using either a double-quote " or a single-quote '.

myvar = "This is a string"
myvar = 'so is this'

Numeric constants

Numeric types in Recital are all stored as floating point numbers with zero or more decimal places.

myvar = 10
myvar = 10.5678

You can also define hexadecimal numeric constants.

myvar = 0x0a

Date constants

Date constants are delimited by curly braces.

// set myvar to 10th of october 2009
myvar = {10/10/2009}

Logical constants

Logical (boolean) constants have one of two values, true or false. The result of any logical comparison expression results in a logical type. (Note: You can also use the older style .t. and .f. to denote true and false respectively.

myvar = true
myvar2 = false
if myvar or myvar2
    /// this will be executed as myvar is true
endif

Currency constants

Currency constants are preceeded by a $.

// set myvar to 1000 dollars
myvar = $1000

Datetime constants

Datetime constants are delimited by curly braces.

// set myvar to 10th of october 2009 at 8.30am
myvar = {10/10/2009 08:30}

Expressions

Expressions and Statements are the building blocks of Recital programs.

Expressions consists of combinations of operands which can be constant values such as strings, numbers, and dates and operands which are symbols that act on these operands in some way e.g. add two numbers together, concatenate two strings etc.

hello = "Hello"
world = "world"
hello_world = hello + " " + world
 
result = 100 * 500 / 2 - 6

Operator precedence in expressions

When you have multiple expression terms as in this example:

result = 100 * 500 / 2 - 6

As a general guideline, the operations are performed in the following order.

  • Expressions are evaluated from left to right
  • Multiplication, Division and exponents are performed before addition and subtraction
  • Expressions in parentheses are evaluated first
  • Mathematical expressions are evaluated before boolean expressions (AND, OR, NOT, XOR)

If in doubt always use parentheses for readability:

result = ((100 * 500) / 2) - 6

Statements

The statement is the basic unit of programming in any programming language. Statements in Recital are delimited by a newline.

echo "Hello world"

You can extend statements over multiple lines by placing a ';' at the end of the line:

echo "Hello ;
world" + ;
" this is a multi-line statement"

Assigment Statements

The assignment statement stores the result of the expression expression into a variable.

variable = expression

If the variable does not exist and STRICT is OFF, then it is created. If the variable already exists, its contents are updated. If the variable does not exist (has not been declared) and STRICT is ON, then an error is thrown. When STRICT is ON, you should pre-declare variables before assigning values to them using the private, public or local commands.

private myvar
 
set strict on
// no error as myvar has already been declared
myvar = "hello world"
 
set strict off
// error as newvar does not been declared
newvar = 10

You can declare and initialize variables in one statement

private myvar = "hello world today is " + cdow( date() )

Recital automatically performs type conversions for variables. If, for example, an existing variable called name contains a character string, and the command name=10 is executed, the variable will automatically be converted to a numeric variable.

If you explicitly tell Recital what type of data can be stored in a variable, it will perform data type checking at runtime.

private myvar as character = "hello world today is " + cdow( date() )
 
// an error will be thrown because myvar was declared as a character
myvar = 10

Control flow statements

The IF command

The if ... endif command is how basic decisions are made in Recital. The if command has a condition and a code body. If the condition evaluates to true then the code body is executed.

name = "bill"
if name = "bill"
    echo "name is bill"
endif

The if ... else ... endif command allows for two-way control flow.

name = "bill"
if name = "bill"
    echo "name is bill"
else
    echo "name is not bill"
endif

The if ... elseif ... endif command allows for multi-way control flow.

name = "bill"
if name = "bill"
    echo "name is bill"
elseif name = "tom"
    echo "name is tom"
elseif name = "mike"
    echo "name is mike"
else
    echo "unknown name"
endif
The DO CASE command

The DO CASE command selects one course of action out of many alternatives. Recital evaluates each CASE condition in turn. As soon as one of the conditions evaluates to true the code body for that CASE is executed and any further case statements are ignored. Following execution of the code body, the program continues after the ENDCASE statement.

OTHERWISE If an OTHERWISE statement is present and no CASE condition evaluates to true the OTHERWISE code body is executed.

ENDCASE If no CASE condition is true and there is no OTHERWISE statement specified, then control skips to the next command following the ENDCASE.

CASE statements, as with all of the other Recital statements can be nested. In other words, a CASE statement can contain further DO CASE commands.

do case
    case upper(command) = "BROWSE"
        echo command
    case upper(command) = "DIR"
        echo command
    otherwise
        echo "Unknown command."
endcase

Looping statements

DO WHILE statement

The DO WHILE command repeats the commands between the DO WHILE and the ENDDO statement, until a specified condition becomes false.

do while condition
    // code body
enddo

If the specified condition is true, then all commands within the DO WHILE loop will be executed. If the specified condition is false, then the first statement following the ENDDO will be executed.

If an EXIT statement is encountered then the DO WHILE loop is exited.

If a LOOP statement is encountered, then control returns to the head of the DO WHILE loop.

Statements within the DO WHILE must be properly nested.

// scan through a database table displaying information about an event
use events
seek "OPERA"
do while event = "OPERA"
    echo event, seats*price
    skip
enddo
FOR statement
for var = startvalue to endvalue [step stepvalue]
    // commands
endfor

The FOR ... ENDFOR command repeats the commands between the FOR and the ENDFOR statement.

The startvalue specifies the loop start point and endvalue the loop end point. These may be numeric or date values.

The FOR...ENDFOR command is equivalent to a counter based DO WHILE ... ENDDO set of commands but FOR ... NEXT is faster.

If the optional STEP stepvalue is specified, then the FOR ... ENDFOR loop will increment by stepvalue. This value can be a positive or negative number. If stepvalue is not specified then the FOR ... ENDFOR loop will increment by 1.

The looping will continue until either endvalue is reached or an EXIT command is encountered.

If a LOOP command is encountered, then control returns to the start of the FOR ... ENDFOR loop.

for i = 1 to 10 step 2
    if i % 1 = 1
        loop
    endif
    echo i*2
endfor
FOREACH statement

The FOREACH command simply gives an easy way to iterate over arrays. FOREACH works on arrays and objects, and will issue an error when you try to use it on a variable with a different data type or an uninitialized variable.

There are two syntaxes; the second is a minor but useful extension of the first:

// static array
private myarray = { "hello", "world" }
 
foreach myarray as value
    echo value
endfor
 
// associative array
private myarray = array("Name" => "Recital", "Description" => "database")
foreach myarray as key => value
    echo "key=" + key + "value=" + value
endfor

The first form loops over the array myarray. On each loop, the value of the current element is assigned to value and the internal array pointer is advanced by one (so on the next loop, you'll be looking at the next element).

The second form does the same thing, except that the current element's key will be assigned to the variable key on each loop. This form works only on associative arrays and objects.

Macros

Variable macro substitution

The & macro function substitutes the contents of the specified variable into the command line. To use a macro in the middle of a word, it is necessary to end the variable name with a '.'. Any type of memory variable can be substituted as a macro.

subscript = 10
i10i = 5
? i&subscript.i
         5

Expression macro substitution

The & macro function can also substitute the result of an expression into the command line. The expression must be enclosed in round brackets.

subscript = "1"
i10i = 5
? i&(subscript + "0")i
         5
str1 = "hello"
str2 = "world"
echo "&str1 &str2"    // output "hello world"

Shell command output substitution

Recital provides tight integration with the unix/linux command shell. The ` ... ` command sequence (backticks) can be used to run external shell commands that are piped together and to substitute the output into a Recital character string.

echo "The default directory is `pwd`"
echo "There are `ls -l *.dbf | wc -l` tables in this directory"

Functions

Defining a Function

Calling a Function

Libraries