Table of contents

Traceur - User guide

Newbie

General information


Scope and usage

This software is designed to produce two-dimensionnal images in PNG format from a source code file. The main idea is that an image is a combination of some parameters such as its size, its background color, and a content. In this language, the content itself of an image is the result of the evaluation of a piece of source code, and then could be assimilated to it.

There are three main usage of this software:


Design constraints

This software has in its design several constraints:


Documentation conventions


Syntax conventions

The syntax of each command will be displayed on a black background, with arguments <within angle brackets and in italic> and optional parts of the instructions [between squared brackets put in italic].

When an optional element can be repeated, a star indicates that [this element can be repeated, and can be absent]* and a plus indicates that [this element can be repeated, but at least one element should be present]+.


Generic programming


What does programming means?

Programming corresponds to give a succession of orders to a computer using a text file. This file is read by a program installed on the computer and this program will execute the orders. This program often produces another file that is only a translation of the orders given in the text file.


Programming actors


The source code

The source code is a text file that contains words, numbers and symbols that shall respect a syntax of a language.

These elements are often arranged to make instructions, which represent the atomic actions in the language. By default, the actions associated to the instructions are executed in the order the instructions are written in the source code. This succession of instruction is generally called execution flow.

Some instructions will modify the execution order. These instructions are called control instructions, as they permit to control the execution flow.

Example of simple source code
disp 2*(3+5)
disp "A"+STRING[3;~03d]
return
disp 2+2

Result:
disp (2)*((3)+(5)): 16 disp ("A")+(STRING[3;~03d]): "A003"

As you can see above, the two first disp instructions where executed in the same order, and the last one was not executed, as it is preceded by a return instruction that terminates the program in this context. In this example, return is a control instruction.


The compiler

The compiler is the program that will read the source code, make several checks on the code, and if the code is correct, will perform some actions.

Strictly speaking, a compiler will translate the source code in another file with another language. The programs that read the source code line by line and execute directly the actions are called interpretors.


The programmer

The programmer is you. You will write the source code with your favourite text editor, call the compiler and check the result of the compiler.


Writing source code

Now, let's go deeper in the art of writting source code! As it has previously written in The source code, the text in the source code follows specific rules that define the programming language.


Lexical rules

Lexical rules indicate how to write every word in the language.

High level languages define several kind of symbols like numbers, reserved words in the language, identifiers, and comments.


Comments

Comments are the only part of the code that will not be read by the compiler. Comments can contain a free text to explain what the code does, or inactivate a part of the code.

Example
This is not a comment //but this is a comment

Constants

The constants are values that are directly written in a text shape in the code. The compiler will automatically convert it to the real value.

Depending on the language, several objects can be written as constants: booleans, numbers, character strings containing text.

Example
2 //is an integer constant
"Traceur" //is a string constant

Types

A type is a special entity that represents the nature of a value, and also specializes the operations that can involve a value of a given type.

The compiler also uses types to check the validity of the operations written in the source code to prevent illegal operations in the code.

When the compiler detects an invalid operation on a type, it usually stops the compilation and answer with an explicit error with the misused operator.

Example
Integer //is the type that represent integers
Boolean //is the type that represent a condition

Identifiers

The role of an identifier is to give a name to a value, to be able to reference it several times in a source code.

A best practice is to give meaningful names to values. For example, bind the name i to an number is not as meaningful as the name point_index.

Example
a_valid_ident1fier_1 //is a valid identifier
1mpossible //is invalid as this one starts with a digit
An_iNvalid_one //is invalid as this one contains at least a capital letter (specific to Traceur)
i //is invalid as this one is too short (specific to Traceur)

Keywords

A keyword is a reserved word in the language, and the compiler will trigger built-in actions on keywords.

You will not be able to define an object with a keyword as name.

Example
error an_error
disp 3 //keywords are in yellow, other elements are in white

Operators

Operators are like keywords, but they represent an explicit operation on values.

Some operators are words, but others are symbols made of a single character that is neither a letter or a digit.

Example
disp 2+3
disp cos (pi/6) //+, cos, pi and / are operators

Syntax

Syntaxic rules indicate how to assemble the words to make valid sentences in the language, such as each instruction and expression.

Example
if Integer index < 5 then
	return "OK"
end //is a valid syntax

then Integer 3 if "KO" return //is not a valid syntax

Semantic

Semantic rules indicate what is the role of each instruction in the language, and what they do.

The semantic analysis can take place only when the syntax of a language is respected.

In the example of the section Syntax, only the first example can be interpreted as an action: if the integer index is lower than five, the string "OK" is returned.


