{"id":13672761,"url":"https://github.com/jsdw/angu","last_synced_at":"2025-08-22T00:07:17.791Z","repository":{"id":45352994,"uuid":"190891341","full_name":"jsdw/angu","owner":"jsdw","description":"A small DSL/interpreter that can be used to evaluate simple expressions","archived":false,"fork":false,"pushed_at":"2022-12-30T17:48:18.000Z","size":237,"stargazers_count":127,"open_issues_count":6,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-09T06:01:58.414Z","etag":null,"topics":["dsl","evaluator","interpreter","javascript","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/jsdw.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-08T13:31:27.000Z","updated_at":"2025-05-23T19:06:39.000Z","dependencies_parsed_at":"2023-01-31T12:25:12.633Z","dependency_job_id":null,"html_url":"https://github.com/jsdw/angu","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/jsdw/angu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdw%2Fangu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdw%2Fangu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdw%2Fangu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdw%2Fangu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jsdw","download_url":"https://codeload.github.com/jsdw/angu/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsdw%2Fangu/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264403795,"owners_count":23602619,"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":["dsl","evaluator","interpreter","javascript","typescript"],"created_at":"2024-08-02T09:01:46.764Z","updated_at":"2025-07-09T06:05:08.111Z","avatar_url":"https://github.com/jsdw.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Angu\n\nA small, zero-dependency library that can be used to build and evaluate mini-languages in the browser \nor in NodeJS. You have complete control over every operation performed, and this library takes care of \nthe nitty gritty of the parsing and such. Comes with TypeScript typings (usage optional).\n\nWe can use this to create a simple in-browser calculator to evaluate things like:\n\n```\n10 + 4 / 2 * (3 - 1)\n```\n\nOr we can use it to manipulate table cells by evaluating something like:\n\n```\nMEAN(A1:A5) + SUM(C1:D2) - 10\n```\n\nOr we can build a small expression-based language that looks like:\n\n```\nfoo = 2;\nbar = 4;\nwibble = foo * bar + pow(2, 10);\nfoo + bar + wibble\n```\n\nOr a range of other things.\n\nIn each case, we define the operators (optionally with precedence and associativity) and functions available\nto the program and exactly what they do with their arguments, and this library takes care of the rest.\n\n[Complete examples can be found here][examples].\n\n# Installation\n\nYou can install the latest release from `npm`:\n\n```\nnpm install angu\n```\n\n# Basic Usage\n\nFirst, you define a `Context` which determines how expressions will be evaluated. For a simple calculator,\nwe might define something like the following:\n\n```javascript\nimport { evaluate } from 'angu'\n\nconst ctx = {\n    // We provide these operators:\n    scope: {\n        '-': (a, b) =\u003e a.eval() - b.eval(),\n        '+': (a, b) =\u003e a.eval() + b.eval(),\n        '/': (a, b) =\u003e a.eval() / b.eval(),\n        '*': (a, b) =\u003e a.eval() * b.eval(),\n    },\n    // And define the precedence to be as expected\n    // (first in array =\u003e evaluated first)\n    precedence: [\n        ['/', '*'],\n        ['-', '+']\n    ]\n}\n```\n\nThen, you can evaluate expressions in this context:\n\n```javascript\nconst r1 = evaluate('2 + 10 * 4', ctx)\nassert.equal(r1.value, 42)\n```\n\nWe can also provide locals at eval time:\n\n```javascript\nconst r1 = evaluate('2 + 10 * four', ctx, { four: 4 })\nassert.equal(r1.value, 42)\n```\n\nIf something goes wrong evaluating the provided string, an error will be returned. All errors returned\ncontain position information (`{ pos: { start, end}, ... }`) describing the beginning and end of the\nstring that contains the error. Specific errors contain other information depending on their `kind`.\n\n[More examples can be found here][examples].\n\n# Details\n\n## Primitives\n\nAngu supports the following literals:\n\n- booleans ('true' or 'false')\n- numbers (eg `+1.2`, `-3`, `.9`, `100`, `10.23`, `-100.4`, `10e2`). Numbers have a string version of themselves stored\n  (as well as a numeric one) so that we can wrap things like big number libraries if we like. The string version\n  applies some normalisation which can help other libraries consume the numbers:\n  - The exponent is normalised to a lowercase 'e'.\n  - Leading '+' is removed.\n  - A decimal point, if provided, is always prefixed with a number ('0' if no number is given)\n- strings (strings can be surrounded in `'` or `\"`, and `\\`'s inside a string escape the delimiter and themselves)\n\nOtherwise, it relies on operators and function calls to transform and manipulate them.\n\n## Operators\n\nAny of the following characters can be used to define an operator:\n\n```\n!£$%^\u0026*@#~?\u003c\u003e|/+=;:.-\n```\n\nOperators can be binary (taking two arguments) or unary. Unary operators cannot have a space between themselves and the\nexpression that they are operating on.\n\nOperators not defined in scope will not be parsed. This helps the parser properly handle multiple operators (eg binary\nand unary ops side by side), since it knows what it is looking for.\n\nSome valid operator based function calls (assuming the operators are in scope):\n\n```javascript\n1+2/3\n1 + 2\n1 + !2\n```\n\n## Functions/variables\n\nFunctions/variables must start with an ascii letter, and can then contain an ascii letter, number or underscore.\n\nSome valid function calls:\n\n```javascript\nfoo()\nfoo(bar)\nfoo(1,2)\n```\n\nIf the function takes exactly two arguments, and is also listed in the precedence list, it can be used infix\ntoo, like so (there must be spaces separating the function name from the expressions on either side):\n\n```\n1 foo 2\n```\n\nAll values passed to functions on scope have the `Value` type. One can call `.eval()` on them to evaluate them and\nreturn the value that that results in. Some other methods are also available:\n\n- `Value.kind()`: Return the kind of the Value (`\"string\" | \"number\" | \"variable\" | \"bool\" | \"functioncall\"`).\n- `Value.pos()`: Return the start and end index of the original input string that this Value was parsed from.\n- `Value.toString()`: (or `String(Value)`) gives back a string representation of the value, useful for debugging.\n- `Value.name()`: Gives back the \"name\" of the value. This is the function/variable name if applicable, else\n  true/false for bools, the string contents for strings, or the numeric representation for numbers.\n\nSee the [examples][examples] for more, particularly `workingWithVariables.ts`.\n\n[examples]: https://github.com/jsdw/angu/blob/master/src/examples\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsdw%2Fangu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjsdw%2Fangu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsdw%2Fangu/lists"}