{"id":27389085,"url":"https://github.com/01mu/interpreter","last_synced_at":"2026-04-30T13:34:25.366Z","repository":{"id":165311873,"uuid":"223979496","full_name":"01mu/interpreter","owner":"01mu","description":"A C implementation of the Monkey programming language defined in Thorsten Ball's book \"Writing A Interpreter In Go\"","archived":false,"fork":false,"pushed_at":"2020-11-24T21:50:39.000Z","size":565,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-20T19:53:46.537Z","etag":null,"topics":["c","compiler","go","interpreter","monkey","writing"],"latest_commit_sha":null,"homepage":"","language":"C","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/01mu.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,"zenodo":null}},"created_at":"2019-11-25T15:21:22.000Z","updated_at":"2024-09-24T17:27:09.000Z","dependencies_parsed_at":"2023-08-31T15:46:02.007Z","dependency_job_id":null,"html_url":"https://github.com/01mu/interpreter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/01mu/interpreter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/01mu%2Finterpreter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/01mu%2Finterpreter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/01mu%2Finterpreter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/01mu%2Finterpreter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/01mu","download_url":"https://codeload.github.com/01mu/interpreter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/01mu%2Finterpreter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32466333,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"ssl_error","status_checked_at":"2026-04-30T13:12:06.837Z","response_time":57,"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":["c","compiler","go","interpreter","monkey","writing"],"created_at":"2025-04-13T19:11:53.585Z","updated_at":"2026-04-30T13:34:25.360Z","avatar_url":"https://github.com/01mu.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# interpreter\nA C implementation of the [Monkey](https://monkeylang.org/) programming language defined in Thorsten Ball's book [\"Writing A Interpreter In Go\"](https://interpreterbook.com/).\n## Compiling and testing\n### Compile without tests\n`gcc -o monkey main.c`\n### Compile with tests\nCompile the interpreter and perform tests of the different statements and expressions available in `tests/repl.c`.\n\n`gcc -o monkey main.c; valgrind --leak-check=full --show-leak-kinds=all ./monkey test`\n```\n(...)\n==5256== Command: ./monkey test\n==5256==\n\n[PASSED] REPL Test | 90 out of 90 passed\n\n==5256==\n==5256== HEAP SUMMARY:\n==5256==     in use at exit: 0 bytes in 0 blocks\n==5256==   total heap usage: 13,549 allocs, 13,549 frees, 293,249 bytes allocated\n==5256==\n==5256== All heap blocks were free\nd -- no leaks are possible\n(...)\n```\n## Types and control flow\nThe language currently supports closures, conditional statements, boolean expressions, integers, strings, arrays, and hash maps. Prefix and infix operations are available for some types.\n\nThe identifiers `let` and `return` define `statements` and do not produce values. The aforementioned type are called `expressions` since they produce values. For example, `let x = 5` does not produce a value, but `5` does.\n\nWhen the code is parsed and evaluated, `x` will refer to the name of an `Object` type containing a reference to an `IntegerObject` type containing the integer literal value of `5`.\n## Running code\n### Execute REPL\nAccess the REPL by providing `repl` as an argument as in `./monkey repl`.\n#### Output\n```\nType '\\h' for help and '\\q' to quit\n\u003e\u003e\u003e let a = 5;\n5\n\u003e\u003e\u003e a + 10;\n15\n\u003e\u003e\u003e \\h\nCommands:\nDisplay environment: ... \\e\nOpen file: ............. \\o\n\u003e\u003e\u003e \\e\n[10] a:  0x557f0a1bd290,\n\u003e\u003e\u003e \\q\nBye!\n```\n### Open a file\nOpen the file `examples/count.in` from within the REPL using `\\o`:\n\n#### examples/count.in\n```\nlet c = fn(x, g) {\n    if(x \u003c g) {\n        return c(x + 1, g);\n    } else {\n        return x * 2;\n    }\n};\n\n\nlet fib = fn(x) {\n    if(x == 0) {\n        return 0;\n    } else {\n        if(x == 1) {\n            return 1;\n        } else {\n            return fib(x - 1) + fib(x - 2);\n        }\n    }\n};\n\nc(0, 1000);\nfib(10);\n```\n#### Output\n```\nType '\\h' for help and '\\q' to quit\n\u003e\u003e\u003e \\o\n*** Open file: examples/count.in\nFile \"examples/count.in\" opened\n2000\n55\n\u003e\u003e\u003e \\q\nBye!\n```\n### Built-in functions\nThe language supports a few built-in functions: `len`, `find`, `str`, `push`, `first`, `last`, `rest`, and `type`.\n#### len(`string` or `array`)\n```\n\u003e\u003e\u003e len(\"abcde\")\n5\n\u003e\u003e\u003e len([1, 2, \"z\"]) + 1\n4\n```\n#### find(`string`, `string`)\n```\n\u003e\u003e\u003e find(\"abc\", \"c\")\n2\n\u003e\u003e\u003e find(\"abc\", \"d\")\n-1\n```\n#### string(`non-string`)\n````\n\u003e\u003e\u003e str([1, 2]) + \" (string)\"\n'[1, 2] (string)'\n````\n#### push(`array`, `object`)\n````\n\u003e\u003e\u003e let a = [1];\n[1]\n\u003e\u003e\u003e push(a, 2);\nNULL\n\u003e\u003e\u003e a\n[1, 2]\n````\n#### first(`array`), last(`array`), rest(`array`)\n````\n\u003e\u003e\u003e first([\"a\", \"b\"])\n'a'\n\u003e\u003e\u003e last([1, 2])\n2\n\u003e\u003e\u003e rest([1,2,3])\n[2, 3]\n````\n#### type(`object`)\n````\n\u003e\u003e\u003e type({'a': 1})\n'HASHMAP'\n\u003e\u003e\u003e type([1])\n'ARRAY'\n\u003e\u003e\u003e type(fn(x) { return false; })\n'FUNCTION'\n````\n## Todo\n- [ ] Implement mark-and-sweep garbage collection\n- [ ] Include support for more control flow statements\n- [ ] Add custom type support\n- [ ] Finish the compiler implementation in Thorsten Ball's [\"Writing A Compiler In Go\"](https://compilerbook.com/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F01mu%2Finterpreter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F01mu%2Finterpreter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F01mu%2Finterpreter/lists"}