Programming language


Expressions

An expression is a concept taken from mathematical world. Its main goal is to provide a way to write computation on differents values using built-in operators.

The expressions will often be a translitteration of the mathematical ones, with some differents when a mathematical notation can not be written into ASCII plain text.


Functions


Goal of functions

The functions are a nice way to simplify the writting of large programs, as it allow to:

  1. put meaningfull names on values, to explain what are their role in the program;
  2. split the code into logical parts, possibly with the less interactions possible between those parts;
  3. factorize in one place a code that needs to be repeated in the text, to simplify code maintainance.
Code without functions
disp 2+4*5
disp "A"
disp cos (pi/5)

disp 2+4*8
disp "B"
disp cos (pi/8)

disp 2+4*6
disp "C"
disp cos (pi/6)
Same code with functions
let Void display_three_values(Integer integer, String string) :=
do
	disp 2+4*Integer integer
	disp String string
	disp cos (pi/Integer integer)
end

disp Void display_three_values(5,"A")
disp Void display_three_values(8,"B")
disp Void display_three_values(6,"C")

As you can see, the identical code is put in the function definition (the let instruction). The function here works like a pattern that will be applied on three set of values in the last disp instructions. In this case, the function is called from the disp instructions.


Function usage


Function definition

A function is made of two elements. The first one is its prototype, working as an interface to the outside of the function. The prototype also represents the type of the function.

The prototype is <return-type> <function-name> or <return-type> <function-name>(<type> <name>[, <type> <name>]*) where:

The second part of the function is its value, also called body. The value of a function can be an expression or a single instruction. Both kind of values can make references to the parameters like functions.

Functions can be defined with the let instruction.


Function call

A function call is an expression that will execute a function, and substitute the function call by the result of the function.

When the function has some parameters, the function call shall precise some expressions that will be linked to the parameters of the function.

The syntax of a function call is <return-type> <function-name>[(<expression>[, <expression>]*)].

The function to be called is automatically resolved by the compiler, by looking for a suitable function defined in the context of the call. The context at a location of the source code is the set of defined functions that can be called. A function with the same return type, the same name, and the same parameters (number of parameters and types of the parameters) will alw


Instructions

The instructions can be classified in two categories:


Basic instructions


disp

disp is the simplest instruction. It allows the programmer to display the value of an expression in the console.

The syntax is disp <expression>.


let


let

let is the instruction that defines functions.

The syntax to define constant functions is let <type> <name> := <body> where name is an identifier.

Examples of definitions of simple functions
let Integer index := 2
let Integer inner_index := Integer index+1
let String a_text :=
do
	disp "text"
	return "text"
end

The syntax to define functions with parameters is let <type> <name>(<type_x> <name_x>[, <type_y> <name_y>]*) := <body>, where each parameter is declared with a type and a name. The parameters are known in the value as constant functions.

Examples of definitions of functions with parameters
let Integer index(Integer origin, Integer index) := Integer origin+Integer index
let String function(Integer a_value, String a_text) :=
do
	disp Integer a_value+|String a_text|
	return "text_"+String a_text
end

Control instructions


if

The if instruction role is to run a list of instructions only if a certain condition is true.

The condition is represented by an expression with a boolean type.

The syntax is if <boolean-expression> then <list-of-instructions-true-condition> [else <list-of-instructions-false-condition>] end.

When the boolean-expression returns:

Example of if instruction
let Integer integer := 4
if Integer integer < 5 then
	disp "Hello world!"
end

if Integer integer > 3 and Integer integer < 10 then
	disp Integer integer-3
else
	disp Integer integer
	disp "True integer"
end

if MAYBE then //This code will compile, but an error will be raised at execution time
	disp 2
end

Result:
disp "Hello world!": "Hello world!" disp (Integer integer)-(3): 1 +---------------------------------------------------------+ | File -, line 13 > Runtime error: Maybe condition found. | +---------------------------------------------------------+

for

The for instruction role is to execute a list of instructions several times. The number of iterations does not depend on the list of instructions that are executed, as it is determined directly in the command.

The syntax is for <numeric-type> <index-name> from <start-value> to <stop-value> [by <step-value>] do <list-of-instructions> end.

The type of the index can be Integer, Real or Number. Please be aware of the type of the start, stop and step values. The following example will not compile, because the to value is an integer, and is not convertible to a real number:

for Real index from 1. to 5
do
	disp Real index
end

