{"id":13537483,"url":"https://github.com/murzagalin/multiplatform-expressions-evaluator","last_synced_at":"2026-03-04T07:10:43.884Z","repository":{"id":52111265,"uuid":"406453824","full_name":"murzagalin/multiplatform-expressions-evaluator","owner":"murzagalin","description":"Kotlin Multiplatform runtime infix expressions evaluator.","archived":false,"fork":false,"pushed_at":"2024-12-05T16:32:55.000Z","size":185,"stargazers_count":41,"open_issues_count":2,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-02T04:35:33.621Z","etag":null,"topics":["evaluation","evaluator","expression-evaluator","expressions","kotlin","kotlin-multiplatform","math","mathematics","runtime"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/murzagalin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-14T17:00:34.000Z","updated_at":"2025-03-25T14:39:37.000Z","dependencies_parsed_at":"2024-03-20T14:09:20.058Z","dependency_job_id":null,"html_url":"https://github.com/murzagalin/multiplatform-expressions-evaluator","commit_stats":null,"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/murzagalin/multiplatform-expressions-evaluator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/murzagalin%2Fmultiplatform-expressions-evaluator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/murzagalin%2Fmultiplatform-expressions-evaluator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/murzagalin%2Fmultiplatform-expressions-evaluator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/murzagalin%2Fmultiplatform-expressions-evaluator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/murzagalin","download_url":"https://codeload.github.com/murzagalin/multiplatform-expressions-evaluator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/murzagalin%2Fmultiplatform-expressions-evaluator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30075425,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T05:31:57.858Z","status":"ssl_error","status_checked_at":"2026-03-04T05:31:38.462Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["evaluation","evaluator","expression-evaluator","expressions","kotlin","kotlin-multiplatform","math","mathematics","runtime"],"created_at":"2024-08-01T09:00:59.505Z","updated_at":"2026-03-04T07:10:43.847Z","avatar_url":"https://github.com/murzagalin.png","language":"Kotlin","funding_links":[],"categories":["Libraries"],"sub_categories":["Math"],"readme":"# Kotlin multiplatform expressions evaluator\n\n[![Version](https://maven-badges.herokuapp.com/maven-central/io.github.murzagalin/multiplatform-expressions-evaluator/badge.svg?style=flat)](https://search.maven.org/search?q=a:multiplatform-expressions-evaluator)\n\n\nThis is a kotlin multiplatform runtime [infix](https://en.wikipedia.org/wiki/Infix_notation) expressions evaluator.\n\n## Overview\n\n### Operators\nThe library supports the following operators and special symbols:\n\n* `+`, `-`, `*`, `/` - mathematical operators\n* `%` - [modulo](https://en.wikipedia.org/wiki/Modulo_operation). Returns the remainder of a division, after one number is divided by another\n*  `^` - exponentiation. `a^b` means `a raised to the power of b` \n* `\u0026\u0026`, `||`, `!` - logical 'and', 'or', 'not' operators\n* `==`, `!=` - equality operators\n* `\u003c`, `\u003e`, `\u003c=`, `\u003e=` - comparison operators\n* `a ? b : c` - ternary operator\n\n### Constants\nThe library supports the following constants:\n* `pi` - [PI](https://en.wikipedia.org/wiki/Pi)\n* `e` - [e](https://en.wikipedia.org/wiki/E_(mathematical_constant))\n* any custom constants.\n\n### Functions\nThe library supports the following functions:\n* `abs(x)` - [absolute value](https://en.wikipedia.org/wiki/Absolute_value)\n* `acos(x)` - [arccosine](https://en.wikipedia.org/wiki/Inverse_trigonometric_functions)\n* `asin(x)` - [arcsine](https://en.wikipedia.org/wiki/Inverse_trigonometric_functions)\n* `atan(x)` - [arctangent](https://en.wikipedia.org/wiki/Inverse_trigonometric_functions)\n* `avg(a1, a2, a3, ..., an)` - average of N values\n* `ceil(x)` - [ceiling](https://en.wikipedia.org/wiki/Floor_and_ceiling_functions)\n* `cos(x)` - [cosine](https://en.wikipedia.org/wiki/Trigonometric_functions)\n* `cosh(x)` - [hyperbolic cosine](https://en.wikipedia.org/wiki/Hyperbolic_functions)\n* `floor(x)` - [floor](https://en.wikipedia.org/wiki/Floor_and_ceiling_functions)\n* `ln(x)` - [natural logarithm](https://en.wikipedia.org/wiki/Natural_logarithm)\n* `log(x, base)` - [logarithm](https://en.wikipedia.org/wiki/Logarithm)\n* `max(a1, a2, a3, ..., an)` - maximum of N values\n* `min(a1, a2, a3, ..., an)` - minimum of N values\n* `round(x)` - [rounding to the nearest integer](https://en.wikipedia.org/wiki/Rounding#Rounding_to_the_nearest_integer)\n* `sin(x)` - [sine](https://en.wikipedia.org/wiki/Trigonometric_functions)\n* `sinh(x)` - [hyperbolic sine](https://en.wikipedia.org/wiki/Hyperbolic_functions)\n* `sum(a1, a2, a3, ..., an)` - summation of N values\n* `tan(x)` - [tangent](https://en.wikipedia.org/wiki/Trigonometric_functions)\n* `tanh(x)` - [hyperbolic tangent](https://en.wikipedia.org/wiki/Trigonometric_functions)\n* any custom function with any number of arguments\n\n### Variables\nAny symbols other than constants and function calls are resolved as variables during evaluation.\n\n## How to get\n### Gradle\n\nThe library is distributed via maven central repositories.\n\nKotlin DSL\n```kotlin\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(\"io.github.murzagalin:multiplatform-expressions-evaluator:x.y.z\")\n}\n```\n\nGroovy\n```groovy\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation \"io.github.murzagalin:multiplatform-expressions-evaluator:x.y.z\"\n}\n```\n\n## Kotlin\n\n### Usage\n\n```kotlin\nimport com.github.murzagalin.evaluator.Evaluator\n\nval evaluator = Evaluator()\n\n//numeric values\nevaluator.evaluateDouble(\"23 + 0.123 * (124 / -60.124)\")\n\n//boolean values\nevaluator.evaluateBoolean(\n    \"x \u003e 1 \u0026\u0026 var\",\n    mapOf(\"x\" to 3, \"var\" to true)\n)\n\n//variables\nevaluator.evaluateDouble(\n    \"1 + x + y\",\n    mapOf(\"x\" to 3, \"y\" to 4)\n)\n\n//functions\nevaluator.evaluateDouble(\n    \"sin(x)^2+cos(x)^2\",\n    mapOf(\"x\" to 2.0)\n)\n\n//constants\nevaluator.evaluateDouble(\"cos(pi)\")\nevaluator.evaluateDouble(\"ln(e^3)\")\n```\n\n### Custom functions\n\nThe library supports custom functions with any number of arguments.\nSupported argument and return types are `Double` and `Boolean`\n\n#### Functions with constant number of arguments \n\nFor the example I will explain how to create a function that represents the general form of normal distribution probability density function:\n![img.png](images/img.png)\n\nThe function will have the following syntax:\n`normal_dist(x, m, sigma)`.\nThe parameter `m` is the mean of the distribution, while the parameter `sigma` is its standard deviation.\n\nWe define a function which is named \"normal_dist\" and has 3 arguments:\n\n```kotlin\nimport com.github.murzagalin.evaluator.Function\n\nobject NormalDist : Function(\"normal_dist\", 3) {\n    override fun invoke(vararg args: Any): Any {\n        val x = args.getAsDouble(0) { \"$name argument must be a number\" }\n        val m = args.getAsDouble(1) { \"$name mean must be a number\" }\n        val sigma = args.getAsDouble(2) { \"$name sigma must be a number\" }\n\n        return 1.0 / sigma / sqrt(2 * PI) * exp(-1.0 / 2.0 * ((x - m) / sigma).pow(2))\n    }\n}\n```\n\n*Note:* the library checks if the number of arguments in an expression is equal to 3, otherwise it throws an exception. But you have to check the types of the arguments by yourself.\nFunctions `getAsDouble(index, lazyMessage)` and `getAsBoolean(index, lazyMessage)` return an element at position `index`, and throw `IllegalArgumentException` with the message returned from `lazyMessage` if it has a wrong type\n\nThen we add this function to the evaluator:\n\n```kotlin\nimport com.github.murzagalin.evaluator.DefaultFunctions\nimport com.github.murzagalin.evaluator.Evaluator\n\nfun main() {\n    val evaluator = Evaluator(functions = DefaultFunctions.ALL + NormalDist)\n    print(evaluator.evaluateDouble(\"normal_dist(12, 9, 3)\"))\n}\n```\n\n\n#### Functions with variable number of arguments \n\nThe process of creating functions with variable number of arguments is pretty much the same. The difference is how we define the function.\n\nAs an example I will create a function `mult(a1, a2, ..., an)` which is defined as `a1 * a2 * ... * an`:\n\n```kotlin\nobject Mult: Function(\"mult\", 2..Int.MAX_VALUE) {\n    override fun invoke(vararg args: Any): Any {\n        require(args.all { it is Double }) { \"$name function requires all arguments to be numbers\" }\n\n        return args.fold(1.0) { acc, x -\u003e acc * (x as Double) }\n    }\n}\n```\n*Note:* we define minimum and maximum number of arguments as a range. It is also possible to define them separately:\n`Function(\"mult\", 2, Int.MAX_VALUE)`\n\nThen we add this function to the evaluator:\n```kotlin\nimport com.github.murzagalin.evaluator.DefaultFunctions\nimport com.github.murzagalin.evaluator.Evaluator\n\nfun main() {\n    val evaluator = Evaluator(functions = DefaultFunctions.ALL + Mult)\n    print(evaluator.evaluateDouble(\"mult(2, 3, 4)\"))\n}\n```\n\n### Custom constants\n\nThe library supports custom constants. For the example I will show you how to add a golden ratio constant.\nWe will define the constant named `phi` with the value `1.6180339887`:\n```kotlin\nimport com.github.murzagalin.evaluator.Constant\nimport com.github.murzagalin.evaluator.DefaultConstants\nimport com.github.murzagalin.evaluator.Evaluator\n\nfun main() {\n    val PHI = Constant(\"phi\", 1.6180339887)\n    val evaluator = Evaluator(constants = DefaultConstants.ALL + PHI)\n    print(evaluator.evaluateDouble(\"x * phi\", mapOf(\"x\" to 2)))\n}\n```\n\n### Expressions preprocessing\n\nBy default, the library does the following steps to evaluate an expression:\n1. Tokenizing - splitting the expression into a list of units (operations, numbers, constants, function calls, etc.)\n2. Converting the expression from [infix notation](https://en.wikipedia.org/wiki/Infix_notation) to [abstract syntax tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree).\n3. Evaluating the abstract syntax tree.\n\nIn case you have an expression with variables, it might make sense to preprocess the expression (do steps 1 and 2 in advance) to improve the performance:\n```kotlin\nimport com.github.murzagalin.evaluator.Evaluator\n\nfun main() {\n    val evaluator = Evaluator()\n    \n    //step 1 and 2\n    val preprocessedExpression = evaluator.preprocessExpression(\"1 + x + y^2\")\n    \n    //step 3\n    val result = evaluator.evaluateDouble(preprocessedExpression, mapOf(\"x\" to 2, \"y\" to 4))\n}\n```\n\n## JVM\n`TBD`\n\n## JS\n`TBD`\n\n## IOS\n`TBD`\n\n## License\nThis library is available for free under [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0).\n\n```\nCopyright (c) 2021 Azamat Murzagalin.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmurzagalin%2Fmultiplatform-expressions-evaluator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmurzagalin%2Fmultiplatform-expressions-evaluator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmurzagalin%2Fmultiplatform-expressions-evaluator/lists"}