{"id":21170018,"url":"https://github.com/bagnalla/holyc_mal","last_synced_at":"2026-01-02T00:39:18.033Z","repository":{"id":26963122,"uuid":"112032005","full_name":"bagnalla/holyc_mal","owner":"bagnalla","description":"Mal Lisp for TempleOS","archived":false,"fork":false,"pushed_at":"2022-01-10T19:14:19.000Z","size":315,"stargazers_count":109,"open_issues_count":0,"forks_count":11,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-21T10:50:57.671Z","etag":null,"topics":["holyc","lisp","mal","templeos"],"latest_commit_sha":null,"homepage":"","language":"HolyC","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bagnalla.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}},"created_at":"2017-11-25T20:21:14.000Z","updated_at":"2024-09-21T16:20:48.000Z","dependencies_parsed_at":"2022-07-27T09:02:37.571Z","dependency_job_id":null,"html_url":"https://github.com/bagnalla/holyc_mal","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bagnalla%2Fholyc_mal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bagnalla%2Fholyc_mal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bagnalla%2Fholyc_mal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bagnalla%2Fholyc_mal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bagnalla","download_url":"https://codeload.github.com/bagnalla/holyc_mal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243616550,"owners_count":20319925,"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":["holyc","lisp","mal","templeos"],"created_at":"2024-11-20T15:55:07.443Z","updated_at":"2026-01-02T00:39:17.988Z","avatar_url":"https://github.com/bagnalla.png","language":"HolyC","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca href=\"TempleOS\"\u003e\u003cimg src=\"TOS_logo.png\" align=\"left\" height=\"180\" \u003e\u003c/a\u003e\n# Mal for TempleOS.\nA complete implementation (with garbage collection) of the [Mal](https://github.com/kanaka/mal)\ndialect of Lisp for TempleOS v5.03 written in HolyC.\nMal includes macro support, tail-call optimization, file I/O, metadata on values,\nClojure-style mutable reference atoms, and more. For more information about Mal,\nvisit the [main repository](https://github.com/kanaka/mal).\n\u003cbr\u003e\n\n## Easy setup\n\nA Docker image is available and can be run with the following command:\n\n```\nsudo docker run -it --privileged --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v /root/.Xauthority:/root/.Xauthority:rw bagnalla/mal-holyc:v1\n```\n\nIf you see something like \"could not initialize SDL\", run the command `xhost +`\nand try again. Afterward, do `xhost -` to restore the original setting.\n\nIf you don't want to use Docker, follow the steps below for manual setup.\n\n## Installation\n\nHere is one way to copy the files over to a TOS installation using qemu-nbd.\nFirst, mount the disk image:\n```\nsudo modprobe nbd max_part=16\nsudo qemu-nbd -c /dev/nbd0 TempleOS.vdi\nsudo partprobe /dev/nbd0\nsudo mount /dev/nbd0p1 /mnt\n```\n\nWhere 'TempleOS.vdi' is replaced with the name of your image.\nThen, copy the files to /mnt/Home/Mal or wherever you would like.\n\nFinally, unmount the image:\n```\nsudo umount /mnt\nsudo qemu-nbd -d /dev/nbd0\n```\n\n## Running Mal\n\nInclude the file \"Interp.HC\" at the command line to bring Mal into scope.\n\nRun the REPL:\n```\nmal;\n```\n\nRun a mal program 'prog.mal':\n```\nmal(\"prog.mal\");\n```\n\n## Implementation info\n\nAll tests pass and self-interpreting is successful\n([dramatized demonstration](https://www.youtube.com/watch?v=tbr-j2_zhgU)).\n\nThe garbage collector uses a simple mark and sweep strategy with the\nglobal environment as the root. It requires some cooperation from\nother parts of the code: since we must allow garbage collection to run\nduring evaluation of terms (e.g., when self-interpreting, the main term\nnever terminates), intermediate values not reachable from the global\nenvironment must be pushed onto a special GC stack to prevent them\nfrom being erroneously collected.\n\nThere's a rudimentary regular expression engine in Regex.HC based on\nBrzozowski derivatives (no finite automata).\n\nArray.HC provides a generic dynamic array which is used internally by\nPArray (arrays of pointers), and String.\n\nLists are implemented with cons cells. Hashmaps are just association\nlists (but backed by arrays), so performance could probably be\nimproved by implementing actual hash tables or some balanced binary\ntree structure with string interning.\n\nThere are a bunch of \"unnecessary\" safety checks for null pointers,\nbut they're useful for debugging.\n\nOne problem is that the call stack for programs is relatively small in\nTempleOS, so the maximum recursion depth is limited. It may sometimes\nbe necessary to write functions in tail-recursive form when it\nwouldn't be an issue in other implementations. I haven't found a way\nto increase the stack size yet.\n\nGetStr is a convenient way to get user input, but it doesn't support\nctrl+d. You can do shift+esc instead, but it kills the entire terminal\nsession, so there is also a 'quit!' special form for cleanly exiting\nthe REPL without closing the terminal. Just type '(quit!)'.\n\n### HolyC interop\n\nThere are two built-in functions to support HolyC interop:\n* run-holyc: JIT compile and run a HolyC source file.\n* load-extern: look up a function in the current task's symbol table and create a closure pointing to it.\n\nThe intent is to use 'run-holyc' to compile a source file\ncontaining function definitions, and then use 'load-extern' to reify\nthem into first-class Mal values. An external function must take a\nlist of Malvals as the argument and return a Malval. See\nextern/test.HC or any of the functions in Intrinsics.HC for an\nexample. 'run-holyc' is obviously not safe since it allows execution\nof arbitrary HolyC code, so use at your own peril.\n\n## Performance benchmarks\nRunning in a VirtualBox VM. CPU is i7-4790k.\n- perf1.mal: 11 ms\n- perf2.mal: 66 ms\n- perf3.mal: 192 iters/s\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbagnalla%2Fholyc_mal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbagnalla%2Fholyc_mal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbagnalla%2Fholyc_mal/lists"}