Result:
+------------------------------------------------------------------------------------------------------------------------+ | File -, line 1 > Compilation error: Incorrect type Integer in to part of for loop. Type compatible with Real expected. | +------------------------------------------------------------------------------------------------------------------------+
Example of for instruction
let Integer total := 0
for Integer index from 1 to 10 by 2 //Integer index will be equal to 1, 3, 5, 7 and 9
do
	disp (Integer index+1)/2
	let Integer total := Integer total+Integer index
	disp Integer total
end
disp "Total:"
disp Integer total

Result:
disp ((Integer index)+(1))/(2): 1 disp Integer total: 1 disp ((Integer index)+(1))/(2): 2 disp Integer total: 4 disp ((Integer index)+(1))/(2): 3 disp Integer total: 9 disp ((Integer index)+(1))/(2): 4 disp Integer total: 16 disp ((Integer index)+(1))/(2): 5 disp Integer total: 25 disp "Total:": "Total:" disp Integer total: 25

while

The while instruction is a loop instruction, like the for instruction, with a small difference: the number of iterations is not known in advance. The instructions in the loop will be executed while a certain condition is true.

The syntax is while <boolean-expression> do <list-of-instructions> end.

Before each execution of the list-of-instructions, the boolean-expression is evaluated. When this expression returns:

Example of while instruction
let Integer randsum := 0
let Integer nbiterations := 0
while Integer randsum <= 100
do
	let Integer randsum := Integer randsum+(rand%10)
	let Integer nbiterations := Integer nbiterations+1
end
disp Integer nbiterations

Result:
disp Integer nbiterations: 20

As the condition is determined by the contents of the loop, you must ensure that the condition becomes false on at least one iteration. If you are not careful about this, the execution can be stuck in an infinite loop.

If the first time the condition is evaluated, the value is FALSE, the list-of-instructions is not executed.


Interruption instructions


return

The return instruction stops the current flow of execution and raise a value to the the upper context. The execution restarts at the level of the latest function call. Its main role is to return the result value of a function.

The syntax is return [expression]. If the expression is not present, the void expression is returned.

The compiler will raise an error when a function with a non void return type can reach the end of its value without any return instruction.

Example of missing return instruction
let Integer function(Boolean param) :=
	if Boolean param then
		return 1
	end

Result:
+-------------------------------------------------------------------------------------------------------------+ | File -, line 1 > Compilation error: Missing return instruction in function Integer function(Boolean param). | +-------------------------------------------------------------------------------------------------------------+

Graphical programming


Images


Image structure

An image is a two-dimensional array of pixels having as value a color. The vertical and horizontal numbers of pixels are called size, and is a characteristic of the image. Before any drawing, an image has each pixel set to a default color called background color.


Instructions

To manipulate images, some specific instructions are needed. Some are dedicated to modify the content of the image, when others will do an operation on the whole image.


Instruction with

The with instruction will change the color used to draw on images.


Instruction draw

The draw instruction will take an argument and write on the image the result of this argument.

This argument can be void or can be a graphical tool such as a point, a line or another graphical tool.


Instruction write

When an image is defined, a normal operation is to write it to a file. The write instruction will take an image and a string containing the file name and will write this image to the file.


Colors


Definitions

A color can be defined in two ways. The first one is purely formal, considering that a color is a combination of values called channels. A color can be represented by a red channel, a blue channel and a green channel, with integer values between 0 and 255. It can also represented by a hue, a saturation and a value. In the last system, a saturation of 100% leads to a color with the full hue, and a saturation to 0% leads to a white color. In the same way, a value of 100% leads to a full color, and a value of 0% leads to black color.

The second way is linked to the language of the traceur. A color is the value linked to a pixel in an image. The traceur has a RGB (Red, Green, Blue) representation with a fourth channel that represents the opacity of the color. This last channel is called alpha. This channel is not part of the color, and you should care about the color when the opacity is set to 0, meaning full transparency. For example, a full transparent black is not the same color as a full transparent white.


Developer

Generic programming


Programming actors


The compiler

Traceur is a compiler that will directly execute the object code contained in its internal memory, right after the compilation and link edition phases.

The compiler is invocated by the command "traceur" followed by the list of source code files to compile. The compiler will compile all files before executing the code.

The character - will force the compiler to read from its standard input. If a file parameter starts with the character =, this character will be replaced by the first existing directory in this order:

  1. contained in the TRACEUR environment variable,
  2. ~/.traceur,
  3. a system directory set up at compilation time (usually in /usr/share/traceur).

Invoked without any parameters, the compiler will read from its standard input.


Writing source code


Lexical rules


Comments

