{"id":26579942,"url":"https://github.com/obriencj/python-sibilant","last_synced_at":"2025-03-23T06:29:35.421Z","repository":{"id":13543884,"uuid":"16235766","full_name":"obriencj/python-sibilant","owner":"obriencj","description":"A dialect of Lisp compiling to Python bytecode","archived":false,"fork":false,"pushed_at":"2023-02-09T20:54:17.000Z","size":1398,"stargazers_count":7,"open_issues_count":30,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-05-01T21:16:31.159Z","etag":null,"topics":["cpython","lisp","macros","python","python-bytecode","python-sibilant"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/obriencj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-01-25T17:26:37.000Z","updated_at":"2023-08-10T03:54:46.000Z","dependencies_parsed_at":"2022-09-04T07:42:34.538Z","dependency_job_id":null,"html_url":"https://github.com/obriencj/python-sibilant","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obriencj%2Fpython-sibilant","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obriencj%2Fpython-sibilant/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obriencj%2Fpython-sibilant/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obriencj%2Fpython-sibilant/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/obriencj","download_url":"https://codeload.github.com/obriencj/python-sibilant/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245066341,"owners_count":20555402,"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":["cpython","lisp","macros","python","python-bytecode","python-sibilant"],"created_at":"2025-03-23T06:29:34.819Z","updated_at":"2025-03-23T06:29:35.412Z","avatar_url":"https://github.com/obriencj.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Overview of python-sibilant\n\n[![Build Status](https://travis-ci.org/obriencj/python-sibilant.svg?branch=master)](https://travis-ci.org/obriencj/python-sibilant)\n\nSibilant is a dialect of [LISP] which compiles to [Python] bytecode.\n\nSibilant is not done. It's still being organically grown in bars and\ncoffee shops whenever I get a chance to sit alone. I will eventually\nget to the point where it seems like a 1.0.0 is sane. Until then, this\nis version 0.9.0 and every commit or pull-request could introduce\ndramatic changes.\n\n[LISP]: https://en.wikipedia.org/wiki/Lisp_(programming_language)\n\n[Python]: https://python.org/\n\n\n## But Why?\n\nMostly \"why not,\" and \"I do what I want,\" with some \"[for myself],\"\nmixed in.\n\n[for myself]: http://obriencj.preoccupied.net/blog/2017/09/17/my-first-lisp-compiler/\n\nBut also because I really love the idea of domain-specific languages.\nEvery single time I wrote a block of configuration for optparse or\nargparse I yearned for defmacro. Whenever I created structured\nunpacking of data, I wanted to just define the shapes and let those be\ntransformed into a parser and object model.\n\n\n## Origins\n\nThis was a project begun in 2007 and subsequently left abaondoned in\nearly 2008.\n\nI believe the concept grew out of my hacking with the absurdity that\nis [Spexy]. But while Spexy was mostly a joke and a puzzle, Sibilant\nhad a goal to create a working and sane-ish LISP compiler.\n\nI wasn't ready for such an undertaking, and a great deal of Real Life\ntook up my time instead. The modest first passes as Sibilant sat\nmostly forgotten in a CVS repo.\n\n[Spexy]: https://github.com/obriencj/python-spexy\n\"A hackish, LISP-like preprocessor for Python\"\n\nSome time in January of 2014 I ran across my checkout. The upstream\n`cvsroot` had disappeared -- it was on a host that had probably been\nmigrated, and I'd not bothered to bring along these repos, or I did a\nreally good job hiding it from myself. I imported what I had left to\nGitHub for posterity, unsure of the fate of the project.\n\nFor the next few years I would idly poke at bits here and there. I\ntoyed with different ideas for some of the basic data types, but never\ngot anywhere serious.\n\nThen suddenly in July of 2017 I went nuts and threw together the\ncompiler in a week while drinking at a [barcade].\n\n[barcade]: https://theboxcarbar.com/raleigh/\n\nIt has been a fantastic learning experience, and excellent mental\nexercise. While the Sibilant user base might always number in just the\nsingle digits, I can never consider the project a failure. The sheer\njoy from when a particular feature comes to life for the first time,\nor the satisfaction of seeing the language develop are enough to merit\ndeclaring it a success. I am excited to continue hacking at it, what\nmore is there?\n\n\n## Python Version Support\n\nCPython 3.5, 3.6, and 3.7 are currently supported. CPython 3.8 has\nmade some bytecode changes (removals) that impact sibilant's ability\nto target it.\n\n\n## References\n\nSibilant targets Python bytecode directly. I rely heavily on the\nauto-generated documentation for the `dis` module, and on its output\nfor seeing just what the default compiler would do for some cases.\n\n* [Module `dis` in Python 3.7](https://docs.python.org/3.7/library/dis.html)\n* [Module `dis` in Python 3.6](https://docs.python.org/3.6/library/dis.html)\n* [Module `dis` in Python 3.5](https://docs.python.org/3.5/library/dis.html)\n\n\n## Features\n\nSibilant is slowly growing as more special forms and macros are\nadded. Below are a few of the key features\n\n\n### Importer\n\nPython 3 provides an extensible import system via `importlib`. When\nthe `sibilant` module is loaded, this system will be extended\nto support treating sibilant source files (files found in `sys.path`\nand ending in `.lspy` or `.sibilant`) as packages or modules.\n\nIn other words, to enable loading of sibilant code at runtime, you\njust need to have `import sibilant` at the beginning of your\ntop-level module.\n\nFrom within a sibilant module the `import` function allows fetching a\nmodule from the importer. `def import` and `def import-from` will bind\nmodules or their contents.\n\n\n### Compile to File\n\nSibilant has the ability to compile a `.lspy` file into a `.pyc` which\ncan then be loaded by the default importer. Modules loaded in this\nmanner skip the parse and compile stages, but still execute in-order\nduring load. These modules have a hard dependency on sibilant -- they\nare not stand-alone. All of the sibilant types are pulled in\ndynamically.\n\n\n### Line Numbers\n\nA big advantage of sibilant over an interpreted lisp using a lambda\nemitter in Python is that the bytecode sibilant emits can have a\nline-number-table associated with it. This means that exceptions or\ntracebacks will interleave between python source code and sibilant\nsource code, and correctly show the line that the raise came from.\n\n\n### Tail-call optimization\n\nThe Sibilant compiler implements simple tail-call optimization via a\ntrampoline. The trampoline will bounce tail-calls out of the calling\nframe where they will be evaluated, consuming no additional stack\nspace. This form of TCO does have the somewhat frustrating side-effect\nof collapsing the call stack, which can make tracebacks difficult to\ndebug. Sibilant will only perform TCO on calls to functions written\nwith TCO enabled -- ie. Python function calls won't get bounced unless\nthey were explicitly created with the sibilant `@trampoline`\ndecorator.\n\n\n### Parse-time Macros: reader macros\n\nParse time macros defined via `set-macro-character` can transform\nthe source stream before it becomes a source object\n\n\n### Compile-time Macros: defmacro\n\nCompile time macros defined via `defmacro` are the simple, low-level\nvariety, transforming the `cons` list from the parsed source code and\nemitting a new list representing the expanded form. An implementation\nof `macroexpand-1` is included for macro debugging purposes.\n\nMacros which expand from a `symbol` rather than a `cons` list can be\ncreated via `defalias`. Alias macros take no arguments.\n\n\n### Compile-time optimized operators\n\nThe common Python operators and comparators are implemented such that\nthey have both a compile-time and run-time representation. Where\npossible, operators will compile to direct bytecode operations, but\ncan also be passed and called as runtime functions.\n\n\n### try/except/else/finally\n\nThe `try` special form can be used as an expression, evaluating to the\nblock that runs last.\n\n\n### the context manager interface\n\nThe `with` special form can be used to enter a context manager and\nbind the result locally, then clean up once execution of the inner\nform ends. The expression evaluates to the last value of the body.\n\n\n### Looping\n\nThe `while` and `for-each` forms can be used to repeatedly execute a\nbody of code. The `break` and `continue` forms can be used from within\nthose blocks as well.\n\n\n### Generators\n\nSibilant can create generators from `function`, `lambda`, and `let`\nforms, by using either the `yield` or `yield-from` expressions.\n\n\n### Future Feature: Rewrite Sibilant in Sibilant\n\nI'd like to get to the point where I can rewrite the compiler\nsubpackage in sibilant itself. Then compile the new compiler in the\nold compiler, and finally re-compile the new compiler using itself.\n\nThe sibilant compiler will eventually become sibilantzero, to be\nrelegated to a simple build dependency in producing sibilant proper.\n\n\n## Should You Use Sibilant?\n\nProbably not. Instead you should almost certainly use a well-defined\nand maintained Lisp or Scheme from the beginning.  Here's some really\ngreat ones:\n\n* Chez Scheme - \u003chttps://www.scheme.com/\u003e\n* Guile - \u003chttps://www.gnu.org/software/guile/\u003e\n* Racket - \u003chttps://racket-lang.org\u003e\n* Clojure - \u003chttps://clojure.org\u003e\n\nHowever if you're really stuck to an existing Python environment, you\njust might enjoying giving Sibilant a shot. [Let me know] your cool\nuse-case!\n\n[let me know]: https://github.com/obriencj/python-sibilant/issues\n\n\n## Installation\n\nSibilant needs to be installed as a wheel to function correctly:\n```bash\npip3 install .\n```\n\n## Contact\n\nAuthor: Christopher O'Brien  \u003cobriencj@gmail.com\u003e\n\nIRC Channel: #py-sibilant on [Libera]\n\nOriginal Git Repository: \u003chttps://github.com/obriencj/python-sibilant\u003e\n\n[Libera]: https://libera.chat\n\n\n## License\n\nThis library is free software; you can redistribute it and/or modify\nit under the terms of the GNU Lesser General Public License as\npublished by the Free Software Foundation; either version 3 of the\nLicense, or (at your option) any later version.\n\nThis library is distributed in the hope that it will be useful, but\nWITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\nLesser General Public License for more details.\n\nYou should have received a copy of the GNU Lesser General Public\nLicense along with this library; if not, see\n\u003chttp://www.gnu.org/licenses/\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobriencj%2Fpython-sibilant","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fobriencj%2Fpython-sibilant","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobriencj%2Fpython-sibilant/lists"}