Each operator is given with its signature, consisting of a list of allowed typings, tried in order.
A typing is of the form type1, …, typen → return-type.
Arithmetic
- addition, concatenation:
+ : int, int → int
+ : uint, uint → uint
+ : float, float → float
+ : ctime, ctime → ctime
+ : ctime, int → ctime
+ : ctime, timeval → timeval
+ : timeval, int → timeval
+ : timeval, ctime → timeval
+ : timeval, timeval → timeval
Note: all of the above forms implement truncated addition, not addition modulo 2N for any N. This is done so that addition is monotonic in its arguments.+ : str, str → str
(string concatenation)+ : db[
type1, …, typen], db[
type1, …, typen] → db[
type1, …, typen]
+ : db[*], db[
type1, …, typen] → db[
type1, …, typen]
+ : db[
type1, …, typen], db[*] → db[
type1, …, typen]
+ : db[*], db[*] → db[*]
(database union)
Note: the two input database types must be identical, or at least one of them is the special typedb[*]
that only the empty database can have..
- subtraction:
- : int, int → int
- : uint, uint → uint
- : float, float → float
- : ctime, ctime → ctime
- : ctime, int → ctime
- : timeval, int → timeval
- : timeval, ctime → timeval
- : timeval, timeval → timeval
Note: all of the above forms implement truncated subtraction, not subtraction modulo 2N for any N. This is done so that subtraction is monotonic in its first argument, and antitonic in its second argument.- : db[
type1, …, typen], db[
type1, …, typen] → db[
type1, …, typen]
- : db[*], db[
type1, …, typen] → db[*]
- : db[
type1, …, typen], db[*] → db[
type1, …, typen]
- : db[*], db[*] → db[*]
(database difference)
Note: the two input database types must be identical, or at least one of them is the special typedb[*]
that only the empty database can have.
Computes first database without all the tuples of the second database.
- opposite:
- : int → int
Note: the above form implements truncated opposite, not opposite modulo 2N for any N. This is done so that opposite is monotonic in its argument. The only surprising case is taking the opposite of the least possible int (-2N-1, where N is the bit size), which yields the largest possible int (2N-1-1) instead of the modulo value, -2N.- : uint → int
Again, this is truncated opposite.- : float → float
- same sign conversion:
+ : int → int
The identity map.+ : uint → int
Conversion from unsigned to signed integer. This is truncated conversion, not conversion module 2N for any N. This is done so as to be monotonic in its argument. Any number strictly greater than-LONG_MIN
is converted toLONG_MIN
+ : float → float
The identity map.
- multiplication:
* : int, int → int
* : uint, uint → uint
Note: the above forms implement multiplication modulo word size, and are not monotonic.* : float, float → float
- division:
/ : int, int → int
(quotient)/ : uint, uint → uint
(quotient)
Note: the above forms implement multiplication modulo word size, and are not monotonic./ : float, float → float
(division)
- modulo:
% : int, int → int
% : uint, uint → uint
Bitwise logic
- bitwise and:
& :
type1,
type2→ type1
where type1, type2 are any types amongint
,uint
,ipv4
.& : ipv6, ipv6 → ipv6
- bitwise or:
| :
type1,
type2→ type1
where type1, type2 are any types amongint
,uint
,ipv4
.| : ipv6, ipv6 → ipv6
- bitwise exclusive or:
^ :
type1,
type2→ type1
where type1, type2 are any types amongint
,uint
,ipv4
.^ : ipv6, ipv6 → ipv6
- bitwise not:
~ : int → int
~ : int → int
~ : ipv4 → ipv4
~ : ipv6 → ipv6
Logic
As in C, int
is equated with the type of booleans, 0 is false, everything else is true.
- logical and:
&& : int, int → int
- logical or:
|| : int, int → int
- logical negation:
! : int → int
- equality:
== : type, type → int
!= : type, type → int
where type is any type among
int
,uint
,float
,str
,ctime
,timeval
,ipv4
,ipv6
, or a database typedb[
type1, …, typen]
;
note that the two arguments must be of the same type—an exception is given by the following typing rules, which apply to the very special case of comparisons with the empty database==
,!= : db[*], db[
type1, …, typen] → int
==
,!
=
: db[
type1, …, typen], db[*] → int
==
,!=
: db[*], db[*] → int
- order:
<= : type, type → int
< : type, type → int
>= : type, type → int
> : type, type → int
where type is any type among
int
,uint
,float
,str
,ctime
,timeval
,ipv4
,ipv6
, or a database typedb[*]
ordb[
type1, …, typen]
(databases are compared for inclusion); the ordering is:- the natural ordering on data of types
int
,uint
,float
,ctime
,timeval
, - the lexicographic ordering on strings (of type
str
), seen as byte strings—not any fancier ordering such as UTF8 collation order: that may come, but no field of typestr
is currently flagged as monotonic anyway; ipv4
addresses are compared as though they were unsigned 32-bit integers;ipv6
addresses are compared lexicographically, considering they are 16-byte strings;- databases, of type
db[*]
ordb[
type1,
…,
typen]
, are compared for inclusion.
Note that the two arguments must be of the same type—an exception is given by the following typing rules, which apply to the very special case of comparisons with the empty database
<=
,<
,>=
,> : db[*], db[
type1, …, typen] → int
<=
,<
,>=
,> : db[
type1, …, typen], db[*] → int
<=
,<
,>=
,> : db[*], db[*] → int
- regexp matching:
=~ : str, regex → int
return true if string matches regexp!~ : str, regex → int
return true if string does not match regexp