Comments starts with // or #! and ends at the end of the line.


Constants


Types

In Traceur, only built-in types are possible. It will be impossible to define user types. All types names begin with a capital letter.

The generic types are:


Identifiers

An identifier starts with a low case letter, contains at least five characters, and can be made of low case letters, digits and underscores.


Keywords

Keywords of Traceur: let, rec, func , :=, disp, do, end, if, then, elif, else, for, from, to, by, while, until, next, return, exit, error, try, catch.

Note that only while, until, return, error and catch are in conflict with identifier namespace.


Operators

Operators are: +, -, *, /, %, ^, ° or deg, rad, cos, sin, tan, acos, asin, atan, exp, ln, sqrt, pi, rand, min, max, gcd, lcm, | value |, int, frac, not, and, or, xor, = or ==, <> or !=, <, <=, >, >=, CATCH.


Constructors

Constructors are specific words all in capital letters used to build values of a specific type from other values.

The syntax of constructors is <CONSTRUCTOR>[[<parameter>[; <parameter>]*]].

Supported constructors are: TRUE, FALSE, MAYBE, INTEGER, REAL, STRING.


Programming language


Expressions

The syntax of constant values are quite important, as the compiler will deduce their type from it:

Operators can be prefixed, infixed or postfixed depending on the operator itself. They are separated from theirs arguments by a space, and arguments does not need to be put inside parenthesis.


Functions


Function usage


Function definition

A function is made of a prototype linked to a value that can be parametrized.

The syntax of the prototype is one of those two possibilities:

The identifier is the function name, and the function can take left and/or right parameters. The return value of a function can be a value (first line) or a function (second line).

There are two kind of functions:

Example of imaginary function
let [Integer function(Integer param)] function(Integer param) :=
do
	let Integer local(Number param1) := Integer param
	let Integer local(Integer param1) := Integer param*(1+Integer param1)
	return func Integer local(Integer param) //imaginary function definition linked to the second local function
end
let Integer (Integer local(Integer param))function(Integer param1, Integer param2) :=
	if Integer param1 < Integer param2 then
		return Integer local(Integer param1)+Integer param2
	else
		return Integer local(Integer param2)
	end

disp Integer ([Integer function(Integer param)] function(2))function(3,5)

Result:
disp Integer ([Integer function(Integer)] function(2))function(3,5): 13

Function call

The syntax of a function call is <return-type> [(<expression>[, <expression>]*)]<function-name>[(<expression>[, <expression>]*)].

The function that will be called is the nearest function with the same name and number of parameters on each side, with the less type conversion possible on the parameters and the return type.


Instructions


Basic instructions


disp

disp <expression> will print the expression and its result on the standard output of the compiler.

disp without argument will print on the standard error the execution back trace with function calls, and for each frame, will display the value of each defined function.


let


let

let is the instruction that defines functions. Its syntax is let <prototype> := <body>.

The value can be an expression or a single instruction. The return type of the value shall match the return type of the prototype.

The prototype structure is defined in Function definition.


let rec

To define a recursive function, the keyword rec need to be added to the let instruction: let rec <prototype> := <body>.

Please note that the context outside a recursive function is not accessible from its body, and no imaginary function can be linked to a recursive function inside its definition. It is also impossible to redefine a function with the same prototype of a recursive function within let and let rec instructions inside the recursive function definition.


Control instructions


do

The role of the do instruction is to reduce the scope of function declaration and redeclaration. The syntax of this instruction is do [<list-of-instructions>] end.

The do effect
let Integer index := 1 //instance one
disp Integer index //index instance one contains 1
do
	disp Integer index //index instance one contains 1
	let Integer index := 2 //instance two
	disp Integer index //index instance two contains 2
	let Integer index2 := 3 //instance three
	disp Integer index2 //index instance three contains 3
end
disp Integer index //index instance one contains 1
//Integer index2 is unknown here

Result:
disp Integer index: 1 disp Integer index: 1 disp Integer index: 2 disp Integer index2: 3 disp Integer index: 1

The do instruction will also agregate several instructions in one. It is useful when defining a function, as it allows function bodies to be more complex than a real simple instruction.


if

The syntax of the if instruction is if <boolean-expression> then <list-of-instructions-true-condition> [elif <alternate-boolean-condition> then <list-of-instructions-alternate-condition>]* [else <list-of-instructions-false-condition>] end.

This structure will play the role of the basic if-then-else instruction, and the role of the switch-case instruction of several languages. The only difference is that all conditions must be explicitly written.

