{"id":20425413,"url":"https://github.com/catseye/flobnar","last_synced_at":"2025-04-12T18:55:34.272Z","repository":{"id":2703248,"uuid":"3696981","full_name":"catseye/Flobnar","owner":"catseye","description":"MIRROR of https://codeberg.org/catseye/Flobnar : This is what happens when you get Befunge-93 drunk","archived":false,"fork":false,"pushed_at":"2023-09-10T14:19:02.000Z","size":22,"stargazers_count":8,"open_issues_count":3,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-26T13:12:07.587Z","etag":null,"topics":["esolang","esoteric-language","esoteric-programming-language","fungeoid"],"latest_commit_sha":null,"homepage":"https://catseye.tc/node/Flobnar","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","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":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-03-12T16:17:07.000Z","updated_at":"2023-11-03T20:29:33.000Z","dependencies_parsed_at":"2022-08-28T12:22:26.539Z","dependency_job_id":null,"html_url":"https://github.com/catseye/Flobnar","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/catseye%2FFlobnar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catseye%2FFlobnar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catseye%2FFlobnar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catseye%2FFlobnar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/catseye","download_url":"https://codeload.github.com/catseye/Flobnar/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248618273,"owners_count":21134200,"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","fungeoid"],"created_at":"2024-11-15T07:13:12.318Z","updated_at":"2025-04-12T18:55:34.252Z","avatar_url":"https://github.com/catseye.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"Flobnar\n=======\n\n_Version 0.1, Chris Pressey, Oct 28 2011_\n\nOne day in September of 2011 -- though I'm not sure precisely which\none -- marked Befunge-93's 18th birthday.  That means that Befunge is\nnow old enough to drink in its native land of Canada.\n\nTo celebrate this, I thought I'd get Befunge-93 drunk to see what\nwould happen.\n\nWhat happened was _Flobnar_, an esolang which is in many respects a\nfunctional dual of Befunge-93; most of the symbols have analogous\nmeanings, but execution proceeds in a much more dataflow-like fashion.\n\nThis document describes Flobnar with a series of examples, presented\nin the format of Falderal 0.7 tests.\n\nConcepts\n--------\n\nA familiarity with Befunge-93 is assumed in this document.  Also,\nsome concepts need to be explained before the description of the\nexamples will make much sense.\n\nLike Befunge-93, Flobnar programs are held in a playfield -- a\ntwo-dimensional Cartesian grid of cells, each of which contains a\nsymbol.\n\nAny cell in a Flobnar playfield may be evaluated.  The meaning of\nthe evaluation of a cell depends on the symbol it contains.  In the\ncontext of execution, this symbol is called a term.\n\nExcept for the first term to be evaluated, all terms are \"evaluated\nfrom\" one of the four cardinal directions: north, south, east, and\nwest.  The direction provides context: a term may evaluate to a\ndifferent value depending on what direction it is evaluated from.\n\nWhen we say something about \"what the cell to the /d/ evaluates to\",\nwhere /d/ is a direction, it is implied that that cell is evaluated\nfrom the direction opposite to /d/.  So, \"what the cell to the north\nevaluates to\" means \"what the cell to the north evaluates to, when\nevaluated from the south.\"\n\nIn addition, when we say \"what the cell on the other side evaluates\nto\", we mean this to be relative to the direction the current term\nwas evaluated from.  So, if the term was evaluated from the east,\nthe \"cell on the other side\" refers to the cell to the west, as\nevaluated from the east.\n\nFlobnar is not a purely functional language; it permits input and\noutput, as well as self-modification, just like Befunge-93 does.\nFor this reason, order of evaluation should be completely defined.\n\nFlobnar Tests\n-------------\n\n    -\u003e Tests for functionality \"Interpret Flobnar program\"\n\n    -\u003e Functionality \"Interpret Flobnar program\" is implemented by\n    -\u003e shell command\n    -\u003e \"bin/flobnar %(test-body-file)\"\n\nBasics of Execution\n-------------------\n\nWhereas in Befunge-93 `@` indicates a stopping point of the program,\nin Flobnar, `@` indicates the starting point.  The program evaluates\nto whatever the `@` it contains evaluates to.  The `@` evaluates to\nwhatever is west of it evaluates to.\n\n    | 4@\n    = Result: 4\n\nThe program must contain one and only one @.\n\n    | 4\n    ? Program does not contain exactly one @\n\n    | 4@@\n    ? Program does not contain exactly one @\n\nSimple Constant Data\n--------------------\n\nAs in Befunge-93, single digits evaluate to the common decimal\ninterpretation of themselves as numbers.  You've already seen this\nfor 4, but it's true for all of them.\n\n    | 0@\n    = Result: 0\n\n    | 1@\n    = Result: 1\n\n    | 2@\n    = Result: 2\n\n    | 3@\n    = Result: 3\n\n    | 5@\n    = Result: 5\n\n    | 6@\n    = Result: 6\n\n    | 7@\n    = Result: 7\n\n    | 8@\n    = Result: 8\n\n    | 9@\n    = Result: 9\n\nPlayfield Traversal\n-------------------\n\nWhereas in Befunge-93 `\u003e\u003c^v` change the direction of the motion\nof the IP, in Flobnar these characters evaluate to what the\nappropriate adjacent cell evaluates to:\n\n    \u003c evaluates to whatever is west of it evaluates to\n    \u003e evaluates to whatever is east of it evaluates to\n    v evaluates to whatever is south of it evaluates to\n    ^ evaluates to whatever is north of it evaluates to\n\n    | 4\u003c\u003c\u003c\u003c\u003c@\n    = Result: 4\n\n    | \u003e\u003e\u003e\u003e\u003ev\n    | ^    v\n    | ^    4\n    | ^\u003c\u003c\u003c\u003c@\n    = Result: 4\n\nAlso, ' ' (blank space) evaluates to whatever the cell on the other\nside of it evaluates to.  So, for example, if evaluated from the\nsouth, it evaluates to what the north of it evaluates to.\n\n    | 4    @\n    = Result: 4\n\n    | \u003e    v\n    |       \n    |      4\n    | ^    @\n    = Result: 4\n\nCells which are not specified are considered to contain blank space.\n(In the example below, the two middle lines have nothing in them, not\neven blank space.)\n\n    |     v@\n    | \n    | \n    | 4   \u003c\n    = Result: 4\n\nLike Befunge-93, there is toroidal wrapping of evaluation: if we try\nto evaluate something outside the bounds of the playfield, we end up\nevaluating whatever is directly on the other side of the playfield.\nUnlike Befunge-93, however, the bounds of the playfield are determined\nsolely by the minimal bounding box that encompasses all the non-' '\nterms in the playfield.\n\n    | @4\n    = Result: 4\n\n    | v@\n    | \u003c  v\n    |   ^\u003c\n    |   4\n    = Result: 4\n\nThere's a \"Bridge\" term, similar to Befunge's `#` instruction.  It\nevaluates to whatever is one cell past the other side of it.\n\n    | 5     6#@\n    = Result: 5\n\n    |  7v @\n    | v8#\u003c\n    | \u003e#9 v\n    |   \u003e^ \n    |  ^  \u003c\n    = Result: 7\n\nAnd `#` is compatible with wrapping.\n\n    | #@   56\n    = Result: 5\n\nAnd we were serious when we said that thing about how the bounds of\nthe playfield are computed.\n\n    |             \n    |     v   @   \n    |    #\u003c  17   \n    |             \n    = Result: 1\n\nArithmetic\n----------\n\nThe `+` term evaluates whatever is to the north of it, then evaluates\nwhatever is to the south of it, and evaluates to the sum of those\ntwo resulting values.\n\n    | 5\n    | +@\n    | 7\n    = Result: 12\n\n    | 5\u003c\u003c    \n    |   +\u003c\u003c  \n    | 7\u003c\u003c +\u003c@\n    |    6\u003c  \n    = Result: 18\n\nThe `*` term evaluates whatever is to the north of it, then evaluates\nwhatever is to the south of it, and evaluates to the product of those\ntwo resulting values.\n\n    | 5\n    | *@\n    | 7\n    = Result: 35\n\nThe `-` term evaluates whatever is to the north of it (and we call that\n/a/), then evaluates whatever is to the south of it (and we call that /b/).\nIt evaluates to the difference, /a/ - /b/.\n\n    | 7\n    | -@\n    | 5\n    = Result: 2\n\nSubtraction resulting in a negative value.\n\n    | 1\n    | -@\n    | 9\n    = Result: -8\n\nThe `/` term evaluates whatever is to the north of it (and we call that\n/a/), then evaluates whatever is to the south of it (and we call that /b/).\nIt evaluates to the quotient of dividing /a/ by /b/.\n\n    | 8\n    | /@\n    | 2\n    = Result: 4\n\nInteger division rounds down.\n\n    | 9\n    | /@\n    | 2\n    = Result: 4\n\nDivision by zero evaluates to whatever the cell on the other side\nof the `/` term evaluates to.\n\n    |  9\n    | 7/@\n    |  0\n    = Result: 7\n\n    | v9#@\n    | \u003e/7\n    |  0\n    = Result: 7\n\nThe `%` term evaluates whatever is to the north of it (and we call that\n/a/), then evaluates whatever is to the south of it (and we call that /b/).\nIt evaluates to the remainder of dividing /a/ by /b/.  This operation is\ncalled \"modulo\".\n\n    | 8\n    | %@\n    | 3\n    = Result: 2\n\nModulo of a negative value has the sign of the dividend.\n\n    |  7\n    | 0%@\n    | +\u003c\n    | 3\n    = Result: 1\n\n    |  7\n    | 0%@\n    | -\u003c\n    | 3\n    = Result: 1\n\nModulo by zero evaluates to whatever the cell on the other side\nevaluates to.\n\n    |  9\n    | 7%@\n    |  0\n    = Result: 7\n\n    | v9#@\n    | \u003e%7\n    |  0\n    = Result: 7\n\nDecision Making\n---------------\n\n'Horizontal if', denoted `_`, checks what the cell on the other side\nof it evaluates to.  If that value is nonzero, it evaluates to what\nthe cell west of it evaluates to; otherwise, it evaluates to what the\ncell east of it evaluates to.  In either case, at most two evaluations\nare made.\n\n    |  0\n    | 5_9\n    |  ^@\n    = Result: 9\n\n    |   7\n    | \n    | 5 _ 9\n    | \n    |   ^@\n    = Result: 5\n\n    |   v\u003c\n    | \n    | 5 _ 9\n    | \n    |   7^@\n    = Result: 5\n\n'Vertical if', denoted `|`, checks what the other side of it evaluates to.\nIf that value is nonzero, it evaluates to what the cell north of it\nevaluates to; otherwise, it evaluates to what the cell south of it\nevaluates to.  In either case, at most two evaluations are made.\n\n    |  3\n    | 0|@\n    |  4\n    = Result: 4\n\n    |   3\n    | \n    | 9 | @\n    | \n    |   4\n    = Result: 3\n\n    |   3\n    | v   @\n    | \u003e | 9\n    | \n    |   4\n    = Result: 3\n\nThese \"if\"s can be used to evaluate a cell for its side-effects only.\nIn the following, the sum is evaluated, but the result is effectively\nthrown out, in preference to the zero.\n\n    | 90 \u003c\n    | +|@\n    | 9\u003e ^\n    = Result: 0\n\nLike Befunge-93, `!` is logical negation: it evaluates to zero if the\ncell on the other side evaluates to non-zero, and to one if the cell on\nthe other side evaluates to zero.\n\n    | 0!@\n    = Result: 1\n\n    | \u003e  v\n    | ^@ !\n    |    9\n    = Result: 0\n\nWe don't need greater than, because we can subtract one value\nfrom other, divide the result by itself (specifying a result of 0\nif the division is by zero), then add one, and check if that is\nnon-zero or not with a horizontal or vertical if.\n\nBut because Befunge-93 has it, we have it too.  The \u003ccode\u003e`\u003c/code\u003e term\nevaluates whatever is to the north of it (and we call that /a/), then\nevaluates whatever is to the south of it (and we call that /b/).  It\nevaluates to 1 if /a/ is greater than /b/, 0 otherwise.\n\n    | 8\n    | `@\n    | 7\n    = Result: 1\n\n    | 8\n    | `@\n    | 8\n    = Result: 0\n\n    | 8\n    | `@\n    | 9\n    = Result: 0\n\n`?` picks one of the cardinal directions at random and evaluates\nto whatever the cell in that direction evaluates to.  `?` should\nuse a fair distribution of the four possible choices, and should\nbe difficult to predict.  We will not present this as a testable\nexample program, because the Falderal test framework doesn't\nprovide a way to test that, currently.  (And it's not implemented\nyet, but never mind that.)  Instead, here is a plain example.\n\n     1\n    2?3#@\n     4\n\nThe above program should evaluate to 1 25% of the time, 2 25% of\nthe time, 3 25% of the time, and 4 the rest of the time.\n\nIntrospection and Self-Modification\n-----------------------------------\n\nJust like Befunge-93, program introspection and self-modification\nare fully supported.\n\nThe `g` term evaluates to the north to get an x coordinate, then\nto the south to get a y coordinate, and evaluates to the ASCII value\nof the symbol that's found in that cell in the playfield.  The origin\n(coordinates (0,0)) of the playfield is the upper-left corner of that\nbounding box I mentioned above, and x values increase to the right,\nand y values to the south.\n\n    | A0\n    |  g@\n    |  0\n    = Result: 65\n\nThe `p` term evaluates to the north to get an x coordinate, then\nto the south to get a y coordinate.  It then evaluates what is on\nthe other side of it to get a value.  It then alters the playfield\nin effect, by placing that value at that (x,y) coordinate.  The\ncoordinate system is the same as that used by `g`.  The `p` term\nalways itself evaluates to zero.\n\n    |    0\n    |   5p  @\n    |    0\n    = Result: 0\n\n    |    0\n    |  5 p  \u003c\n    |    0  +@\n    |    g  \u003c\n    |    0\n    = Result: 5\n\n    |    0\n    |  \u003e p 5\n    |  +@\n    |    0\n    |  \u003e g\n    |    0\n    = Result: 5\n\nWriting a space over an existing cell deletes that cell, and affects\nthe calculation of the bounds of the playfield.\n\n    | 85   5\n    | *p\u003c\n    | 40+@\n    |   \u003e  +\n    |      9\n    |      9\n    = Result: 18\n\n    |      5\n    | 85   #\n    | *p\u003c\n    | 40+@\n    |   \u003e  ^\n    |      6\n    |      9\n    = Result: 6\n\nWriting outside the bounds of the playfield expands those bounds.\nSince only cardinal directions are allowed in evaluation, the space\nis still topologically a torus; no Lahey-space-like construction\nis necessary.\n\n    |  99\u003e v  \n    | 7p*^@ \u003e\u003e#\n    |  16  \u003e+\n    |       \u003c^\n    = Result: 7\n\nEvery cell in the playfield can hold a signed, unbounded integer.\n\n    | c 00\n    |   -p  \u003c\n    |   90  +@\n    |    g  \u003c\n    |    0\n    = Result: -9\n\n    |  9\n    |  *\u003c 0\n    |  9* p  \u003c\n    |  *\u003c 0  +@\n    |  9  g  \u003c\n    |     0\n    = Result: 6561\n\n(One consequence of the above two facts is that there are at least\ntwo tactics available for demonstrating that Flobnar is Turing-\ncomplete; the playfield could be used as a tape in the simulation\nof a Turing machine, or two cells could be used as registers in\nthe simulation of a Minsky machine.)\n\nEvaluating a cell whose value is not the ASCII value of any of the\ncharacters which denote terms defined in this document is a\nruntime error, which results in the immediate termination of the\nprogram, without producing a result value.\n\n    9  \n    *\u003c5\n    9*p\u003c\n    *\u003c0+@7\n    9  \u003e v\n\nThe above program will result in a runtime error.\n\nFunctions\n---------\n\nThere's no real equivalent to Befunge-93's `:`, because there's no\nneed.  Common subexpressions can be shared geometrically.\n\n    | v\u003c\n    | 5+@\n    | ^\u003c\n    = Result: 10\n\nLikewise, there are no equivalents for `\\` and `$`.  Therefore, these\nsymbols have different meanings in Flobnar.\n\nOriginally, my idea for Flobnar included function values (lambda\nfunctions.)  But eventually these struck me as un-Befunge-like.\nA function is just some code you want to be able to evaluate more\nthan once without repeating verbatim.  And in the context of Befunge,\na function is just a part of the playfield.  It's already possible\nto execute the same part of the playfield from different points in\nyour program, using arrows; and in Flobnar this is even easier,\nsince evaluation of a part of th playfield \"remembers\" where it was\n\"evaluated from\".\n\nWhat's really useful in a function is that it can take an argument.\nSo I retained the idea of having arguments available -- a call stack.\nSurprisingly, it turned out to be similar to Befunge-93's stack, so I\nconsider that a bonus.\n\nThe `\\` term takes what to the south of it evaluates to, and uses\nthat as the argument as it \"applies\" the \"one-argument\" \"function\" on\nthe other side of it.  The `:` term evaluates to the current argument.\n\n    | 5\\@\n    |  0\n    = Result: 5\n\n    | :\n    | +\\@\n    | 54\n    = Result: 9\n\n    | v 1#  \\ @\n    | \u003e +      \n    |       \n    |   :   7  \n    = Result: 8\n\n    | \u003e v :\n    | ^@\u003e\\*\n    |    7:\n    = Result: 49\n\nIf no function is being applied, `:` evaluates to zero.\n\n    | :@\n    = Result: 0\n\nA function can call another function.  The outer function retains its\nargument after the inner function returns.\n\n    | 1\n    | +\\\u003c\n    | :4+\\@\n    |   :7\n    = Result: 12\n\nHellooooo, factorial!\n\n    | \u003e     v\n    | ^\\ \u003c   \n    |        \n    | :v    v   \\\u003c@\n    | -\u003c      : 6\n    | 1 :   \u003e *\n    |   -|    \u003c\n    |   11\n    = Result: 720\n\nThe `$` term removes the top value from the call stack and \"calls\" the\n\"function\" on the other side with this reduced call stack.  This, in\neffect, lets you write functions which take multiple arguments.\n\n    | :\n    | +\\\u003c\u003c\\@\n    | :7  9\n    = Result: 14\n\n    | :\n    | $\n    | +\\\u003c\u003c\\@\n    | :7  9\n    = Result: 16\n\nInput and Output\n----------------\n\nFlobnar supports input and output of ASCII characters, although\nbecause the Falderal test framework doesn't handle tests with\ninput very well (and because I would have to refactor my beautiful\nimplementation in a major way, either threading an IO monad\nthrough all the evaluation functions, or converting those\nfunctions to continuation-passing style), they are only briefly\ncovered here, with only plain examples.  My apologies if they are\nnot very well defined; a future version of the language and the\ntest suite may attempt to rectify that.\n\nThe `,` term evaluates what is on the other side of it and\noutputs the character with that ASCII value to standard output.\nThe `,` term itself evaluates to zero.  So, the following\nexample should output the two-character string 'Hi', and evaluate\nto a result of zero.\n\n    8\n    *,\u003c  5\n    9 +@\u003e*\n      \u003e,*7\n        3\n\nNote that the convention of the result of each program being\nprinted after \"Result: \", in the tests here, is merely a convention.\nWhat the implementation does with the result of the main Flobnar\nexpression is outside the domain of Flobnar proper.  (Of course,\nit is extremely useful if it can make this value available to the\noutside world somehow, for example by outputting it after the\nstring \"Result: \".)\n\nIn similar vein, attempting to output and integer outside the range\nof ASCII is, as of this writing, undefined.\n\nThe `~` term reads a character from standard input and evaluates\nto the ASCII value of that character.  So, the following program\nreads two characters, and evaluates to 1 if they are the same\ncharacter, and 0 if they are not.\n\n    ~\n    -!@\n    ~\n\nPutting these two together, the following program should be the\nvirtual equivalent of the Unix `cat` utility:\n\n    ~,\u003c\n      +\u003c@\n      \u003e^\n\nOther Things\n------------\n\nThe terms denoted by all characters not mentioned in the above\nsections are undefined.  For maximum compatibility with future\nversions of Flobnar, they should not appear in a Flobnar program.\n\nSpecifically, I have a vague idea that extensions to Flobnar\nmay be indicated by the presence of a certain characters or\ncombination of characters immediately and non-wrappingly to\nthe east of the `@` term.  So, best to leave that cell blank or\nmake it an arrow.\n\nAs you've probably noticed, I've referred to the character set\nas ASCII in this entire document.  I actually mean \"printable\nASCII\" -- control characters and whitespace (aside from space\nand linefeed) are not defined, and (except for specific cases\naddressed in this document) an implementation is not expected\nto load them into the playfield.  If at some point Flobnar is\never extended into the realm of Unicode, source files will be\nexpected to be encoded in UTF-8.\n\nTo be really true to Befunge-93, Flobnar should support `.` for\noutputting integers formatted in conventional decimal notation,\nand `\u0026` for inputting integers in that format too.  They may\nappear in a future version of the language.  On the other hand,\nthey may not.  I can't see the future.\n\nAfter all that, the only thing from Befunge-93 that's missing a\ncounterpart in Flobnar is stringmode.  I originally added it to\nFlobnar, having each string evaluate to a string value, but that\ncomplicated evaluation rules by adding a new type that would have\nto be handled everywhere.  I afterwards considered making it more\nlike ':', pushing the ASCII value of each character onto the call\nstack, but decided that was a little awkward too.  So, for\nsimplicity, I just left it out of this version.\n\nThat's All\n----------\n\nHappy bar-hopping!  \nChris Pressey  \nEvanston, Illinois  \nOctober 28, 2011\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatseye%2Fflobnar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcatseye%2Fflobnar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatseye%2Fflobnar/lists"}