{"id":17791587,"url":"https://github.com/chiroptical/snail","last_synced_at":"2025-03-16T16:30:42.310Z","repository":{"id":70171956,"uuid":"545483901","full_name":"chiroptical/snail","owner":"chiroptical","description":"A programming language for gastropods","archived":false,"fork":false,"pushed_at":"2024-06-20T13:37:02.000Z","size":53,"stargazers_count":12,"open_issues_count":3,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-09-23T04:11:01.368Z","etag":null,"topics":["lisp-dialect","parser","programming-language"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chiroptical.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2022-10-04T13:01:23.000Z","updated_at":"2024-06-20T13:37:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"e8fae21e-b9c0-4cef-99f8-e21277ad6fbc","html_url":"https://github.com/chiroptical/snail","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiroptical%2Fsnail","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiroptical%2Fsnail/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiroptical%2Fsnail/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chiroptical%2Fsnail/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chiroptical","download_url":"https://codeload.github.com/chiroptical/snail/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221665792,"owners_count":16860315,"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":["lisp-dialect","parser","programming-language"],"created_at":"2024-10-27T10:54:12.627Z","updated_at":"2024-10-27T10:54:13.155Z","avatar_url":"https://github.com/chiroptical.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Snail\n\nA no-semantics programming language for gastropods.\n\n## Why?\n\nMy colleagues and I are going to start working through [Types and Programming\nLanguages][tapl]. In the book you implement languages of varying feature sets.\nThe book implements these languages in OCaml, however I had this Lisp parser\nessentially ready for awhile. There are a handful of \"Write you a Scheme\nInterpreters\"-like tutorials and they all use a parser relatively similar to\nthis one. However, there are some pretty subtle issues with most of the ones I\nhave seen. For example, the two examples below parse as two lexemes in a lot of\nexamples. Even Haskell's parser has [this issue][haskell-parse-issue]!\n\n```\n(1a)\n(1 a)\n```\n\n## Is this really a programming language?\n\nFrom the [\"Programming language\" Wikipedia page][pl-wikipedia],\n\n\u003e A programming language is a system of notation for writing computer programs.\n\n\u003e The description of a programming language is usually split into the two components of syntax (form) and semantics (meaning)\n\nSnail is used for writing interpreters or compilers. However, it doesn't define\n**any** semantics. So, maybe?\n\n## Syntax (form)\n\nSnail describes valid lexemes, text literals, and s-expressions. The valid\nlexemes are approximately from R5RS Scheme but this may change in the future.\nWe also use Haskell's line and block comments. Here is a valid snail program,\n\n```\n-- Prints `hello \"world\"` to the console\n(print \"hello \\\"world\\\"\")\n\n-- Prints 3 to the console\n(print (+ 1 2))\n\n{-\n  Defines a function to add two numbers\n  Applies the function to generate 3\n  Prints 3 to the console\n-}\n(let\n  (f (lambda (x y) (+ x y)))\n  (print (f 2 1)))\n\n(quote hello)\n\n(nil)\n\n(print true)\n\n(print false)\n\n-- end comment\n```\n\nReminder, this program has no semantics. It is your job to take Snail's\nAbstract Syntax Tree (AST) and define the semantics of an interpreter or\ncompiler.\n\n## Getting the AST\n\nYou have two options: `readSnailFile` or `parseSnail`.\n\n`readSnailFile` can be used like this, assuming you have put some valid snail\ninto a file `./hello.snail`,\n\n```haskell\nimport Snail\n\nprintSnail :: IO ()\nprintSnail = do\n  eResults \u003c- readSnailFile \"./hello.snail\"\n  case eResults of\n    Right ast -\u003e print ast\n    Left failureString -\u003e print failureString\n```\n\n`parseSnail` doesn't require `IO` the only parameter is `Text`. This is useful\nfor one-line programs, e.g.,\n\n```haskell\n{-# LANGUAGE OverloadedStrings #-}\n\nimport Snail\n\nexample :: Either String [SnailAst]\nexample = parseSnail \"(print false)\"\n```\n\n## Example Interpreters\n\n1. The `arith` language from [Types and Programming Languages][tapl]: https://github.com/chiroptical/snail-arith/blob/main/src/Lib.hs\n2. Languages from [essentials-of-compilation][essentials-of-compilation]: https://github.com/chiroptical/essentials-of-compilation (each chapter is a module)\n\n## Differences from S-Cargot\n\nI was recently reminded of [s-cargot][s-cargot]. From their GitHub,\n\n\u003e S-Cargot is a library for parsing and emitting S-expressions, designed to be\n\u003e flexible, customizable, and extensible.\n\nThis is quite different from Snail. Snail is not flexible, customizable, or\nextensible. I have chosen a syntax and either you use it or you don't.\nWith S-Cargot, you can build a custom S-expression parser. Snail provides one.\n\nI don't think you can re-write Snail using S-Cargot? It doesn't appear to\nsupport `'(x)` or `(let [x 10] x)`. Please correct me if I missed something.\n\nI tried to mimic their example\n(https://github.com/aisamanra/s-cargot/blob/master/example/example.hs) in\n./example/Main.hs.\n\n## Resources for implementing interpreters and compilers\n\nThese are resources I am personally interested in exploring, there are **many** others\n\n- [Types and Programming Languages][tapl]\n- [Essentials of Compilation][essentials-of-compilation]\n- [Compiler Design][cs4410]\n- [Compiler Construction][cse131]\n\n[tapl]: https://www.cis.upenn.edu/~bcpierce/tapl\n[haskell-parse-issue]: https://twitter.com/chiroptical/status/1471568781906518018\n[pl-wikipedia]: https://en.wikipedia.org/wiki/Programming_language\n[essentials-of-compilation]: https://mitpress.mit.edu/9780262047760/essentials-of-compilation\n[s-cargot]: https://github.com/aisamanra/s-cargot\n[cs4410]: https://course.ccs.neu.edu/cs4410sp21/\n[cse131]: https://ucsd-cse131-f19.github.io/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchiroptical%2Fsnail","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchiroptical%2Fsnail","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchiroptical%2Fsnail/lists"}