Skip site navigation (1)Skip section navigation (2)

  
 
  

home | help
KLELLANG(1)			     libklel			     KLELLANG(1)

INTRODUCTION
     This manual page documents the language as understood by the KL-EL library.
     For documentation on how to embed the KL-EL compiler and interpreter in an
     application, see klelapi(3).  For a tutorial on how to use the library, see
     kleltut(3).

     The language understood by KL-EL is an expression language.  Everything in
     the language is an expression that has a value.  The purpose of the library
     is to allow these expressions to be input at runtime and have the applica-
     tion make use of the resulting values in some fashion.

     There are two kinds of KL-EL expressions: value expressions (often referred
     to as simply "expressions") and guarded commands.	Guarded commands are
     more complicated, but they are also very useful in certain situations.  Be-
     cause guarded commands are more complex than value expressions, they will
     be covered second.

     Expressions in KL-EL are not sensitive to whitespace; whitespace is only
     significant inside literal strings.

A NOTE ON TYPES
     Every value in KL-EL has one and only one type, and the type of a given ex-
     pression never changes.  That makes KL-EL strongly typed, and this typing
     discipline is possibly its most interesting feature.  KL-EL was designed to
     be useful in applications where an expression is compiled only once but ex-
     ecuted thousands or millions of times with different parameters, and possi-
     bly on ephemeral or forensic data.  If typechecking were not performed un-
     til evaluation, it is possible that a failure could occur after millions of
     executions on some set of inputs, rendering the entire run (or a large por-
     tion of it) invalid.  In the best case, the expression could be fixed and
     execution could pick up where it left off, but in the worst case, it may be
     impossible to recover the values used previously or begin execution again.
     Checking types at compile time also makes things faster for multiple execu-
     tions of a given expression, since types do not need to be checked on each
     execution.

     KL-EL understands four types:

     Booleans (either true or false)
     Integers (signed 64-bit)
     Reals (IEEE double-precision floating point)
     Strings (sequences of bytes with no length limitations, embedded NULL bytes
     are allowed)

     Functions are provided to transform values of one type to another type as
     necessary.  In general, there is no concept of type promotion.  Expressions
     like

	 "123" + 5

     don't work since addition is not defined for strings.  There is a slight
     relaxation of this restriction for expressions involving a mixture of inte-
     gers and reals -- integers are silently promoted to real values when they
     are used in arithmetic expressions involving reals.  This is the only ex-
     ception to the typing discipline.	Note that the exception only applies to
     arithmetic expressions -- functions expecting real arguments will not ac-
     cept integer arguments.

NAMES
     Any top-level expression can be named, and this name can be extracted from
     the compiled expression at runtime.  This is useful in situations where
     there may be many unrelated expressions (say, in a configuration file), and
     it would be useful to identify expressions in diagnostics or other output.

     To name an expression, simply prefix it with a name and a colon.  A name in
     this case may consist of letters, numbers, and underscores, and must begin
     with a letter.  For example, this gives an expression "1 + 1" the name "Ex-
     ample":

       Example : 1 + 1

     Once again, note that only top-level expressions may be named.

