Data types

The type system of Perun2 is very primitive. It consists of 9 internally defined data types and there are no more. Perun2 performs automatic casting between higher and lower data types when it is possible as shown in the image below. For example, bool casted into string becomes a text value 0 or 1. It works only one direction.

Perun2 is statically typed. New variables are declared implicitly, with no need to specify their type.


Generic

Several expressions can be applied to multiple data types.

Ternary

structurereturns
[bool] ? [value] : [value]value
Ternary conditional operator. If the first argument is true, then the second argument is returned. Otherwise the result is the third argument. This structure works on every data type.

Binary

structurereturns
[bool] ? [value]value
This is a simplified ternary operator. If the first argument equals false, then the whole expression returns empty value of certain data type. This value is empty text for string, integer zero for number, empty period for period and empty collection for collections. This structure works on every data type.

Function

See functions.

Filter

Filters work only with collections. See filters.

Join

structurereturns
[value] , [value]value collection
[value] , [value collection]value collection
[value collection] , [value]value collection
[value collection] , [value collection]value collection
Multiple elements can be joined together by commas in order to create a merged collection. If one of joined elements is a lazy evaluated collection (also known as definition), then the whole chain of elements becomes lazy evaluated.

Value At Index

structurereturns
[value collection variable] [ [number] ]value

To reach a certain element of a collection variable, use square brackets with an index written inside them. Indexing is zero-based. If index is out of range, then an empty value is returned.


Bool

The boolean data type can store only two values: true and false. When casted into number or string, true is treated as 1 and false is treated as 0.

Boolean Constant

structurereturns
truebool
falsebool
New boolean constants can be called by keywords true and false.

Comparison

structurereturns
[value] = [value]bool
[value] == [value]bool
[value] != [value]bool
[value] < [value]bool
[value] <= [value]bool
[value] > [value]bool
[value] >= [value]bool
Any two valid data type instances can be compared. Comparisons are carried out according to several rules. Boolean value true is considered greater than false. Two times are equal, if they share any common moment in time. Strings are compared by their alphabetic order and they are sensitive to case size. Two collections are equal, if they contain the same elements in the same places. A collection that contains more elements is considered greater.

Boolean Operators

structurereturns
not [bool]bool
[bool] and [bool]bool
[bool] or [bool]bool
[bool] xor [bool]bool
Unlike other programming languages, Perun2 uses keywords instead of symbols for boolean operators. Elements can be grouped by brackets to determine the order of operations. All binary operators (and, or, xor) have the same priority.

In

structurereturns
[value] in [value collection]bool
[value] not in [value collection]bool
Checks if a specified value can be found inside a collection. Inclusion of the not keyword reverses the result.

Like

structurereturns
[string] like [string]bool
[string] not like [string]bool
This expression can be used to compare a string with a pattern. It uses several wildcart characters explained here. If the pattern is not valid and for example contains not closed brackets, then this expression always returns false.

Resembles

structurereturns
[string] resembles [string]bool
[string] not resembles [string]bool
This operator works similar to the Like operator. Go here for more info.

Between

structurereturns
[value] between [value] and [value] bool
[value] not between [value] and [value] bool
The Between operator works with any data type that is not a collection. Bounding values are included, so this expression is an equivalent to >= and <=. The order of bounds does not matter. A non-existent value (NaN or never) as any argument makes the Between operator always return false provided there are no casts.

Regexp

structurereturns
[string] regexp [string]bool
[string] not regexp [string]bool

Perun2 uses the ECMAScript convention for regular expression matches. This operator is case sensitive.


Number

Numbers in Perun2 can appear in three forms: as integers, in double-precision format or as NaN (not a number). The type of a number is assigned dynamically after every performed operation. For example, division of two integers can result in an integer (8/4), a fraction (8/5) or NaN (8/0). In order to avoid integer overflows, the greatest effective amount of bits is used for integer representation. This value depends on the operating system and equals at least 64 bits. The dot is always the decimal separator.

Numeric Literal

100 -100 15.23 -15.23
Numberic literals are consecutive digits with one optionary dot sign inside as a decimal separator. Preceding sign - makes the number negative.

File Size Literal

suffixmultiplier
kb1024
mb1024²
gb1024³
tb1024⁴
pb1024⁵
Numbers can be followed by a suffix. This suffix multiplies the number, so it can be treated as a file size unit. Make sure that there is no space between the number and the suffix. For example, 100 megabytes would be expressed as 100mb.

Decimal Literal

suffixmultiplier
k1000
m1000²
We can use these two decimal suffixes to express thousands and millions. For example, 3k means three thousand.

Integer Literal With K Infix

