Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I create a new language in racket?

Tags:

racket

I would like to create a new language that has the same syntax as typed racket, but when executed will do two things:

  1. run the given program as typed racket
  2. if type checks, then translates the input into another language (say python). I am planning to write a translator from typed racket forms to python syntax.

Any suggestions on how to start or pointers to some skeleton code? I have read this tutorial but it mostly talks about creating new syntax which I don't need in my case.

I understand how I can write racket code to translate from one language to another, what I don't get is how I can do both of the above, i.e., first run it as another language, and then do something else with the same input.

like image 235
JRR Avatar asked Aug 05 '18 06:08

JRR


1 Answers

It sounds like you want to make a language with a new #%module-begin form. This form is either inserted by the reader (when you do a #lang .... line at the top of your file, or by the language if you wrote the module out by hand. Either way, its generally associated with your language definition. This macro has full access to the entire module's unexpanded syntax. So for example, a macro like this:

(provide (rename-out [-module-begin #%module-begin]))
(define-simple-macro (-module-begin body ...)
  (#%module-begin
    (writeln '(body ...))
    body ...))

Would create a language that does two things:

  1. Print out the body of the code (as an s-expression), and

  2. Run the body with the #%module-begin that the language definition was written in.

You can see how you can use this technique to grab the body of your program twice, and do two different things with it. So let's try running this example. First, lets take the sample from above, and put it in a file "mylang.rkt":

#lang racket
(provide (rename-out [-module-begin #%module-begin])
         (except-out (all-from-out racket) #%module-begin))
(require syntax/parse/define)
(define-simple-macro (-module-begin body ...)
  (#%module-begin
    (writeln '(body ...))
    body ...))

And now we can write a program in mylang like this:

#lang s-exp "mylang.rkt"
(+ 1 2)

And when you run it, you'll get something like this:

((+ 1 2))
3

First its printing out the program text, then running it.

You can read more about this process in a paper I wrote discussing this aspect of the Video language. You might also find the book Beautiful Racket to have some examples you might find useful.

like image 185
Leif Andersen Avatar answered Jan 02 '23 19:01

Leif Andersen