VALUE EXPRESSIONS
     Value expressions are simple expressions that, when evaluated, produce a
     value.  There are seven different kinds of value expressions:

     Literals
     Variables
     Function calls
     Unary (arithmetic negation, logical negation, bitwise negation)
     Binary (arithmetic, string concatenation, comparison)
     Ternary (conditional evaluation)
     Let (lexical scoping)

     Each of these expression types is covered below.  For more information on
     how to retrieve the value of an evaluated expression using the library, see
     klelapi(3).

   LITERAL BOOLEANS
     There is no literal syntax for Boolean values.  The standard variables
     "true" and "false" are defined and have their expected meanings.

   LITERAL NUMBERS
     Numbers can be written in octal, decimal, or hexadecimal.	Octal numbers
     are prefixed with '0o', and hexadecimal numbers are prefixed with '0x'.
     Sequences of decimal digits with no prefix are assumed to be in decimal.

     Real numbers are written in decimal, with '.' as the decimal point.  The
     decimal point and one digit after it are obligatory.  An optional exponent
     can be provided by suffixing the number with 'e', an optional minus sign
     (indicating a negative exponent), and at least one decimal digit.

   LITERAL STRINGS
     Literal strings are written enclosed in double quotes.  Any character may
     appear between the double quotes except for newlines, double quotes, back-
     slashes, percent signs, and literal zeros (NULL bytes).  By using escapes,
     these and other characters can be conveniently inserted.  The following es-
     capes are defined:

     \\ (backslash)
     \" (double quote)
     \r (carriage return)
     \n (linefeed)
     \% (percent sign)
     \xHH (the byte whose value is HH in hexadecimal)

     Literal strings may also contain interpolations.  Interpolations are of one
     of the forms

	 %{name}

	 %(name)

     It is because of this syntax that percent signs are recognized as an es-
     capable character.  Interpolations take the value of the named variable,
     convert that value to a string, and embed the stringified value into the
     string produced by evaluating the string literal.	Variable names enclosed
     in curly brackets have their value inserted as is, while those enclosed in
     parentheses have their values inserted after any special characters have
     been quoted (this is referred to as a quoted interpolation).  In this case
     "special characters" and the character used to quote them are defined by
     the application using the library, with sensible defaults.

   VARIABLES
     Variables can be used anywhere where an expression is expected.  Variables
     are of static type, but their values may change at any time.  Variables are
     either exported from the application using the library (referred to as the
     "host" or "host application"), or they are introduced by a let expression
     (see below).  Applications using the library can export any number of vari-
     ables into the KL-EL environment, allowing for simple interaction between
     the host application and KL-EL.  For information on how applications export
     variables into the KL-EL environment, see klelapi(3).

     KL-EL comes with a standard library that defines several variables.  New
     variables can be introduced inside an expression by introducing a new scope
     using a let expression; these expressions are discussed below.

   FUNCTION CALLS
     It is not possible to define a function in KL-EL, but the application using
     the library can export as many functions as it needs.  KL-EL also comes
     with a standard library of functions.  The functions in this library are
     automatically available for use in any expression unless specifically dis-
     allowed by the host application.

     A function call uses syntax familiar from C:

	 name(arg0, arg1, ... argN)

     Due to the way types are represented in the type checker, functions are
     limited to thirteen arguments.  It is important to note that functions are
     not first-class values; they can neither be passed as arguments to nor re-
     turned as the result of other functions.

     For more information on how to export a function into the KL-EL environ-
     ment, see klelapi(3).

   UNARY OPERATIONS
     Below three (3) unary operators are defined in terms of their operator sym-
     bol, operand type, and result type.  The type codes B, I, and R represent
     boolean, integer, and real types, respectively.

			    ======= DEFINITION =======
				    o  l  r  r
				    p  e  i  e
				    e  f  g  s
				    r  t  h  u
				    a  t  t  l
				    t	     t
				    o
				    r
	======	OPERATION  ===========================
	Arithmetic Negation	    -	  I  I
	Arithmetic Negation	    -	  R  R
	Bitwise NOT		    ~	  I  I
	Boolean Negation	    !	  B  B

     Note that unary operators bind more tightly than any binary operator.

   BINARY OPERATIONS
     Below twenty-one (21) binary operators are defined in terms of their opera-
     tor symbol, operand types, and result type.  These operators are listed in
     decreasing order of precedence.  The type codes B, I, R, and S represent
     boolean, integer, real, and string types, respectively.

			    ======= DEFINITION =======
				    o  l  r  r
				    p  e  i  e
				    e  f  g  s
				    r  t  h  u
				    a  t  t  l
				    t	     t
				    o
				    r
	======	OPERATION  ===========================
	Multiplication		    *  I  I  I
	Multiplication		    *  R  I  R
	Multiplication		    *  I  R  R
	Multiplication		    *  R  R  R
	Division		    /  I  I  I
	Division		    /  R  I  R
	Division		    /  I  R  R
	Division		    /  R  R  R
	Modular Division	    %  I  I  I
	Logical Conjunction	   &&  B  B  B
	Bitwise Roll Left	   <<  I  I  I
	Bitwise Roll Right	   >>  I  I  I
	String Concatenation	    .  S  S  S
	Addition		    +  I  I  I
	Addition		    +  R  I  R
	Addition		    +  I  R  R
	Addition		    +  R  R  R
	Subtraction		    -  I  I  I
	Subtraction		    -  R  I  R
	Subtraction		    -  I  R  R
	Subtraction		    -  R  R  R
	Logical Disjunction	   ||  B  B  B
	Bitwise AND		    &  I  I  I
	Bitwise XOR		    ^  I  I  I
	Bitwise OR		    |  I  I  I
	Less than		    <  I  I  B
	Less than		    <  R  R  B
	Less than		    <  S  S  B
	Greater than		    >  I  I  B
	Greater than		    >  R  R  B
	Greater than		    >  S  S  B
	Less than or equal	   <=  I  I  B
	Less than or equal	   <=  R  R  B
	Less than or equal	   <=  S  S  B
	Greater than or equal	   >=  I  I  B
	Greater than or equal	   >=  R  R  B
	Greater than or equal	   >=  S  S  B
	Equal			   ==  B  B  B
	Equal			   ==  I  I  B
	Equal			   ==  R  R  B
	Equal			   ==  S  S  B
	Not equal		   !=  B  B  B
	Not equal		   !=  I  I  B
	Not equal		   !=  R  R  B
	Not equal		   !=  S  S  B
	Regex match		   =~  S  S  B
	Regex non-match 	   !~  S  S  B

     Note that the environment's localization settings (particularly collation
     order) may affect the result when comparing strings using the relational
     operators.

     For regular expression matches, the right operand is the expression; it is
     expected to be a string in PCRE syntax.  For more information, see pcre(3).

     Parentheses can be used to override the normal order of operations when
     necessary.

   THE TERNARY OPERATOR
     KL-EL defines a single ternary operator, '?'.  Ternary expressions are of
     the form:

	 predicate ? expr1 : expr2

     where predicate is an expression of Boolean type and expr1 and expr2 are
     two expressions of the same type.	If predicate evaluates to true, expr1 is
     evaluated, otherwise expr2 is evaluated.  Note that parenthesis are gener-
     ally required around predicates unless they are syntactically trivial.  The
     type of a ternary expression is the type of expr1 or expr2.

   LET EXPRESSIONS
     KL-EL is lexically scoped in the ALGOL tradition.	New environments are
     created using let expressions.  These expressions are of the form:

	 let var = expr1 in expr2

     The value of this expression is the value of expr2 with every occurrence of
     var substituted by the value of expr1.  As let expressions are normal ex-
     pressions, they can be nested.  In particular, this is a valid (and common)
     idiom:

	 let var1 = expr1 in
	   let var2 = expr2 in
	     let var3 = expr3 in
	       var1 + var2 + var3

     Variables in nested scopes can shadow variables in outer scopes, though
     this functionality is best used sparingly.  Variables exported from the
     host application are in the outermost scope.

