{"id":20425386,"url":"https://github.com/catseye/pophery","last_synced_at":"2026-04-21T13:31:21.812Z","repository":{"id":142239945,"uuid":"4618295","full_name":"catseye/Pophery","owner":"catseye","description":"MIRROR of https://codeberg.org/catseye/Pophery : (WIP) An imperative string-rewriting language. I know right?","archived":false,"fork":false,"pushed_at":"2022-09-24T12:22:16.000Z","size":16,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-15T15:12:48.531Z","etag":null,"topics":["esolang","esoteric-language","esoteric-programming-language","string-rewriting","unfinished","wip"],"latest_commit_sha":null,"homepage":"https://catseye.tc/node/Pophery","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/catseye.png","metadata":{"files":{"readme":"README.markdown","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2012-06-10T20:56:16.000Z","updated_at":"2023-11-11T08:47:04.000Z","dependencies_parsed_at":"2023-03-21T19:17:25.718Z","dependency_job_id":null,"html_url":"https://github.com/catseye/Pophery","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/catseye%2FPophery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catseye%2FPophery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catseye%2FPophery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catseye%2FPophery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/catseye","download_url":"https://codeload.github.com/catseye/Pophery/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241966977,"owners_count":20050324,"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":["esolang","esoteric-language","esoteric-programming-language","string-rewriting","unfinished","wip"],"created_at":"2024-11-15T07:13:09.253Z","updated_at":"2026-04-21T13:31:16.784Z","avatar_url":"https://github.com/catseye.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Pophery\n=======\n\nVersion 0.1 or something\nChris Pressey, Cat's Eye Technologies\n\nIntroduction\n------------\n\n_Pophery_ is an imperative string-rewriting language.  I know right?\n\nIn Pophery, each program state is a single string, and a program is simply\nthe initial program state.  As execution proceeds, the string is rewritten\nbased on instructions found within the string.  Pophery is a \"visible\"\nprogramming language, in the sense that there is no program state that is\nnot part of the string.\n\nPophery provides primitive instructions which allow the programmer to\nconstruct their own control flow mechanisms, including at least conventional\nbackwards-branch looping, but possibly also permitting alternative\ntechniques such as [SMITH](http://catseye.tc/projects/smith/)-style\nprogram-extension and [Muriel](http://catseye.tc/projects/muriel/)-style\nquine-continuation.\n\nAs a reaction against the proliferation of stack-based esolangs, Pophery's\ndesign explicitly avoids having a stack, preferring instead register-like\nstorage in the form of delimited substrings, called _slots_, which may be\naccessed directly and indirectly, updated, created, destroyed, and moved\nabout.\n\nAdditionally, Pophery has, incidentally during the course of its design,\nbecome centrally oriented around the editing metaphors provided both by\nclassic word processors and modern graphical user interfaces — the\nso-called \"copy and paste\" operations.\n\nProgram Structure\n-----------------\n\nAll program state (instructions and variables) are encoded in a single\nstring, which is a finite but unbounded sequence of non-combining Unicode\ncode points.  The string may contain any number of _locators_, which\ntake the form `(α)` where `α` is any string which does not contain `(` or\n`)` symbols.  (In the sequel, Greek letters will denote variables for\nsimilar such strings.)  Only the rightmost occurrence of the sequence `(α)`\nis regarded as the locator, for the purposes of operations on that locator —\nany other occurrences are ignored.\n\nA pair of locators of the form `(^α)` and `(α$)`, where `(^α)` occurs to the\nleft of `(α$)`, is caled a _slot_.  In the sequence `(^α)β(α$)`, `α` is\ncalled the _name_ of the slot, and `β` is called the _contents_ of the slot.\n\nA slot may contain any number of other locators.  In fact, slots can overlap,\nin the sense that a slot may contain one locator of another slot, but not the\nother.\n\nA slot can also be referenced indirectly, in which case the contents of the\nslot gives the name of another slot which is the actual subject of the\noperation.  For example, `(^α)β(α$)` might refer to a slot `(^β)(β$)`\nelsewhere in the same string.  We use the terminology _slot β_ to refer to\ndirect access to the slot named `β`, and _slot indirect by β_ to refer to\naccess to a slot named by the contents of the slot named `β`.\n\nWhile the programmer may define, create, and destroy slots as they like,\nsome slots have meaning to Pophery's execution model.  Each of these\n_built-in_ slots has a default name by which it is accessed.  However, if a\n_name slot_ for the built-in slot is present in the program, access is\nindirect by the name slot.  The name slot of a built-in slot named `β` is\nnamed `` `β ``.  (A clarifying example will appear shortly.)\n\nA single locator can also sometimes be referenced indirectly; in this case,\na slot contains the substring `β` identifying the locator `(β)`.  Locators\nalso support an operation called _sliding_; they may slide leftward or slide\nrightward.  When sliding rightward (resp. leftward), the character\nimmediately to the right (resp. left) of the locator is transferred to\nimmediately left (resp. right) of that locator.   However, there are two\nexceptions: other locators are disregarded when sliding (they are slid over,\nand not counted as characters); and when there are no characters to the\nright of the locator when sliding rightward (resp. left and leftward),\nneither the locator nor any character moves.\n\nExamples follow. In the program `J(X)A`, if `(X)` were to slide leftward the\nresult would be `(X)JA` and if it were to slide rightward the result would\nbe `JA(X)`.\n\nIn `J(X)(C)A(D)`, if `(X)` were to slide rightward we would have\n`J(C)A(D)(X)`.\n\nIn `JA(X)`, if `(X)` were to slide rightward, we would still have\n`JA(X)`.\n\nFinally, in `JA(X)(Y)`, if `(X)` were to slide rightward, we would still\nhave `JA(X)(Y)`.\n\nAn entire slot slides leftward (resp. rightward) when both of its locators\nslide leftward (resp. rightward.)\n\nBuilt-in Slots\n--------------\n\nThe most central built-in slot is the _instruction slot_, from which is\nfetched the instruction to be executed on any particular rewrite step.  The\ndefault name of the instruction slot is `!`.  Therefore, in the program\n`(^!)M(!$)`, the next instruction to be executed will be `M`.  Further, in\nthe program ``(^`!)k(`!$)(^k)b(k$)``, the instruction slot, accessed\nindirectly by `` `! ``, is named `k`, and the next instruction to be executed\nis `b`.\n\nOther built-in slots are:\n\n* The _accumulator_, by default named `?`;\n* The _clipboard_, by default named `%`; and\n* The _selection_, by default named `/`.\n\nPursuant to this last built-in slot, when we say a substring is _selected_,\nwe mean that the selection locators are inserted on either side of it\n(`(^/)` on the left and `(/$)` on the right), and that all other occurrences\nof these locators elsewhere in the string are removed.\n\nExecution Model\n---------------\n\nAt each rewriting step, the contents of the instruction slot, called the\n_current instruction_, are examined.  The string is rewritten according to\nthe current instruction.  The instruction slot then slides rightward in the\nstring.\n\nExecution halts when there is no instruction slot in the program, or when\nthe contents of the instruction slot have zero length.\n\nWhen examining the current instruction to determine the command which is\nexecuted and how the string will be re-written, we interpret it as follows.\nWe ignore any locators in the current instruction, and we assume it to be\none character long — if it is longer, we only regard the leftmost\ncharacter in it.\n\n### Commands ###\n\n* `0` through `9` update the accumulator to the literal strings `0` through\n  `9`, respectively.\n* `X` (\"cut\") erases (updates with the zero-length string) the selection.\n* `C` (\"copy\") updates the contents of the clipboard with the contents of\n  the selection.\n* `V` (\"paste\") updates the contents of the selection with the contents of\n  the clipboard.\n* `S` (\"select\") selects the contents of the slot indirect by the\n  accumulator.\n* `A` (\"select all\") selects the contents of the accumulator.\n* `L` (\"left\") slides the left locator of the selection leftward.\n* `R` (\"right\") slides the left locator of the selection rightward.\n* `E` (\"end\") moves the left locator of the selection to immediately to the\n  left of the right locator of the selection, resulting in the selection\n  containing the zero-length string.\n* `F` (\"find\") searches everywhere in the contents of the accumulator for the\n  contents of the clipboard.  If found, that substring is selected.\n* `D` (\"drag-and-drop\") updates the contents of the accumulator with the\n  contents of the selection, then selects the contents of the accumulator.\n* `I` (\"input\") waits for a line to appear on standard input, then places it\n  (sans newline) in the accumulator.\n* `O` (\"output\") outputs the string in the accumulator to standard output,\n  followed by a newline.\n\nNote that the concepts \"standard input\" and \"standard output\" are defined\nsolely by the operating system.\n\n### Idioms ###\n\nWe pause to consider some useful idioms constructed from the commands\npresented thus far.\n\nAssume the inital program defines some slots such as `(^0)data(0$)` to\ncontain initial data.  That data can then be loaded into the accumulator\nwith the sequence `0SCAV`, and new data, say the literal string `1`, can be\nstored into slot `0` with `1AC0SV`.\n\nTo copy from any arbitrary slot (say `0`) to another (say `1`), we can say\n`0SC1SV`.\n\nAccessing a slot with a longer name, such as `(^123)xyz(123$)`, can be done\nwith the help of a free slot like `0` and a program fragment such as\n`1AC0SV2AC0SEV3AC0SEV0SCAVSD`.\n\nTo write data, say `(^8)foo(8$)`, into a slot whose name is stored in\nanother slot, such as `(^9)jim(9$)`, we can say: `8SC9SDSV`.\n\nFinally, a complete, if simple, program: the ubiquitous \"Hello, world!\" can\nbe accomplished very simply like so: `(^?)Hello, world!(?$)(^!)O(!$)`.\n\nConstructing Control Flow Mechanisms\n------------------------------------\n\nTo perform a conditional branch in the program, one would ensure there are\nslots at the start of each alternative block of code to execute: call them\n`α` and `β`.  One would then update slot `` `! `` to contain either `α` or\n`β`, making that slot the new instruction slot.\n\nUnfortunately, you can't do that in Pophery as it stands, basically because\nthere aren't enough built-in slots to say \"put the value from slot blah\ninto the slot named by the accumulator.\"  TODO: add another built-in slot,\nand an instruction to either swap its contents with, or copy its contents\nto or from, and existing slot.\n\nThe slots `α` (and of course `β` as well) could be anywhere in the program,\nso a backward branch, and thus a loop, may be affected.  The only issue is\nthat the `α` slot must be re-inserted each time, as, when it is used as the\ninstruction slot, it will begin to move rightward through the program.  Also,\nas it needs to have a different name from the instruction slot currently in\nuse, switching back and forth between two instruction slot names would be a\nnecessity of such a loop.\n\nPophery Carrier Format: \"Tranzy\"\n--------------------------------\n\nPophery also defines a file format for Pophery programs and their metadata;\nthis file format is called _Tranzy_.  A Tranzy file is a text file consisting\nof a number of lines.  The encoding of characters is not specified.  Each\nline may begin with a `#` character, or not.  Lines which do begin with `#`\nare \"comment\" lines in which metadata may be embedded; these are lines which\nare being carried in the Tranzy file, but which do not form any part of the\nPophery program.  The non-comment lines are concatenated (sans newlines, but\nincluding other whitespace) to form the Pophery program.\n\nTranzy does not currently define any metadata which can reside in comment\nlines, but acknowledges and permits metadata defined by external standards\n(de facto or otherwise).  An example Tranzy file is depicted below.\n\n    #!/usr/bin/my-pophery-interpreter -w\n    # encoding: UTF-8\n    0@SLX1@SL@SXS\n    (^0)(0$)(^1)!(1$)\n\nNotes\n-----\n\nPophery came more or less into its present form on or about September 6th,\n2010.  It has lain about since then, collecting dust.\n\nThe name _Pophery_ is a mutant hybrid of the ancient Greek _Porphyry_,\nmeaning \"purple\", and _Poreef_, itself a mutant hybrid of pork and beef\nfeatured in a certain _The Kids in the Hall_ skit.  (Arguably, my\n[Unlikely](http://catseye.tc/projects/unlikely/) language would have been a\nbetter candidate for the moniker \"Poreef\", but unfortunately, I missed that\nopportunity, and this is the way things turned out.)\n\nWhile working up to the current design, a design plateau was reached; it had\na more machine-language-like feel to it, with slots called the _accumulator_,\nthe _index slot_, and the _ancillary slot_.  (For posterity, I've called the\nlanguage that follows this design _Pophery version -1.0_, and have retained\nits implementation in this distribution as `minus-one.py`, but it is not my\nfocus of interest and will discuss it no further here.)  The ancillary slot\nhappened to have operations devised for it which resembled cut, copy, and\npaste, and was renamed the clipboard for this reason; then everything you\nsee now kind of followed from that.\n\nThe \"string rewriting\" part of the description kind of has a double meaning\nnow.  Not only is the imperative execution described in terms of string\nrewriting (to the point where you could probably implement it\nstraightforwardly, or nearly so, in a language like\n[Thue](http://catseye.tc/projects/thue/),) but the imperative instructions\nalso perform operations which are recognizably text editing — which is just\na politically correct way of saying \"string rewriting\", *n'est-ce pas*?\n\nTODO: Find a way to manipulate data satisfactorily.\n\nOne of the original goals of the language design was to support the\nconstruction of multiple control flow mechanisms from simple primitives.\nDue to time and concentration constraints, only the conventional\nlooping-by-backwards-branching mechanism of control flow was explored.\nHowever, we will speculate on two other mechanisms, which may be\nimplementable in Pophery or a modest extension thereof, in the next two\nparagraphs.\n\nTo affect SMITH-style self-extension, one would need only make sure there is\na slot named `β` located to the right of the currently-executing code, and\nthen write instructions into it.  The instruction slot will eventually slide\nrightward into it.  For authentic SMITH-like behavior, the instructions would\nbe written into `β` by having a slot `ζ` encompass the currently executing\nblock of code, and copying the contents of `ζ` wholesale into `β`.\n\nTo affect Muriel-style quine-continuation, one would need to establish a\nbuffer slot named `β`, write instructions into it piecemeal until it looks\nlike the desired next leg of the program, and then replace the entire\nrunning program with it.  This can be done by having a slot named `ζ`\nencompass the entire program, and copying `β` into it.  The only subtlety is\nthe instruction slot; once the contents of `β` have become the entire\nprogram, you will want the intended instruction slot in `β` to become the\nactive instruction slot, which means switching the instruction slot at the\nsame time `β` is copied into `ζ`.  This would probably necessitate an\nextension to Pophery.\n\nHappy re: righting!  \nChris Pressey  \nSeptember 6, 2010  \nEvanston, IL\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatseye%2Fpophery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcatseye%2Fpophery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatseye%2Fpophery/lists"}