{"id":23579638,"url":"https://github.com/matejamaric/tinyc-in-go","last_synced_at":"2026-05-16T18:06:06.003Z","repository":{"id":266069825,"uuid":"895798910","full_name":"MatejaMaric/tinyc-in-go","owner":"MatejaMaric","description":"A Go implementation of Marc Feeley's TinyC","archived":false,"fork":false,"pushed_at":"2024-12-14T16:00:38.000Z","size":108,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-30T01:51:17.681Z","etag":null,"topics":["bytecode-interpreter","compiler","functional-programming","golang","recursive-descent-parser"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"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/MatejaMaric.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-11-28T23:43:24.000Z","updated_at":"2024-12-13T22:43:48.000Z","dependencies_parsed_at":"2024-12-26T23:11:57.498Z","dependency_job_id":"b0a08d34-0cef-4134-896b-d95de0999445","html_url":"https://github.com/MatejaMaric/tinyc-in-go","commit_stats":null,"previous_names":["matejamaric/tinyc-in-go"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/MatejaMaric/tinyc-in-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatejaMaric%2Ftinyc-in-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatejaMaric%2Ftinyc-in-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatejaMaric%2Ftinyc-in-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatejaMaric%2Ftinyc-in-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MatejaMaric","download_url":"https://codeload.github.com/MatejaMaric/tinyc-in-go/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MatejaMaric%2Ftinyc-in-go/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274935969,"owners_count":25376834,"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","status":"online","status_checked_at":"2025-09-13T02:00:10.085Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["bytecode-interpreter","compiler","functional-programming","golang","recursive-descent-parser"],"created_at":"2024-12-26T23:11:55.331Z","updated_at":"2026-05-16T18:06:05.976Z","avatar_url":"https://github.com/MatejaMaric.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"### About:\n\nA Go implementation of Marc Feeley's TinyC \"compiler\" (bytecode interpreter) from 2001.\n\nThe are considerable differences between [the original Marc Feeley's implementation](https://www.iro.umontreal.ca/~felipe/IFT2030-Automne2002/Complements/tinyc.c) and this one:\n1. The original has ~300loc, while this one has ~750loc.\nAlthough, just by applying different formatting to the original, it would probably double it's loc count.\n1. The original implementation heavily relied on global variables, this one does not.\nIn this implementation the lexer, the parser, the code generator and the virtual machine are implemented as pure functions.\n1. This implementation has unit tests with coverage of ~93%.\n\n### How to use:\n\nThe integer global variables \"a\" to \"z\" are predefined and initialized to zero.\nIt is not possible to declare new variables.\nThe compiler reads the program from standard input and prints out the value of the variables that are not zero.\nThe grammar in EBNF is:\n\n```\n\u003cprogram\u003e ::= \u003cstatement\u003e\n\u003cstatement\u003e ::= \"if\" \u003cparen_expr\u003e \u003cstatement\u003e |\n                \"if\" \u003cparen_expr\u003e \u003cstatement\u003e \"else\" \u003cstatement\u003e |\n                \"while\" \u003cparen_expr\u003e \u003cstatement\u003e |\n                \"do\" \u003cstatement\u003e \"while\" \u003cparen_expr\u003e \";\" |\n                \"{\" { \u003cstatement\u003e } \"}\" |\n                \u003cexpr\u003e \";\" |\n                \";\"\n\u003cparen_expr\u003e ::= \"(\" \u003cexpr\u003e \")\"\n\u003cexpr\u003e ::= \u003ctest\u003e | \u003cid\u003e \"=\" \u003cexpr\u003e\n\u003ctest\u003e ::= \u003csum\u003e | \u003csum\u003e \"\u003c\" \u003csum\u003e\n\u003csum\u003e ::= \u003cterm\u003e | \u003csum\u003e \"+\" \u003cterm\u003e | \u003csum\u003e \"-\" \u003cterm\u003e\n\u003cterm\u003e ::= \u003cid\u003e | \u003cint\u003e | \u003cparen_expr\u003e\n\u003cid\u003e ::= \"a\" | \"b\" | \"c\" | \"d\" | ... | \"z\"\n\u003cint\u003e ::= \u003can_unsigned_decimal_integer\u003e\n```\n\n#### Example:\n\n```bash\ngo build\necho \"{ i=125; j=100; while (i-j) if (i\u003cj) j=j-i; else i=i-j; }\" | ./tinyc-in-go\n```\n\nOutput:\n```\ni = 25\nj = 25\n```\n\nAdditional examples of the compiler invocations can be found in the `main_test.go` file.\n\n### To do:\n\n- While making this implementation, I tried to follow the principles of functional programming (no variables or loops, only constants and functions).\nI'm probably going to make a new implementation (on a different branch) using parser combinators, and make this code even more purely functional. \nParser combinators would replace the current state machine lexer and recursive descent parser.\n- I'm probably going to refactor the virtual machine implementation (make it more functional).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatejamaric%2Ftinyc-in-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatejamaric%2Ftinyc-in-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatejamaric%2Ftinyc-in-go/lists"}