GUARDED COMMANDS
     Aside from value expressions, KL-EL supports guarded commands.  A guarded
     command consists of a guard of boolean type, a call to the special function
     eval, and an optional list of return codes.  The intent of guarded commands
     is to provide the host application with a command (where the meaning of
     "command" is defined by the host application), along with a set of support-
     ing arguments, that is valid only when the guard expression is valid.

     Guarded commands have one of the following forms:

       if (guard) then eval(interpreter, program, arg0, ... argN)

       if (guard) then eval(interpreter, program, arg0, ... argN) pass [code0, ... codeN]

       if (guard) then eval(interpreter, program, arg0, ... argN) fail [code0, ... codeN]

     In these forms guard must be a value expression of boolean type, inter-
     preter and program must be constant strings, and codes must be literal in-
     tegers.  The remaining arguments may be of any type.

     Guarded commands are useful in situations where it is important to distin-
     guish between the action and the guard.  Take for example a file-finding
     application.  In this hypothetical application, a guarded command is used
     to specify a command to execute on every file that matches its expression
     thereby allowing the application to customize its behavior based on ob-
     served file attributes.

     In a guarded command, the arguments to the eval function and the code val-
     ues are passed as-is to the host application.  It is up to the application
     to determine their meaning.  For a discussion on how guarded commands are
     represented in host applications, see klelapi(3).

     It is important to note that guarded commands cannot be nested inside other
     expressions or guarded commands.

SEE ALSO
     klel-expr(1), klelapi(3), klelstdlib(3), kleltut(3), pcre(3)

1.1.0				   2026-08-27			     KLELLANG(1)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=klellang&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help