Expressions

  • assignment: $var=expr
    $var[expr1][expr2]…[exprn]=expr
    evaluate expr and assign its value val to variable $var, or to the entry indexed expr1, expr2, …, exprn in array $var.
    return value val
    Typing:

    • Requires: $var and expr have the same type type
    • Yields: result of type type

 

  • variables $var                                                     $[AZaz_][AZaz09_.]*
    ordinary variables, can be read and assigned to
    type will be inferred automatically

 

  • array elements $var[expr1][expr2]…[exprn]
    where $var holds an n-dimensional array
    again, type and dimensionality will be inferred automatically
    the indices expr1, expr2, …, exprn can have any basic type (int, uint, str, bstr, ipv4, ipv6, etc.), and one can even use indices of different types for the same array

 

  • logical variables Var                                         [AZ][AZaz09_.]*
    start with a capital letter
    used in database collections
    can be read but not assigned to
    type will be inferred automatically

 

  • field names .module.field                           .[AZaz09_]+.[AZaz09_.]*
    type is given in its respective module

 

  • constants:
    • integer constants                               [09]+
      type: uint

      • integer constants do not start with a sign; if you write -123, this will be interpreted as the arithmetic operator - applied to the number 123, resulting in an expression of type int, not uint
    • floating-point constants                 ([09]*\.[09]+)([eE][-+]?[09]+)?
      type: float

      • these are really double precision floating-point numbers, equivalent to double in C
    • string constants
      See the STRING token on the Orchids language page
      type: str

      • as in C, writing two or more string constants in succession produces their concatenation; this allows one to write multi-line string constants, notably
    • ctime constants                                    _CTIME(integer constant),
      or                                                                  _CTIME(string constant)
      type: ctime

      • the first syntax uses a number of seconds since the epoch (January 1, 1970)
      • while the second syntax uses a human-readable date string
    • ipv4 constants                                      _IPV4(string constant)
      type: ipv4

      • string can be of the form “aa.bb.cc.dd“, or “host.subnet.domain
    • ipv6 constants                                      _IPV6(string constant)
      type: ipv6

      • string can be of the form “aa:bb:cc:dd:ee:ff:gg” (or any of the usual variants), or “host.subnet.domain
    • timeval constants                        _TIMEVAL(integer constant, integer constant),
      or                                                           _TIMEVAL(string constant, integer constant)
      type: timeval

      • the first syntax uses a pair of a number of seconds and a number of microseconds
      • the second syntax instead specifies the number of seconds as a date, in a human-readable format
    • regexp constants                          _REGEX(string constant)
      type: regex

      • actually compiles the given string to a regexp-matching machine,
        usable as second argument to operators =~, !~

 

  • expr1 binop expr2
    where binop is a binary operator

 

  • monop expr
    where monop is a unary operator

 

  • function(expr1,, exprn)
    evaluate expr1,, exprn, yielding values val1,, valn, then call function on the latter

    • function must be one of the Orchids primitives, defined in the core language or in one of the modules

 

  • synthetic event:                                  .{field1=expr1,, fieldn=exprn}
    create a synthetic event

    • evaluate expr1, …, exprn, yielding values val1, …, valn then create an event with bindings fieldi=vali
    • fields may appear in duplicate, however stupid that may seem; if two values are mapped to the same field, only the last one will be kept
    • synthetic events can be posted using inject_event, provided the metaevent module is loaded
    • Typing:
      • Requires: each expri is of the type of fieldi, as given in its respective module
      • Yields: event

 

  • event enrichment:                             expr + .{field1=expr1,, fieldn=exprn}
    create a synthetic event

    • evaluate expr to an event evt, evaluate expr1, …, exprn, yielding values val1, …, valn then append the indicated bindings fieldi=vali to evt
    • this is non-destructive, and creates a new synthetic event
    • fields may appear in duplicate, however stupid that may seem; if two values are mapped to the same field, only the last one will be kept; in particular, this allows one to hide field values from evt and replace them with new values
    • synthetic events can be posted using inject_event
    • expr can be obtained as a previously synthesized event, or using current_event
    • Typing:
      • Requires: expr : event
        each expri is of the type of fieldi,
        as given in its respective module
      • Yields: event

 

  • database expressions
    • You should understand that all Orchids databases are applicative (non-destructive): you do not modify a database, add a tuple to a database, delete tuples from a database; instead, you build new databases from old, using the empty database nothing, singleton databases, database collections, as well as database unions (+) and differences (-)
    • empty database                                      nothing
      • of type db[*], convertible to any actual database type db[type1,…,typen]
    • singleton database                              {{expr1, …, exprn}}
      • of type db[type1,…,typen], where expr1 : type1, …, exprn : typen
      • contains just one tuple
    • database collection:
      for db_pattern [and db_pattern]* [{ statement* }] [collect expr]

      • where                                     db_pattern ::= expr1, ..., exprn in expr
      • computes a generalized join of the databases given at the right of the collect keyword: for each tuple in the generalized join, build a database as given after the collect keyword, finally compute the union of all the computed databases (see examples below);
        if the collect keyword is absent, return the empty database nothing
      • if the optional block { statement* } is present, execute it for each matching list of db_pattern
      • this is non-destructive, and creates new databases
      • Example 1:
        for User, Id, Euid in $mydb collect {{User, Euid}}
        builds a new database from $mydb where the middle field (Id) has been removed; this is an example of projection: for each tuple User, Id, Euid in $mydb, we build a tuple containing just User, Euid, and take the union of all those tuples
      • Example 2:
        for "Bill", Id, Euid in $mydb collect {{Id, Euid}}
        builds a new database from $mydb of those tuples whose first field matches the string "Bill"exactly: this is an example of filtering.
      • Example 3:
        for User, Service in $jobs and Service, Manager in $mgmt
        collect {{User, Manager}}

        builds a new database of pairs User, Manager such that the tuple User, Service is in $jobs and Service, Manager is in $mgmt for some value Service: this is an example of a join (followed by projection, since we discard Service)
      • Example 4 (more involved):
        for User, Pid, $epid in $mydb + $myotherdb
        and Perm, Pid in $perm_db
        collect ( {{Pid*128+Perm, User + " authorized"}} + {{Perm, "denied"}}
        )
        computes the union of the two databases $mydb and $myotherdb, then looks for all triples in it where the third field is equal to $epid (obtaining the first and second fields in User and Pid respectively),
        then does a join with $perm_db on the value of the logical variable Pid,
        and for each set of values User, Pid, Perm thus found, collects the two tuples computed as Pid*128+Perm, User + " authorized" and {{Perm, "denied"}}
        (this is a fancy formula meant to illustrate what we can do with database collections, but has no practical use a priori)