{"id":40252423,"url":"https://github.com/grol-io/grol","last_synced_at":"2026-02-13T05:13:51.942Z","repository":{"id":244718068,"uuid":"816051406","full_name":"grol-io/grol","owner":"grol-io","description":"Go REPL Open Language","archived":false,"fork":false,"pushed_at":"2026-01-28T23:22:41.000Z","size":1041,"stargazers_count":42,"open_issues_count":31,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-29T14:22:31.138Z","etag":null,"topics":["golang","interpreted-programming-language","interpreter","monkey"],"latest_commit_sha":null,"homepage":"https://grol.io","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/grol-io.png","metadata":{"files":{"readme":"README.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-06-16T23:31:38.000Z","updated_at":"2026-01-28T23:20:18.000Z","dependencies_parsed_at":"2024-06-18T01:43:09.753Z","dependency_job_id":"cb75baa6-d387-4e71-93d3-c25ba7a37b42","html_url":"https://github.com/grol-io/grol","commit_stats":null,"previous_names":["ldemailly/gorpl","ldemailly/gorepl","grol-io/grol"],"tags_count":221,"template":false,"template_full_name":null,"purl":"pkg:github/grol-io/grol","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grol-io%2Fgrol","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grol-io%2Fgrol/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grol-io%2Fgrol/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grol-io%2Fgrol/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grol-io","download_url":"https://codeload.github.com/grol-io/grol/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grol-io%2Fgrol/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29396847,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T04:26:15.637Z","status":"ssl_error","status_checked_at":"2026-02-13T04:16:29.732Z","response_time":78,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["golang","interpreted-programming-language","interpreter","monkey"],"created_at":"2026-01-20T01:22:13.013Z","updated_at":"2026-02-13T05:13:51.938Z","avatar_url":"https://github.com/grol-io.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca id=\"grol\"\u003e\u003c/a\u003e\n\u003cimg alt=\"GROL\" src=\"https://grol.io/grol_mascot.png\" width=\"33%\"/\u003e\n\n\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/grol-io/grol)\n[![Go Report Card](https://goreportcard.com/badge/grol.io/grol)](https://goreportcard.com/report/grol.io/grol)\n[![GoDoc](https://godoc.org/grol.io/grol?status.svg)](https://pkg.go.dev/grol.io/grol)\n[![CI Checks](https://github.com/grol-io/grol/actions/workflows/gochecks.yml/badge.svg)](https://github.com/grol-io/grol/actions/workflows/gochecks.yml)\n\n## About\n\nGo Repl Open Language is a small extensible interpreted (for now) language implemented in Go (golang).\n\nWebsite: [grol.io](https://grol.io/)\n\nTour: [grol.io/tour](https://grol.io/tour)\n\n## History\n\nInitially created by following along https://interpreterbook.com and making many changes/simplification/cleanups. And pretty much a complete rewrite in 0.25 with interning, everything a node/expression (flatter ast), etc... (kept the tests though).\n\nThere is also now a [discord bot](https://github.com/grol-io/grol-discord-bot#grol-discord-bot) as well as a `wasm` version that runs directly in your browser, try it on [grol.io](https://grol.io/)\n\nAnd [fortio](https://github.com/fortio/fortio) for instance now embeds it and gives access to programmable network operations like curl and UDP/TCP/HTTP/gRPC load tests.\n\n## Install\n\nInstall/run it:\n```shell\nCGO_ENABLED=0 go install -trimpath -ldflags=\"-w -s\" -tags \"no_net,no_json,no_pprof\" grol.io/grol@latest\n```\n\nOr with docker:\n```\ndocker run -ti ghcr.io/grol-io/grol:latest\n```\n\nOn a mac\n```\nbrew install grol-io/tap/grol\n```\n\nOr get one of the [binary releases](https://github.com/grol-io/grol/releases)\n\n## What it does\n\nSee the [Tour of grol](https://grol.io/tour/) for a more step by step set of examples.\n\nSample:\n```go\n$ grol -parse\n10:53:12.675 grol 0.29.0 go1.22.5 arm64 darwin - welcome!\n$ fact = func(n) {if (n\u003c=1) {return 1} n*self(n-1)} // could be n*fact(n-1) too\n== Parse ==\u003e fact = func(n) {\n\tif n \u003c= 1 {\n\t\treturn 1\n\t}\n\tn * self(n - 1)\n} // could be n*fact(n-1) too\n== Eval  ==\u003e func(n){if n\u003c=1{return 1}n*self(n-1)}\n$ n=fact(6)\n== Parse ==\u003e n = fact(6)\n== Eval  ==\u003e 720\n$ m=fact(7)\n== Parse ==\u003e m = fact(7)\n== Eval  ==\u003e 5040\n$ m/n\n== Parse ==\u003e m / n\n== Eval  ==\u003e 7\n$ func fx(n,s) {if n\u003e0 {return fx(n-1,s)}; info.stack}; fx(3,\"abc\")\n== Parse ==\u003e func fx(n, s) {\n\tif n \u003e 0 {\n\t\treturn fx(n - 1, s)\n\t}\n\tinfo.stack\n}\nfx(3, \"abc\")\n== Eval  ==\u003e [{\"s\":true},{\"s\":true},{\"s\":true},{\"s\":true}] // registers don't show up, so only s does and not n\n$ info[\"gofuncs\"] // other way to access map keys, for when they aren't strings for instance\n== Parse ==\u003e info[\"gofuncs\"] // other way to access map keys, for when they aren't strings for instance\n== Eval  ==\u003e [\"acos\",\"asin\",\"atan\",\"ceil\",\"cos\",\"eval\",\"exp\",\"floor\",\"json\",\"ln\",\"log10\",\"pow\",\"round\",\"sin\",\"sprintf\",\"sqrt\",\"tan\",\"trunc\",\"unjson\"]\n$ info.keywords\n== Parse ==\u003e info.keywords\n== Eval  ==\u003e [\"else\",\"error\",\"false\",\"first\",\"func\",\"if\",\"len\",\"log\",\"macro\",\"print\",\"println\",\"quote\",\"rest\",\"return\",\"true\",\"unquote\"]\n```\n\nThe interactive repl mode has extra features:\n- Editable history (use arrow keys, Ctrl-A etc...) to navigate previous commands\n- Hit the `\u003ctab\u003e` key at any time to get id/keywords/function completion\n- `history` command to see the current history, prefixed by a number\n- You can use for instance `!23` to repeat the 23rd statement\n- State is auto saved/loaded from `.gr` file in current directory unless `-no-auto` is passed\n- A short `help`\n\n## Language features\n\nFunctional int, float, string and boolean expressions\n\nFunctions, lambdas, closures (including recursion in anonymous functions, using `self()`)\n\nArrays, ordered maps (including map.key as map[\"key\"] shorthand access and ability to put any type, including arrays, maps and functions as keys)\n\nprint, log\n\nmacros and more all the time (like canonical reformat using `grol -format` and wasm/online version etc)\n\nautomatic memoization\n\nfor loops (in addition to recursion based iterations)\n\neasy extensions/adding Go functions to grol (see [extensions/extension.go](extensions/extension.go) for a lot of `math` additions)\n\nvariadic functions both Go side and grol side (using `..` on grol side)\n\nUse `info` to see all the available functions, keywords, operators etc... (can be used inside functions too to examine the stack)\n\n`save(\"filename\")` and `load(\"filename\")` current state.\n\nSee also [sample.gr](examples/sample.gr) and others in that folder, that you can run with\n```shell\nGOMEMLIMIT=1GiB grol examples/*.gr\n```\n\nor copypaste to the online version on [grol.io](https://grol.io).\n\nThere is also more involved code in [grol-io/grol-discord-bot/discord.gr](https://github.com/grol-io/grol-discord-bot/blob/main/discord.gr).\n\n## Dev mode:\n```shell\ngo install golang.org/x/tools/cmd/stringer@latest\nmake # for stripped down executable including build tags etc to make it minimal\n```\n\n### Reading notes\nSee [Open Issues](https://github.com/grol-io/grol/issues) for what's left to do\n\n\u003cdetails\u003e\u003csummary\u003eClick for detailed reading notes\u003c/summary\u003e\n\n- See the commit history for improvements/changes (e.g redundant state in lexer etc)\n\n- [x] interface nil check in parser\n\n- [x] Do we really need all these `let `, wouldn't `x = a + 3` be enough? made optional\n\n- Seems like ast and object are redundant to a large extent\n\n- [x] Introduced errors sooner, it's sort of obviously needed\n\n- [x] Put handling of return/error once at the top instead of peppered all over\n\n- [x] Make all the Eval functions receiver methods on State instead of passing environment around\n\n- [x] made built ins like len() tokens (cheaper than carrying the string version during eval)\n\n- fix up == and != in 3 places (int, string and default)\n\n- change int to ... float? number? or rather add float/double (maybe also or big int?...)\n\n- [x] use + for concat of arrays and merging of maps\n\n- [x] call maps maps and not hash (or maybe assoc array but that's long)\n\n- [x] don't make a slice to join with , when there is already a strings builder. replace byte buffers by string builder.\n\n- [x] generalized tokenized built in (token id based instead of string)\n\n-  Add \"extension\" internal functions (calling into a go function), with variadic params, param types etc\n\n- [x] Identifiers are letter followed by alphanum*\n\n- [x] map of interface correctly equals the actual underlying types, no need for custom hashing\n  -\u003e implies death to pointers (need non pointer receiver and use plain objects and not references)\n\n- unicode (work as is in strings already)\n\n- [x] flags for showing parse or not (default not pass `-parse` to see parsing)\n\n- [x] file input vs stdin repl (made up .gr for gorepl)\n\n- actual name for the language - it's not monkey (though it's monkey ~~compatible~~ derived, just better/simpler/...)\n\n- multiline support in stdin repl\n\n- [x] add \u003e= and \u003c= comparison operators\n\n- [x] add comments support (line)\n   - add /* */ style\n\n- line numbers for errors (for file mode)\n\n- [x] use `func` instead of `fn` for functions\n\n- [x] figure out how to get syntax highlighting (go style closest - done thx to viulisti -\u003e .gitattributes)\n\n- assignment to maps keys and arrays indexes\n\n- for loop\n\n- [x] switched to non pointer receivers in Object and (base/integer) Ast so equality checks in maps work without special hashing (big win)\n\u003c/details\u003e\n\n### CLI Usage\n\n```\ngrol 0.72.0 usage:\n\tgrol [flags] *.gr files to interpret or `-` for stdin without prompt or no arguments for stdin repl...\nor 1 of the special arguments\n\tgrol {help|envhelp|version|buildinfo}\nflags:\n  -c string\n    \tcommand/inline script to run instead of interactive mode\n  -compact\n    \tWhen printing code, use no indentation and most compact form\n  -empty-only\n    \tonly allow load()/save() to ./.gr\n  -eval\n    \tshow eval results (default true)\n  -format\n    \tdon't execute, just parse and reformat the input\n  -history file\n    \thistory file to use (default \"~/.grol_history\")\n  -max-depth int\n    \tMaximum interpreter depth (default 149999)\n  -max-duration duration\n    \tMaximum duration for a script to run. 0 for unlimited.\n  -max-history size\n    \tmax history size, use 0 to disable. (default 99)\n  -max-save-len int\n    \tMaximum len of saved identifiers, use 0 for unlimited (default 4000)\n  -no-auto\n    \tdon't auto load/save the state to ./.gr\n  -no-load-save\n    \tdisable load/save of history\n  -panic\n    \tDon't catch panic - only for development/debugging\n  -parse\n    \tshow parse tree\n  -parse-debug\n    \tshow all parenthesis in parse tree (default is to simplify using precedence)\n  -quiet\n    \tQuiet mode, sets loglevel to Error (quietly) to reduces the output\n  -restrict-io\n    \trestrict IOs (safe mode)\n  -s\t#! script mode: next argument is a script file to run, rest are args to the script\n  -shared-state\n    \tAll files share same interpreter state (default is new state for each)\n```\n(excluding logger control, see `gorepl help` for all the flags, of note `-logger-no-color` will turn off colors for gorepl too, for development there are also `-profile*` options for pprof, when building without `no_pprof`)\n\nIf you don't want to pass a flag and want to permanently change the `grol` history file location from your HOME directory, set `GROL_HISTORY_FILE` in the environment.\n\nThere is a special variant of `-c` if the string starts with `exec ` the subsequent command will replace grol and be exec'ed like a shell would.\n\n### Contributing\n\nContributions are most welcome! If you use GROL, feel free to open a PR or issue to be listed here.\n\nIf making changes to parser, running `make check` is important (it's pretty slow so not part of the regular CI but probably should be).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrol-io%2Fgrol","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrol-io%2Fgrol","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrol-io%2Fgrol/lists"}