{"id":13577729,"url":"https://github.com/eudoxia0/magma","last_synced_at":"2025-04-10T01:11:40.396Z","repository":{"id":20282988,"uuid":"23556312","full_name":"eudoxia0/magma","owner":"eudoxia0","description":"Extending C with cmacro","archived":false,"fork":false,"pushed_at":"2020-08-04T20:24:13.000Z","size":160,"stargazers_count":336,"open_issues_count":1,"forks_count":11,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-10T01:11:02.050Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"apache/carbondata","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eudoxia0.png","metadata":{"files":{"readme":"README.rst","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-09-01T21:30:57.000Z","updated_at":"2025-04-07T14:14:49.000Z","dependencies_parsed_at":"2022-07-25T07:30:06.371Z","dependency_job_id":null,"html_url":"https://github.com/eudoxia0/magma","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/eudoxia0%2Fmagma","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eudoxia0%2Fmagma/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eudoxia0%2Fmagma/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eudoxia0%2Fmagma/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eudoxia0","download_url":"https://codeload.github.com/eudoxia0/magma/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137888,"owners_count":21053775,"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-01T15:01:23.876Z","updated_at":"2025-04-10T01:11:40.376Z","avatar_url":"https://github.com/eudoxia0.png","language":"C","funding_links":[],"categories":["C","Other projects"],"sub_categories":[],"readme":"################################\nMagma: `cmacro`_ extensions to C\n################################\n\n.. contents::\n    :local:\n    :depth: 2\n\n.. _cmacro: https://github.com/eudoxia0/cmacro\n\n********\nOverview\n********\n\nC is a tremendously useful language: It compiles everywhere, is generally fast,\nhas a very long history and a stable standard, and comes with few bedrock\nabstractions.\n\nHigher-level languages, like Common Lisp and Haskell, provide excellent\nmetaprogramming systems and a very expressive type system, but have the cost of\nvarious bedrock abstractions like garbage collection, dynamic typing (In the\ncase of Lisp), and exception handling.\n\ncmacro provides a middleground: It bridges the power and control of C with the\nhigh-level metaprogramming systems of Lisp. This library uses cmacro to extend\nthe capabilities of the C language.\n\n*****\nUsage\n*****\n\nOnce you've `built and installed`_ cmacro, simply put these files in a directory\nwhere they can be included by cmacro.\n\n.. _built and installed: https://github.com/eudoxia0/cmacro#installing\n\n*********\nFunctions\n*********\n\nAnonymous Functions\n===================\n\nSyntax\n------\n\n:code:`lambda (\u003cargs\u003e*) -\u003e \u003cret\u003e { \u003cbody\u003e* }`\n\nDescription\n-----------\n\nDefines an anonymous function, returning a pointer to it.\n\nExamples\n--------\n\n.. code-block:: c\n\n   cmacro_import \"fn/lambda.c\"\n\n   int main() {\n     int array[] = {423, 61, 957, 133, 969,\n                    829, 821, 390, 704, 596};\n\n     qsort(array, 10, sizeof(int),\n           lambda (const void* a, const void* b) -\u003e int\n           { return *(int*)a - *(int*)b; });\n     for(size_t i = 0; i \u003c 10; i++){\n       printf(\"%i \", array[i]);\n     }\n     return 0;\n   }\n\n\nLazy Evaluation\n===============\n\nSyntax\n------\n\n- :code:`delay \u003cexpr\u003e`\n- :code:`force \u003cexpr\u003e`\n\nDescription\n-----------\n\n:code:`delay` takes an expression :code:`expr` and delays its computation until\nthe required time. :code:`force` takes this computation and executes it,\nreturning its value.\n\nExamples\n--------\n\n.. code-block:: c\n\n   force (delay 1) == 1;\n\n***********\nType System\n***********\n\nType-Inferenced Variables\n=========================\n\nSyntax\n------\n\n:code:`var \u003cname\u003e = \u003cvalue\u003e`\n\nDescription\n-----------\n\nDefines an implicitly-typed variable :code:`var`, giving it the value\n:code:`value`. It is not possible to define a variable without an initial value.\n\nExamples\n--------\n\n.. code-block:: c\n\n   /* Input */\n   cmacro_import \"type/var.c\"\n\n   void f() {\n     var a = 10;\n     var b = 3.14;\n   }\n\n   /* Output */\n   void f() {\n     typeof(10) a = 10;\n     typeof(3.14) b = 3.14;\n     /* The above is, in fact, valid */\n   }\n\nAlgebraic Data Types\n====================\n\nSyntax\n------\n\nDescription\n-----------\n\nExamples\n--------\n\n.. code-block:: c\n\n   #include \u003cstdio.h\u003e\n\n   cmacro_import \"type/adt.c\"\n\n   data Token {\n     Integer { int i; };\n     String  { char* str; };\n   }\n\n   int main() {\n     Token a, b;\n     construct(a, Token -\u003e Integer) { 10 };\n     construct(b, Token -\u003e String) { \"test\" };\n     switch(a.type) {\n       case TokenInteger:\n         return a.Integer.i;\n         break;\n       case TokenString:\n         puts(b.String.str);\n         break;\n     }\n   }\n\nTuples\n======\n\nSyntax\n------\n\nDescription\n-----------\n\nExamples\n--------\n\n.. code-block:: c\n\n   /* Input */\n   cmacro_import \"type/tuple.c\"\n\n   typedef tup(int, int) pair;\n\n   pair divrem(int n, int d) {\n     return (pair){n/d, n%d};\n   }\n\n   /* Output */\n   typedef struct { int first; int second; } pair;\n\n   pair divrem(int n, int d) {\n     return (pair){n/d, n%d};\n   }\n\n****************\nAnaphoric Macros\n****************\n\nAnaphoric macros store the output of an important argument (Like the condition\nin the :code:`if` statement) in a variable named :code:`it` so they can be\naccessed in the statement body.\n\n:code:`if`\n==========\n\nSyntax\n------\n\n- :code:`aif \u003ccond\u003e \u003ctrue-branch\u003e`\n- :code:`aif \u003ccond\u003e \u003ctrue-branch\u003e else \u003cfalse-branch\u003e`\n\nDescription\n-----------\n\nThe value of :code:`cond` is stored in the variable :code:`it`, which is\naccessible in the scope of either branch.\n\nExamples\n--------\n\n.. code-block:: c\n\n   /* Input */\n   cmacro_import \"anaphoric/if.c\"\n\n   int main() {\n     aif(5 \u003e 1)\n       return it;\n   }\n\n\n   /* Output */\n   int main() {\n     typeof(5 \u003e 1) it = 5 \u003e 1;\n     if(it)\n       return it;\n   }\n\n*********\nUtilities\n*********\n\n:code:`doto`\n============\n\nSyntax\n------\n\n:code:`doto(obj) { \u003cfn\u003e(\u003cargs\u003e*);+ }`\n\nDescription\n-----------\n\nCalls every :code:`fn`, with :code:`obj` appended to the beginning of its\nargument list.\n\nExamples\n--------\n\n.. code-block:: c\n\n   /* Input */\n   cmacro_import \"util/doto.c\"\n\n   void cancelAccount(Account* account) {\n     doto(account) {\n       setBalance(0);\n       setStatus(DISABLED);\n     }\n   }\n\n   /* Output */\n   void cancelAccount(Account* account) {\n     setBalance(account, 0);\n     setStatus(account, DISABLED);\n   }\n\n:code:`with_allocation`\n=======================\n\nSyntax\n------\n\n- :code:`with_allocation(\u003cptr\u003e, \u003ctype\u003e) { \u003cbody\u003e* }`\n- :code:`with_allocation(\u003cptr\u003e, \u003ctype\u003e, \u003clength\u003e) { \u003cbody\u003e* }`\n\nDescription\n-----------\n\nAllocates memory to hold :code:`type`, optionally an array of :code:`type` if\n:code:`length` is specified. The pointer is stored in the variable :code:`ptr`\nand `free`'d after :code:`body` is executed.\n\nExamples\n--------\n\n.. code-block:: c\n\n   cmacro_import \"util/with_allocation.c\"\n\n   int main() {\n     with_allocation(ptr, int, 10) {\n       size_t i;\n       for(i = 0; i \u003c 10; i++) {\n         ptr[i] = i*2;\n       }\n     }\n     with_allocation(p, int) {\n       *p = 10;\n       return *p;\n     }\n   }\n\n:code:`with_open_file`\n======================\n\nSyntax\n------\n\n`with_open_file(\u003cstream\u003e, \u003cfilepath\u003e, \u003cmode\u003e) { \u003cbody\u003e* }`\n\nDescription\n-----------\n\nOpens :code:`filepath` with mode :code:`mode`, assigning it to the variable\n:code:`stream`, then executes body and closes the stream.\n\nExamples\n--------\n\n.. code-block:: c\n\n   cmacro_import \"util/with_open_file.c\"\n\n   int main() {\n     with_open_file(file, \"README.md\", \"r\") {\n       printf(\"The first character in the README is: %c\\n\",\n              fgetc(file));\n     }\n     return 0;\n   }\n\n*******\nLicense\n*******\n\nCopyright (c) 2014 Fernando Borretti (eudoxiahp@gmail.com)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feudoxia0%2Fmagma","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feudoxia0%2Fmagma","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feudoxia0%2Fmagma/lists"}