Package: transmler
# WhatSML compilers, such as [MLton](http://mlton.org/MLBasis) and[SML/NJ](http://www.smlnj.org/doc/CM/new.pdf), are designed torelieve the programmer to a large extent from managing the dependencygraph of individual source files, beyond specifying the imports andexports, typically for a group of source files constituting a librarycomponent.Depending on one's workflow and the project's complexity,the cognitive load on the programmer may in fact be minimized bykeeping the import and export statements within the context ofthe module where they apply. In this approach, the link between thedeclarations and their uses is made explicit. This enforces a certaindiscipline by limiting the unintentional snowballing of names in scope.In addition, one can incrementally type check the program one file at a time,perhaps as a background process,as suggested in https://sourceforge.net/p/mlton/mailman/message/31513087/The goal is to develop a proof of concept for a transpiler step added toan [MLBasis](http://mlton.org/MLBasis) based compilation workflow and testit on a non-trivial SML project. It should be emphasizedthat no changes are planned to how MLBasis manages the namespacesbehind the scenes. A subset of[MLBasis](http://mlton.org/MLBasisSyntaxAndSemantics) constructswill be supported (excluding `ann`).# Use caseThe `transmile` utility may be invoked as in the following`Makefile` target:```shellSML=mlton.PHONY: foofoo: src/foo.smlbtransmile src --out dist --skip README --copy-files$(SML) -stop tc ./dist/foo.sml.mlb```The `transmile` commandline utility (here assumed to be on the shellsearch path) will pick up any `*.smlb`,`*.sigb` or `*.funb` files in the `src` directory and transpile them into aset of `*.sml`, `*.sig`, or `*.fun` files in the `dist` directory, eachwith a corresponding `*.mlb` MLBasis file.With the above flags, it will also copy any files that itdidn't transpile, with the exception of explicitly excluded files.`import` and `export` statements in a `*b` source file must come before anySML program, except that SML-style comments (and line directives) areallowed within the import/export block.The syntax for importing entities is any combination of:```import $(SML_LIB)/basis/basis-1997.mlbimport "/path/to/moduleA.sigb"import (functor X, structure Z = Y) from "../path/to/moduleB.funb"```By default, every module will implicitly import the SML Basis library(`$(SML_LIB)/basis/basis.mlb`), except where overriden by any explicit`import $(SML_LIB)/...` directive as in the above example.`transmile` will try to resolve any path (except any path from the`$(SML_LIB)` root) in this order:* searching the directory relative to the `*b` source file (exceptwhere an absolute path is specified);* followed by the environment variable `SMLPATH` (set to, e.g.,`<project-root>/src:<project-root>/sml-modules` in the `Makefile`);* followed by any installation-dependent default search path (shell `PATH`).For example, resolving `import X.sigb` entails looking up `./X.sig.mlb`,then `<($SMLPATH)>/X.sig.mlb`, then `<($PATH)>/X.sig.mlb`, and returning withan error if none is found.Assuming the above import statements are placed in an `example.smlb`,and that all the referenced `*.mlb` files can be found relative to thelocation of `example.smlb`,the outcome will be an `example.sml` file with the SML program, plusan `example.sml.mlb` file:```smllocalbasis a = bas (*#line 1.8 "example.smlb"*)$(SML_LIB)/basis/basis-1997.mlb endbasis b = bas (*#line 2.8 "example.smlb"*)"/path/to/moduleA.sig.mlb" endbasis c =let(*#line 3.42 "example.smlb"*)"../path/to/moduleB.fun.mlb"inbas(*#line 3.9 "example.smlb"*)functor X(*#line 3.20 "example.smlb"*)structure Z = Yendendopen a b cinexample.smlend```The syntax for exporting entities is along the lines of:```export (signature K, structure M = L)%% (* for the time being signals the end of import/export block *)```Assuming this `export` statement follows the `import` statements in theabove `example.smlb`, the resulting `example.sml.mlb`will contain:```smllocallocalbasis a = bas (*#line 1.8 "example.smlb"*)$(SML_LIB)/basis/basis-1997.mlb endbasis b = bas (*#line 2.8 "example.smlb"*)"/path/to/moduleA.sig.mlb" endbasis c =let(*#line 3.42 "example.smlb"*)"../path/to/moduleB.fun.mlb"inbas(*#line 3.9 "example.smlb"*)functor X(*#line 3.20 "example.smlb"*)structure Z = Yendendopen a b cinexample.smlendin(*#line 4.9 "example.smlb"*)signature K(*#line 4.22 "example.smlb"*)structure M = Lend```If an `export` statement were missing from `example.smlb`, the modulewould effectively export all its top-level identifiers.# InstallationCurrently requires Python 3. (I plan to rewrite the transpiler in SML.)Clone the repository and run `python transmile.py` to display theusage message, or alternatively install with `pip`:```shellpip install transmlertransmile```See `./example/` for an extended example.