{"id":22601274,"url":"https://github.com/blvckbytes/gpeee","last_synced_at":"2025-04-11T02:41:46.038Z","repository":{"id":64652189,"uuid":"577159138","full_name":"BlvckBytes/GPEEE","owner":"BlvckBytes","description":"A very small and versatile parser used to evaluate simple expressions","archived":false,"fork":false,"pushed_at":"2025-01-23T14:21:27.000Z","size":1617,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T00:29:06.252Z","etag":null,"topics":["ast","configuration","environment","expression","interpreter","language","optimizer","parser","tokenizer"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BlvckBytes.png","metadata":{"files":{"readme":"README-X.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-12-12T05:13:35.000Z","updated_at":"2025-01-23T14:21:31.000Z","dependencies_parsed_at":"2023-02-08T08:31:27.170Z","dependency_job_id":"0b646892-a056-4079-88a7-281c59cd52f2","html_url":"https://github.com/BlvckBytes/GPEEE","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlvckBytes%2FGPEEE","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlvckBytes%2FGPEEE/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlvckBytes%2FGPEEE/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlvckBytes%2FGPEEE/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BlvckBytes","download_url":"https://codeload.github.com/BlvckBytes/GPEEE/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248331078,"owners_count":21085833,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ast","configuration","environment","expression","interpreter","language","optimizer","parser","tokenizer"],"created_at":"2024-12-08T12:14:05.860Z","updated_at":"2025-04-11T02:41:46.018Z","avatar_url":"https://github.com/BlvckBytes.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- This file is rendered by https://github.com/BlvckBytes/readme_helper --\u003e\n\n# GPEEE\n\n![build](https://github.com/BlvckBytes/GPEEE/actions/workflows/build.yml/badge.svg)\n[![coverage](https://codecov.io/gh/BlvckBytes/GPEEE/branch/main/graph/badge.svg?token=WGWX8IDT00)](https://codecov.io/gh/BlvckBytes/GPEEE)\n\n![logo](readme_images/logo.png)\n\nThe opensource `General Purpose Environment Expression Evaluator` (GPEEE) which you most definitely\nwant to integrate into your next project.\n\n\u003c!-- #toc --\u003e\n\n## Mission Statement\n\nWhile this *is* a general purpose evaluator, it has been designed to solve a very specific problem\nmany bukkit plugin developers face: Allowing the user to easily describe dynamic and possibly complex\nbehavior inside a *YAML* configuration file. Many successful projects offer such a feature, but - at least\nto my knowledge - they all painstakingly implement their own evaluator. Not only does this suck for\nthe end user who has to learn a million different flavors for basic operation expressions, but it also\nheavily constrains lots of plugin developers who don't know how to write a parser in the user experience\nof their software.\n\nIn order to keep this already pretty complex project as dead simple as possible, I've set a few\nmain guidelines in stone:\n\n* Very clean, maintainable and well documented codebase to make it accessible for everyone\n* Implement all generally known and loved operators but **don't** add anything fancy\n* Expressions will **not** keep any state between evaluations\n* Next to basic terminal values, operators and if-then-else, there will be **no** keywords\n* **All** remaining control flow and complex logic will be outsourced to Java and hidden behind functions\n\nWithout adhering to these, I'm sure the project would grow into an unmaintainable beast of \"one more\nfeature please\". The restrictions may seem harsh, but you're still able to get up and running with\nall customizations by defining your own *evaluation environment* exactly to your needs in no time.\n\n## Getting Started\n\n### Installation\n\nFor now, this resource won't be hosted anywhere. Please clone the last successfully built commit,\nnavigate into it and run `mvn install` to install it into your local maven repository.\n\nThen, add the project as a dependency to your new project:\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eme.blvckbytes\u003c/groupId\u003e\n  \u003cartifactId\u003eGPEEE\u003c/artifactId\u003e\n\n  \u003c!-- Use whatever the pom.xml of GPEEE currently specifies --\u003e\n  \u003cversion\u003e0.1-SNAPSHOT\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nAs soon as this software has proven itself useful, releases and hosted dependencies will be set up.\n\n### Evaluator Instance\n\nThe working principle of this evaluator is as simple as it gets: You provide an *evaluation environment*\nas well as a string containing the target expression and the evaluator returns an *evaluation result* or\nthrows an error to be properly handled by the caller.\n\n\u003c!-- #include src/main/java/me/blvckbytes/gpeee/IExpressionEvaluator.java --\u003e\n\nIn order to allow for pre-parsed expressions which can be evaluated over and over again while their environment\nmay change it's values, the parsing, evaluating and optimizing stages have been strictly separated. Generally\nspeaking, you do **not** want to optimize only once evaluated expressions, but most definitely want to do so if\nthey're used multiple times.\n\nThis interface has been implemented by the `me.blvckbytes.gpeee.GPEEE` class, which can be easily\ninstantiated by providing an optional logger to it's constructor. As soon as you got an instance, you can evaluate\nas many expressions in as many environments with it as you'd like.\n\n### Creating An Environment\n\nThe evaluation environment tells the interpreter of your expressions which variables and which functions are available\nand may be substituted/called from within an expression and how different types of values are to be handled.\n\n\u003c!-- #include src/main/java/me/blvckbytes/gpeee/interpreter/IEvaluationEnvironment.java --\u003e\n\nIf a value is going to be constant throughout the lifetime of an environment, you may use a static variable. Otherwise,\nit's advised to not update the map over and over again, but to rather specify a live variable supplier. This supplier\nwill be called whenever the interpreter needs this variable's value.\n\nThe *value interpreter* is used to define how different data-types can be interpreted and combined using various\noperations. Implementing such an instance can take a lot of time and is prone to errors, which is why there's a very\nsensible default implementation which' use is recommended, as described in the comment inside the above interface.\n\nThere's a builder to concisely create custom environments:\n\n\u003c!-- #include src/main/java/me/blvckbytes/gpeee/interpreter/EvaluationEnvironmentBuilder.java --\u003e\n\nIn order to create a new expression function, it's best practice to create a separate class which inherits the\nfollowing abstract base class:\n\n\u003c!-- #include src/main/java/me/blvckbytes/gpeee/functions/AExpressionFunction.java --\u003e\n\nIf argument validation is not required, the argument list getter can always just return null. Otherwise, arguments\nmay be specified in order, where non-required (non-positional) arguments may only follow after all required arguments. An\nargument consists of it's name, description, required-flag as well as an optional list of accepted types. Leave this\nargument empty to not type-check at all.\n\n\u003c!-- #include src/main/java/me/blvckbytes/gpeee/functions/AExpressionFunction.java --\u003e\n\nThis class will also itself try to convert passed values to the required type before letting the interpreter throw a\nmismatch error by making use of the *value interpreter*.\n\n### Function Implementation Example\n\nThere are a few standard (std) functions already included in this software package you can take a look at in order\nto get a feel for how functions are intended to be used and created. As an example, an excerpt from the std function\n`iter_cat` has been provided for you.\n\n\u003c!-- #include src/main/java/me/blvckbytes/gpeee/functions/std/IterCatFunction.java --\u003e\n\nWhile this implementation is a standard function, the exact same way of implementing functions applies to custom functions, \nminus the registration- as well as the result return boolean parts.\n\n### Full Use Example\n\nThe following class shows a compact but complete use-case of the `GPEEE`.\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/FullUseExample.java --\u003e\n\n## Syntax\n\nThe syntax of this language has been mostly inspired by *JavaScript* as well as *Python* and is easy to grow accustomed\nto once you've spent a few minutes to experiment with it.\n\n### Multiline Programs\n\nA program may only consist of a single expression if that's sufficient for the use-case at hand, but it may also involve\nmultiple expressions which get processed top-down. For example: One expression can assign a variable which then can be\naccessed by another expression later on.\n\nThe following program represents a really simple example:\n\n```\nadd_prefix = (input) =\u003e \"prefix: \" \u0026 input\nadd_prefix(\"Hello\") \u0026 \", \" \u0026 add_prefix(\"World\")\n```\n\nWhich results in: `prefix: Hello, prefix: World`\n\nThis functionality can be useful to extract reused expressions for a single program. If you notice similar patterns across\nmultiple programs, it would be advised to rather create a function in Java, which will then be accessible to all programs.\n\n### Operator Precedence\n\nThis operator table lists all available operators as well as their precedence when evaluating expressions. A lower\nprecedence number means that the value of that expression is evaluated first.\n\n| Operator                            | Name                           | Example                                          | Precedence |\n|-------------------------------------|--------------------------------|--------------------------------------------------|------------|\n| (...)                               | Parentheses                    | (5 + 3) * 2                                      | 0          |\n| (...) =\u003e ...                        | Callback                       | (a, b) =\u003e a + b                                  | 1          |\n| if ... then ... else ...            | If-Then-Else                   | if a \u003e 5 then b else c                           | 2          |\n| my_function(...), my_function?(...) | (Optional) Function Invocation | map_of(\"k1\", \"v1\", \"k2\", \"v2\")                   | 3          |\n| (...).(...), (...)?.(...)           | (Optional) Member Access       | a.b, a?.b?.c, a?.(my_field_name_expr)            | 4          |\n| (...)\\[(...)\\], (...)?\\[(...)\\]     | (Optional) Indexing            | a\\[0\\], a?\\[\"key\"\\]?\\[c\\], a?\\[(my_index_expr)\\] | 5          |\n| -(...)                              | Flip Sign                      | -a, -5, -my_function(), 2^-(1/2)                 | 6          |\n| not (...)                           | Negation                       | not a, not my_function(), not a or b             | 7          |\n| (...) ^ (...)                       | Exponentiation                 | a^2, (a+b)^(c-d)                                 | 8          |\n| (...) * (...)                       | Multiplication                 | a * 2, (a+b) * (c-d)                             | 9          |\n| (...) / (...)                       | Division                       | a / b, (a+b) / (c-d)                             | 9          |\n| (...) % (...)                       | Modulo                         | a % b, (a+b) % (c-d)                             | 9          |\n| (...) + (...)                       | Addition                       | a + b                                            | 10         |\n| (...) - (...)                       | Subtraction                    | a - b, (a+b) - (a-b)                             | 10         |\n| (...) \u003e (...)                       | Greater Than                   | a \u003e b                                            | 11         |\n| (...) \u003c (...)                       | Less Than                      | a \u003c b                                            | 11         |\n| (...) \u003e= (...)                      | Greater Than Or Equal          | a \u003e= b                                           | 11         |\n| (...) \u003c= (...)                      | Less Than Or Equal             | a \u003c= b                                           | 11         |\n| (...) == (...)                      | Equals                         | a == b                                           | 12         |\n| (...) != (...)                      | Not Equals                     | a != b                                           | 12         |\n| (...) === (...)                     | Equals Exact                   | a === b                                          | 12         |\n| (...) !== (...)                     | Not Equals Exact               | a !== b                                          | 12         |\n| (...) and (...)                     | Boolean Conjunction            | a and b                                          | 13         |\n| (...) or (...)                      | Boolean Disjunction            | a or b                                           | 14         |\n| (...) \u0026 (...)                       | Concatenation                  | a \u0026 b                                            | 15         |\n| (...) ?? (...)                      | Null Coalescence               | a ?? b                                           | 16         |\n| my_variable = (...)                 | Simple Assignment              | a = 5                                            | 17         |\n\n### Optional Access\n\nWhile all other operators should be pretty self-explanatory, some of their optional access versions\nmight need a little description of themselves. They can be made use of whenever it's preferred to not\nthrow errors on invalid access, but rather just return null.\n\n#### Members\n\nIf a variable value is an object and thus contains fields, these fields can be accessed by the member access\noperator. As long as the requested field name exists, it's value will be substituted properly. Otherwise, an\nerror will be thrown. The optional member access operator can be used and even chained together by just prepending\na question-mark to the operator itself.\n\n```\na?.b?.c?.d\n```\n\n#### Indexing\n\nIf a variable value is either of type map and thus contains key-value pairs or of type list/array which contains\nnumerically indexed values, all of these values can be accessed by their key. As long as the requested key exists,\nit's value will be substituted properly. Otherwise, an error will be thrown. The optional indexing can be used and\neven chained together by just prepending a question-mark to the opening bracket itself.\n\n```\nmy_map?[\"key1\"]?[0]?[1]\n```\n\n#### Function Calls\n\nIf a function exists within the environment of an evaluation, it may be called an arbitrary number of times within the\nexpression itself. To just receive a null-value whenever the target function isn't available, a question-mark can be\nprepended to the opening parenthesis of the call notation.\n\n```\nmy_function?()\n```\n\n#### Null Coalescence\n\nWhile this operator is often used in combination with optional access operators, it also makes a lot of sense to be used\non it's own. It checks whether the left-hand-side value is null. If it is, it returns it's right-hand-side value, otherwise\nthe left-hand-side value will be just passed through without any modifications.\n\n```\nmy_maybe_null ?? \"Fallback value\"\n```\n\n#### Comments\n\nComments are defined as a pound symbol (`#`), followed by any character sequence, except a newline (`\\n`). Newlines break comments,\nbut comments can either span across the full line, or live at the end of a line.\n\n```\n# This is a line-comment\n5 + 10 * 2 # This is an inline comment\n```\n\n### Primary Expressions\n\nA primary expression is an immediate value and the most simple type of expression possible. These types of primary expressions are\navailable:\n\n| Name          | Example                     | Description                          |\n|---------------|-----------------------------|--------------------------------------|\n| Literal True  | true                        | A positive boolean value             |\n| Literal False | false                       | A negative boolean value             |\n| Literal Null  | null                        | The null value                       |\n| Double        | 12.3, .4, -.8, -1, .5e-4    | A non-whole number                   |\n| Long          | 123, 4, -8, -1, 2e3         | A whole number                       |\n| String        | \"my string\", \"my \\\\\" quote\" | An immediate string of characters    |\n| Identifier    | a, my_var, my_func          | Either a variable or a function name |\n\n### Grammar Definition\n\nThe following *EBNF* describes the grammar of this small expression language precisely:\n\n\u003c!-- #include src/main/resources/grammar.ebnf --\u003e\n\n## Standard Functions\n\nStandard functions are functions which are always going to be available, no matter of the current environment. They cannot be shadowed\nby environment identifiers and provide basic features which you're likely going to need if you're notating logic.\n\nFor the sake of readability, functions are notated in `TypeScript` notation within this list of functions. The type follows after\nthe colon (`:`) and a question mark (`?`) signals an optional input. In order to help you to understand their behaviour, their\ntest cases have been added in an expandable container, which provide use-case examples.\n\n### bool\n\nInterpret the input value as a boolean by making use of the environments value interpreter.\n\n| Argument | Description                     |\n|----------|---------------------------------|\n| input    | Value to interpret as a boolean |\n\n```\nbool(input?: Object): Boolean\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/BoolFunctionTests.java --\u003e\n\n### date_format\n\nFormat dates with a specified format by making use of the specified time-zone offset.\n\n| Argument | Description                                                                                                  |\n|----------|--------------------------------------------------------------------------------------------------------------|\n| date     | Date value to format                                                                                         |\n| type     | Type of the provided date value                                                                              |\n| format   | [Format](https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html) to apply when formatting |\n| timezone | Timezone to use, defaults to UTC                                                                             |\n\nThe following `type` variations are currently available:\n\n| type    | Description                    |\n|---------|--------------------------------|\n| seconds | Unix timestamp in seconds      |\n| millis  | Unix timestamp in milliseconds |\n| date    | Java Date Object               |\n\n```\ndate_format(date: Number|Date, type: String, format: String, timezone?: String): String\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/DateFormatFunctionTests.java --\u003e\n\n### iter_cat\n\nIterate over a collection while mapping each iteration through a lambda function, who's result\nis being appended to the final result string.\n\n| Argument  | Description                                                |\n|-----------|------------------------------------------------------------|\n| items     | Collection to iterate                                      |\n| mapper    | Lambda function to map items with                          |\n| separator | Separator to use when concatenating items, defaults to \",\" |\n| fallback  | Value to return if the collection is empty                 |\n\n```\niter_cat(items: Collection\u003c?\u003e, mapper: (item: Object, index: Number) =\u003e String, separator?: String, fallback?: Object): String\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/IterCatFunctionTests.java --\u003e\n\n### key\n\nExtracts the key from a Java `Map.Entry\u003c?, ?\u003e`.\n\n| Argument | Description           |\n|----------|-----------------------|\n| entry    | Entry to extract from |\n\n```\nkey(entry: Map.Entry\u003c?, ?\u003e): Object\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/KeyFunctionTests.java --\u003e\n\n### len\n\nReturns the length of the provided value, based on it's type.\n\n| Argument | Description                |\n|----------|----------------------------|\n| input    | Value to get the length of |\n\n```\nlen(value: Object): Number\n```\n\nWhere the following value types are supported\n\n| Input Type    | Description              |\n|---------------|--------------------------|\n| null, default | Always returns 0         |\n| String        | Length of the string     |\n| Collection\u003c?\u003e | Length of the collection |\n| Map\u003c?, ?\u003e     | Length of the map        |\n| Array         | Length of the array      |\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/LenFunctionTests.java --\u003e\n\n### l_index\n\nReturns the first index of the passed substring within the input string. Returns -1 if the searched\nstring is not at all present in the input string.\n\n| Argument | Description          |\n|----------|----------------------|\n| input    | Input to search in   |\n| search   | String to search for |\n\n```\nl_index(input: String, search: String): Number\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/LIndexFunctionTests.java --\u003e\n\n### list\n\nInterpret the input value as a list. Scalar values will create singleton lists, lists will be passed through and\nmaps will be converted to lists of their entry-sets.\n\n| Argument | Description                  |\n|----------|------------------------------|\n| input    | Input to interpret as a list |\n\n```\nlist(input?: Object): List\u003c?\u003e\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/ListFunctionTests.java --\u003e\n\n### list_of\n\nCreate a list from a variable amount of scalar input values.\n\n| Argument | Description                     |\n|----------|---------------------------------|\n| input... | Variable amount of input values |\n\n```\nlist_of(value...?: Object): List\u003c?\u003e\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/ListOfFunctionTests.java --\u003e\n\n### map\n\nIterate over a collection while mapping each iteration through a lambda function, whose result\nis being appended to the final result list.\n\n| Argument  | Description                                                |\n|-----------|------------------------------------------------------------|\n| items     | Collection to iterate                                      |\n| mapper    | Lambda function to map items with                          |\n| fallback  | Value to return if the collection is empty                 |\n\n```\nmap(items: Collection\u003c?\u003e, mapper: (item: Object, index: Number) =\u003e String, fallback?: Object): List\u003c?\u003e\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/MapFunctionTests.java --\u003e\n\n### filter\n\nIterate over a collection while mapping each item through a lambda function, whose result\nis being interpreted as a filter predicate.\n\n| Argument  | Description                          |\n|-----------|--------------------------------------|\n| items     | Collection to iterate                |\n| mapper    | Lambda function to filter items with |\n\n```\nfilter(items: Collection\u003c?\u003e, mapper: (item: Object, index: Number) =\u003e String): List\u003c?\u003e\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/FilterFunctionTests.java --\u003e\n\n### map_of\n\nCreate a list from a variable amount of scalar input value pairs.\n\n| Argument | Description                                     |\n|----------|-------------------------------------------------|\n| input... | Variable amount of input values, taken in pairs |\n\n```\nmap_of(value...?: Object): Map\u003c?, ?\u003e\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/MapOfFunctionTests.java --\u003e\n\n### print\n\nPrint the input values to STDOUT.\n\n| Argument | Description                     |\n|----------|---------------------------------|\n| input... | Variable amount of input values |\n\n```\nprint(input...?: Object): void\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/PrintFunctionTests.java --\u003e\n\n### r_index\n\nReturns the last index of the passed substring within the input string. Returns -1 if the searched\nstring is not at all present in the input string.\n\n| Argument | Description          |\n|----------|----------------------|\n| input    | Input to search in   |\n| search   | String to search for |\n\n```\nr_index(input: String, search: String): Number\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/RIndexFunctionTests.java --\u003e\n\n### split\n\nReturns a list of resulting substrings based on splitting the input string based on the delimiter.\n\n| Argument  | Description                       |\n|-----------|-----------------------------------|\n| input     | Input string to split             |\n| delimiter | Delimiter to split on, default \",\" |\n\n```\nsplit(input: String, delimiter?: String): List\u003cString\u003e\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/SplitFunctionTests.java --\u003e\n\n### str\n\nInterpret the input value as a string by making use of the environments value interpreter.\n\n| Argument | Description                    |\n|----------|--------------------------------|\n| input    | Value to interpret as a string |\n\n```\nstr(input?: Object): String\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/StringFunctionTests.java --\u003e\n\n### substring\n\nReturns a substring of the input, based on the start- and end indices.\n\n| Argument | Description                                                  |\n|----------|--------------------------------------------------------------|\n| input    | Input string to compute a substring of                       |\n| start    | Start index, inclusive, zero-based                           |\n| end      | End index, exclusive, zero-based, defaults to input's length |\n\n```\nsubstring(input: String, start: Number, end?: Number): String\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/SubstringFunctionTests.java --\u003e\n\n### title_case\n\nTransform the input string to title case (capitalize every word).\n\n| Argument | Description                               |\n|----------|-------------------------------------------|\n| input    | Input string to transform into title case |\n\n```\ntitle_case(input: String): String\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/TitleCaseFunctionTests.java --\u003e\n\n### value\n\nExtracts the value from a Java `Map.Entry\u003c?, ?\u003e`.\n\n| Argument | Description           |\n|----------|-----------------------|\n| entry    | Entry to extract from |\n\n```\nvalue(entry: Map.Entry\u003c?, ?\u003e): Object\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/ValueFunctionTests.java --\u003e\n\n### range\n\nReturns a list containing all the numbers included in the range.\n\n| Argument | Description            |\n|----------|------------------------|\n| start    | Start index, inclusive |\n| end      | End index, inclusive   |\n\n```\nrange(start: Number, end: Number): List\u003cNumber\u003e\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/RangeFunctionTests.java --\u003e\n\n### flatten\n\nReturns a list containing all parameters provided, where collection items are flattened into the result.\n\n| Argument | Description                     |\n|----------|---------------------------------|\n| input... | Variable amount of input values |\n\n```\nflatten(input...?: Object): List\u003cObject\u003e\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/FlattenFunctionTests.java --\u003e\n\n### min\n\nReturns the smaller of two values.\n\n| Argument | Description |\n|----------|-------------|\n| a        | Value A     |\n| b        | Value B     |\n\n```\nmin(a: Object, b: Object): Object\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/MinFunctionTests.java --\u003e\n\n### max\n\nReturns the bigger of two values.\n\n| Argument | Description |\n|----------|-------------|\n| a        | Value A     |\n| b        | Value B     |\n\n```\nmax(a: Object, b: Object): Object\n```\n\n\u003c!-- #include src/test/java/me/blvckbytes/gpeee/std/MaxFunctionTests.java --\u003e\n\n\u003c!-- #configure include SKIP_LEADING_COMMENTS true --\u003e\n\u003c!-- #configure include SKIP_LEADING_EMPTY true --\u003e\n\u003c!-- #configure include SKIP_LEADING_PACKAGE false --\u003e\n\u003c!-- #configure include SKIP_LEADING_IMPORTS true --\u003e\n\u003c!-- #configure include WRAP_IN_COLLAPSIBLE true --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblvckbytes%2Fgpeee","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblvckbytes%2Fgpeee","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblvckbytes%2Fgpeee/lists"}