Add explanation about functions and precedences

This commit is contained in:
Sebastian Schmidt 2019-03-19 12:22:06 +02:00
parent 2b9d50909e
commit ed73f779e9
3 changed files with 63 additions and 7 deletions

View File

@ -96,6 +96,9 @@ Supported unary operators:
| - | 110 | Negation | | - | 110 | Negation |
| ! | 110 | Logical not | | ! | 110 | Logical not |
Operators with higher precedence have a higher priority when determining the order of evaluation.
The precedence of variables and values is 200, and the precedence of function literals is 190.
### Values ### Values
Operators take values as arguments and produce values as results. Operators take values as arguments and produce values as results.
@ -114,6 +117,8 @@ Operators that take numbers as arguments can either take integers or floating po
If one of the arguments is a floating point number, all others are converted to floating point numbers as well, and the resulting value is a floating point number as well. If one of the arguments is a floating point number, all others are converted to floating point numbers as well, and the resulting value is a floating point number as well.
Otherwise, the result is an integer. Otherwise, the result is an integer.
Values have a precedence of 200.
### Variables ### Variables
This crate allows to compile parameterizable formulas by using variables. This crate allows to compile parameterizable formulas by using variables.
@ -127,15 +132,38 @@ Variables do not have fixed types in the expression itself, but aer typed by the
The `Configuration` trait contains a function that takes a string literal and returns a `Value` enum. The `Configuration` trait contains a function that takes a string literal and returns a `Value` enum.
The variant of this enum decides the type on evaluation. The variant of this enum decides the type on evaluation.
Variables have a precedence of 200.
### Functions ### Functions
This crate also allows to define arbitrary functions to be used in parsed expressions. This crate also allows to define arbitrary functions to be used in parsed expressions.
A function is defined as a `Function` instance. A function is defined as a `Function` instance.
It contains two properties, the `argument_amount` and the `function`. It contains two properties, the `argument_amount` and the `function`.
The `function` is a boxed `Fn(&[Value]) -> Result<Value, Error>`. The `function` is a boxed `Fn(&[Value]) -> Result<Value, Error>`.
The `argument_amount` is verified on execution by the crate and does not need to be verified by the `function`. The `argument_amount` determines the length of the slice that is passed to `function`.
It determines the length of the slice that is passed to `function`. It is verified on execution by the crate and does not need to be verified by the `function`.
See the examples section above for examples on how to construct a function instance.
Be aware that functions need to verify the types of values that are passed to them.
The `error` module contains some shortcuts for verification, and error types for passing a wrong value type.
Also, most numeric functions need to differentiate between being called with integers or floating point numbers, and act accordingly.
Functions are identified by literals, like variables as well.
A literal identifies a function, if it is followed by an opening brace `(`, another literal, or a value.
Same as variables, function bindings are provided by the user via a `Configuration`.
Functions have a precedence of 190.
### Examplary variables and functions in expressions:
| Expression | Valid? | Explanation |
|------------|--------|-------------|
| `a` | yes | |
| `abc` | yes | |
| `a<b` | no | Expression is interpreted as variable `a`, operator `<` and variable `b` |
| `a b` | no | Expression is interpreted as function `a` applied to argument `b` |
| `123` | no | Expression is interpreted as `Value::Int` |
| `true` | no | Expression is interpreted as `Value::Bool` |
| `.34` | no | Expression is interpreted as `Value::Float` |
## License ## License

View File

@ -34,7 +34,7 @@ pub enum Error {
/// A `FunctionIdentifier` operation did not find its value in the configuration. /// A `FunctionIdentifier` operation did not find its value in the configuration.
FunctionIdentifierNotFound(String), FunctionIdentifierNotFound(String),
/// A value has the wrong type. /// A value has the wrong type. Only use this if there is no other error that describes the expected and provided types in more detail.
TypeError, TypeError,
/// An opening brace without a matching closing brace was found. /// An opening brace without a matching closing brace was found.

View File

@ -86,6 +86,9 @@
//! | - | 110 | Negation | //! | - | 110 | Negation |
//! | ! | 110 | Logical not | //! | ! | 110 | Logical not |
//! //!
//! Operators with higher precedence have a higher priority when determining the order of evaluation.
//! The precedence of variables and values is 200, and the precedence of function literals is 190.
//!
//! ### Values //! ### Values
//! //!
//! Operators take values as arguments and produce values as results. //! Operators take values as arguments and produce values as results.
@ -104,6 +107,8 @@
//! If one of the arguments is a floating point number, all others are converted to floating point numbers as well, and the resulting value is a floating point number as well. //! If one of the arguments is a floating point number, all others are converted to floating point numbers as well, and the resulting value is a floating point number as well.
//! Otherwise, the result is an integer. //! Otherwise, the result is an integer.
//! //!
//! Values have a precedence of 200.
//!
//! ### Variables //! ### Variables
//! //!
//! This crate allows to compile parameterizable formulas by using variables. //! This crate allows to compile parameterizable formulas by using variables.
@ -117,15 +122,38 @@
//! The `Configuration` trait contains a function that takes a string literal and returns a `Value` enum. //! The `Configuration` trait contains a function that takes a string literal and returns a `Value` enum.
//! The variant of this enum decides the type on evaluation. //! The variant of this enum decides the type on evaluation.
//! //!
//! Variables have a precedence of 200.
//!
//! ### Functions //! ### Functions
//! //!
//! This crate also allows to define arbitrary functions to be used in parsed expressions. //! This crate also allows to define arbitrary functions to be used in parsed expressions.
//! A function is defined as a `Function` instance. //! A function is defined as a `Function` instance.
//! It contains two properties, the `argument_amount` and the `function`. //! It contains two properties, the `argument_amount` and the `function`.
//! The `function` is a boxed `Fn(&[Value]) -> Result<Value, Error>`. //! The `function` is a boxed `Fn(&[Value]) -> Result<Value, Error>`.
//! The `argument_amount` is verified on execution by the crate and does not need to be verified by the `function`. //! The `argument_amount` determines the length of the slice that is passed to `function`.
//! It determines the length of the slice that is passed to `function`. //! It is verified on execution by the crate and does not need to be verified by the `function`.
//! See the examples section above for examples on how to construct a function instance. //!
//! Be aware that functions need to verify the types of values that are passed to them.
//! The `error` module contains some shortcuts for verification, and error types for passing a wrong value type.
//! Also, most numeric functions need to differentiate between being called with integers or floating point numbers, and act accordingly.
//!
//! Functions are identified by literals, like variables as well.
//! A literal identifies a function, if it is followed by an opening brace `(`, another literal, or a value.
//!
//! Same as variables, function bindings are provided by the user via a `Configuration`.
//! Functions have a precedence of 190.
//!
//! ### Examplary variables and functions in expressions:
//!
//! | Expression | Valid? | Explanation |
//! |------------|--------|-------------|
//! | `a` | yes | |
//! | `abc` | yes | |
//! | `a<b` | no | Expression is interpreted as variable `a`, operator `<` and variable `b` |
//! | `a b` | no | Expression is interpreted as function `a` applied to argument `b` |
//! | `123` | no | Expression is interpreted as `Value::Int` |
//! | `true` | no | Expression is interpreted as `Value::Bool` |
//! | `.34` | no | Expression is interpreted as `Value::Float` |
//! //!
//! ## License //! ## License
//! //!