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.

Reply via email to