Built-ins in Evy are pre-defined functions and events that allow for user interaction, graphics, animation, mathematical operations, and more.
Functions are self-contained blocks of code that perform a specific task. Events are notifications that are sent to a program when something happens, such as when a user moves the mouse or presses a key.
For a more formal definition of the Evy syntax, see the Language Specification, and for an intuitive understanding see syntax by example.
- Input and Output
print, read, cls, printf - Types
len, typeof - Map
has, del - Program control
sleep, exit, panic, test - Conversion
str2num, str2bool - Errors
Panic, Recoverable Errors - String
sprint, sprintf, join, split, upper, lower, index, startswith, endswith, trim, replace, repr - Random
rand, rand1 - Math
min, max, abs, floor, ceil, round, pow, log, sqrt, pi, sin, cos, atan2 - Graphics
move, line, rect, circle, color, colour, hsl, width, clear, grid, gridn, poly, ellipse, stroke, fill, dash, linecap, text, font - Event Handlers
key, down, up, move, animate, input
print prints the arguments given to it to the output area. It separates them by
a single space and outputs a newline character at the end.
print "Hello"
print 2 true "blue"
print "array:" [1 2 3]
print "map:" {name:"Scholl" age:21}
Output
Hello
2 true blue
array: [1 2 3]
map: {name:Scholl age:21}
print a:any...
The print function prints its arguments to the output area, each
separated by a single space and terminated by a newline character. If
no arguments are provided it only prints the newline character.
The backslash character \ can be used to represent special characters
in strings. For example, the \t escape sequence represents a tab
character, and the \n escape sequence represents a newline character.
Quotes in string literals must also be escaped with backslashes,
otherwise they will be interpreted as the end of the string literal.
For example:
print "Here's a tab: 👉\t👈\nShe said: \"Thank you!\""
Output
Here's a tab: 👉 👈
She said: "Thank you!"
In a browser environment print outputs to the output area. When
running Evy from the command line interface, print prints to standard
out.
read reads a line of input from the user and returns it as a
string. The newline character is not included in the returned string.
name := read
print "Hello, "+name+"!"
Input
Mary Jackson
Output
Hello, Mary Jackson!
read:string
The read function returns a string that contains the line of input
that the user entered up until, excluding the newline character. It is
a blocking functions, which means that it will not return until the
user has entered a line of input and pressed the Enter key.
In a browser environment read reads from the text input area. When
running Evy from the command line interface, read reads from standard
in.
cls clears the output area of all printed text.
print "Hello"
sleep 1
cls
print "Bye"
Output
Bye
cls
The cls function clears all text output. In a browser environment
cls clears the output area. When running Evy from the command line
interface, cls clears the terminal, similar to the Unix clear or
Windows cls commands.
printf stands for print formatted.
printf prints its arguments to the output area according to a format
string. The format string is the first argument, and it
contains specifiers. Specifiers start with a percent sign %. They
tell the printf function how and where to print the remaining
arguments inside the format string. The rest of the format string is
printed to the output area without changes.
Here are some valid specifiers in Evy:
| Specifier | Description |
|---|---|
%v |
the argument in its default format |
%q |
a double-quoted string |
%% |
a percent sign % |
printf "The tank is 100%% full.\n\n"
weather := "rainy"
printf "It is %v today.\n" weather
rainfall := 10
printf "There will be %vmm of rainfall.\n" rainfall
unicorns := false
printf "There will be unicorns eating lollipops: %v.\n\n" unicorns
quote := "Wow!"
printf "They said: %q\n" quote
printf "Array: %v\n" [1 2 3]
printf "Map: %v\n" {a:1 b:2}
Output
The tank is 100% full.
It is rainy today.
There will be 10mm of rainfall.
There will be unicorns eating lollipops: false.
They said: "Wow!"
Array: [1 2 3]
Map: {a:1 b:2}
printf format:string a:any...
The printf function prints its arguments to the output area according
to the format string that is the first argument. The specifiers
that start with % and are contained in the format string are replaced
by the remaining arguments in the given order. For example, the
following code printf "first: %s, second: %s" "A" "B" prints first: A, second: B.
Full list of valid specifiers in Evy:
| Specifier | Description |
|---|---|
%v |
the argument in a default format |
%t |
the word true or false |
%f |
decimal point (floating-point) number, e.g. 123.456000 |
%e |
scientific notation, e.g. -1.234456e+78 |
%s |
string value |
%q |
a double-quoted string |
%% |
a literal percent sign %; consumes no value |
If the arguments for the %s, %q, %f, %e, and %t specifiers do
not match the required type, a panic will occur.
The width and precision of a floating-point number can be specified
with the %f and %v format specifiers.
- Width is the number of characters that will be used to print the number. If the width is not specified, it will be calculated based on the size of the number. It can be useful for padding and aligned output.
- Precision is the number of decimal places that will be displayed. If
the precision is not specified, it will be set to 6 for
%f.
Here is a table that shows the different ways to specify the width and precision of a floating-point number:
| Verb | Description |
|---|---|
%f |
default width, default precision |
%7f |
width 7, default precision |
%.2f |
default width, precision 2 |
%7.2f |
width 7, precision 2 |
%7.f |
width 7, precision 0 |
If the width/precision is preceded by a -, the value is padded with
spaces on the right rather than the left. If it is preceded by a 0, the
value is padded with leading zeros rather than spaces.
The width, precision and alignment prefix (- or 0) can be used with
all valid specifiers. For example:
printf "right: |%7.2f|\n" 1
printf "left: |%-7.2v|\n" "abcd"
printf "zeropad:|%07.2f|\n" 1.2345
Output
right: | 1.00|
left: |ab |
zeropad:|0001.23|
len returns the number of characters in a string, the number of
elements in an array or the number of key-value pairs in a map.
l := len "abcd"
print "len \"abcd\":" l
l = len [1 2]
print "len [1 2]:" l
l = len {a:3 b:4 c:5}
print "len {a:3 b:4 c:5}:" l
Output
len "abcd": 4
len [1 2]: 2
len {a:3 b:4 c:5}: 3
len:num a:any
The len function takes a single argument, which can be a string, an
array, or a map. If the argument is a string, len returns the number
of characters in the string. If the argument is an array, len returns
the number of elements in the array. If the argument is a map, len
returns the number of key-value pairs in the map. If the argument is of
any other type, a panic will occur.
typeof returns the type of the argument as string value.
a:any
a = "abcd"
t := typeof a
print "typeof \"abcd\":" t
t = typeof {kind:true strong:true}
print "typeof {kind:true strong:true}:" t
t = typeof [[1 2] [3 4]]
print "typeof [[1 2] [3 4]]:" t
t = typeof [1 2 true]
print "typeof [1 2 true]:" t
print "typeof []:" (typeof [])
Output
typeof "abcd": string
typeof {kind:true strong:true}: {}bool
typeof [[1 2] [3 4]]: [][]num
typeof [1 2 true]: []any
typeof []: []any
typeof:string a:any
The typeof function takes a single argument, which can be of any type.
The function returns a string that represents the type of the argument.
The string returned by typeof is the same as the type in an Evy
program, for example num, bool, string, []num, {}[]any. For
an empty composite literal, typeof returns [] or {} as it can be
matched to any subtype, e.g. [] can be passed to a function that
takes an argument of []num, or []string.
has returns whether a map has a given key or not.
map := {a:1}
printf "has %v %q: %t\n" map "a" (has map "a")
printf "has %v %q: %t\n" map "X" (has map "X")
Output
has {a:1} "a": true
has {a:1} "X": false
has:bool map:{} key:string
The has function takes two arguments: a map and a key. It returns true
if the map has the key, and false if the map does not have the key. The
map can be of any value type, such as {}num or {}[]any and the key
can be any string.
del deletes a key-value entry from a map.
map := {a:1 b:2}
del map "b"
print map
Output
{a:1}
del map:{} key:string
The del function takes two arguments: a map and a key. It deletes the
key-value entry from the map if the key exists. If the key does not
exist, the function does nothing. The map can have any value type, and
the key can be any string. It is safe to delete values from the map
with del while iterating with a for … range loop.
sleep pauses the program for the given number of seconds.
sleep can be used to create delays in Evy programs. For example, you
could use sleep to create a countdown timer.
In the browser platform sleep pauses a minimum of 1
millisecond.
print "2"
sleep 1
print "1"
Output
2
1
sleep seconds:num
The sleep function pauses the execution of the current Evy program for
at least the given number of seconds. Sleep may also pause for a
fraction of a second, e.g. sleep 0.1.
exit terminates the program with the given status code.
input := "not a number"
n := str2num input
if err
print errmsg
exit 1
end
print n
Output
str2num: cannot parse "not a number"
panic prints the given error message and terminates the program
immediately. It is used to report unrecoverable errors.
scale := -5
if (scale) <= 0
panic "scale must be positive"
end
Output
line 4 column 5: scale must be positive
panic msg:string
The panic function takes a single argument, which is the error message
that the program will print before it terminates with exit status 1.
test is used to check if a condition is true or two values – want and
got – are the same. If the condition is not true or the two values are not
the same, the program will print the failed test and terminate with exit
status 1.
test optionally takes a message or a format string with arguments to
print along with the failed test as a third and following arguments:
answer := 6 * 9
test 42 answer "answer is 42 not %v" answer
Output
❌ 1 failed test
✔️ 0 passed tests
line 2 column 9: failed test: want != got: 42 != 54 (answer is 42 not 54)
test cond:bool
test want:any got:any [msg:string [argsany...]]
The test function takes either a single boolean argument cond
and ensures it is true, or two arguments want and got, in that order,
and ensures they are the same.
In the case of the single argument, the argument must be of type bool.
test verifies that this argument has the value true. If cond is false,
test terminates the program execution and prints the failed test.
In the case of two arguments, want and got, test verifies
the arguments are the same. If they are not the same test terminates the
program execution and prints the failed test.
Sameness of want and got means either want == got or want and
got are composite values, arrays or maps, containing the same values.
want can be of a more specific type than got as long as their values
are the same. For example, the following test holds true even though
want is of type [][]num and got is of type []any.
got:[]any
got = [[1] [2 3]]
test [[1] [2 3]] got
In the case of three arguments, the third argument is a message of type
string that is printed if the test fails.
In case of four or more arguments, the third argument is a format string
with specifiers. The remaining arguments are the arguments are used to
replace these specifiers, see sprintf for details on
formatting. This means the following two tests are equivalent.
val := 2
test 1 val "val is %v" val
test 1 val (sprintf "val is %v" val)
Using test with four or more arguments is a convenience compared to adding
an inline call to sprintf.
str2num converts a string to a number. If the string is not a valid
number, it returns 0 and sets the global err variable to true.
n:num
n = str2num "1"
print "n:" n "err:" err
n = str2num "NOT-A-NUMBER"
print "n:" n "err:" err
Output
n: 1 err: false
n: 0 err: true
str2num:num s:string
The str2num function converts a string to a number. It takes a single
argument, which is the string to convert. If the string is a valid
number, the function returns the number. Otherwise, the function
returns 0 and sets the global err variable to true. For more
information on err, see the Recoverable Errors section.
str2bool converts a string to a boolean. If the string is not a valid
boolean, it returns false and sets the global err variable to
true.
b:bool
b = str2bool "true"
print "b:" b "err:" err
b = str2bool "NOT-A-BOOL"
print "b:" b "err:" err
Output
b: true err: false
b: false err: true
str2bool:bool s:string
The str2bool function converts a string to a bool. It takes a single
argument, which is the string to convert. The function returns true
if the string is equal to "true", "True", "TRUE", or "1", and
false if the string is equal to "false", "False", "FALSE", or
"0". The function returns false and sets the global err variable
to true if the string is not a valid boolean. For more information
on err, see the Recoverable Errors section.
Evy has two types of errors: parse errors and run-time errors.
- parse errors are reported before the program is executed. They
report errors with the syntax, such as a missing closing quote for
print "abc, an illegal character, such as#, or type errors, such asmin "a" "b". - Run-time errors only occur if there are no parse errors and the code path causing the error is executed.
For example, the following code will sometimes cause a run-time error:
n:num
if (rand1) < 0.5
n = str2num "not-a-number"
else
n = str2num "5"
end
print "n:" n "error:" err
Half the time, the program above will cause a run-time error and print
n: 0 error: true. The other half of the time, no error will occur and
the program will print n:5 error:false.
Evy has two types of run-time errors: panic and error.
- A panic is non-recoverable. It causes the program to exit immediately.
- An error is recoverable. The program can continue running after the error is handled.
A panic causes the program to exit immediately and print an error message. Panics typically occur when the program encounters a situation that it cannot handle, such as trying to access an element of an array that is out of bounds. Panics cannot be intercepted by the program, so it is important to take steps to prevent them from occurring in the first place.
One way to do this is to use guarding code, which is code that checks for potential errors and takes steps to prevent them from occurring. For example, guarding code could be used to check the length of an array before trying to access an element to avoid an out of bounds error. If the access index is out of bounds, the guarding code could report the error.
Here is an example of a panic:
arr := [0 1 2]
i := 5 // e.g. user input
print arr[i] // out of bounds
print "This line will not be executed"
This code will cause a panic because the index 5 is out of bounds
for the array arr. The program will exit with the error message
line 3: panic: index out of bounds: 5
If you want your own code to panic, you can use the built-in panic
function. This is typically used to highlight mistakes or bugs in your
program, such as invalid function arguments or conditions that should
never occur. The panic function exits your program immediately, so it
should only be used when it is clear that the program cannot continue.
For more information, see the Panic section under Program
Control above.
The global err variable is used to indicate whether a recoverable
error has occurred. The global errmsg variable stores a detailed
message about the error that occurred.
Recoverable errors are caused by code that could not be prevented from
running, such as converting a user input string to a number if the
string is not a number. This recoverable error will set the global err
variable to true and the program will continue executing. If there is
no error, err is set to false.
The global errmsg variable stores a detailed message about the error
which is set alongside err. errmsg is set to the empty string ""
if no error has occurred. If an error does occur, errmsg is set to a
message that describes the error.
When a function that could potentially cause an error finishes executing
without an error, the err variable is reset to false and the
errmsg variable is set to the empty string. This is done even if the
err variable was previously set to true or the errmsg variable
was not empty. Therefore, it is up to the program to check the err
variable after any possible error occurrence.
Here is an example of a recoverable error:
n := str2num "NOT A NUM"
print "num:" n
print "err:" err
print "errmsg:" errmsg
Output
num: 0
err: true
errmsg: str2num: cannot parse "NOT A NUM"
If you want your own code or function to cause a recoverable error,
follow the convention of setting the err variable to true and the
errmsg variable to a message describing the error in the error case.
In the non-error case, make sure to set the err variable to false.
sprint stands for print to string.
It returns a string representation of the arguments given to it. It
separates them by a single space. Unlike print, there is no newline
added to the end.
s := sprint "a" [true] {a:1 b:2}
printf "%q\n" s
printf "%q\n" (sprint)
Output
"a [true] {a:1 b:2}"
""
sprint:string a:any...
The sprint function takes any number of arguments and returns a string
that represents them, separated by a single space. The arguments can be
of any type, including strings, numbers, booleans, and maps. Unlike the
print function, there is no newline added to the end of the string.
sprintf stands for print formatted to string.
sprintf returns a string representation of its arguments according to
a format string. Formatting in sprintf and printf work the same
way, see printf.
s := sprintf "%10q: %.f" "val" 123.45
print s
Output
"val": 123
sprintf:string format:string a:any...
The sprintf function returns a string representation of its arguments
according to a format string. The format string controls how the
arguments are formatted. The sprintf function works the same way as
the printf function, and the formatting syntax is the same, see
printf.
join concatenates the elements of an array of values into a single
string, with the given separator string placed between elements. Any
elements of the array that are not strings are formatted as strings.
s := join ["a" "b" "c" 1 3.141592654 true] ", "
print s
Output
a, b, c, 1, 3.141592654, true
join:string elems:[]any sep:string
The join function takes two arguments: an array of any and a separator
string. The array of any is the list of elements to be concatenated. The
separator string is the string that will be placed between elements in
the resulting string. Values of the array that are not strings are
formatted as strings.
The join function returns a single string that is the concatenation of
the elements in the list of any, with the separator string placed
between elements.
split splits a string into a list of substrings separated by the given
separator. The separator can be any string, including the empty
string.
print (split "a,b,c" ",")
print (split "a,b,c" ".")
print (split "a,b,c" "")
Output
[a b c]
[a,b,c]
[a , b , c]
split:[]string s:string sep:string
The split function takes two arguments: the string to be split and the
separator string. The string to be split is the string that will be
split into substrings. The separator string is the string that will be
used to split the string.
The split function returns a list of substrings. The list of substrings
contains all of the substrings of the original string that are
separated by the separator string.
If the string does not contain the separator, the split function returns
an array of length 1 containing the original string.
If the separator is the empty string, the split function splits the
string after each character (UTF-8 sequence).
If both the string and the separator are empty, the split function
returns an empty list.
upper returns a string with all lowercase letters converted to
uppercase.
s := upper "abc D e ü"
print s
Output
ABC D E Ü
upper:string s:string
The upper function takes a single argument: the string to be converted
to uppercase. The function returns a new string with all lowercase
letters converted to uppercase. All other characters are left unchanged.
The upper function uses the Unicode character database to determine
which characters are lowercase and their equivalent uppercase form.
lower returns a string with all uppercase letters converted to
lowercase.
s := lower "abc D e ü"
print s
Output
abc d e ü
lower:string s:string
The lower function takes a single argument: the string to be converted
to lowercase. The function returns a new string with all uppercase
letters converted to lowercase. All other characters are left
unchanged.
The lower function uses the Unicode character database to determine
which characters are uppercase and their equivalent lowercase form.
index returns the position of a substring in a string, or -1 if the
substring is not present.
n := index "abcde" "de"
print n
Output
3
index:num s:string sub:string
The index function finds the index of a substring sub in a string
s. It returns the index of the first occurrence of a sub within
s, or -1 if the substring is not present.
startswith tests whether a string begins with a given prefix.
b := startswith "abcde" "ab"
print b
Output
true
startswith:bool s:string prefix:string
The startswith function tests whether the string s begins with
prefix and returns true if s starts with prefix, false
otherwise.
endswith tests whether a string ends with a given suffix.
b := endswith "abcde" "ab"
print b
Output
false
endswith:bool s:string suffix:string
The endswith function tests whether the string s ends with suffix
and returns true if s ends with suffix, false otherwise.
trim removes leading and trailing characters from a string.
s := trim ".,..abc.de." ".,"
print s
Output
abc.de
trim:string s:string cutset:string
The trim function removes any characters in cutset from the
beginning and end of string s. It returns a copy of the resulting
string.
replace replaces all occurrences of a substring with another substring
in a string.
s := replace "abc123xyzabc abc" "abc" "ABC"
print s
Output
ABC123xyzABC ABC
replace:string s:string old:string new:string
The replace function replaces all occurrences of the substring old
in the string s with the substring new.
repr returns a string representation of its arguments, typically as valid,
formatted Evy code. The notable exception are maps with keys that could not be
used in a map literal.
s := repr 1 "abc"
print s
Output
1 "abc"
repr:string a:any...
The repr function returns a string representation of its arguments,
typically as valid, formatted Evy code. The notable exception are maps with
keys that could not be used in a map literal.
| Type | Representation |
|---|---|
num |
as is |
bool |
as is |
string |
double-quoted with internal quotes escaped |
[]... |
enclosed in square brackets, details below |
{}... |
enclosed in curly braces, details below |
The elements of an array are printed according to repr and space-separated.
The key-value pairs of a map are space-separated, with keys separated from
values by :. Keys are printed without quotes if they are valid identifiers
or Evy keywords, and surrounded by quotes with escaped internal quotes if
not. Values are printed according to repr.
rand returns a random, non-negative integer less than the argument.
print (rand 3)
print (rand 3)
Sample output
2
0
rand:num n:num
The rand functions returns, a non-negative pseudo-random integer
number in the half-open interval [0,n). A panic occurs
for n <= 0.
rand1 returns a random, non-negative floating point number less than 1.
print (rand1)
print (rand1)
Sample output
0.7679753163102002
0.6349044894123325
rand1:num
The rand1 function returns a pseudo-random floating point number in
the half-open interval [0.0,1.0).
min returns the smaller of the two given numbers.
print (min 3 1)
Output
1
min:num n1:num n2:num
The min function returns the smaller of the two given number
arguments.
max returns the greater of the two given numbers.
print (max 3 1)
Output
3
max:num n1:num n2:num
The max function returns the greater of the two given number
arguments.
abs returns the absolute value of a number.
print (abs 3)
print (abs -2.5)
Output
3
2.5
abs:num n:num
The abs function returns the absolute value of a number, which is its
magnitude without regard to its sign.
floor returns the greatest integer value less than or equal to the given
number.
print (floor 2.7)
print (floor 3)
Output
2
3
floor:num n:num
The floor function returns the greatest integer value less than or
equal to its number argument n.
ceil returns the smallest integer greater than or equal to the given
number.
print (ceil 2.1)
print (ceil 4)
Sample output
3
4
ceil:num n:num
The ceil function returns the smallest integer greater than or equal
to its number argument n.
round returns the nearest integer to the given number, rounding half
away from 0.
print (round 2.4)
print (round 2.5)
Sample output
2
3
round:num n:num
The round function returns the nearest integer to the given number
argument n, rounding half away from 0.
pow returns the value of the first number raised to the power of the
second number.
print (pow 2 3)
Output
8
pow:num b:num exp:num
The pow function returns b to the power of exp. The first number
argument b is the base. The second number argument exp is the
exponent.
log returns the logarithm of the given number, to the base of e.
printf "%.2f\n" (log 1)
printf "%.2f\n" (log 2.7183) // e
Output
0.00
1.00
log:num n:num
The log function returns the natural logarithm, the logarithm of the
given number argument n, to the base of e.
sqrt returns the square root of the given number.
print (sqrt 9)
Output
3
sqrt:num n:num
The sqrt function returns the positive square root of the number
argument n.
pi is a global variable with the value of the mathematical constant π.
sin returns the sine of the given angle in radians.
print (sin 0.5*pi)
Output
1
sin:num n:num
The sin function returns the sine of the given angle n in radians.
cos returns the cosine of the given angle in radians.
print (cos pi)
Output
-1
cos:num n:num
The cos function returns the cosine of the given angle n in radians.
atan2 returns the angle in radians between the positive x-axis and the
ray from the origin to the point x y.
rad := atan2 1 1
degrees := rad * 180 / pi
printf "rad: %.2f degrees: %.2f" rad degrees
Output
rad: 0.79 degrees: 45.00
atan2:num y:num x:num
The atan2 function returns the angle in radians between the positive
x-axis and the ray from the origin to the point x y. More formally,
it returns the arc tangent of y/x for given arguments y and x,
using the signs of the two to determine the quadrant of the return
value.
Evy on the web outputs drawing commands to a drawing area called the canvas.
Positions on the canvas are defined by a coordinate system, similar to the Cartesian coordinate system used in mathematics. The horizontal dimension is called the x-axis, and the vertical dimension is called the y-axis.
A point on the canvas is defined by its x and y coordinates,
which are written as x y. For example, the point 30 60 has an
x-coordinate of 30 and a y-coordinate of 60. It is located 30 units
from the left edge of the canvas and 60 units from the bottom edge.
The canvas ranges from coordinates 0 0 to 100 100. The center of the
canvas has the coordinates 50 50.
Shapes are drawn on the canvas using a pen. The pen has an x y
position and a style. The position of the pen is also known as the
current cursor position.
Some graphics functions, like line, rect, circle, and text,
create shapes on the canvas. Other graphics functions such as
color, width, and font set the style of the pen for subsequent
drawing commands.
move sets the position of the pen to the given coordinates.
grid
move 30 60
circle 1
Output
move x:num y:num
The move function sets the position of the cursor to the given x and
y coordinates. The initial cursor position is 0 0.
line draws a line from the current position of the pen to the given
coordinates.
The following example draws a triangle.
move 30 20
line 70 20
line 50 50
line 30 20
Output
line x:num y:num
The line function draws a line from the current cursor position to the
given x and y coordinates. The cursor position is then updated to
the given coordinates, which allows for easy polygon drawing.
rect draws a rectangle with the given width and height at the pen's
current position.
grid
move 40 20
rect 10 30
rect 40 20
Output
rect width:num height:num
The rect function draws a rectangle with the given width and
height at the current cursor position. The cursor position is then
updated to the position that is the width and height away from the
current position. In other words, the opposite corner of the
rectangle is at the new cursor position.
circle draws a circle with given radius at the pen's current position.
grid
move 50 50
circle 10
Output
circle radius:num
The circle function draws a circle with the given radius centered
at the current cursor position. The cursor position does not change
after drawing a circle.
color changes the color of the pen. All
CSS (Cascading Style Sheets) color values are supported. You can start
by using the simpler named CSS colors , such as "red",
"darkmagenta", and "springgreen".
color "darkmagenta"
rect 20 20
Output
color c:string
The color function changes the color of the stroke and the fill to
the given CSS color string c. Evy supports all CSS color values,
including semi-transparent ones. For example, the following code
changes the color to a shade of red that is 60% opaque:
color "rgb(100% 0% 0% / 60%)".
Named CSS colors, such as "red", "darkmagenta", and
"springgreen", are a simpler way of specifying common colors. For a
complete list of named CSS colors, see the Mozilla Developer
documentation.
If the color string c is not recognized as a valid CSS color, the color
does not change. The initial color is "black".
colour is an alternate spelling of color. See color.
hsl returns a string to be used with the color and
clear functions. The arguments to the hsl function are numbers
and therefore are more suited to mathematical manipulation, e.g. to find the
complimentary color, create a trail in animations with the alpha value or
create color gradients.
hsl takes one to four arguments - hue, saturation, lightness, and
alpha - and returns a CSS (Cascading Style Sheets) hsl function string
specifying a color.
The hue argument is required. It is a number from 0 to 360 that represents
the color on the color wheel:
hue |
color | |
|---|---|---|
| 0 | "red" | |
| 60 | "yellow" | |
| 120 | "lime" green | |
| 180 | "cyan" | |
| 240 | "blue" | |
| 300 | "magenta" |
The saturation, lightness and alpha arguments are optional and must
range between 0 and 100 percent if given:
saturationis measure for vibrancy with 100 meaning maximum vibrancy and 0 meaning a shade of grey (default: 100)lightnessis measure for brightness with 100 meaning white and 0 meaning black (default: 50)alphais measure for opacity or transparency with 100 meaning fully opaque and 0 meaning fully transparent (default: 100)
for i := range 360
color (hsl i)
move i/3.6 0
rect 1/3.6 100
end
Output
hsl:string hue:num [saturation:num [lightness:num [alpha:num]]]
hsl returns a string to be used with the color and
clear functions. hsl takes one to four num arguments - hue,
saturation, lightness, and alpha - and returns string containing a
CSS hsl function string.
The hue value must be between 0 and 360. The saturation, lightness and
alpha values must be between 0 and 100. See the Mozilla Developer
documentation on the CSS hsl function for more details.
width sets the thickness of the lines drawn by the pen.
width 10
line 30 30
width 1
line 60 60
width 0.1
line 90 90
grid
Output
width n:num
The width function sets the thickness of the stroke to the given n
units. The stroke is the visible line that is drawn when using the
line function or any other shape function after setting
fill "none". The initial stroke width it 0.1 units.
clear clears the canvas. Optionally, it can take a color argument to
clear the canvas to.
The following example code shows how to draw a magenta square, clear the
canvas, and then draw a blue circle. The final result is a canvas with
a blue circle centered at 20 20. The magenta square is not visible
because it has been removed by the clear function.
color "darkmagenta"
rect 20 20
clear
color "blue"
circle 5
grid
Output
clear [c:string]
The clear function clears the canvas. It can optionally take a color
as a string argument, in which case the canvas will be cleared to that
color. If no color is specified, the canvas will be cleared to
"white". Initially the canvas is cleared to "white", not
"transparent".
grid draws a grid on the canvas. The grid is parallel to the x and y
axes, and each grid line is spaced 10 units apart.
grid
Output
grid
The grid function draws a grid on the canvas. The grid lines are
parallel to the x and y axes, and each grid line is spaced 10 units
apart. The grid lines are 0.1 units thin and have a semi-transparent
gray color, with an opacity of 50%. This makes the grid lines faint
enough to be drawn on top of other shapes. The grid lines that go
through the point 50 50, which is the center of the canvas, are
slightly thicker. The thickness of these grid lines is 0.2 units, which
makes it easier to see the center of the canvas.
The grid function is a shorthand of the gridn function with the
arguments 10 and "hsl(0deg 100% 0% / 50%)", see gridn.
It is roughly equivalent to the following Evy code. However, the current
color, cursor position, and line width are not affected by the built-in
grid function.
color "hsl(0deg 100% 0% / 50%)"
for i := range 0 101 10
width 0.1
if i == 50
width 0.2
end
move i 0
line i 100
move 0 i
line 100 i
end
gridn draws a grid on the canvas. The grid is parallel to the x and y
axes, and each grid line is spaced the given number of units apart. The
color of the grid is set to the given color.
gridn 2 "red"
Output
gridn n:num c:string
The gridn function draws a grid on the canvas. The grid lines are
parallel to the x and y axes, and each grid line is spaced n units
apart. The color of the grid is set to the color specified by the
string argument c. The default line width is 0.1 units. Every fifth
grid line is slightly thicker, with a line width of 0.2 units.
The gridn function is roughly equivalent to the following Evy code,
but the current color, cursor position, and line width are not affected
by the built-in gridn function.
c := "red"
n := 2
color c
linecnt := 0
for i := range 0 101 n
width 0.1
if linecnt % 5 == 0
width 0.2
end
linecnt = linecnt + 1
move i 0
line i 100
move 0 i
line 100 i
end
poly draws polylines and polygons for the given coordinates.
The following code draws a w-shaped red polyline and a yellow triangle.
width 1
color "red"
fill "none"
poly [10 80] [30 60] [50 80] [70 60] [90 80]
fill "gold"
poly [10 20] [50 50] [20 10] [10 20]
Output
poly xy:[]num...
The poly function draws polylines and polygons for the given
coordinates. A polyline is a sequence of connected line segments, and a
polygon is a closed polyline.
The poly function takes a variadic number of arguments of type
[]num. Each argument has to be a number array with two elements
[x y]. The first element representing the x coordinate and the second
the y coordinate of a vertex in the polyline or polygon. If the array
does not have two elements, a panic occurs. For example,
the poly function can be called as follows:
poly [x1 y1] [x2 y2] [x3 y3]
Use fill "none" to draw a line without filling. To draw a closed
polygon, make sure that the first and last coordinates are the same.
The poly function does not use or change the cursor position.
ellipse draws an ellipse for given center, radii and optional tilt,
start and end angles.
// red circle
color "red"
ellipse 50 50 40
// yellow, flat ellipse
color "gold"
ellipse 50 50 40 10
// blue, flat ellipse tilted by 45°
color "blue"
ellipse 50 50 40 10 45
// white, flat, half ellipse tilted by 135°
color "white"
ellipse 50 50 40 10 135 0 180
Output
ellipse x:num y:num rx:num [ry:num [tilt:num [start:num end:num]]]
The ellipse function draws an ellipse with the given center, radii,
tilt, and start and end angles. It can take 3, 4, 5, or 7 arguments.
Default values are used for omitted arguments.
The first two arguments are the coordinates of the center of the ellipse. The third argument is the radius of the ellipse in the x direction. The fourth argument is the radius of the ellipse in the y direction. If the fourth argument is omitted, the ellipse is drawn as a circle. The fifth argument is the tilt of the ellipse in degrees, with a default value of 0. The sixth and seventh arguments are the start and end angles of the ellipse in degrees, with default values of 0 and 360, respectively.
stroke sets the color of the outline of shapes.
The following code draws two red squares, one with a blue outline.
width 1
color "red"
rect 30 30
stroke "blue"
rect 30 30
Output
stroke c:string
The stroke function sets the color of the stroke to the given string
argument c. The stroke is the visible line that is drawn when you use
the line function or any other shape function after calling
fill "none". The initial stroke color is "black".
fill sets the color of the interior of shapes.
The following code draws a red square and a blue square with a red outline.
width 1
color "red"
rect 30 30
fill "blue"
rect 30 30
Output
fill c:string
The fill function sets the color of the fill to the given string
argument c. The fill is the interior of a shape. The initial fill
color is "black".
dash sets the line dash pattern.
width 2
dash 5 // same as: dash 5 5, dash 5 5 5
hline 85 "red"
dash 10 4 1 4
hline 75 "blue"
dash 10 5 10 // same as: dash 10 5 10 10 5 10
hline 65 "gold"
dash // reset dash
hline 50 "black"
gridn 5 "gray"
func hline y:num c:string
color c
move 0 y
line 100 y
end
Output
dash segments:num...
The dash function sets the line dash pattern used when stroking lines.
The dash pattern is specified as a variadic number of arguments, where
each argument represents the length of a dash or gap. For example, the
arguments 5 10 would create a line with 5-unit long dashes and 10-unit
long gaps.
If the number of arguments is odd, they are copied and concatenated. For
example, the arguments 10 5 10 would become 10 5 10 10 5 10. If no
arguments are given, the line returns to being solid.
The initial dash pattern is a solid line.
linecap sets the shape of the ends of lines.
width 5
grid
linecap "round"
hline 70
linecap "butt"
hline 50
linecap "square"
hline 30
func hline y:num
move 10 y
line 90 y
end
Output
linecap style:string
The linecap function sets the shape of the ends of lines to the
style string argument. Valid styles are "round", "butt" or
"square". An invalid style takes no effect.
| Style | Description |
|---|---|
"round" |
The ends of the line are rounded. |
"butt" |
The ends of the line are squared off at the endpoints. |
"square" |
The ends of the line are squared off by adding a box with an equal width and half the height of the line's thickness. |
The initial linecap style is "round".
text prints text to the canvas at the current cursor position.
move 20 70
text "“Time is an illusion."
move 20 63
text "Lunchtime doubly so.”"
move 35 48
text "― Douglas Adams"
Output
text s:string
The text function prints the string argument s to the canvas at the
current cursor position. The cursor position is not updated after
writing text. Only fill and color have an effect on the text;
stroke has no effect. For more text styling, such as setting
font size or font family, see font.
font sets the font properties for text. The font properties are
family,size, weight, style, letterspacing, baseline, and
align.
font {family:"Bradley Hand, cursive" size:4}
move 10 65
text "“The wonderful thing about programming"
move 10 60
text "is that anyone can learn it and do it. You"
move 10 55
text "don't have to be a genius or have a specific"
move 10 50
text "background. You just need curiosity and"
move 10 45
text "the willingness to try.”"
// all font properties
font {
size:9
style:"normal" // "normal"
family:"Tahomana, sans-serif" // see https://developer.mozilla.org/en-US/docs/Web/CSS/font-family
weight:900
letterspacing:-0.5 // extra inter-character space. negative allowed. default:0
align:"right" // "left", "right"
baseline:"middle" // "top", "bottom", "alphabetic" (default)
}
move 90 32
color "red"
text "Grace Hopper"
color "black"
font {size:4 letterspacing:0 weight:100 style:"normal"}
move 90 25
text "computer scientist, compiler builder"
Output
The following example shows the effect of the align and baseline
properties:
font {size:6 family:"Fira Code, monospace"}
move 25 78
line 25 86
move 25 80
font {align:"left"}
text "left"
move 25 63
line 25 71
move 25 65
font {align:"right"}
text "right"
move 25 48
line 25 56
move 25 50
font {align:"center"}
text "center"
move 55 80
line 90 80
move 55 80
font {baseline:"bottom" align:"left"}
text "bottom"
move 55 65
line 90 65
move 55 65
font {baseline:"top"}
text "top"
move 55 50
line 90 50
move 55 50
font {baseline:"middle"}
text "middle"
move 55 35
line 90 35
move 55 35
font {baseline:"alphabetic"}
text "alphabetic"
Output
font props:{}any
The font function sets the font properties for text. The font
properties are family, size, weight, style, letterspacing,
align, and baseline.
The family property specifies a prioritized list of one or more font
family names. Values are separated by commas to indicate that they are
alternatives. The browser will select the first available font. For
example, the value "Fira Code, monospace" would specify that the
browser should try to use the Fira Code font, but if that font is not
available, it should use a monospace font. The default font family is
the browser default.
The size property specifies the height of a letter in canvas units.
The default size is 6.
The weight property specifies the boldness of the font. The values
100, 200, ..., 900 can be used to specify the weight of the font. The
value 400 is normal, 700 is bold. The default weight is 400.
The style property specifies the sloping of the font. The values
"normal" and "italic" can be used to specify the style of the font.
The default style is "normal".
The letterspacing property specifies the additional horizontal space
between text characters in canvas units. The default value is 0.
The align property specifies the horizontal alignment of the text. The
values "left", "right", and "center" can be used to specify the
alignment. The default value is "left".
The baseline property specifies the vertical cursor position relative to
the vertical text position. The values "top", "bottom", "middle",
and "alphabetic" can be used to specify the baseline. The default value
is "alphabetic".
Here is an example of how to use the font function:
font {
family:"Fira Code, monospace"
size:9
weight:700
style:"italic"
letterspacing:0.5
baseline:"top"
align:"center"
}
This code sets the font properties to use the Fira Code font, a size of 9, a weight of 700, an italic style, a letterspacing of 0.5, a top baseline, and a center alignment.
Evy first executes all top-level code in the order it appears in the source code. If there is at least one event handler, Evy then enters an event loop. In the event loop, Evy waits for external events, such as a key press or a pointer down event. When an event occurs, Evy calls the corresponding event handler function if it has been implemented. The event handler function can optionally receive arguments, such as the key character or the pointer coordinates. Once the event handler function has finished, Evy returns to the event loop and waits for the next event.
Event handlers are declared using the on keyword. Only predefined
events can be handled: key, down, up, move, animate, and
input. For example, the following code defines an event handler for
the key press event:
on key k:string
print k
end
The parameters to the event handlers must match the expected signature.
The key event handler expects a single parameter of type string,
which is the character that was pressed. The parameters can be fully
omitted or fully specified. If only some parameters are needed, use the
anonymous _ parameter. The down event handler, for instance,
expects two parameters, the x and y coordinates of the pointer. If you
only need the x coordinate, you can use on down x:num _:num.
Pointer events, such as down, up, and move, occur when a pointing
input device, such as a mouse, a pen or stylus, or a finger, is used to
interact with the canvas.
key is called when a key on the keyboard is pressed.
on key k:string
print k
end
Sample output
Escape
Shift
R
o
key k:string
The key event handler is called when a keydown event occurs. The
handler is passed a string argument which is the character of the key
that was pressed. For example, if the user presses the a key, the
argument would be the string "a".
Some keys do not have a character representation, such as the arrow keys
or the shift key. For these keys, the argument is a special string,
such as "ArrowRight", "ArrowUp", "Shift", "Enter", "Control",
"Alt", "Backspace", or "Escape".
When the shift key is pressed and then another key is pressed, the
argument is the uppercase or special character representation of the
key that was pressed. For example, if the user presses shift+a, the
argument is the string "A".
down is called when the pointer is pressed down.
on down x:num y:num
printf "x: %2.0f y: %2.0f\n" x y
end
Sample output
x: 42 y: 85
x: 7 y: 6
down x:num y:num
The down event handler is called when a pointerdown event occurs on
the canvas. The handler is passed two number arguments, x and y,
which are the coordinates of the pointer location when the pointer was
pressed down. The pointer is typically a mouse, stylus or finger.
up is called when the pointer is lifted up.
on up x:num y:num
move x y
color "red"
circle 1
end
Sample output
up x:num y:num
The up event handler is called when a pointerup event occurs on the
canvas. The handler is passed two number arguments, x and y, which
are the coordinates of the pointer location when the pointer was lifted
up. The pointer is typically a mouse, stylus or finger.
move is called when the pointer is moved.
The following sample draws a line following the pointer's movement.
down := false
width 1
on down x:num y:num
down = true
move x y
end
on move x:num y:num
if down
line x y
end
end
on up
down = false
end
Sample output
move x:num y:num
The move event handler is called when a pointermove event occurs on
the canvas. The handler is passed two number arguments, x and y,
which are the coordinates of the position that the pointer has moved
to. The pointer is typically a mouse, stylus or finger.
animate gets called periodically around 60 times per second.
semiblack := "hsl(0deg 0% 0% / 10%)"
width 1
fill semiblack
stroke "red"
on animate ms:num
clear semiblack
y := 100 - (ms / 20) % 100
move 50 y
circle 10
end
Output
animate elapsed:num
The animate event handler is called when an animation frame is
available. This means that the handler will be called typically 60
times in a second, but it will generally match the display refresh
rate. If the computations within a single animate call take too long,
the frame rate will drop.
The animate event handler is passed a single numeric argument which is the number of elapsed milliseconds since the start of the animation. This allows you to track the progress of the animation and to update the animation accordingly.
input is called when the value of an input element changes.
on input id:string val:string
print "id:" id "val:" val
end
Sample Output from the Evy website
id: sliderx val: 15
id: slidery val: 0
id: slidery val: 100
input id:string val:id
The input event handler is called when the value of an input element
changes. The handler is passed two string arguments: the id of the
input element and its new value.
For example, if you have an input element with the id sliderx and the
user changes the value of the slider to 15, the input event handler
will be called with the arguments sliderx and 15.
The Evy web interface has two sliders that are used as input elements.
The sliders range from 0 to 100, and their ids are sliderx and
slidery. When you change the position of the sliders the input
event handler is called with the new position value of the slider.






















