{"id":28146837,"url":"https://github.com/susam/fxyt","last_synced_at":"2026-01-27T00:37:45.543Z","repository":{"id":213021909,"uuid":"732832336","full_name":"susam/fxyt","owner":"susam","description":"Tiny, esoteric, stack-based, postfix, canvas colouring language with only 36 simple commands","archived":false,"fork":false,"pushed_at":"2025-02-16T00:31:43.000Z","size":240,"stargazers_count":125,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-14T23:14:45.057Z","etag":null,"topics":["canvas2d","graphics","programming","stack"],"latest_commit_sha":null,"homepage":"https://susam.net/fxyt.html","language":"HTML","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/susam.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE.md","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-12-18T00:29:47.000Z","updated_at":"2025-05-11T16:51:05.000Z","dependencies_parsed_at":"2024-03-27T20:26:20.792Z","dependency_job_id":"b40a6c14-0de4-4de9-ad0e-5f65f451c82e","html_url":"https://github.com/susam/fxyt","commit_stats":null,"previous_names":["susam/fxyt"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/susam/fxyt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Ffxyt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Ffxyt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Ffxyt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Ffxyt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/susam","download_url":"https://codeload.github.com/susam/fxyt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Ffxyt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28793928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T21:49:50.245Z","status":"ssl_error","status_checked_at":"2026-01-26T21:48:29.455Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["canvas2d","graphics","programming","stack"],"created_at":"2025-05-14T23:14:41.551Z","updated_at":"2026-01-27T00:37:45.531Z","avatar_url":"https://github.com/susam.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"FXYT\n====\n\nFXYT is a tiny canvas colouring language that consists of 36 simple\nstack-based commands.  The input code is evaluated for each cell of a\n256x256 graphical canvas.  The colour of each cell is determined by\nthe result of the evaluation.  Here is an extremely simple FXYT code:\n\n```\nXY^\n```\n\nThe result looks like this:\n\n[![Screenshot of XOR pattern][IMG1]][DEMO1]\n\nSee some more demos here:\n\n- [Demo 1](https://susam.net/fxyt.html#XYxTN1srN255pTN1sqD)\n- [Demo 2](https://susam.net/fxyt.html#XYaTN1srN255pTN1sqN0)\n- [Demo 3](https://susam.net/fxyt.html#XYoTN1srN255pTN1sqDN0S)\n- [Demo 4](https://susam.net/fxyt.html#XYpTN1srN255pTN1sqD)\n- [Demo 5](https://susam.net/fxyt.html#XYN256sTdrD)\n- [Community Demos][demo.html]\n\nVisit https://susam.net/fxyt.html to write your own code!\n\nThis project is inspired by Martin Kleppe's [Tixy][TIXY] project.\nWhile Tixy supports JavaScript expressions to determine the size and\ncolour of circles in a 16x16 grid, FXYT comes with its own tiny,\nstack-based language that is written in postfix notation.  Further,\nFXYT provides a 256x256 grid of cells each of which can be painted\nwith an arbitrary colour determined by the result of the evaluation of\nthe input code.\n\nThis project is intentionally minimal in nature.  It is intended to be\na creative code golfing playground that offers the challenge of\ncrafting interesting visuals with a limited set of commands.\n\nFXYT stands for *function of x, y and t* and it may be pronounced\n/fɒksɪt/ (\"foxit\").\n\n[IMG1]: https://susam.github.io/blob/img/fxyt/fxyt-0.1.0-xor.png\n[DEMO1]: https://susam.net/fxyt.html#XYx\n[TIXY]: https://github.com/aemkei/tixy\n[DRAW1]: https://susam.net/fxyt.html\n[demo.html]: http://susam.github.io/fxyt/demo.html\n\n\nContents\n--------\n\n* [Coordinates](#coordinates)\n* [Data Stack](#data-stack)\n* [Loop Control Stack](#loop-control-stack)\n* [Colours](#colours)\n* [Integers](#integers)\n* [Arithmetic](#arithmetic)\n* [Division by Zero](#division-by-zero)\n* [Comparison](#comparison)\n* [Inversion](#inversion)\n* [Bitwise Operations](#bitwise-operations)\n* [Clip](#clip)\n* [Duplicate](#duplicate)\n* [Pop](#pop)\n* [Swap](#swap)\n* [Rotate](#rotate)\n* [Loops](#loops)\n* [Frame Interval](#frame-interval)\n* [Print Data Stack](#print-data-stack)\n* [Idioms](#idioms)\n* [Common Mistakes](#common-mistakes)\n* [Constraints](#constraints)\n* [Distributable Links](#distributable-links)\n* [FAQ](#faq)\n* [Licence](#licence)\n* [Support](#support)\n* [See Also](#see-also)\n\n\nCoordinates\n-----------\n\n### X\n\nEnter the following code in the input field:\n\n```\nX\n```\n\nThe output consists of a blue gradient spread across the canvas that\ngradually changes from black on the left hand side to bright blue on\nthe right hand side.\n\nThe input code is evaluated for each cell in a 256x256 graphical\ncanvas.  Each cell has a coordinate which we represent here as (x, y)\nwhere x represents the column of the cell and y represents the row of\nthe cell.  The value of x varies from 0 to 255 as we move from the\nleftmost column to the rightmost column.  Similarly, the value of y\nvaries from 0 to 255 as we move from the bottommost row to the topmost\nrow.\n\nThus the cell at the bottom-left corner of the canvas has the\ncoordinate (0, 0).  Similarly, the cell at the top-right corner of the\ncanvas has the coordinate (255, 255).\n\nThe command `X` pushes the x-coordinate value of the current cell to\nthe data stack.  When the above piece of code is evaluated for each\ncell in the canvas, we get the result 0 for all cells at x = 0, the\nresult 1 for all cells at x = 1 and so on up to the final column where\nthe result is 255 for all cells at x = 255.  The result obtained for\neach cell determines the colour of each cell.  In particular, in this\nexample, the result obtained for each cell determines the blue\ncomponent of the colour of each cell.  As a result, all cells at x = 0\nappear black and all cells at x = 255 appear bright blue.\n\n\n### Y\n\nNow enter the following code:\n\n```\nY\n```\n\nWe get a blue gradient again.  However, this time the blue gradient\nchanges from black to bright blue as we move gradually from the\nbottommost row of cells at y = 0 to the topmost row at y = 255.\n\n\n### T\n\nFinally, enter the following code:\n\n```\nT\n```\n\nNow we get an output that changes with time where the colour of the\nentire canvas changes from black to blue gradually in 256 iterations.\n\nWe call any input code that contains at least one occurrence of the\n`T` command as time-dependent code.  Such code is evaluated in 256\niterations represented with the time variable t that changes from t =\n0 to t = 255.  By default, there is a 100 ms interval between two\niterations.  This interval is known as the frame interval.\n\nThus we can say that any time-dependent code is evaluated for each\ncell at the coordinate (x, y, t) where the x-value and y-value\nrepresent the location of the cell as explained before and t\nrepresents the current iteration.\n\nThe command `T` pushes the t-value of the current iteration to the\nstack.  When the above piece of code is evaluated, we get the result 0\nfor all cells at t = 0, the result 1 for all cells at t = 1 and so on\nup to the final iteration when the result is 255 for all cells at t\n= 255.  As a result, the colour of all the cells change from dark to\nbright blue gradually with each iteration.\n\n\nData Stack\n----------\n\nThe runtime environment contains exactly one data stack.  Most FXYT\ncommands manipulate this data stack.  This data stack can contain at\nmost 8 integer values.  It is an error to push a value to the stack\nwhen the stack is full.\n\nIn the remainder of this document, sometimes we will provide examples\nof stack.  Such examples will be written using an array notation where\nthe elements that appear on the left are at the bottom of the stack\nand the elements on the right are at the top of the stack.  For\nexample, a stack that contains (from bottom to top) the values 10, 20,\n30 and 40 will be written as [10, 20, 30, 40].  If we push 50 to this\nstack, we will write the resulting stack as [10, 20, 30, 40, 50].\n\n\nLoop Control Stack\n------------------\n\nApart from the data stack, there is a loop control stack.  Unlike the\ndata stack, the loop control stack cannot be manipulated directly.\nThe loop control stack is an internal implementation detail of the two\nlooping commands `[` and `]` introduced later in this document.  Each\nentry in the loop control stack is a pair of integers: loop counter\nand loop body position.  This stack can contain at most 8 such\nentries.  As a result, while executing nested loops, at most 8 nested\nloop bodies can be entered.  It is an error to enter a loop that is 9\nlevels deep.  To learn more about loops, see the section\n[Loops](#loops).\n\n\nColours\n-------\n\nCommands of FXYT manipulate the data stack.  As mentioned before, the\ninput code is evaluated for each cell at (x, y) for time-independent\ncode.  If the input code is time-dependent, then it is evaluated for\neach cell at (x, y, t).\n\nAt the end of evaluation of the code for each cell, the top 3 values\nof the data stack is inspected to determine the red, blue and green\n(RGB) components of the colour of the cell.  The value at the top of\nthe data stack is used as the blue component, the second value from\nthe top is the green component and the third value from the top is the\nred component.\n\nSuppose the data stack looks like the following after the evaluation of the\ninput code for a certain cell: [10, 20, 30, 40, 50].  Then the colour\nused to paint that cell in RGB notation is rgb(30, 40, 50).\n\nFor example, consider the following code:\n\n```\nYYY\n```\n\nWhen this code is evaluated for each cell of the canvas, the\ny-coordinate value of the cell is pushed to the data stack three\ntimes.  At the end of each evaluation, the three values at the top of\nthe data stack determine the RGB components of the colour.  Since they\nare all equal, we get a shade of grey for each cell.\n\nIf less than three values exist on the data stack at the end of\nevaluation, then values for the missing RGB components are set to 0.\nFor example, consider the following code:\n\n```\nYY\n```\n\nAt the end of evaluation, the data stack contains only two values, so\nthey decide the values of the blue and green components.  The red\ncomponent is set to 0.  Thus each cell gets a shade of cyan.  Finally\nconsider this code:\n\n```\nY\n```\n\nThis time we get only one value on the data stack at the end of each\nevaluation and that only value determines the blue component of the\ncolour of each cell.\n\nIf the data stack is empty at the end of evaluation, then all three\ncomponents of the RGB colour is set to 0 and the corresponding cell is\npainted black.  For example, consider the following code:\n\n```\nXP\n```\n\nThe `X` command pushes the x-coordinate value to the data stack but\nthen the `P` command pops it off the data stack.  Thus the data stack\nbecomes empty at the end of each evaluation.  As a result, all cells\nare painted black.  In fact, when the input code is empty, the\nevaluation of the empty code results in an empty stack thus leading to\na black canvas too.\n\nThe three values at the top of the data stack must be integers between\n0 and 255, inclusive, because they are interpreted as the red, blue\nand green components of the resulting RGB colour.  If any value among\nthese three values is negative, it is an error.  Similarly, if any of\nthese values exceed 255, it is an error.\n\nIf an error occurs during the evaluation of the code, the error is\ndisplayed in the status panel and the entire canvas is painted red.\n\n\nIntegers\n--------\n\nThe commands `X`, `Y` and `T` push integer values to the data stack\nthat correspond to the x, y and t coordinates respectively of the\ncurrent cell.  It is also possible to place arbitrary integers on the\nstack by using `N` along with the digit commands introduced in this\nsection.\n\nThe following code pushes the integer 0 to the data stack:\n\n```\nN\n```\n\nThe `N` command stands for *nil* which pushes the nil value (the zero\nvalue) to the data stack.\n\nA digit command like `1`, `2`, etc. multiplies the value at the top of\nthe data stack with 10 and adds the integer value of the digit to it.\nFor example, consider the following code:\n\n```\nN125\n```\n\nThere are 4 distinct commands in this code: `N`, `1`, `2` and `5`.\nThe evaluation of these commands occur as follows:\n\n 1. `N` pushes the value 0 to the data stack.\n 2. `1` multiplies the value 0 at the top of the data stack with 10\n    and then adds 1 to it to get 1.  Thus the value at the top of the\n    stack is now 1.\n 3. `2` multiplies the value 1 at the top of the data stack with 10\n    and then adds 2 to it to get 12.\n 4. `5` multiplies the value 12 at the top of the data stack with 10\n    and then adds 5 to it to get 125.\n\nThus at the end of the evaluation, the value at the top of the data\nstack is 125.\n\nThe command sequence consisting of `N` followed by some digits is an\nidiom for composing an integer on the data stack.  For example, the\nfollowing code places the three integers 147, 112 and 219 to the\nstack.\n\n```\nN147N112N219\n```\n\nThe data stack looks like [147, 112, 219] at the end of the evaluation\nand each cell of the canvas gets painted with the RGB colour (147,\n112, 219) thereby making the entire canvas look medium purple.\n\n\nArithmetic\n----------\n\nThe commands `+`, `-`, `*`, `/` and `%` perform arithmetic operations.\nEach command pops two values from the data stack, performs the\narithmetic operation and pushes the result back to the data stack.\n\nFor example, the following code leaves the result 120 on the data\nstack.\n\n```\nN70N50+\n```\n\nThe command sequence `N70` leaves the integer 70 on the data stack.\nThen the command sequence `N50` puts another integer 50 on the data\nstack.  Finally, the command `+` replaces both integers with their\nsum.\n\nThe commands `+`, `-`, `*`, `/` and `%` perform the addition,\nsubtraction, multiplication, division and modulus operations\nrespectively.  These commands are explained with the following\nexamples:\n\n| Example | Result  | Remarks                                    |\n|---------|---------|--------------------------------------------|\n| `XY+`   | X + Y   |                                            |\n| `XY-`   | X - Y   |                                            |\n| `XY*`   | X * Y   |                                            |\n| `XY/`   | X / Y   | Fractional part is discarded               |\n| `XY%`   | X mod Y | Result lies between 0 and Y - 1, inclusive |\n\nNote that in case of subtraction, the value at the top of the data\nstack is subtracted from the second value from the top of the data\nstack.  Similarly, in case of division and modulo, the value at the\ntop of the data stack divides the second value from the top of the\ndata stack.\n\nAlso note that all arithmetic operations result in integers.  Thus any\nfractional part is discarded from the result.  For example, the\nfollowing code leaves the result 7 on the data stack:\n\n```\nN73N10/\n```\n\nThe following code leaves the result -7 on the data stack:\n\n```\nNN73-N10/\n```\n\nThe modulo command leaves a nonnegative remainder that is less than\nthe divisor.  For example, the following code leaves the remainder 2\n(not -3) on the data stack:\n\n```\nNN8-N5%\n```\n\n\nDivision by Zero\n----------------\n\nThe FXYT evaluator has different modes for handling division by zero.\nThe default mode is mode 0 in which any division by zero is considered\nan error.  When such an error occurs, the evaluator halts and the\nentire canvas is painted red.\n\nIn mode 1, when division by zero occurs while evaluating the code for\na certain cell, the error is ignored and the cell is painted black.\n\nIn mode 2, when division by zero occurs while evaluating the code for\na certain cell, the error is ignored and the cell is painted red\ninstead.\n\nThe command `M` can be used to change modes.  Each `M` increments the\nmode number.  It is an error to increment the mode number to 3.\n\nThe following code demonstrates the default behaviour which leads to\nan error because a division by zero occurs at the coordinate (0, 0):\n\n```\nXY%\n```\n\nThe following code demonstrates mode 1 where division by zero error is\nignored and the cells at which such errors occur are painted black.\n\n```\nMXY%\n```\n\nThe following code demonstrates mode 2 where division by zero error is\nignored and the cells at which such errors occur are painted red.\n\n```\nMMXY%\n```\n\nIn practice, `M` (mode 1) may be useful to get a nice output with\ndivision by zero errors ignored.  The command sequence `MM` (mode 2)\non the other hand may be useful to conspicously display all cells\nwhere division by zero error occurred.\n\n\nComparison\n----------\n\nThe commands `=`, `\u003c` and `\u003e` perform comparison operations.  Each\ncommand pops two values from the data stack, compares them and pushes\nthe result of the comparison back to the data stack.  The result of\neach comparison command is explained in table below:\n\n| Example | Result                  |\n|---------|-------------------------|\n| `XY=`   | 1 if X = Y, 0 otherwise |\n| `XY\u003c`   | 1 if X \u003c Y, 0 otherwise |\n| `XY\u003e`   | 1 if X \u003e Y, 0 otherwise |\n\nFor example, the following code leaves the value 1 on the data stack:\n\n```\nXX=\n```\n\nThe following code leaves the value 0 on the data stack:\n\n```\nN1N2=\n```\n\nThe following code draws a blue diagonal along the cells (x, y) where\nx = y:\n\n```\nXY=N255*\n```\n\n\nInversion\n---------\n\nThe command `!` may be used to invert the result of comparison.\nPrecisely speaking, this command changes the integer at the top of the\nstack according to these two simple rules:\n\n- If the integer at the top of the data stack is 0, change it to 1.\n- Otherwise change it to 0.\n\nThe following code paints all cells blue except the ones on the x = y\ndiagonal:\n\n```\nXY=!N255*\n```\n\n\nBitwise Operations\n------------------\n\nThe commands `^`, `\u0026` and `|` perform bitwise operations on integer\nvalues.  Each command pops two values from the data stack, performs\nbitwise operations on them and pushes the result back to the data\nstack.  The result of each command is explained in the table below:\n\n| Example | Result          |\n|---------|-----------------|\n| `XY^`   | X bitwise-XOR Y |\n| `XY\u0026`   | X bitwise-AND Y |\n| `XY\\|`  | X bitwise-OR Y  |\n\n\nClip\n----\n\nThe command `C` clips the value at the top of the data stack between 0\nand 255.  This can be useful for ensuring that a value at the top of\nthe data stack is always a valid colour value.\n\nConsider the following code:\n\n```\nXY+\n```\n\nThis code produces an error at the cell (1, 255) where this code\nevaluates to the result 266.  However, adding the command `C` as\nfollows resolves the error:\n\n```\nXY+C\n```\n\nNow whenever the result exceeds 255, the `C` command clips the result\nto 255 thus leading to a valid value for the blue component of the\ncell's colour.\n\nSimilarly, while the code `XY-` produces an error, the code `XY-C`\ndoees not.  Whenever the result is negative, the command `C` clips the\nresult to 0.\n\n\nDuplicate\n---------\n\nThe command `D` duplicates one item on the data stack.  It pushes a\ncopy of the value at the top of the data stack to the top.  For\nexample, consider the following code:\n\n```\nN1N2N3D\n```\n\nThe resulting stack is [1, 2, 3, 3].\n\n\nPop\n---\n\nThe command `P` pops one item off the top of the data stack.  The\npopped value is dropped.  For example, consider the following code:\n\n```\nN1N2N3P\n```\n\nThe resulting stack is [1, 2].\n\n\nSwap\n----\n\nThe command `S` swaps the two values at the top of the data stack.\nFor example, consider the following code:\n\n```\nN1N2N3S\n```\n\nThe resulting stack is [1, 3, 2].\n\n\nRotate\n------\n\nThe command `R` rotates the three values at the top of the data stack\nsuch that the third value from the top of the data stack moves to the\ntop, the value at the top of the data stack moves to the second place\nfrom the top and the second value from the top of the data stack moves\nto the third place from the top.  For example, consider the following\ncode:\n\n```\nN1N2N3N4N5R\n```\n\nThe resulting stack is [1, 2, 4, 5, 3].\n\n\nLoops\n-----\n\nLooping is supported with the commands `[` and `]`.  Each time `[` is\nencountered, the evaluator picks a loop counter from the data stack\nand remembers the code position after the `[` as the beginning of the\nloop body.  It maintains this information in the loop control stack.\nThe loop control stack is not directly accessible to the programmer.\nIt is an internal implementation detail of the commands `[` and `]`.\n\nTo elaborate, the command `[` pops off one value from the data stack\nand uses this value as the loop counter.  The command that comes after\nthe `[` is considered to be the beginning of the loop body.  If the\nloop counter is a positive integer, the loop body is entered.\nOtherwise, a corresponding `]` is found (nested `[` and `]` pairs are\nskipped) and the evaluator skips ahead to the command after the\ncorresponding `]`.\n\nThe command `]` decrements the loop counter of the current loop.\nAfter decrementing the loop counter, if its value is still positive,\nthen the evaluator jumps back to the beginning of the current loop's\nbody.  Otherwise, the evaluator exits the loop.  While exiting a loop,\nthe current loop's data is removed from the loop control stack.\n\nConsider the following input code:\n\n```\nNN5[N10+]\n```\n\nAt first, `N` pushes the integer 0 to the data stack.  We will refer\nto this place of the data stack where 0 has been pushed as the\n*initial place*.  The remainder of the code will increment the value\nin this initial place.  The command sequence `N5` places the integer 5\non the stack.  Then `[` pops off 5 from the data stack, uses it as the\nloop counter and begins a loop.  Each iteration of the loop executes\n`N10+` which adds the integer 10 to the value in the initial place.\nEach time `]` is encountered, the loop counter is decremented by 1 and\nif the loop counter is still 0, the evaluator jumps back to the\nbeginning of the loop body.  As a result, the loop containing `N10+`\nis executed 5 times before the loop counter becomes 0 and the loop is\nexited.  Thus the value at the initial place is incremented by 50.\nWhen the evaluation completes, the value 50 is left on the data stack.\n\nHere is an example of nested loops that leaves the value 200 on the\ndata stack.\n\n```\nNN5[N10[N4+]]\n```\n\n\nFrame Interval\n--------------\n\nThe frame interval determines the time interval between two\nconsecutive iterations of the evaluator for time-dependent code.  The\ndefault frame interval is 100 ms.  The frame interval may be changed\nwith the command `F`.  This command pops an integer value from the top\nof the data stack.  It is an error if the popped value is negative.\nIf the popped value is nonnegative, it is considered to be a candidate\nframe interval expressed in milliseconds.  The frame interval thus\nobtained during the evaluation of the cell (0, 0) is set as the frame\ninterval between the current iteration and next iteration of\nevaluation.\n\nFor example, the following code sets the frame interval to 1000 ms and\nexecutes a time-dependent code:\n\n```\nN1000FXT^\n```\n\nRemember that the input code is evaluated for each cell.  It is\npossible to write code such that the evaluation of the code for\ndifferent cells leads to different frame intervals.  As explained\nearlier, it is the frame interval set in the evaluation of cell (0, 0)\nthat determines the frame interval for the next iteration of\nevaluation.  For example, consider the following time-dependent code:\n\n```\nXY+N200+FT\n```\n\nIn the above example, the command `F` pops an integer value 200 while\nthe code is evaluated at the cell (0, 0).  However it pops an integer\nvalue 710 when the same code is evaluated at the cell (255, 255).  The\nframe interval for the next iteration of evaluation is thus 200 ms\n(not 710 ms).\n\nThe renderer for time-dependent code tries to schedule each iteration\nof the evaluation in such a manner that the average frame interval\nequals the set frame interval.  However, if the frame interval is set\nto a very small value (say, less than 100 ms or so), the renderer may\nfail to maintain the set frame interval on an average, especially,\nwhen the time to render the canvas exceeds the chosen frame interval.\n\n\nPrint Data Stack\n----------------\n\nThe command `W` provides a very minimal debugging facility.  It prints\nthe current coordinate followed by the data stack to the status panel\nand halts evaluation.\n\nType the following code as the input:\n\n```\nXYW\n```\n\nThe following data should appear in the status panel:\n\n```\n(0, 0) -\u003e [0, 0]\n```\n\nDuring the evaluation of the code at coordinate (0, 0), the `W`\ncommand prints the coordinate (0, 0) followed by the data stack [0, 0]\nand halts the evaluation.\n\nA more typical requirement may be to find out what the input code\nevaluates to at a particular coordinate.  This can be accomplished by\ncombining comparison commands with looping commands.  Here is an\nexample that shows the result of evaluating `XY^` at the coordinate\n(7, 9):\n\n```\nXY^XN7=YN9=\u0026[W]\n```\n\nFor each cell, first `XY^` is evaluated and the result is left on the\nstack.  Then `XN7=` compares if x-coordinate value equals 7 and pushes\nthe result (either 1 or 0) to the data stack.  Similarly, `YN9=`\ncompares if the y-coordinate value equals 9 and pushes the result\n(either 1 or 0) to the data stack.  Then `\u0026` pops both the comparison\nresults and combines them with the bitwise AND operation and pushes\nthe result to the data stack.  Note that this command pushes 1 if both\ncomparisons earlier evaluated to 1, otherwise 0 is pushed to the\nstack.  Thus the following loop body is entered if and only if x = 7\nand y = 9.  As soon as the loop body is entered, `W` writes the\ncurrent coordinate (7, 9) and the result 14 (the bitwise XOR of 7 and\n9 is 14) and halts the evaluation.\n\n\nIdioms\n------\n\nThe following idioms may be useful while writing FXYT code:\n\n- To place an arbitrary positive integer on the data stack, write `N`\n  followed by the decimal digits of the integer.  For example, `N105`\n  places the integer 105 on the data stack.  The code `N105` may be\n  informally read as the *number 105*.  See the section\n  [Integers](#integers) to learn more about why this works.\n\n- To place an arbitrary negative integer on the data stack, write `NN`\n  followed by the digits of the integer followed by `-`.  For example,\n  `NN105-` places the integer -105 on the data stack.  The code\n  `NN105-` may be informally read as the *negative number 105*.\n\n- To increment an integer at the top of the data stack, write `N1+`.\n  Similarly, to decrement an integer at the top of the data stack,\n  write `N1-`.\n\n- To check if the top two values on the data stack are unequal, write\n  `=!`.  This replaces the two values at the top of the data stack\n  with 1 if they are unequal, 0 otherwise.  See section\n  [Inversion](#inversion) for details.\n\n- To execute a block of code conditionally, push 1 on the data stack\n  if the block should be executed and 0 otherwise and then write a\n  loop with the code block in it.  For example, the code `YN10=[N255]`\n  places the integer 255 on the data stack if the y-coordinate value\n  equals 10.\n\n\nCommon Mistakes\n---------------\n\n- Forgetting to write `N` before entering a new integer is a common\n  mistake.  For example, the code `X1+` does not push x-coordinate\n  value and increment it by 1.  Instead it is an error.  Remember that\n  `1` (a digit command) multiplies the existing number at the top of\n  the data stack with 10 and then adds 1 to it.  Thus `X1` effectively\n  replaces the integer x on the stack with 10x + 1.  The `+` command\n  then fails to add two integers at the top of the data stack because\n  the data stack contains only one integer.  The correct input code\n  may be something like `XN1+` instead.  Always remember to write `N`\n  while forming a new integer on the data stack.\n\n\nConstraints\n-----------\n\nThe reference implementation that comes with this project enforces the\nfollowing constraints:\n\n- Whenever a command produces an integer result, the result must not\n  not exceed 2147483647 and it must not be less than -2147483648.\n\n- The input code must not exceed 1024 bytes in length.\n\n- The number of commands executed to evaluate the colour for a cell\n  must not exceed 1000.\n\nIf any of these contraints are violated during evaluation, the\nevaluation halts with an error.\n\n\nDistributable Links\n-------------------\n\nThe reference implementation provides distributable links when the\ninput code is 64 bytes or less in length.  Note that the\nimplementation allows code up to a maximum length of 1024 bytes.\nHowever, no distributable link is generated when the code length\nexceeds 256 bytes.  Thus code that does not exceed 256 bytes in length\nhas a special status in the reference implementation.\n\nThe distributable link encodes the input code and appends it as a URL\nfragment to the address of the current page.  Copy the URL with the\nencoded input code embedded in it from the address bar of the web\nbrowser in order to share it with others.  When the recipient of the\nURL opens it with their web browser, the implementation reads the code\nembedded in the URL, decodes it and executes it.\n\n\nFAQ\n---\n\n 1. Can you add feature X to this project?\n\n    I have no intention of adding new features to this project.  The\n    language defined and implemented by this project is intentionally\n    minimal.  Inspired by esoteric programming languages with concise\n    instruction sets, this tiny drawing language is meant to serve as\n    a challenge for creating interesting visuals using a limited set\n    of commands.\n\n\nLicence\n-------\n\nThis is free and open source software.  You can use, copy, modify,\nmerge, publish, distribute, sublicence and/or sell copies of it, under\nthe terms of the MIT Licence.  See [LICENSE.md][L] for details.\n\nThis software is provided \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nexpress or implied.  See [LICENSE.md][L] for details.\n\n[L]: LICENSE.md\n\n\nSupport\n-------\n\nTo report bugs or ask questions, [create issues][ISSUES].\n\n[ISSUES]: https://github.com/susam/fxyt/issues\n\n\nSee Also\n--------\n\nSee [Andromeda Invaders](https://github.com/susam/invaders), a\n1980s-arcade-style game written using HTML5, Canvas and Web Audio.\n\nSee [CFRS[]](https://github.com/susam/cfrs), an extremely minimal\nturtle graphics language with only 6 simple commands.\n\nSee [this demo page][demo.html] for FXYT community demos.\n\n\n\u003c!--\nRelease Checklist\n-----------------\n\n- Update version in package.json.\n- Update version in HTML (1 place).\n- Update copyright in HTML (1 place).\n- Update copyright in LICENSE.md.\n- Disable logging.\n- Update CHANGES.md.\n- Run: the following commands:\n\n  npm run lint\n  git status\n  git add -p\n\n  VER=\u003cVER\u003e\n  git commit -em \"Set version to $VER\"\n  git tag $VER -m \"FXYT $VER\"\n  git push origin main $VER\n\n  git remote add cb https://codeberg.org/susam/fxyt.git\n  git push cb --all\n  git push cb --tags\n  git push cb main:pages\n--\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusam%2Ffxyt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsusam%2Ffxyt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusam%2Ffxyt/lists"}