When several conditions are present in the instruction, the first clause found with a true condition is executed. If no condition equals true, and a else clause is present, this clause is executed.

If a condition is evaluated to MAYBE, the runtime error maybe_condition_found is raised.


for

The syntax of the for instruction is for <numeric-type> <index-name> from <start-value> to <stop-value> [by <step-value>] do <list-of-instructions> end.

The start value, stop value, and step value are evaluated only once, before running the for loop. If the start value is greater than the stop value, with a positive step value, the loop will not be executed.

The keywords do and end are parts of the instruction, and are not a do instruction. The functions defined outside the for loop can be modified inside the loop.


while

The syntax of the while loop is while <boolean-expression> do <list-of-instructions> end.

The condition is evaluated before the instructions, and the list-of-instructions is executed while the condition is true. When the boolean-expression becomes MAYBE, a runtime error maybe_condition_found is raised during the execution.


until

The syntax of the until loop is do <list-of-instructions> until <boolean-expression> end.

The condition is evaluated after the instructions, and the list-of-instructions is executed until the boolean-expression is true. The list-of-instructions is executed at least once with this instruction. When the boolean-expression becomes MAYBE, a runtime error maybe_condition_found is raised during the execution.


try catch

The syntax of the try instruction is try <list-of-instructions-try> [catch(<name-of-error>[, <name-of-error>]*) <list-of-instructions-specific-catch>]* [catch <list-of-instructions-generic-catch>] end with at least one catch clause.

The try instruction will execute the list-of-instructions-try. If no runtime error is raised, the execution continues after the end of the instruction. Otherwise, the first catch clause that contains the name of the raised error will be executed. If no specific catch clause is found and the generic clause is present, this clause is executed.

The name of an error can be easily found from the error message. For example,

+---------------------------------------------------+
| File -, line 1 > Runtime error: Division by zero. |
+---------------------------------------------------+

is the division_by_zero runtime error. The name is deduced from the error message, putting a low case letter at the beginning, and replacing all spaces by an underscore.


Interruption instructions


return

The syntax of the return instruction is return [<expression>].

When the expression is missing, the void expression is returned. All functions with non void return type shall terminate on an interruption instruction. When it is not the case, a compilation error is raised by the compiler.

The expression of the return instruction can be an imaginary Function definition.


error

The syntax of the error instruction is error <error-name>, where an error name is an identifier. This identifier shall not be declared, and has no relation with function names.

The error will be raised like an error from an operator or an instruction, and can be catched with the try catch instruction.


exit

The syntax of the exit instruction is exit [<level>], where level is a positive integer constant. When the level is not given, one is taken by default.

The exit instruction will immediately exit every nested for, while, and until loop instruction. The number of exited loop equals to the level given in argument.

One exception: if zero is given in argument, the execution ends immediately without error.


next

The syntax of the next instruction is next [<level>], where level is a positive integer constant. When the level is not given, one is taken by default.

The next instruction will immediately jump to the next iteration of the n-th nested for, while, and until loop instruction, where n is the level given in argument.


Graphical programming


Images


Image structure

The syntax of an image is IMAGE[<first-size>;<second-size>] [<coordinate-system>] [<background-color>] { <content> } where the sizes are integer, the coordinate system is a special concept having its own constructors and the content is a sequence of instructions.

The images have their own type: Image.


Kernels

Kernels are special bitmaps used for the convolution instruction. Kernels has odd sizes, no background color, and the values of the color and alpha channels are real numbers initialised to zero.

The syntax of a kernel is quite similar to images: KERNEL[<first-size>;<second-size>] [<coordinate-system>] { <content> }.

Kernels have their own type: Kernel.


Coordinates systems


Geometrical system

The geometry coordinate system is the default one. The origin is set to the center of the image, the first axis is horizontal, oriented to the right, and the second axis is vertical, to the upper side of the image. The center of each pixel has an integral coordinate on both axis.

When explicitely mentionned, the syntax of this coordinate system is GEOMETRY.


Standard system

The standard coordinate system has its origin set to the top left corner of the image, the first axis is vertical, oriented to the bottom, and the second axis is horizontal, to the right side of the image. The center of each pixel has an integral coordinate on both axis.

The syntax of this coordinate system is STANDARD.


Mathematical system

The mathematical coordinate system allows the programmer to define the coordinates of the center of the bottom-left and top-right pixels of the image.

This coordinate system has two possible syntax: MATHEMATICAL[<Point bottom-left>;<Point top-right>] or MATHEMATICAL[<Number xmin>;<Number xmax>;<Number ymin>;<Number ymax>]


Instructions