infixmultiplier
k1000
An integer literal can contain one K infix. It multiplies the preceding part by one thousand. This feature can be used to express years in a shorter way. For example, instead of 2023, we can write 2k23.

Numeric Operators

structurereturns
- [number]number
[number] + [number]number
[number] - [number]number
[number] * [number]number
[number] / [number]number
[number] % [number]number
Operators for multiplication, division and modulo have higher priority than operators for addition and subtraction. Expression elements can be grouped by brackets to enforce a desired order of operations.

Number From Time Variable

structurereturns
[time variable].[time variable number]number

Numeric values can be obtained from time variables.

time variable number
year years
month months
weekday -
day days
hour hours
minute minutes
second seconds

Values are subject to two rules. Month take value from 1 (January) to 12 (December). Week days start from 1 (Monday) to 7 (Sunday). After all, these values do not have to be used by the language user at all, as convenient time constants are more readable and not ambiguous.


Time

Time expresses one moment in time. Time can point either a certain month, a certain day, a certain minute or a certain second. When casted into a string, time is written the same way as an equivalent time constant or clock constant would be expressed. Month name is written in lowercase except for the first letter that is in uppercase.

Time Constant

structurereturns
[month name] [nc]time
[nc] [month name] [nc]time
[nc] [month name] [nc] , [nc] : [nc]time
[nc] [month name] [nc] , [nc] : [nc] : [nc]time

Time constants can be built in four ways. All of them require an English month name and several numeric constants (shown above as [nc]). In the final presented form, numeric constants are in sequence: days, years, hours, minutes and seconds.

month name
january february march april
may june july august
september october november december

You probably know English month names, but they are presented above anyway.

Clock Constant

structurereturns
[nc] : [nc]time
[nc] : [nc] : [nc]time
Clock constants need hours, minutes and (optionary) seconds.

Shifted Time

structurereturns
[time] + [period]time
[time] - [period]time
Time can be increased or decreased by a period.

Date From Time Variable

structurereturns
[time variable].datetime

This expression returns a value of a time variable excluding its clock part (hours, minutes and seconds).


Period

Period describes a period of time expressed in years, months, days, hours, minutes and seconds. Each of these units is an integer and can be negative. The ambiguity of years and months may introduce a bit of confusion, as in reality each of them consists of different amount of days. Perun2 tries to represent them as realistically as possible. When conversion into days in inevitable, each ambiguous month is treated as 30 days and each ambiguous year as 365 days. Period remembers several details such as amount of leap years it contains or days in months and uses them behind the curtain for comparisons.

Period Unit

structurereturns
1 [period singular]period
[number] [period plural]period

A new period unit can be defined by a number and a period keyword.

period singularperiod plural
year years
month months
week weeks
day days
hour hours
minute minutes
second seconds

Period keywords can take either singular or plural form.

Period Operators

structurereturns
- [period]period
[period] + [period]period
[period] - [period]period
Negation, addition and subtraction can be performed on periods.

Time Difference

structurereturns
[time] - [time]period

Subtraction performed on two times returns a period as a result.


String

String represents a sequence of Unicode characters.

String Literal (Apostrophe)

'string content'
Characters placed between two apostrophes form a new string literal. There is an exception: it cannot contain asterisks nor apostrophes. An asterisk turns this structure into an Asterisk Pattern. For the sake of simplicity, string literals in Perun2 do not involve any escape characters nor escape sequences. Strings mean exactly what they show, so backslashes can be used safely for filesystem paths.

String Literal (Backtick)

`string content`
This is the way to omit the limitations of apostrophe-defined string literals. A string literal formed with backtick characters can additionally contain asterisks and apostrophes. Just like before, there are no escape sequences.

Character At Index

structurereturns
[string variable] [ [number] ]string
Reach certain character of a string variable and return it as a new string. Indexing is zero-based. Negative indexes are allowed and enable reversed access from end to start. For example, character at index -1 is the last one and at -2 is the penultimate. If index is out of range, then an empty string is returned.

String Concatenation

structurereturns
[string] + [string]string

Multiple strings can be concatenated by pluses. You should pay attention to adjacent elements. If two adjacent elements are numbers, they are summed. The same rule goes for periods and combinations of times and periods.


Definition

Definition is a lazy evaluated collection of strings. Unlike all other data types, definition generates values on demand instead of generating all of them at once. This data type is crucial for Perun2, as it enables efficient iteration over filesystem elements. It appears through important built-in variables such as files and directories.

Asterisk Pattern

'*.txt'
Asterisk Patterns are apostrophe-defined string literals that contain at least one asterisk. They are explained deeply here.

List, Numeric List, Time List

Lists are just vectors of values. The easiest way to initialize them is by writing several values with commas between them. List of strings is the lowest data type in Perun2.