{"id":16022371,"url":"https://github.com/horazont/while-to-sed","last_synced_at":"2025-03-15T07:24:24.592Z","repository":{"id":66139566,"uuid":"171344887","full_name":"horazont/while-to-sed","owner":"horazont","description":"A transpiler from the academic turing-complete WHILE language to sed","archived":false,"fork":false,"pushed_at":"2020-06-09T19:19:43.000Z","size":22,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-21T22:29:23.468Z","etag":null,"topics":["compiler","sed","transpiler","while-language"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"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/horazont.png","metadata":{"files":{"readme":"README.md","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":"2019-02-18T19:39:12.000Z","updated_at":"2023-01-30T04:57:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"8d8b0b94-7a9b-490a-aadf-44344c0ffd46","html_url":"https://github.com/horazont/while-to-sed","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/horazont%2Fwhile-to-sed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/horazont%2Fwhile-to-sed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/horazont%2Fwhile-to-sed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/horazont%2Fwhile-to-sed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/horazont","download_url":"https://codeload.github.com/horazont/while-to-sed/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243697761,"owners_count":20333012,"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":["compiler","sed","transpiler","while-language"],"created_at":"2024-10-08T18:23:29.745Z","updated_at":"2025-03-15T07:24:24.565Z","avatar_url":"https://github.com/horazont.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Transpiler to sed\n\nThis repository contains two different languages which are compiled to sed.\nBoth of them are turing complete and support arbitrary-precision non-negative\ninteger arithmetics.\n\n* The [`WHILE` language](#while)\n* A [custom assembly language](#assembly)\n\n## Input/Output format\n\nThe state of each program (no matter the input language) must be initialised\ncompletely. It is given by binary numbers separated by hashes. Thus, an\ninput of `0#10000000000#0#0#0` initialises all but the second variable to zero;\nthe second variable is initialised to 1024 (binary `10000000000`).\n\nThe output format is the same as the input format.\n\nThe heading of the generated program contains the names of the variables in the\norder they are expected in the input.\n\n## Assembly\n\nThe `asmsed.py` program converts a custom assembly-style language to a sed\nprogram.\n\n### Usage\n\n```\n$ python3 asmsed.py -o logn.sed logn.ass\n$ chmod +x logn.sed\n$ echo '1000000000#1010' | ./logn.sed\n10\n```\n\nThis example program calculates the integer logartihm to an arbitrary base. In\nthis case, it is invoked to calculate the logarithm 512 (`1000000000`) to the\nbase 10 (`1010`). The output is rounded down, so it prints 2 (`10`).\n\n### Examples\n\n- [`logn.ass`](logn.ass) Calculate the floored integer logartihm.\n- [`div.ass`](div.ass) Divide two integer numbers, returning the floored\n  result.\n\n### Machine model\n\nThe machine corresponding to the instruction set is a stack machine with\nan arbitrarily high stack of non-negative integer numbers.\n\nOn the sed level, the numbers are encoded as ASCII-binary (that is, sequences\nof ASCII `0` and `1`) and the stack slots are separated by hashes (`#`).\n\n### Input/Output format\n\nThe input is the initial stack of the program as ASCII binary numbers (see\nabove) separated by hashes. The usage example above initialises the stack with\ntwo elements, `1000000000` (512) and `1010` (10) on the stack, with 10 being\nthe topmost element.\n\nThe output format is the same as the input format. The entire stack at program\nexit is printed.\n\n### Language\n\n#### Comments\n\nAnything following a semicolon (`;`) in a line is treated as a comment.\n\n#### Whitespace\n\nNon-newline is used to separate different tokens in a single line. A newline\nends a mnemonic.\n\n#### Mnemonics / Instruction set\n\n##### load\n\n```\nload STACKPOS\n```\n\nLoads the value from the given STACKPOS (counting from the bottom starting at\n0) and pushes it onto the stack. The element at STACKPOS is left in place.\n\n##### store\n\n```\nstore STACKPOS\n```\n\nStores the topmost stack value into the given stack position (counting from the\nbottom starting at 0) and removes the topmost value from the stack.\n\n##### pushc\n\n```\npushc NUMBER\n```\n\nPushes the given constant NUMBER onto the stack.\n\n##### dup\n\n```\ndup\n```\n\nLoads the topmost stack element and pushes it onto the stack, effectively\nduplicating it.\n\n##### pop\n\n```\npop\n```\n\nDiscard the topmost element from the stack.\n\n##### inc\n\n```\ninc\n```\n\nIncrement the topmost stack element in-place.\n\n##### dec\n\n```\ndec\n```\n\nDecrement the topmost stack element in-place.\n\n##### add\n\n```\nadd\n```\n\nAdd the two topmost stack elements, remove them from the stack and push the\nresult of the addition onto the stack.\n\n##### sub\n\n```\nsub\n```\n\nSubtract the topmost element from the second-topmost element of the stack,\nremove both from the stack and push the result.\n\nIf the subtraction underflows, it saturates to zero.\n\n##### Labels\n\n```\n.LABELNAME\n```\n\nNot an instructino per-se, but a label to which a jump can be executed.\n\nThe labelname must be a valid sed label name and must not start with an\nunderscore.\n\n##### jmp\n\n```\njmp LABELNAME\n```\n\nJump to the given label unconditionally.\n\n##### jz\n\n```\njz LABELNAME\n```\n\nIf the topmost stack value is zero, pop it from the stack and jump to the\ngiven label.\n\n## WHILE\n\nThe `whilesed.py` program converts a WHILE program (see below) to a sed program.\n\n### Usage\n\n```\n$ python3 whilesed.py -o outfile.sed log10.while\n$ chmod +x outfile.sed\n$ echo '0#10000000000#0#0#0' | ./outfile.sed\n11#0#0#0#1010#0\n```\n\n### Input/Output format\n\nThe state of the program must be initialised completely. It is given by binary\nnumbers separated by hashes. The above example initialises all but the second\nvariable to zero; the second variable is initialised to 1024 (binary\n`10000000000`).\n\nThe output format is the same as the input format. In the above example, the\nfirst output is 3 (binary `11`), which is the correct (rounded down) for\nlog10(1024).\n\nThe heading of the generated program contains the names of the variables in\nthe order they are expected in the input.\n\n### WHILE language\n\nThe WHILE language has been described in academia, but I don’t know the original source to quote. If you know it, let me know. It is an extension of the [LOOP](https://en.wikipedia.org/wiki/LOOP_(programming_language)) language.\n\n#### Identifiers\n\nIdentifiers in this WHILE implementation match the following regular expression (since you are looking at this, I assume that you  know at least the very basics of regular expressions): `x_?([0-9]+)`. The prefix (`x_?`) is ignored. The capture group is converted to an integer. This is the actual identifier of the variable. So `x_2`, `x2`, `x00002` and `x_002` refer all to the same variable.\n\n#### Variables\n\nYou do not need to declare variables.\n\nUndeclared variables are initialised to zero.\n\nAll variables are non-negative integers. There is no upper bound on the value.\n\n#### Statements\n\nThe following statements exist in the language:\n\n##### Assign constant\n\nAssigns a constant integer to a variable. Example (assigns 2 to `x3`):\n\n```\nx3 := 2\n```\n\n##### Assign variable / copy\n\nCopy the value of one variable to another:\n\n```\nx2 := x3\n```\n\n##### Assign-and-add\n\nAdd/subtract a value from a variable and assign the result to a (possibly different) variable:\n\n```\nx1 := x2 - 3\n```\n\nNote: since the values can never be negative, negative results are clamped to 0.\n\n##### Loop\n\nExecute a block of statements a semi-fixed amount of times. The value of the loop variable is evaluated when the loop is *first* entered. The loop executes as many times as the value of the variable at enter time; modifying the variable during loop execution has no effect on the number of iterations.\n\n```\nloop x1\n  ... more statements ...\nend\n```\n\n##### While\n\nExecute a block of statements until a variable becomes zero.\n\n```\nwhile x1\n  ... more statements ...\nend\n```\n\n##### If\n\nExecute a block of statements once if a variable is non-zero.\n\n```\nif x1\n   ... more statements ...\nend\n```\n\nControl structures can be arbitrarily nested.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhorazont%2Fwhile-to-sed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhorazont%2Fwhile-to-sed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhorazont%2Fwhile-to-sed/lists"}