{"id":13779587,"url":"https://github.com/luser-dr00g/inca","last_synced_at":"2025-05-11T13:30:53.522Z","repository":{"id":15291387,"uuid":"18020990","full_name":"luser-dr00g/inca","owner":"luser-dr00g","description":"an APL-style array calculator/interpreter in C based on the J-incunabulum, extended to allow propagating specifications a+2+a\u003c3, more functions and operators.","archived":false,"fork":false,"pushed_at":"2016-12-02T05:52:05.000Z","size":1507,"stargazers_count":29,"open_issues_count":2,"forks_count":0,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-08-03T18:14:09.955Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","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/luser-dr00g.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}},"created_at":"2014-03-22T22:12:12.000Z","updated_at":"2024-04-11T11:11:42.000Z","dependencies_parsed_at":"2022-07-31T03:48:53.291Z","dependency_job_id":null,"html_url":"https://github.com/luser-dr00g/inca","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/luser-dr00g%2Finca","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luser-dr00g%2Finca/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luser-dr00g%2Finca/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luser-dr00g%2Finca/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/luser-dr00g","download_url":"https://codeload.github.com/luser-dr00g/inca/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225056719,"owners_count":17414191,"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":[],"created_at":"2024-08-03T18:01:06.743Z","updated_at":"2024-11-17T15:30:32.012Z","avatar_url":"https://github.com/luser-dr00g.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"newest (incomplete) version is code-named 'olmec'. See olmec/README.md .\n\ninca\n====\n\nThis document describes the interpreter implemented in inca.c,\nor inca \"1\". A revised and expanded version is implemented in inca2.c,\nand documented in README2.md and in \n[the wiki page](https://github.com/luser-dr00g/inca/wiki).\n\nA third rewrite has begun in inca3.c. Its documentation is (predictably)\nnamed README3.md. \n\nThe newest (incomplete) version is code-named 'olmec'. See olmec/README.md .\n\nThe final two commits of inca.c illustrate the problem inherent in\nthe design. Add the new feature (user-function call without the ' or '' \nfunction-call functions) broke the existing code in tea.sh\n(the \"use-case\"). And so, the project was begun anew with a better design.\n\nIt may surprise or amuse readers to learn that even the earliest inca.c was not my first brush with APL. Some years ago I read a great deal of the J wiki and then could not get it to compile and completely forgot. A few years later, having issued a programming challenge and received a few J answers, I looked again and wrote two postscript programs to simulate what I thought was going on. https://gist.github.com/luser-dr00g/9382217 and https://gist.github.com/luser-dr00g/9502855\n\nAnd some time later I stumbled upon some very old source code of mine which attempted (anticipated?) a similar arbitrary-dimensional system in C++. https://groups.google.com/d/topic/comp.lang.apl/3VNPOzcQMMI/discussion\n\nSummary:\nmonadic functions: + id  { size  ~ iota  \u003c box  # shape  \u003e unbox  | abs  ! not  @ rev  \ndyadic function: + add  { from  ~ find  \u003c assign  # reshape  , cat  ; rowcat  - minus  . time  \n\u0026nbsp;\u0026nbsp;    * pow  % divide  | mod  \u0026 and  ^ or  = eq  / compress  \\ expand  \nmon ops: / reduce  (.-|/\\+\u003e\u003c)@ transpose    dy op: . matrix product  \nvariable ` (backtick) is set to result of the previous command. (was underscore)\n\nAn online version is available courtesy of Thomas Baruchel.\nhttp://baruchel.hd.free.fr/apps/apl/inca/ \nwhich is awesome and even handles cut+paste.\n\nThe program is based on and directly derived from the J-incunabulum,  \n      http://www.jsoftware.com/jwiki/Essays/Incunabulum  \nand extended to allow propagating specifications \"a+2+a\u003c3\",\nnew functions minus,times,unbox. multi-digit integers.\nidentity element for monadic use of minus,times,cat.\nMost extensions have been incorporated \"ad-hoc\", with\nan attempt to maintain consistency of style, balanced \nagainst a need (demand) for more commentary and more visible\ntype identifiers.\n\nThe name \"inca\" was chosen for its similarity to \"incunabulum\",\nas well as its obvious (to me) decomposition \"In C, A\",\nas well as the apparent similarity between array-structured data\nand the ancient Incan data-storage device, the quipu.\nhttp://en.wikipedia.org/wiki/Quipu\n\nThe file inca.c compiles for me with cygwin32 gcc.\nThe code does not consistently adhere to any particular\nversion of the C standard, and may fail to compile with -pedantic,\nor any other options to enforce standards-conformance.\n\nI first found the J incunabulum through this SO question:\nhttp://stackoverflow.com/questions/13827096/how-can-i-compile-and-run-this-1989-written-c-program\nAnd I've added links to various explanatory pages as comments to that question, and a bugfix \nfor the original. Here are the helpful links:\nhttp://www.jsoftware.com/papers/AIOJ/AIOJ.htm  \nhttps://groups.google.com/d/msg/sayeret-lambda/Oxffk3aeUP4/QEuZocgVh5UJ  \nhttp://archive.vector.org.uk/trad/v094/hui094_85.pdf  \n\nInca has been submitted for critique on comp.lang.c and and comp.lang.apl.\nAnd *some* of the advice given has been followed. It has not been tested\nwith a 64-bit intptr_t. The code may make 32bit assumptions, although I've\ntried to be careful not to do this. I may not have been completely succesful.\nThe basis of the interpreter is the ability to treat a pointer as an integer\nand pack them in the same-sized fields. Additionally, it assumes that pointer\nvalues may be distinguished from character values from their integer \nrepresentations. This assumption is not guaranteed by the standard, but \nappears empirically to be true on my cygwin and ubuntu gnu linux testbeds.\nThe original code also assumed that these pointer values will be positive,\nwhich is empirically *not* true on cygwin. Not sure about ubuntu, the code\nwas fixed to use abs(intptr) before the range::type comparison well before\nit was ported.\n\nInca will also accept command-line arguments into the program. These are\navailable in the 'a' variable as a box-array of command-string arrays.\nAlso included with the distribution is the small lib.inca file which\naccumulates a few functions that arose in postings to comp.lang.apl.\nIf inca is invoked thusly:\n\n     ./inca `cat lib.inca`\n\nThen the library can be executed by putting the box-array a in a box '\u003c',\nmaking it executeable '$', and executing it ';'.\n\n               ;$\u003ca\n\nWhich should respond with the friendly message:\n\n     2:11 \n     lib_loaded\n\nWith the simple code representation of small integers for operators,\nascii for variables and other non-operator punctuation, and pointers\n(boxed arrays, which here are just scalars (array rank=0)), code can \nbe generated and executed on the fly. The r function in lib.inca\nillustrates this:\n\n     r\u003c:(40.'iy);(1+~\u003cy);((0{:\").'iy);((0{:u).'iy);(@~\u003cy);(41.'iy);((0{:;).'iy-1),0\n\nThe basic structure here is a series of parenthesized expressions which are \nstrung together with ; (rowcat). (40.'iy) makes a vector of y left parens.\n(1+~\u003cy) makes a boxed iota vector 1..y. (0{:\") is the quote literal, used the\nsame way the 40 was for left paren. Since double-quote \" is a function,\nits code representation is not the same as its ascii representation, so we extract\nit from a short code sequence which starts at the colon and goes until the closing\nparen, so just the double-quote *function*. ((0{:u).'iy) is the same, but with \nthe 'u' variable, which could be accessed by ascii, if you want to, or by pulling\nit out of a short code sequence. (@~\u003cy) gives a reversed box iota y-1..0. \n(41.'iy) is a vector of closing parens. And the final row is y-1 semicolons, and\na final terminating null.\n\nThis produces the transpose of several expresions (j\"uk); with j and k varying.\nAnd it can be executed by transposing, ravelling, making executable and then\nexecuting. ;$,\\@ which the s function does.\n\nExecuting the s function calls r to generate a procedure to produce a triangular\nmatrices by a run-length encoded representation, built using iotas, directly\ninto the form of function calls to the function u which takes two numbers \nand produces a row of the matrix.\n\nFunctions can also call themselves recursively.\n\nFibonacci function:\n\n     f\u003c:;(y\u003e1){(\u003c:1);\u003c:('fy-1)+'fy-2\n\nFactorial function:\n\n     f\u003c:;(y\u003e1){(\u003c:1);\u003c:y.fy-1\n\nIn the run-length-encoded triangular matrix example, the rows were all the\nsame length, so rowcat has an easy time to combine rows. But here, the two\ncode sequences\n\n     :1\n     :('fy-1)+'fy-2\n\nare different lengths. So we box them, so rowcat doesn't screw things up.\n(FIXME: fix rowcat to pad unequal widths).\n\n     \u003c:1\n     \u003c:('fy-1)+'fy-2\n\nrowcat them together `((...);...)`, select one using a boolean expression `(y\u003e1){`, and execute\nthe resulting expression `;`.\n\nAnd also *not* executing a command-string prints the string, so:\n\n        :Hello World!\n    Hello World!\n\n\nRecalling the syntax for *executing* code from the command-line.\n\n       ;$\u003ca\n\nThis illustrates a means by which \"multi-line\" functions may\nbe conveniently constructed, via a confusing arrangement of\nvaguely-defined concepts like \"box\" and \"box-array\".\nThe text lines of the file from `cat file` are, again,\ndefined in the variable a as a box-array, an array of pointers,\nof command-strings. To execute the box-array as a whole, it\nmust be put into a single box. (Errmm. This feels like an \nartificial restriction, and it is with difficulty that I document\nthe current behavior of the implementation here...)\n\nFollowing this pattern, one might define a multi-statement \nfunction in the same manner, as an executable box of a box-array\nof command strings.\n\n        f\u003c$\u003c(\u003c:a\u003c1);(\u003c:b\u003c2);(\u003c:c\u003c3)\n\nExecuting ;f should then be equivalent to the separate statements.\n\n        a\u003c1\n        b\u003c2\n        c\u003c3\n\nImplements monadic functions m  mW\n\n     + identity   +1  =\u003e  1\n     { size      1 1 1  =\u003e  3\n     ~ iota       ~9   =\u003e   0 1 2 3 4 5 6 7 8\n     \u003c box        \u003c1 1 1  =\u003e   \u003c1 1 1  (bad example)\n     # shape      #~9  =\u003e  9\n     \u003e unbox      \u003e\u003c1 1 1  =\u003e   1 1 1\n     | absolute    |-12   =\u003e   12\n     ! not         !0 1 0   =\u003e   1 0 1\n     @ reverse     @~9    =\u003e   8 7 6 5 4 3 2 1 0\n     : yield array of remaining command string\n     ; execute command string array\n     $ convert array to command-string type\n     'w  call function w with y as right arg\n         function may be a variable containing code (with colon :), eg. square\n             s\u003c:y.y\n             's6\n        36\n         or a parenthesized expression, without colon :\n             '(y.y)6\n        36\n                                                            \n\ndyadic functions d  AdW\n\n     + plus\n     { from       2 3{@~9   =\u003e   6 5\n     ~ find       6 5~@~9   =\u003e   2 3\n     \u003c assign if a is a var (not really a function, but an interpreter action) \n     # reshape\n     , cat \n     ; rowcat\n     - minus   (monadic: a=0)\n     . times   (monadic: a=1)\n     * power   (monadic: a=2)  \u003c-- this will be e with floating-point\n     % divide  (monadic: a=1)  \u003c-- this will make more sense with floating-point\n     | modulus   (reverse of C: w%a, divisor on the right)\n     \u0026 and \n     ^ or \n     = equals?\n     ! not-equal?\n     : match\n     \u003c less-than   (if a is not a var, see assign above)\n     / compress\n     \\ expand\n     \"w  call function w with x as left arg and y as right arg\n         function may be a variable containing code (with colon :), eg x+1-y\n             f\u003c:x+1-y\n             3\"f2\n        2\n         or a parenthesized expression, without colon :\n             3\"(x+1-y)2\n        2\n\nmonadic operators\n\n     / reduce  f/W  =\u003e w0 f (w1 f (w2 f ( ... wn-2 f wn-1)))\n     \\ scan    f\\W  =\u003e (w0 f w1), ((w0 f w1) f w2), ... ) f wn-2) f wn-1)\n     @ transpose   .@  identity transpose\n                   -@  vertical transpose\n                   |@  horizontal transpose\n                   \\@  y=x transpose\n                   /@  y=-x transpose\n                   +@  horz then vert\n                   \u003e@  horz then y=x\n                   \u003c@  horz then y=-x\n\ndyadic operator\n\n     . matrix product Af.gW =\u003e f/Ag\\@W\n       ( @ for the left function designates \"jot-dot\", a null-scan over the matrix product )\n        eg. plus over times:       +..\n            plus over plus:        +.+\n            addition table:        @.+\n            multiplication table:  @..\n\nover multidigit numbers and variables  \n     \u003cpre\u003e`\u003c/pre\u003e (backtick), and [a-z]   \n\u003cpre\u003e`\u003c/pre\u003e (backtick) is set to the result of the previous line.   (was underscore)\n\nThe interpreter also implements a non-greedy \"cat\" for \nnumber vectors separated by spaces. Hence `1 2 3+~3` =\u003e `1 3 5`\nwhere `~` is the zero-based iota. Spaces must only be used between\nnumbers. You may not pad operators with extra space or it will be\nmisinterpreted.\n\nIf the length of the command string exceeds 998 characters,\nthe behavior is undefined.\n\nIf array operands have incompatible sizes, the behavior\nis undefined.\n\nExample sessions: \n\nmonadic functions.\n\n    josh@Z1 ~/inca\n    $ !.\n    ./inca\n            +5\n\n    5 \n            {1 2 3\n    1 \n    3 \n            ~9\n    9 \n    0 1 2 3 4 5 6 7 8 \n            ~0\n    0 \n\n            \u003c12\n\n    \u003c \n    12 \n            #1 2 3;4 5 6\n    2 \n    2 3 \n            |-25\n\n    25 \n            !4\n\n    0 \n            !0\n\n    1 \n            \\@1 2 3;4 5 6;7 8 9;10 11 12\n    3 4 \n    1 4 7 10 \n    2 5 8 11 \n    3 6 9 12 \n            \\@4 3#1+~12\n    3 4 \n    1 4 7 10 \n    2 5 8 11 \n    3 6 9 12 \n            @`\n    3 4 \n    12 9 6 3 \n    11 8 5 2 \n    10 7 4 1 \n\n    josh@Z1 ~/inca\n    $ \n\nExample session: dyadic functions and operators.  \n(output has been augmented with a type-specifier then colon : then dims)\n\n    $ ./inca\n            2 3+7 6\n    0:2 \n    9 9 \n            1{52 53 54\n    0:\n    53 \n            5~4+~9\n    0:\n    1 \n            4+~9\n    0:9 \n    4 5 6 7 8 9 10 11 12 \n            a\u003c10\n    0:\n    10 \n            b+a+b\u003c6\n    0:\n    22 \n            b\n    0:\n    6 \n            ~64\n    0:64 \n    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 \n            8 8#`\n    0:8 8 \n    0 1 2 3 4 5 6 7 \n    8 9 10 11 12 13 14 15 \n    16 17 18 19 20 21 22 23 \n    24 25 26 27 28 29 30 31 \n    32 33 34 35 36 37 38 39 \n    40 41 42 43 44 45 46 47 \n    48 49 50 51 52 53 54 55 \n    56 57 58 59 60 61 62 63 \n            `,~9\n    0:73 \n    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 0 1 2 3 4 5 6 7 8 \n            12 6#`\n    0:12 6 \n    0 1 2 3 4 5 \n    6 7 8 9 10 11 \n    12 13 14 15 16 17 \n    18 19 20 21 22 23 \n    24 25 26 27 28 29 \n    30 31 32 33 34 35 \n    36 37 38 39 40 41 \n    42 43 44 45 46 47 \n    48 49 50 51 52 53 \n    54 55 56 57 58 59 \n    60 61 62 63 0 1 \n    2 3 4 5 6 7 \n            5.-2\n    0:\n    -10 \n            2*3\n    0:\n    8 \n            3*2\n    0:\n    9 \n            *3\n    0:\n    8 \n            **3\n    0:\n    256 \n            2*2*3\n    0:\n    256 \n            +/~9\n    0:\n    36 \n            ./~9\n    0:\n    0 \n            ./1+~9\n    0:\n    362880 \n            ./1+~4\n    0:\n    24 \n            1.2.3.4\n    0:\n    24 \n            1 2 3 4+..5 6 7 8\n    0:\n    70 \n            1.5\n    0:\n    5 \n            `+2.6\n    0:\n    17 \n            `+3.7\n    0:\n    38 \n            `+4.8\n    0:\n    70 \n\n\n\nExample session: general transpose operator.\n\n    $ ./inca\n            3 4#~12\n    0:3 4 \n    0 1 2 3 \n    4 5 6 7 \n    8 9 10 11 \n            \u003e@`\n    0:4 3 \n    8 4 0 \n    9 5 1 \n    10 6 2 \n    11 7 3 \n            \\@`\n    0:3 4 \n    8 9 10 11 \n    4 5 6 7 \n    0 1 2 3 \n            -@`\n    0:3 4 \n    0 1 2 3 \n    4 5 6 7 \n    8 9 10 11 \n            \u003c@`\n    0:4 3 \n    3 7 11 \n    2 6 10 \n    1 5 9 \n    0 4 8 \n            /@`\n    0:3 4 \n    8 9 10 11 \n    4 5 6 7 \n    0 1 2 3 \n            -@`\n    0:3 4 \n    0 1 2 3 \n    4 5 6 7 \n    8 9 10 11 \n            +@`\n    0:3 4 \n    11 10 9 8 \n    7 6 5 4 \n    3 2 1 0 \n            |@`\n    0:3 4 \n    8 9 10 11 \n    4 5 6 7 \n    0 1 2 3 \n            -@`\n    0:3 4 \n    0 1 2 3 \n    4 5 6 7 \n    8 9 10 11 \n            .@`\n    0:3 4 \n    0 1 2 3 \n    4 5 6 7 \n    8 9 10 11 \n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluser-dr00g%2Finca","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fluser-dr00g%2Finca","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluser-dr00g%2Finca/lists"}