{"id":15060040,"url":"https://github.com/susji/lc","last_synced_at":"2026-01-02T09:07:49.835Z","repository":{"id":255415287,"uuid":"849528270","full_name":"susji/lc","owner":"susji","description":"Self-hosting toy compiler for a language which resembles a subset of ANSI C","archived":false,"fork":false,"pushed_at":"2024-10-05T05:27:33.000Z","size":354,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-21T19:48:55.952Z","etag":null,"topics":["ansi-c","assembly","assembly-x86","c","compiler"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/susji.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}},"created_at":"2024-08-29T18:47:08.000Z","updated_at":"2024-10-05T05:27:36.000Z","dependencies_parsed_at":"2024-09-14T17:19:23.221Z","dependency_job_id":null,"html_url":"https://github.com/susji/lc","commit_stats":null,"previous_names":["susji/lc"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susji%2Flc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susji%2Flc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susji%2Flc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susji%2Flc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/susji","download_url":"https://codeload.github.com/susji/lc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243681084,"owners_count":20330155,"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":["ansi-c","assembly","assembly-x86","c","compiler"],"created_at":"2024-09-24T22:51:35.453Z","updated_at":"2026-01-02T09:07:49.794Z","avatar_url":"https://github.com/susji.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lc\n\n`lc` is a small self-hosting toy compiler. This means it can compile itself. The\nlanguage closely resembles a simplified subset of ANSI C. `lc` targets only\nGNU/Linux and x86. The goal was to support just enough features to make\nself-hosting a reasonable effort with close to zero emphasis on general\nrobustness, feature completeness, and accurate ANSI C semantics.\n\nTo see the exact subset that `lc` supports, check out [the code](lc.c). If you\ndo not see a feature used in the sources, most likely it is unsupported. Some\nthings, even if we might parse and try compiling them, will behave wrongly. As\nan example, we treat all integers as word-sized. Also, we produce diagnostic\noutput for some typical errors and warnings, but very few errors actually stop\nthe compilation process.\n\n## Bootstrapping and self-hosting\n\nWe want to produce `lc`, a version of the compiler compiled by the compiler\nitself. Bootstrapping is done by using any reasonably compliant C compiler to\nproduce `lc0`. We self-compile the full compiler twice to ensure that `lc0` and\n`lc1` produce identical output. The steps are these:\n\n1. Compile the `lc0` executable with some existing C compiler\n2. Produce `lc1.s` with `lc0`\n3. Assemble and link `lc1.s` to create the `lc1` executable\n4. Produce `lc.s` with `lc1`\n5. Assemble and link `lc.s` to create the `lc` executable\n6. Verify that `lc1.s` and `lc.s` are equal\n\nFor details, see [the Makefile](Makefile).\n\n## The implementation\n\nI did not do any serious planning beforehand. If you browse the code starting\nfrom the beginning, you'll see a fairly well-contained progression into lexer,\nparser, tree rewriter, and code generator stages -- this is intentional. As\nmentioned, I dropped every single feature and semantic concept if I could not\neasily justify the effort in comparison to its benefit for self-hosting. Structs\nare probably the single greatest complication but I really did not want to\nsimulate them with arrays even though that is a perfectly fine approach. I had\nno need for floats, alternative integers, or function pointers. Adding any of\nthese things *individually* is easy, but the problems begin after one buys into\na *dozen* \"easy things\". In aggregate, they need real effort.\n\nIt would be nice to have a strict subset of ANSI C, but to me, it is not worth\nthe effort. Having previously implemented a subset of the classic C\npreprocessor, I realized that I really did not want that side quest either. As\ncan be seen from the code, this means that we lose some idiomatic features like\nplain macros, variadic macros, and includes. For this purpose, they are not\nneeded either. Handling codegen with a trivial stack machine and these absurd\n\"push pop push pop\" chains is anything but efficient. Still, to me, all the\ninteresting bits and pieces are here.\n\nIn retrospect, I think the nastiest parts are some of the ad hoc simplifications\nI did without much thought when implementing the parser. This uneasiness applies\nespecially to parsing of definitions and declarations. As a result, we have some\naccidental complexity in the AST. I also attempted to simplify codegen by doing\nthe tree rewrites, but I think it just complicated things. I do not like the\nresult. It is what it is.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusji%2Flc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsusji%2Flc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusji%2Flc/lists"}