On Sat, Sep 3, 2022, at 2:09 PM, Shu-Hung You wrote: > ---------- Forwarded message --------- > From: Shu-Hung You <[email protected]> > Date: Sat, Sep 3, 2022 at 1:03 PM > Subject: Re: [racket-users] Writing a "command-line front-end" for a language > To: Reuben Thomas <[email protected]> > > > Running `racket foo.asm` will produce the desired output, so a shell > script that directly passes the arguments to Racket could work. > Otherwise, just use (dynamic-require filename #f) in main.rkt. > > At the technical level, foo.asm is in fact an ordinary Racket module, > just like any other .rkt file. Therefore it can be run in the same way > using APIs that require and instantiate modules. > > ----------- > > On a side note, the forum has mostly moved to Discourse > (https://racket.discourse.group/). >
This is all correct, and you can also make just `./foo.asm` work: https://docs.racket-lang.org/guide/scripts.html However, in some cases you might really want a program other than `racket` as the entry point for your language: for instance, maybe you want to have flags for controlling where the output goes. One example of such a program is the `scribble` executable included in the main Racket distribution. The implementation is in <https://github.com/racket/scribble/blob/master/scribble-lib/scribble/run.rkt>, and the associated "info.rkt" file (<https://github.com/racket/scribble/blob/master/scribble-lib/scribble/info.rkt>) arranges for `raco setup` to create a `scribble` to run it. (This example uses the old mzscheme-launcher-names/mzscheme-launcher-libraries instead of the newer racket-launcher-names/racket-launcher-libraries: see documentation at <https://docs.racket-lang.org/raco/setup-info.html#%28idx._%28gentag._18._%28lib._scribblings%2Fraco%2Fraco..scrbl%29%29%29>.) A couple additional details: > On Sat, Sep 3, 2022 at 6:01 AM 'Reuben Thomas' via Racket Users > <[email protected]> wrote: >> >> I have a partial implementation up and running using #lang lines. I would >> like to add a more traditional command-line interface, so I can (eventually) >> say: >> >> hackasm foo.asm >> >> on a file without a #lang line. >> >> My code is available at https://github.com/rrthomas/hackasm >> >> [...] >> >> So far, all I've worked out how to do is run the language's read-syntax >> function (imported from parser.rkt), and thereby return the parsed syntax >> object as the result. >> >> What I'd like to do is call the evaluator on the parse tree, but after a lot >> of scratching my head over the Racket documentation and search results, I >> cannot work out how to do that. It is possible to use Racket to implement languages that don't use #lang, but you would loose many advantages like IDE support and well-defined separate compilation, and you would need to use some fairly low-level mechanisms. Unless there is a hard requirement, I'd recommend that you just use #lang in your programs. For example, the whole family of languages supported by the `scribble` command-line tool use #lang. (Indeed, #lang is how the tool can support a whole *family* of languages.) > On Sat, Sep 3, 2022 at 6:01 AM 'Reuben Thomas' via Racket Users > <[email protected]> wrote: >> >> I have implemented the language as a dialect, so that the "main.rkt" module >> is "free" to be used for the command-line interface. (Perhaps this can be >> fixed too, that would be nice!) >> >> [...] >> >> The contents of my main.rkt looks like this: >> >> #lang br/quicklang >> (require "parser.rkt" "tokenizer.rkt" (submod "asm.rkt" reader)) >> >> (module+ main >> (require racket/cmdline) >> (let ((filename >> (command-line >> #:program "hackasm" ; >> #:args (filename) >> filename))) >> (read-syntax filename (open-input-file filename)))) >> There are many possible ways to organize this: to some extent it's a matter of how you expect your language and cli to be used, and to some extent it's a matter of taste. I wouldn't consider your current organization "wrong", necessarily. But, if you'd like hackasm to be a multi-purpose entry point, one way to do that would be: 1. Move "expander.rkt" to "main.rkt" 2. Add a reader submodule like the one in "asm.rkt", but using just hackasm where you currently have hackasm/expander in the result of read-systax. Optionally, you might consider using syntax/module-reader (Guide: <https://docs.racket-lang.org/guide/syntax_module-reader.html> Reference: <https://docs.racket-lang.org/syntax/reader-helpers.html#%28mod-path._syntax%2Fmodule-reader%29>) with the #:whole-body-readers? option for your reader submodule. 3. Add a main submodule like the one in the current version of "main.rkt", but implemented more like scribble/run. You might want to write it as `(module* main racket/base ...)` unless you want to implement the command line tool in your hackasm language. If you do that, `(require hackasm)`, `(module foo hackasm)` and `#lang hackasm` will all access your language, and running the file will run your command-line tool. Personally, I might instead combine "expander.rkt" and "asm.rkt" into "main.rkt", but put the cli tool in "cli.rkt". The name you give the tool via racket-launcher-names doesn't have to match the file name of the implementation, and I might find it easier to experiment with the language in DrRacket if the tool were separate. But it all depends on what seems most useful to you and your users. -Philip -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/33a28e7e-b4e7-4256-a0d4-53c79a328313%40www.fastmail.com.

