kasbah
kasbah

Reputation: 943

Rebinding the name `module` in Racket

I'd like to get Racket to evaluate the syntax of .kicad_mod files that are s-expression data of the form:

(module LED-10MM (layer F.Cu) (tedit 55BDE3C5)
  (descr "LED 10mm")
  ...)

full file here

I want to be able to mix Racket and "kicad_mod" syntax so I am trying to redefine the module function. As a start I tried:

;kicad_mod.rkt

#lang racket
(provide
 (except-out (all-from-out racket) #%module-begin module)
 (rename-out [module-begin #%module-begin]))

(define kicad_module "you got me")

(define-syntax-rule (module-begin expr ...)
  (#%module-begin
   (provide (rename-out [kicad_module module]))))

and what finally kind of worked (though not in drracket but with racket interpreter direct) on the loading side:

;main.rkt

#lang racket
(module kicad_mod "kicad_mod.rkt")
(require 'kicad_mod)
(println module)
; => "you got me"

But if I try any other way it fails:

1.

;main.rkt

#lang racket
(require "kicad_mod.rkt")` 

results in an error:

 main.rkt:3:9: module: bad syntax
      in: module
      context...:
       standard-module-name-resolver

2.

;main.rkt

#lang s-exp "kicad_mod.rkt"
(println module)

results in no outputs on stdout

Upvotes: 1

Views: 84

Answers (2)

kasbah
kasbah

Reputation: 943

soegaard put me on the right track even though it wasn't a full answer.

What I was doing didn't make much sense since I didn't understand the #%module-begin redefinition and in what context the the code was being called.

If you amend kicad_mod.rkt to include a quoted expr like soegaard suggests:

(define-syntax-rule (module-begin expr ...)
  (#%module-begin
   (provide (rename-out [kicad_module module]))
   'expr ...))

and have:

;main.rkt
#lang s-exp "kicad_mod.rkt"
(println module)

You actually get an output of '(println module) on stdout. So the (provide (rename-out... is being called in the context of the module using our new language, executed just before the expressions (if you remove the quote from expr like soegaard's initial suggestion).

What I really wanted was to re-define module before that, at the same time as I am re-defining #%module-begin:

;kicad_mod.rkt

#lang racket
(provide
 (except-out (all-from-out racket) #%module-begin module)
 (rename-out [module-begin #%module-begin])
 (rename-out [kicad_module module]))

(define kicad_module "you got me")

(define-syntax-rule (module-begin expr ...)
  (#%module-begin
   expr ...))

Which will work correctly with the main.rkt using #lang s-exp above. You still need the #%module-begin binding, even though it doesn't do anything at this point if you want to use #lang s-exp. It will come in handy later anyway, I am sure.

Upvotes: 1

soegaard
soegaard

Reputation: 31147

This is not an answer, but I can't write code in the comments.

This looks odd - shouldn't the expression be in the output?

(define-syntax-rule (module-begin expr ...)
  (#%module-begin
   (provide (rename-out [kicad_module module]))))

Perhaps

(define-syntax-rule (module-begin expr ...)
  (#%module-begin
   (provide (rename-out [kicad_module module]))
   expr ...))

or

(define-syntax-rule (module-begin expr ...)
  (#%module-begin
   (provide (rename-out [kicad_module module]))
   'expr ...))

?

Upvotes: 1

Related Questions