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.