{"id":22235286,"url":"https://github.com/williamthome/parserl","last_synced_at":"2025-03-25T09:24:33.367Z","repository":{"id":169227651,"uuid":"609960292","full_name":"williamthome/parserl","owner":"williamthome","description":"A helper library to simplify modules transformation","archived":false,"fork":false,"pushed_at":"2023-10-13T22:04:54.000Z","size":100,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-30T08:43:19.875Z","etag":null,"topics":["erlang","erlang-library","metaprogramming","parse-transform","rebar3","work-in-progress"],"latest_commit_sha":null,"homepage":"","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/williamthome.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":["williamthome"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":["https://www.buymeacoffee.com/williamthome"]}},"created_at":"2023-03-05T18:39:06.000Z","updated_at":"2023-03-25T04:40:29.000Z","dependencies_parsed_at":"2023-10-14T22:37:48.502Z","dependency_job_id":"47d1bcf7-96ad-4360-90b3-ec6a80b8bdb5","html_url":"https://github.com/williamthome/parserl","commit_stats":null,"previous_names":["williamthome/parserl"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamthome%2Fparserl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamthome%2Fparserl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamthome%2Fparserl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamthome%2Fparserl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/williamthome","download_url":"https://codeload.github.com/williamthome/parserl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245433157,"owners_count":20614447,"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":["erlang","erlang-library","metaprogramming","parse-transform","rebar3","work-in-progress"],"created_at":"2024-12-03T02:12:41.516Z","updated_at":"2025-03-25T09:24:33.343Z","avatar_url":"https://github.com/williamthome.png","language":"Erlang","funding_links":["https://github.com/sponsors/williamthome","https://www.buymeacoffee.com/williamthome"],"categories":[],"sub_categories":[],"readme":"# parserl\n\nA helper library to simplify modules transformation.\n\n## Introduction\n\nIn a nutshell, `parserl` is a recursive function.\nThe transform function receives `ASTs` (Abstract Syntax Trees), and the output is also ASTs but transformed along the way. It can also receive a module name and build the module from scratch, which is used in the [example](#example) below, but it isn't usual.\n\n## Disclaimer\n\nThis is a work in progress lib.\n\n## Installation\n\nAdd `parserl` to rebar.config deps:\n\n```erlang\n{deps, [{ parserl, { git, \"https://github.com/williamthome/parserl.git\"\n                   , {branch, \"main\"} }}]}.\n```\n\nRun `rebar3 compile`.\n\n## Example\n\n```erlang\n-module(example).\n\n-export([parse_transform/2]).\n-export([write_module_from_scratch/0]).\n\n% Use as parse transform ...\nparse_transform(Forms, _Options) -\u003e\n    do_transform(Forms).\n\n% ... or start a module from scratch\nwrite_module_from_scratch() -\u003e\n    Module = parserl_example,\n    do_transform(Module),\n    ok.\n\ndo_transform(ModuleOrForms) -\u003e\n    Module = get_module(ModuleOrForms),\n    % Global options are optional.\n    GlobalOpts = #{ env =\u003e #{module =\u003e Module}\n                  , log =\u003e true\n                  , if_function_exists =\u003e append },\n    % Context is optional and can be anything.\n    Context = #{replace_temp_fun_by =\u003e \"bar() -\u003e bar.\"},\n    parserl:transform(ModuleOrForms, GlobalOpts, Context, [\n        parserl:insert_attribute(\"-on_load(init/0).\"),\n        parserl:insert_function(\n            [ \"init() -\u003e\"\n            , \"    io:format(\\\"Module ~p loaded.\\\", [_@module]).\" ]),\n            % The _@module can looks weird, but it's a metavariable.\n            % parserl uses merl under the hood, this gives the\n            % power to do metavariable substitution.\n            % See the merl documentation for more information:\n            %     https://www.erlang.org/doc/man/merl.html\n        parserl:insert_function(\n            [ \"foo(Foo, _) when is_atom(Foo) -\u003e\"\n            , \"    foo.\" ]\n            , [export]),\n        parserl:insert_function(\n            [ \"foo(Foo, Bar) -\u003e\"\n            , \"    case Foo == Bar of\"\n            , \"        true -\u003e equal;\"\n            , \"        false -\u003e not_equal\"\n            , \"    end.\" ]),\n        parserl:insert_function(\"temp() -\u003e deleteme.\"),\n        parserl:if_true(\n            parserl:function_exists(temp, 0),\n            % if statements also accepts lists\n            parserl:replace_function(\n                fun(#{replace_temp_fun_by := FunBody} = Ctx0) -\u003e\n                    % Context can be transformed.\n                    Ctx = maps:without([replace_temp_fun_by], Ctx0),\n                    {temp, 0, FunBody, Ctx}\n                end,\n                [export]\n            )\n            % The function above can be written as\n            %\n            %     parserl:replace_function(temp, 0, \"bar() -\u003e bar.\", [export])\n            %\n        ),\n        parserl:write_file([\"/tmp\", parserl_trans:module_suffix(Module, \".erl\")])\n        % =NOTICE REPORT==== 25-Mar-2023::01:27:53.989528 ===\n        % File saved in /tmp/parserl_example.erl\n        % ---\n        % -module(parserl_example).\n        % -export([foo/2]).\n        % -export([bar/0]).\n        % init() -\u003e\n        %     io:format(\"Module ~p loaded.\", [parserl_example]).\n        % foo(Foo, _) when is_atom(Foo) -\u003e\n        %     foo;\n        % foo(Foo, Bar) -\u003e\n        %     case Foo == Bar of\n        %         true -\u003e\n        %             equal;\n        %         false -\u003e\n        %             not_equal\n        %     end.\n        % bar() -\u003e\n        %     bar.\n        %\n        %\n        % ---\n    ]).\n\nget_module(Module) when is_atom(Module) -\u003e\n    Module;\nget_module(Forms) when is_list(Forms) -\u003e\n    parserl_trans:get_module(Forms).\n```\n\n## Next steps\n\n- Improve this README file\n- Functions documentations\n- Functions specs\n- Test everything\n\n## Sponsors\n\nIf you liked this or any of my libs, please consider [sponsoring me](https://github.com/sponsors/williamthome).\\\nI'm thankful for your never-ending support :heart:\n\nI also accept coffees :coffee:\n\n[![\"Buy Me A Coffee\"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/williamthome)\n\n## Contributing\n\nFeels free to [submit an issue on GitHub](https://github.com/williamthome/parserl/issues/new).\n\n## License\n\n`parserl` is under the Apache 2.0 License. Please refer to the included [LICENSE](LICENSE.md) file for more information.\n\n## Credits\n\nThis lib uses [merl](https://www.erlang.org/doc/man/merl.html) and [parse_trans](https://github.com/uwiger/parse_trans) under the hood, so, many thanks to [Richard Carlsson](https://github.com/richcarl) and [Ulf Wiger](https://github.com/uwiger).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilliamthome%2Fparserl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwilliamthome%2Fparserl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilliamthome%2Fparserl/lists"}