Skip to content

Latest commit

 

History

History
46 lines (38 loc) · 2.59 KB

MultipleLanguages.md

File metadata and controls

46 lines (38 loc) · 2.59 KB

This is a very preliminary idea for Scheme systems to support multiple languages by translation. I don't know if it will ever be proposed for R7RS-large.

At the top of a file containing non-Scheme or a different variant of Scheme there is a line beginning with #!lang and followed on the same line by the name of a module such as (picrin javascript), (chibi lua), (chicken awk) or (johnwcowan algol60). This line appears after any shebang line but before any source code.

The Scheme system imports this module, which must export the procedure transpile. This procedure is invoked on three arguments: an input port, the filename of the source, and a line number representing the first line of source code, normally 3 if there is a shebang line and 2 if there is not.

Transpile then reads source code from the port in whatever language or languages it understands, known here as the source language, and returns a list of Scheme definitions and expressions that represent a translation of the source code into Scheme, which the Scheme system then processes like any other code. If the language in question is a Lispy one, transpile may be able to use read, but if not it will have to have its own parser.

If an element of the output is an exact integer (which would not do anything useful as a top-level expression), it indicates the line of the original source code; A string indicates a filename from which source is now being read, either the original filename or one due to an include analogue in the source language.

Syntax or static semantic errors in the source code are raised as exceptions that satisfy the predicate transpiler-error?. Accessors pull out the filename and line number of the error as well as a message indicating what is wrong.

Implementations of transpile should themeselves attempt to be as reusable as possible by being written in and generating Scheme that conforms to some standard and makes a minimal use of implementation-specific features. It is good if the output of transpile allows reasonable access to the procedures of the source language from Scheme code, and even better if it permits calling Scheme procedures from the source language as if they were external procedures in the source language. Of course this interoperability depends on the particular source language.

The only prior art for this is Racket's #lang directive, which works similarly except that the output of the front end is Racket syntax objects (which carry source file and line information) rather than Scheme source code, which makes for greater flexibility but also more complexity and less portability.