Instruction with

While defining the content of an image, the drawing instructions will use a color defined by the context of the instruction. The with instruction will modify the current color on the current image.

The syntax the the with instruction is with <Color new_color>.


Instruction draw

In order to draw on images and kernels, the draw instruction should be used. Depending on the arguments, draw can do several operations:

The syntax of the draw command is draw <expression> or draw <image> at <position> [by <alpha>].


Instruction write

The write instruction will write an image to a file in the PNG format. The files will be written only if no error is raised by the program.

The syntax is write <image> to <filename> where the file name is a string with the .png extension.


Instruction read

The read instruction will open the file named by the instruction argument, and will replace the content of the bitmap of the current image by the bitmap contained in the file.

The syntax is read from <filename> where the file name is a string containing the path and whole file name of the image to read.


Instruction conv

The conv instruction will compute the convolution on the current image by the kernel given in argument. All the pixels outside the image will have the background color as value for the computation of the convolution. The result of the convolution replaces the content of the current image.

The syntax of the conv instruction is conv <kernel>.


Instruction for

The for instruction can be used with a point as index value. The start value and end value are then points and the step is a vector.

In this case, the for loop will be equivalent to two for loops, the outer one on the first coordinate, the inner one on the second coordinate. This loop will not be considered as two loops for the next and exit instructions.

The syntax is for Point <index-name> from <start-point> to <stop-point> [by <step-vector>] do <list-of-instructions> end


Instruction next

When invoqued with the argument 0, the next instruction will terminate the code that defines the current image. The next executed instruction is the one right after the end of the image.

The syntax is next 0.


Geometry


Point


Definition

A point is the representation in the language of a pixel on one image. The coordinates of a point is linked to the coordinates system of the current image, and are linked to the center of each pixel in the image.


Syntax

A point has its own type Point, and has two constructors: POINT[<first coordinate>; <second coordinate>] where each coordinate is a number, and POINT[<vector>].

The meaning of the first and second coordinates depends on the coordinates system of the current image.


Vector


Definition

A vector is a pure geometrical entity like in the mathematical world. It supports some basic geometrical operations such as the Chasles operations, homothetias, symetries, projections and rotations.


Syntax

A vector has its own type Vector, and has several constructors:


Geometrical operators


Point operators

The vector operators are the common operations between vectors:

Operator Return type Comment
cos <Point> Number First cartesian coordinate
sin <Point> Number Second cartesian coordinate
| <Point> | Real Distance to the origin
atan <Point> Real Angle in radians between the first axis and the point
<Point> = <Point> Boolean Return TRUE when the two points are the same pixel on the current image
<Point> <> <Point> Boolean Return TRUE when the two points are not the same pixel on the current image

Vector operators

The vector operators are the common operations between vectors:

Operator Return type Comment
+ <Vector> Vector Identity
- <Vector> Vector Opposite
<Vector> + <Vector> Vector Chasles operation
<Vector> - <Vector> Vector Chasles operation
<Vector> * <Vector> Number Scalar product
<Vector> ^ <Vector> Number Norm of the vectorial product
cos <Vector> Number First cartesian coordinate
sin <Vector> Number Second cartesian coordinate
| <Vector> | Real Norm of the vector
atan <Vector> Real Argument of the vector
<Vector> = <Vector> Boolean Return TRUE when the two vectors have the same cartesian coordinates
<Vector> <> <Vector> Boolean Return TRUE when the two have not the same cartesian coordinates

Transformations

Transformations are operations on vectors and points that have a meaning in geometry:

Operators Return type Comment
<Point> + <Vector> Point Translation
<Point> - <Point> Vector Offset
<Vector> * <Number> Vector Homothety
<Vector> / <Number> Vector Homothety
<Number> * <Vector> Vector Homothety
<Vector> ^ <Number> Vector Rotation with angle in radians
<Vector> / <Vector> Vector Projection on the second vector
<Vector> % <Vector> Vector Symetry by the second vector

Colors


Definitions

The traceur uses a RVBA representation of colors with 8 bits depth, and can handle the HSVA representation as well.

The color on a kernel is a RVBA representation with real numbers instead of 8 bits channels.


Syntax

The color has it own type Color and has several constructors:


Color operators

Colors can be computed using some operators:

