{"id":28210899,"url":"https://github.com/darinm223/smlgen","last_synced_at":"2026-01-25T02:31:23.892Z","repository":{"id":172518572,"uuid":"631476298","full_name":"DarinM223/smlgen","owner":"DarinM223","description":"Code generator for Standard ML","archived":false,"fork":false,"pushed_at":"2025-08-31T14:35:27.000Z","size":311,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-31T16:22:49.178Z","etag":null,"topics":["code-generator","compare","deriving","generics","hash","show","sml","standard-ml"],"latest_commit_sha":null,"homepage":"","language":"Standard ML","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/DarinM223.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,"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-04-23T06:16:03.000Z","updated_at":"2025-08-26T15:24:36.000Z","dependencies_parsed_at":"2024-01-23T04:23:38.137Z","dependency_job_id":"561ef4c3-90c3-46c7-b26b-0e09d7d87afd","html_url":"https://github.com/DarinM223/smlgen","commit_stats":null,"previous_names":["darinm223/smlgen"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/DarinM223/smlgen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarinM223%2Fsmlgen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarinM223%2Fsmlgen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarinM223%2Fsmlgen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarinM223%2Fsmlgen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DarinM223","download_url":"https://codeload.github.com/DarinM223/smlgen/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DarinM223%2Fsmlgen/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28742491,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T01:40:51.112Z","status":"online","status_checked_at":"2026-01-25T02:00:06.841Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["code-generator","compare","deriving","generics","hash","show","sml","standard-ml"],"created_at":"2025-05-17T17:10:46.472Z","updated_at":"2026-01-25T02:31:23.886Z","avatar_url":"https://github.com/DarinM223.png","language":"Standard ML","funding_links":[],"categories":[],"sub_categories":[],"readme":"smlgen\n======\n\nA code generator for Standard ML that generates boilerplate functions for\nthings like converting types to strings, comparing types, etc.\n\nBuilding\n--------\n\nAfter cloning the repo, run:\n\n```\ngit submodule update --init --recursive\n```\n\nto clone the submodules, then run:\n\n```\nmlton smlgen.mlb\n```\n\nto build the project in MLton.\n\nTo build the project in Poly/ML, run:\n\n```\n./build_polyml.sh\npolyc build.sml -o smlgen\n```\n(MLton libraries are required to be in `/usr/local/lib/mlton` or `/usr/lib/mlton` for this to work)\n\nTo build the project in MLKit, run:\n\n```\n./build_mlkit.sh\nmlkit -o smlgen smlgen.mlkit.mlb\n```\n\nTo build the project in SML/NJ, run:\n\n```\n./build_smlnj.sh\n```\n\nto build a SML/NJ heap image file that looks something like `smlgen.amd64-linux`,\ndepending on the target architecture and OS. Then to run this heap image, run:\n\n```\nsml @SMLload=smlgen.amd64-linux \u003cargs\u003e\n```\n\nwhere `\u003cargs\u003e` is the command line arguments to smlgen.\n\nTo build the project in [SML.NET](https://github.com/DarinM223/smldotnet), run:\n\n```\n./build_smlnet.sh\n$SMLNETPATH/bin/smlnet.sh @Smlgen\n```\n\nthe resulting program is `SmldotnetMain.exe` which can be ran with Mono\nlike `mono SmldotnetMain.exe ...`.\n\nTo run the SML.NET compiled executable with .NET Core, run:\n\n```\ncd smldotnet/\ndotnet build\n./build_net_core.sh\n```\n\nThen `dotnet smlgen.exe` will run smlgen with the .NET Core runtime. With .NET Core, there\nare currently some differences when it comes to reading input. One Ctrl-D will count as an\nEnter key when submitting input and three Ctrl-Ds will count as one Ctrl-D input.\n\n\nRunning\n-------\n\nThe first argument is the path of the Standard ML\nfile to run the generator on. The next arguments are\nthe type name and generators to run on the type separated by colons.\n\n```\n./smlgen foo.sml Ast.Str.strdec:g Parser.t:u Person.t:s\n```\n\nYou can combine generators for a type like:\n```\nAst.t:gu\n```\n\nThe characters corresponding to each generator are listed below:\n\n| Option |        Generator                                |\n|--------|-------------------------------------------------|\n|   u    | Functional record update                        |\n|   g    | [Generic](https://github.com/DarinM223/generic) |\n|   s    | Show                                            |\n|   c    | Compare                                         |\n|   e    | Equality                                        |\n|   h    | Hash                                            |\n\nsmlgen will prompt you for every type name that matches to generate code for that type. It will then overwrite the file with the formatted and generated code.\n\nIn order to print out the generated code without formatting and overwriting the file, you can pass in a `--print` option.\n\nTo write to a test file, you can pass in a `--test` option.\n`smlgen --test file.sml ...` will create a `file.sml.test` file\nin the same directory as `file.sml`.\n\nsmlgen also allows you to generate many commonly used files for things like array literal syntax, printf syntax, etc. To generate these files, run:\n\n```\n./smlgen -gen \u003cgenerator\u003e\n```\n\nThe list of file generators is shown below:\n\n| Generator |             Description                                                 |\n|-----------|-------------------------------------------------------------------------|\n| fru       | [Functional record update](http://www.mlton.org/FunctionalRecordUpdate) |\n| fold      | [Fold](http://www.mlton.org/Fold)                                       |\n| fold01n   | [Fold01N](http://www.mlton.org/Fold01N)                                 |\n| product   | [Product](http://www.mlton.org/ProductType)                             |\n| printf    | [Printf](http://www.mlton.org/Printf)                                   |\n| num       | [Numeric literals](http://www.mlton.org/NumericLiteral)                 |\n| literal   | [Array \u0026 Vector literals](http://www.mlton.org/ArrayLiteral)            |\n| optarg    | [Optional arguments](http://www.mlton.org/OptionalArguments)            |\n\nsmlgen also allows you to generate an initial project with the `-proj` option. For example, to generate\nan initial project named `hello`, run:\n\n```\n./smlgen -proj hello\n```\n\nAnd it will create a `hello` directory with initial project files.\n\nsmlgen also has experimental support for generating recursive modules. If there is a `file.sml` with structures that contain datatypes which refer to other structure's datatypes in a cyclic way, then the command\nline option `--recurmod` will generate a file `file.rec.sml` which breaks the cyclic parts into component modules\nand then replicates the datatypes in the original structures. For an example, look at this [sample cyclic IR example](/test/test21.sml) and its [generated output](/test/test21.sml.expected) which is valid SML97.\n\nTesting\n-------\n\nTo run the tests, run:\n\n```\nsh test.sh\n```\n\nin the project directory. It should list the number of succeeded and failed tests and\nthe diff between the generated code and the expected code for each failed test.\n\nCurrent limitations\n-------------------\n\nRight now, the generic generation doesn't handle constructor names that conflict\nwith the existing generic constructors like `T` or `C1`, etc. So this:\n\n```sml\ndatatype 'a t = T of 'a * 'a t * int t * string t (* BAD *)\n```\n\nwill generate a function that doesn't compile. Instead, rename the constructor\nto not conflict:\n\n```sml\ndatatype 'a t = T' of 'a * 'a t * int t * string t\n```\n\nAll of the generator functions handle some types of polymorphic recursive use inside its definition. In the above example, the constructor of `'a t` contains monomorphic uses of `t` (`int t` and `string t`), and a naive recursive function will not work with these, since it will unify `'a` with either `int` or `string`.\nThe generator functions work around this by creating separate functions for `int t` and `string t`.\nHowever, if the type itself grows infinitely, the generator will skip the type\nand print the message `Max type size limit exceeded`. So a generator for something like this cannot be done:\n\n```sml\ndatatype 'a t = T' of 'a * 'a list t (* BAD *)\n```\n\nYou may hit the maximum type size limit error unintentionally, from having a very large record or tuple.\nIn that case you can increase the maximum type size with the `-maxsize` flag. For example:\n\n```\n./smlgen file.sml ... -maxsize 1000\n```\n\nwill set the max type size limit to 1000. The default max type size is set at 100.\n\nThe hashing functions created by the hash generator are similar to Java's `hashCode` functions\nand are not resilient to collision based attacks. Don't use the default generated functions for hashing untrusted input.\n\n`real` types are supposed to be hashed by bitwise casting them into a `word` of the same size, but there is no standards compliant way to do this. Currently, the hash function for `real` types converts them to strings and hashes the strings, but if you are only using one compiler, you should use the implementation-specific functions for casting reals to words.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarinm223%2Fsmlgen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdarinm223%2Fsmlgen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarinm223%2Fsmlgen/lists"}