NAME

Zapp::Formula - Formula interpreter

VERSION

version 0.005

SYNOPSIS

my $f = Zapp::Formula->new;

# [ call => [ var => 'UPPER' ], [ binop => '&', [ string => "hello " ], [ var => "name" ] ] ]
my $tree = $f->parse( 'UPPER( "hello " & name )' );

# HELLO LEELA
my $res = $f->eval( 'UPPER( "hello " & name )', { name => 'Leela' } );

# { greeting => "HELLO LEELA" }
my $data = $f->resolve( { greeting => 'UPPER( "hello " & name )' }, { name => 'Leela' } );

DESCRIPTION

This module parses and evaluates formulas. Formulas are strings that begin with one = and contain an expression. Formula expressions can contain strings, numbers, variables, binary operations, function calls, and array or hash literals.

METHODS

parse

my $tree = $f->parse( $formula )

Parse the given formula (without = prefix) and return an abstract syntax tree that can be evaluated.

eval

my $value = $f->eval( $formula, $context );

Parse and execute the given formula (without = prefix) using the given context as values for any variables.

resolve

my $data = $f->resolve( $data, $context );

Resolve all formulas in the data structure $data and return a new data structure with the resolved values. Formulas are strings that begin with =. Use == to escape parsing.

# { val => 1, str => '=num' }
$f->resolve( { val => '=num', str => '==num' }, { num => 1 } );

FORMULA SYNTAX

Where possible, the formula syntax resembles the syntax from popular spreadsheet programs like Lotus 1-2-3, Excel, and Sheets, and Microsoft's Power Fx.

Strings

Strings are surrounded by double-quotes ("Professor Fisherprice Shpeekenshpell"). Double-quotes can be inserted into strings by adding a backslash ("The horse says \"Doctorate Denied\"").

Numbers

Numbers can be integers (312) or decimals (3.12). Negative numbers have - in front (-3.12).

Variables

Variables start with a letter and can contain letters, numbers, and underscores (_). Variable values are defined in the context. Variables cannot be created by formulas (yet).

Binary Operators

Mathematical Operators
# Addition
1.2 + 3             -> 4.2

# Subtraction
4 - 2.3             -> 1.7

# Multiplication
2 * 3               -> 6

# Division
8 / 2               -> 4

# Exponentation
2 ^ 3               -> 8
String Operators
# Concatenation
"Hello, " & "World" -> "Hello, World"
Logical Operators
# Equality
2 = 2               -> TRUE

# Inequality
3 <> 3              -> FALSE

# Less-/Greater-than
3 < 8               -> TRUE
3 > 8               -> FALSE

# Less-/Greater-than-or-equal
3 <= 2              -> FALSE
3 >= 3              -> TRUE

Function Calls

Function calls start with the name of the function followed by empty parentheses or parentheses containing function parameters (expressions) separated by commas.

IF( name = "Leela", TRUE(), FALSE() )

See "FUNCTIONS" for a list of available functions.

Arrays

Arrays begin with square brackets and contain expressions separated by commas.

[ name, name = "Leela", TRUE() ]

Get a value from an array using square brackets and the index of the item (0-based).

# Characters = [ "Fry", "Leela", "Bender" ]
Characters[2]       # Bender

Hashes

Hashes begin with curly braces and contain key/value pairs separated by commas. Keys must be strings (for now) and are separated from values with colons.

{ "name": "Leela", "captain": TRUE() }

Get a value from a hash using dot followed by the key.

# Employees = { "Pilot": "Leela", "Cook": "Bender", "Person": "Fry" }
Employees.Pilot     # Leela

SEE ALSO

Zapp::Task, Zapp

FUNCTIONS

Logic/Control Functions

AND

=AND( <expression>... )

Returns TRUE if all expressions are true.

EVAL

=EVAL( <string> )

Evaluate the string as a formula and return the result. The string must not begin with an =.

FALSE

=FALSE()

Returns a false value.

IF

=IF( <expression>, <true_result>, <false_result> )

Evaluate the expression in expression and return true_result if the condition is true, or false_result if the condition is false.

IFS

=IFS( <expression>, <result>, ..., <default_result> )

Evaluate each expression and return its corresponding result if the expression is true. Return default_result if no condition is true.

NOT

=NOT( <expression> )

Returns TRUE if the expression is true, FALSE otherwise.

OR

=OR( <expression>... )

Returns TRUE if one expression is true.

TRUE

=TRUE()

Returns a true value.

XOR

=XOR( <expression>... )

Returns TRUE if one and only one expression is true.

AUTHOR

Doug Bell <preaction@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2021 by Doug Bell.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.