Operator Return type Comment
<Color> + <Number> Color Increase saturation
<Color> - <Number> Color Decrease saturation
<Color> * <Number> Color Increase value
<Color> / <Number> Color Decrease value
<Color> % <Number> Color Increase alpha
<Color> ^ <Number> Color Change hue, with angle in degrees
<Color> - <Color> Number Distance between two colors
| <Color> | Color Equivalent color in grey level
<Color> / <Color> Color Resulting color after application of the first one on the second one
RED[<color>] Number Returns the red channel of the given color
GREEN[<color>] Number Returns the green channel of the given color
BLUE[<color>] Number Returns the blue channel of the given color
ALPHA[<color>] Number Returns the alpha channel of the given color
HUE[<color>] Number Returns the hue of the given color
SATURATION[<color>] Number Returns the saturation of the given color
VALUE[<color>] Number Returns the value of the given color

The operators that increases or decreases the saturation and the value work in the opposite way when the number is negative.


Drawing tools


Syntax

The drawing tools are special expressions that can be used by the draw instruction to draw some specific elements to the current image.

All tools can be designed under the type Tool and each tool has its own type that is compatible with the generic tool type.

Each time options are availables for a tool, they are written after the last argument, separated from the other arguments by a semi-colon, and are separated by a coma between options. When options have their own parameters, the syntax is the same as the constructors.


Tools based on a point


Point

The draw instruction can take a point as argument, and will draw a dot on the image at the given coordinates.

There is no option available for this tool.


Solid

The solid tool has its own type , and has one constructor: SOLID[<point>].

This tool will draw a dot, by replacing the color by the current color, instead of applying it on the previous color.

There is no option available for this tool.


Eraser

The eraser tool has its own type Eraser, and has one constructor: ERASER[<point>].

This tool will draw a dot, by replacing the color by the background color, instead of applying the current color on the previous color.

There is no option available for this tool.


Fill

The fill tool has its own type Fill, and has one constructor: FILL[<point>].

This tool will fill a surface from the point given in argument. The surface that will be colored is the smallest contiguous region with pixels of the same color of the color of the pixel at the given point before drawing the current color.

There are three options available:


Tools based on a line


Line

The line tool has its own type Line, and has two constructors:


Options

There are some options for line based tools:


Tools based on a surface


Triangle

The triangle tool has its own type Triangle, and has two constructors:


Rectangle

The rectangle tool has its own type Rectangle, and has several constructors:


Circle

The circle tool has its own type Circle, and has several constructors:


Options

There are three options available for all surface based tools:


Guru

Generic programming


Writing source code

Traceur grammar is LALR(1) strict.


Lexical rules


Types

No array and no map are defined in Traceur language. As Traceur is function oriented, both structures will be represented by functions.

The returned value can be partially computed from the key, like every function. Only a prototype that can be identified to an array or a map is sufficient to reproduce the behaviour of these structures.


Operators


Simple operators

Concerned operators are:

Syntax Return type Comment Errors
pi Real
rand Integer

Unary operators

Concerned operators are:

Syntax Return type Comment Errors
+<Integer> Integer
+<Real> Real
+<Number> Number
-<Integer> Integer
-<Real> Real
-<Number> Number
int <Integer> Integer
int <Real> Real
int <Number> Number
frac <Integer> Integer
frac <Real> Real
frac <Number> Number
<Integer> deg Integer Converts angle in degrees to radians.
<Real> deg Real Converts angle in degrees to radians.
<Number> deg Number Converts angle in degrees to radians.
<Integer> rad Integer Converts angle in radians to degrees.
<Real> rad Real Converts angle in radians to degrees.
<Number> rad Number Converts angle in radians to degrees.
|<Integer>| Integer
|<Real>| Real
|<Number>| Number
|<String>| Number String length.

Mathematical functions

All mathematical operators are prefixed. Concerned operators are:

Returned type:

Argument Returned type
<Integer> Real
<Real> Real
<Number> Real

All these operators raise out_of_range when the argument is outside its mathematical definition range.


Binary operators

All binary operators are infixed. Concerned operators are:

Returned type:

left\right <Integer> <Real> <Number> <String>
<Integer> Integer Real Number
<Real> Real Real Number
<Number> Number Number Number
<String> String

Special cases:


GCD and LCM operators

All binary operators are infixed. Concerned operators are:

Syntax Return type Comment Errors
<Integer> gcd <Integer> Integer
<Integer> lcm <Integer> Integer

Boolean operators

Concerned operators are:

Returned type:

Syntax Return type Comment Errors
not <Boolean> Boolean
<Boolean> and <Boolean> Boolean
<Boolean> or <Boolean> Boolean
<Boolean> xor <Boolean> Boolean

Logical table:

