{"id":13786649,"url":"https://github.com/maja42/goval","last_synced_at":"2026-01-16T19:31:42.213Z","repository":{"id":41308928,"uuid":"137666483","full_name":"maja42/goval","owner":"maja42","description":"Expression evaluation in golang","archived":false,"fork":false,"pushed_at":"2025-02-19T16:16:50.000Z","size":3012,"stargazers_count":166,"open_issues_count":1,"forks_count":25,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-11T22:39:00.786Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","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/maja42.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2018-06-17T15:43:44.000Z","updated_at":"2025-03-27T06:39:54.000Z","dependencies_parsed_at":"2025-02-19T16:31:10.450Z","dependency_job_id":"e693c2d4-1e9b-499c-afee-ee5539b209ec","html_url":"https://github.com/maja42/goval","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/maja42/goval","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maja42%2Fgoval","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maja42%2Fgoval/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maja42%2Fgoval/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maja42%2Fgoval/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maja42","download_url":"https://codeload.github.com/maja42/goval/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maja42%2Fgoval/sbom","scorecard":{"id":613113,"data":{"date":"2025-08-11","repo":{"name":"github.com/maja42/goval","commit":"1613c838b2991ea762b8526c288f219024e9f430"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.2,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":1,"reason":"Found 3/29 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: MIT License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 4 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-21T03:08:40.697Z","repository_id":41308928,"created_at":"2025-08-21T03:08:40.697Z","updated_at":"2025-08-21T03:08:40.697Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28481801,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: 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":[],"created_at":"2024-08-03T19:01:26.972Z","updated_at":"2026-01-16T19:31:42.204Z","avatar_url":"https://github.com/maja42.png","language":"Go","funding_links":[],"categories":["公用事业公司","Utilities","Utility"],"sub_categories":["实用程序/Miscellaneous","Utility/Miscellaneous","Fail injection","HTTP Clients"],"readme":"goval\n=====\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/maja42/goval)](https://goreportcard.com/report/github.com/maja42/goval)\n[![GoDoc](https://godoc.org/github.com/maja42/goval?status.svg)](https://godoc.org/github.com/maja42/goval)\n\n\nThis library allows programs to evaluate arbitrary arithmetic/string/logic expressions.\nAccessing variables and calling custom functions is supported.\n\nThis project is considered stable and already used in production systems. \\\nPlease use the issue-tracker for any questions, feedback and bug-reports.\n\nThis project is licensed under the terms of the MIT license.\n\n# Demo\n\nA small CLI demo that evaluates expressions can be found in the example folder:\n\n```\ngo get -u github.com/maja42/goval\ncd $GOPATH/src/github.com/maja42/goval/\ngo run example/main.go\n```\n\n![Demo](goval.gif)\n\n\n# Usage\n\nMinimal example:\n\n```go\neval := goval.NewEvaluator()\nresult, err := eval.Evaluate(`42 \u003e 21`, nil, nil) // Returns \u003ctrue, nil\u003e\n```\n\nAccessing variables:\n```go\neval := goval.NewEvaluator()\nvariables := map[string]interface{}{\n    \"uploaded\": 146,\n    \"total\":  400,\n}\nresult, err := eval.Evaluate(`uploaded * 100 / total`, variables, nil)  // Returns \u003c36, nil\u003e\n```\n\n\nCalling functions:\n\n```go\n// Implementing strlen()\neval := goval.NewEvaluator()\nvariables := map[string]interface{}{\n    \"os\":   runtime.GOOS,\n    \"arch\": runtime.GOARCH,\n}\n\nfunctions := make(map[string]goval.ExpressionFunction)\nfunctions[\"strlen\"] = func(args ...interface{}) (interface{}, error) {\n    str := args[0].(string)\n    return len(str), nil\n}\n\nresult, err := eval.Evaluate(`strlen(arch[:2]) + strlen(\"text\")`, variables, functions) // Returns \u003c6, nil\u003e\n```\n\nCustom functions allow the extension with arbitrary features like regex-matching:\n```go\n// Implementing regular expressions (error handling omitted)\nfunctions := make(map[string]goval.ExpressionFunction)\nfunctions[\"matches\"] = func(args ...interface{}) (interface{}, error) {\n    str := args[0].(string)\n    exp := args[1].(string)\n    reg := regexp.MustCompile(exp)\n    return reg.MatchString(str), nil\n}\n\neval.Evaluate(`matches(\"text\", \"[a-z]+\")`, nil, functions)  // Returns \u003ctrue, nil\u003e\neval.Evaluate(`matches(\"1234\", \"[a-z]+\")`, nil, functions)  // Returns \u003cfalse, nil\u003e\n```\n\n\n\n# Documentation\n\n## Types\n\nThis library fully supports the following types: `nil`, `bool`, `int`, `float64`, `string`, `[]interface{}` (=arrays) and `map[string]interface{}` (=objects). \n\nWithin expressions, `int` and `float64` both have the type `number` and are completely transparent.\\\nIf necessary, numerical values will be automatically converted between `int` and `float64`, as long as no precision is lost.\n\nArrays and Objects are untyped. They can store any other value (\"mixed arrays\").\n\nStructs are note supported to keep the functionality clear and manageable. \nThey would introduce too many edge cases and loose ends and are therefore out-of-scope. \n\n## Variables\n\nIt is possible to directly access custom-defined variables.\nVariables are read-only and cannot be modified from within expressions.\n\nExamples:\n\n```\nvar\nvar.field\nvar[0]\nvar[\"field\"]\nvar[anotherVar]\n\nvar[\"fie\" + \"ld\"].field[42 - var2][0]\n```\n\n## Functions\n\nIt is possible to call custom-defined functions from within expressions.\n\nExamples:\n\n```\nrand()\nfloor(42)\nmin(4, 3, 12, max(1, 3, 3))\nlen(\"te\" + \"xt\")\n```\n\n## Literals\n\nAny literal can be defined within expressions. \nString literals can be put in double-quotes `\"` or back-ticks \\`.\nHex-literals start with the prefix `0x`.\n\nExamples:\n\n```\nnil\ntrue\nfalse\n3\n3.2\n\"Hello, 世界!\\n\"\n\"te\\\"xt\"\n`te\"xt`\n[0, 1, 2]\n[]\n[0, [\"text\", false], 4.2]\n{}\n{\"a\": 1, \"b\": {c: 3}}\n{\"key\" + 42: \"value\"}\n{\"k\" + \"e\" + \"y\": \"value\"}\n\n0xA                    // 10\n0x0A                   // 10\n0xFF                   // 255 \n0xFFFF_FFFF            // 32bit appl.: -1  64bit appl.: 4294967295\n0xFFFF_FFFF_FFFF_FFFF  // 64bit appl.: -1  32bit appl.: error\n```\n\nIt is possible to access elements of array and object literals:\n\nExamples:\n\n```\n[1, 2, 3][1]                // 2\n[1, [2, 3, 42][1][2]        // 42\n\n{\"a\": 1}.a                  // 1\n{\"a\": {\"b\": 42}}.a.b        // 42\n{\"a\": {\"b\": 42}}[\"a\"][\"b\"]  // 42\n```\n\n## Precedence\n\nOperator precedence strictly follows [C/C++ rules](http://en.cppreference.com/w/cpp/language/operator_precedence).\n\nParenthesis `()` is used to control precedence.\n\nExamples:\n\n```\n1 + 2 * 3    // 7\n(1 + 2) * 3  // 9\n```\n\n## Operators\n\n### Arithmetic\n\n#### Arithmetic `+` `-` `*` `/`\n\nIf both sides are integers, the resulting value is also an integer.\nOtherwise, the result will be a floating point number.\n\nExamples:\n\n```\n3 + 4               // 7\n2 + 2 * 3           // 8\n2 * 3 + 2.5         // 8.5\n12 - 7 - 5          // 0\n24 / 10             // 2\n24.0 / 10           // 2.4\n```\n\n#### Power `**`\n\nIf both sides are integers, and the result can be represented as an integer, the resulting value is also an integer.\nOtherwise, the result will be a floating point number.\n\nExamples:\n\n```\n2 ** 4              // 16\n10 ** 3             // 1000\n10 ** -6            // 0.000001\n2.5 ** -2.5         // 0.10119...\n```\n\n#### Modulo `%`\n\nIf both sides are integers, the resulting value is also an integer.\nOtherwise, the result will be a floating point number.\n\nExamples:\n\n```\n4 % 3       // 1\n144 % 85    // -55\n5.5 % 2     // 1.5\n10 % 3.5    // 3.0\n```\n\n#### Negation `-` (unary minus)\n\nNegates the number on the right.\n\nExamples:\n\n```\n-4       // -4\n5 + -4   // 1\n-5 - -4  // -1\n1 + --1  // syntax error\n-(4+3)   // -7\n-varName\n```\n\n\n### Concatenation\n\n#### String concatenation `+`\n\nIf either the left or right side of the `+` operator is a `string`, a string concatenation is performed.\nSupports strings, numbers, booleans and nil.\n\nExamples:\n\n```\n\"text\" + 42     // \"text42\"\n\"text\" + 4.2    // \"text4.2\"\n42 + \"text\"     // \"42text\"\n\"text\" + nil    // \"textnil\"\n\"text\" + true   // \"texttrue\"\n```\n\n#### Array concatenation `+`\n\nIf both sides of the `+` operator are arrays, they are concatenated\n\nExamples:\n\n```\n[0, 1] + [2, 3]          // [0, 1, 2, 3]\n[0] + [1] + [[2]] + []   // [0, 1, [2]]\n```\n\n#### Object concatenation `+`\n\nIf both sides of the `+` operator are objects, their fields are combined into a new object.\nIf both objects contain the same keys, the value of the right object will override those of the left.\n\nExamples:\n\n```\n{\"a\": 1} + {\"b\": 2} + {\"c\": 3}         // {\"a\": 1, \"b\": 2, \"c\": 3}\n{\"a\": 1, \"b\": 2} + {\"b\": 3, \"c\": 4}    // {\"a\": 1, \"b\": 3, \"c\": 4}\n{\"b\": 3, \"c\": 4} + {\"a\": 1, \"b\": 2}    // {\"a\": 1, \"b\": 2, \"c\": 4}\n```\n\n### Logic\n\n#### Equals `==`, NotEquals `!=`\n\nPerforms a deep-compare between the two operands.\nWhen comparing `int` and `float64`, \nthe integer will be cast to a floating point number.\n\n#### Comparisons `\u003c`, `\u003e`, `\u003c=`, `\u003e=`\n\nCompares two numbers. If one side of the operator is an integer and the other is a floating point number,\nthe integer number will be cast. This might lead to unexpected results for very big numbers which are rounded\nduring that process.\n\nExamples:\n\n```\n3 \u003c-4        // false\n45 \u003e 3.4     // true\n-4 \u003c= -1     // true\n3.5 \u003e= 3.5   // true\n```\n\n#### And `\u0026\u0026`, Or `||`\n\nExamples:\n\n```\ntrue \u0026\u0026 true             // true\nfalse || false           // false\ntrue || false \u0026\u0026 false   // true\nfalse \u0026\u0026 false || true   // true\n```\n\n\n#### Not `!`\n\nInverts the boolean on the right.\n\nExamples:\n\n```\n!true       // false\n!false      // true\n!!true      // true\n!varName\n```\n\n\n### Ternary `? :`\n\nIf the expression resolves to `true`, the operator resolves to the left operand. \\\nIf the expression resolves to `false`, the operator resolves to the right operand.\n\nExamples:\n\n```\ntrue  ? 1 : 2                         // 1\nfalse ? 1 : 2                         // 2\n\t\n2 \u003c 5  ? \"a\" : 1.5                    // \"a\"\n9 \u003e 12 ? \"a\" : [42]                   // [42]\n\nfalse ? (true ? 1:2) : (true ? 3:4)   // 3\n```\n\n\nNote that all operands are resolved (no short-circuiting). \nIn the following example, both functions are called (the return value of `func2` is simply ignored):\n\n```\ntrue ? func1() : func2()\n```\n\n### Bit Manipulation\n\n#### Logical Or `|`, Logical And `\u0026`, Logical XOr `^`\n\nIf one side of the operator is a floating point number, the number is cast to an integer if possible. \nIf decimal places would be lost during that process, it is considered a type error.\nThe resulting number is always an integer.\n\nExamples:\n\n```\n8 | 2          // 10\n9 | 5          // 13\n8 | 2.0        // 10\n8 | 2.1        // type error\n\n13 \u0026 10        // 8\n10 \u0026 15.0 \u0026 2  // 2\n\n13 ^ 10        // 7\n10 ^ 15 ^ 1    // 4\n```\n\n#### Bitwise Not `~`\n\nIf performed on a floating point number, the number is cast to an integer if possible. \nIf decimal places would be lost during that process, it is considered a type error.\nThe resulting number is always an integer.\n\nThe results can differ between 32bit and 64bit architectures.\n\nExamples:\n\n```\n~-1                   // 0\n(~0xA55A) \u0026 0xFFFF    // 0x5AA5\n(~0x5AA5) \u0026 0xFFFF    // 0xA55A\n\n~0xFFFFFFFF           // 64bit appl.: 0xFFFFFFFF 00000000; 32bit appl.: 0x00\n~0xFFFFFFFF FFFFFFFF  // 64bit appl.: 0x00; 32bit: error\n```\n\n#### Bit-Shift `\u003c\u003c`, `\u003e\u003e`\n\nIf one side of the operator is a floating point number, the number is cast to an integer if possible. \nIf decimal places would be lost during that process, it is considered a type error.\nThe resulting number is always an integer.\n\nWhen shifting to the right, sign-extension is performed.\nThe results can differ between 32bit and 64bit architectures.\n\nExamples:\n\n```\n1 \u003c\u003c 0    // 1\n1 \u003c\u003c 1    // 2\n1 \u003c\u003c 2    // 4\n8 \u003c\u003c -1   // 4\n8 \u003e\u003e -1   // 16\n\n1 \u003c\u003c 31   // 0x00000000 80000000   64bit appl.: 2147483648; 32bit appl.: -2147483648\n1 \u003c\u003c 32   // 0x00000001 00000000   32bit appl.: 0 (overflow)\n\n1 \u003c\u003c 63   // 0x80000000 00000000   32bit appl.: 0 (overflow); 64bit appl.: -9223372036854775808\n1 \u003c\u003c 64   // 0x00000000 00000000   0 (overflow)\n\n0x80000000 00000000 \u003e\u003e 63     // 0xFFFFFFFF FFFFFFFF   64bit: -1 (sign extension); 32bit: error (cannot parse number literal)\n0x80000000 \u003e\u003e 31              // 64bit: 0x00000000 0000001; 32bit: 0xFFFFFFFF (-1, sign extension)\n```\n\n### More\n\n#### Array contains `in`\n\nReturns true or false whether the array contains a specific element.\n\nExamples:\n\n```\n\"txt\" in [nil, \"hello\", \"txt\", 42]   // true\ntrue  in [nil, \"hello\", \"txt\", 42]   // false\nnil   in [nil, \"hello\", \"txt\", 42]   // true\n42.0  in [nil, \"hello\", \"txt\", 42]   // true\n2         in [1, [2, 3], 4]          // false\n[2, 3]    in [1, [2, 3], 4]          // true\n[2, 3, 4] in [1, [2, 3], 4]          // false\n```\n\n#### Substrings `[a:b]`\n\nSlices a string and returns the given substring.\nStrings are indexed byte-wise. Multi-byte characters need to be treated carefully.\n\nThe start-index indicates the first byte to be present in the substring.\\\nThe end-index indicates the last byte NOT to be present in the substring.\\\nHence, valid indices are in the range `[0, len(str)]`.\n\nExamples:\n\n```\n\"abcdefg\"[:]    // \"abcdefg\"\n\"abcdefg\"[1:]   // \"bcdefg\"\n\"abcdefg\"[:6]   // \"abcdef\"\n\"abcdefg\"[2:5]  // \"cde\"\n\"abcdefg\"[3:4]  // \"d\"\n\n// The characters 世 and 界 both require 3 bytes:\n\"Hello, 世界\"[7:13]    // \"世界\"\n\"Hello, 世界\"[7:10]    // \"世\"\n\"Hello, 世界\"[10:13]   // \"界\"\n```\n\n\n#### Array Slicing `[a:b]`\n\nSlices an array and returns the given subarray.\n\nThe start-index indicates the first element to be present in the subarray.\\\nThe end-index indicates the last element NOT to be present in the subarray.\\\nHence, valid indices are in the range `[0, len(arr)]`.\n\nExamples:\n\n```\n// Assuming `arr := [0, 1, 2, 3, 4, 5, 6]`:\narr[:]    // [0, 1, 2, 3, 4, 5, 6]\narr[1:]   // [1, 2, 3, 4, 5, 6]\narr[:6]   // [0, 1, 2, 3, 4, 5]\narr[2:5]  // [2, 3, 4]\narr[3:4]  // [3]\n```\n\n# Alternative Libraries\n\nIf you are looking for a generic evaluation library, \nyou can also take a look at [Knetic/govaluate](https://github.com/Knetic/govaluate).\nI used that library myself, but due to a several shortcomings I decided to create goval. \nThe main differences are:\n\n- More intuitive syntax\n- No intermediate AST - evaluation and parsing happens in a single step  \n- Better type support:  \n    - Full support for arrays and objects.\n    - Opaque differentiation between `int` and `float64`. \\\n      The underlying type is automatically converted as long as no precision is lost.\n    - Type-aware bit-operations (they only work with `int`-numbers).\n    - No support for dates (strings are just strings, they don't have a special meaning, even if they look like dates).\\\n      Support for dates and structs *could* be added if needed.\n- More operators:      \n    - Accessing variables (maps) via `.` and `[]` syntax\n    - Support for array- and object concatenation.\n    - Slicing and substrings\n- Hex-Literals (useful as soon as bit-operations are involved).\n- Array literals with `[]` as well as object literals with `{}`\n- Useful error messages.\n- Highly optimized parser code by using go/scanner and goyacc. \\\n    This leads to vastly reduced code size (and therefore little bug potential)\n    and creates super-fast code.\n- High test coverage (including lots of special cases).\\\n  Also tested on 32 and 64bit architectures, where some (documented) operations like a bitwise-not can behave differently depending on the size of `int`. \n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaja42%2Fgoval","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaja42%2Fgoval","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaja42%2Fgoval/lists"}