<A> <B> not <A> <A> and <B> <A> or <B> <A> xor <B>
TRUE TRUE FALSE TRUE TRUE FALSE
TRUE FALSE FALSE FALSE TRUE TRUE
FALSE TRUE TRUE FALSE TRUE TRUE
FALSE FALSE TRUE FALSE FALSE FALSE
TRUE MAYBE FALSE MAYBE TRUE MAYBE
FALSE MAYBE TRUE FALSE MAYBE MAYBE
MAYBE TRUE MAYBE MAYBE TRUE MAYBE
MAYBE FALSE MAYBE FALSE MAYBE MAYBE
MAYBE MAYBE MAYBE MAYBE MAYBE MAYBE

Comparison operators

All binary operators are infixed. Concerned operators are:

Returned type:

left\right <Integer> <Real> <Number> <String>
<Integer> Boolean Boolean Boolean
<Real> Boolean Boolean Boolean
<Number> Boolean Boolean Boolean
<String> Boolean

Special cases:


Catch operator

The catch operator will evaluate an expression, and if this expression raises an error, will replace this error by the result of the evaluation of an alternate expression.

The catch operator can catch a specific error, or catch all possible errors. The type returned by the alternate expression shall be compatible with the normal expression.

The syntax of the catch operator with specific error is CATCH[<expression>; <name of the error>; <alternate expression>].

The syntax of the catch operator with any error is CATCH[<expression>; <alternate expression>].


Constructors

Syntax Return type Comment Errors
TRUE Boolean
FALSE Boolean
MAYBE Boolean Neither true or false.
INTEGER[<Integer>] Integer
INTEGER[<Real>] Integer Build the nearest integer.
INTEGER[<Number>] Integer Build the nearest integer when the parameter is a real value.
INTEGER[<String>] Integer Build integer with litteral value. Raise error invalid_integer_conversion if the string does not represent an integer.
REAL[<Integer>] Real
REAL[<Real>] Real
REAL[<Number>] Real
REAL[<String>] Real Build real with litteral value. Raise error invalid_real_conversion if the string does not represent a real.
STRING[<Integer>;<format>] String Integer format is ~i, ~d, ~o, ~x, ~X with printf options. Raise error invalid_format if the first argument is not an integer.
STRING[<Real>;<format>] String Real format is ~f, ~F, ~e, ~E with printf options. Raise error invalid_format if the first argument is not a real.
STRING[<Number>;<format>] String Try to build the string from a number. Raise error invalid_format if the first argument does not correspond to the format.
STRING[<String>;<format>] String String format is ~s. Raise error invalid_format if the first argument is not a string.

Programming language


Functions


Function usage


Function definition

Let see deeper in imaginary functions. A value can in fact be bound to an imaginary function during its creation. The syntax of the imaginary function definition with a body is func <prototype> := <body>. In this case, two functions are defined, a real one and an imaginary one, linked to the real one. This imaginary function scope is the instruction where it is defined, like a lambda function.

The value can have access to the parameters defined in the prototype, and the real function implied here can be recursive. To define a recursive lambda function, the syntax is func rec <prototype> := <body>.

Example of lambda function
let [Integer function(Integer param)] function(Integer param) :=
	return func Integer local(Integer param1) := Integer param*(1+Integer param1)

let Integer (Integer local(Integer param))function(Integer param1, Integer param2) :=
	if Integer param1 < Integer param2 then
		return Integer local(Integer param1)+Integer param2
	else
		return Integer local(Integer param2)
	end

disp Integer ([Integer function(Integer param)] function(2))function(3,5)
disp Integer (func Integer lambda(Integer param) :=
do
	disp "lambda function called"
	return 12+5*Integer param
end
)function(3,5)

Result:
disp Integer ([Integer function(Integer)] function(2))function(3,5): 13 disp "lambda function called": "lambda function called" disp Integer (func Integer lambda(Integer param) := do disp "lambda function called" return (12)+((5)*(Integer param)) end )function(3,5): 32

Function call

There are two ways of passing functions in parameter of another function:


Instructions


Basic instructions


let


let func

The syntax of the let func instruction is let func <prototype> := <body>.

The difference with the simple let (Developer) is on the the match between the prototype and the return type of the value. In the simple let instruction, the return type of the value must match the return type of the prototype. In a let func instruction, this return type shall match the whole prototype. The value is an instruction or an expression, and can not call the parameters defined in the prototype.

There are two main usages of the let func instruction:


Graphical programming


Instructions


Instruction with

When the previous color need to be restored after some drawing, the with instruction can be used with a sequence of instructions, using the syntax with <Color new_color> { <list-of-instructions> }.