Initial commit
This commit is contained in:
commit
4a09246307
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
*~
|
||||
\#*
|
||||
.\#*
|
||||
.DS_Store
|
||||
compiled/
|
||||
/doc/
|
37
.travis.yml
Normal file
37
.travis.yml
Normal file
|
@ -0,0 +1,37 @@
|
|||
language: c
|
||||
sudo: false
|
||||
|
||||
env:
|
||||
global:
|
||||
# RACKET_DIR is an argument to install-racket.sh
|
||||
- RACKET_DIR=~/racket
|
||||
- PATH="$RACKET_DIR/bin:$PATH"
|
||||
matrix:
|
||||
# RACKET_VERSION is an argument to install-racket.sh
|
||||
- RACKET_VERSION=6.0 COV=false
|
||||
- RACKET_VERSION=6.1 COV=false
|
||||
- RACKET_VERSION=6.1.1 COV=false
|
||||
- RACKET_VERSION=6.2 COV=false
|
||||
- RACKET_VERSION=6.3 COV=true
|
||||
- RACKET_VERSION=6.4 COV=true
|
||||
- RACKET_VERSION=6.5 COV=true
|
||||
- RACKET_VERSION=6.6 COV=true
|
||||
- RACKET_VERSION=6.7 COV=true
|
||||
- RACKET_VERSION=6.8 COV=true
|
||||
- RACKET_VERSION=RELEASE COV=true
|
||||
- RACKET_VERSION=HEAD COV=true
|
||||
|
||||
before_install:
|
||||
- curl -L https://raw.githubusercontent.com/greghendershott/travis-racket/master/install-racket.sh | bash
|
||||
- if $COV; then raco pkg install --deps search-auto doc-coverage cover cover-codecov; fi # or cover-coveralls
|
||||
|
||||
install:
|
||||
- raco pkg install --deps search-auto -j 2
|
||||
|
||||
script:
|
||||
- raco test -x -p "$(basename "$TRAVIS_BUILD_DIR")"
|
||||
- if $COV; then raco setup --check-pkg-deps --no-zo --no-launcher --no-install --no-post-install --no-docs --pkgs "$(basename "$TRAVIS_BUILD_DIR")"; fi
|
||||
- if $COV; then raco doc-coverage "$(basename "$TRAVIS_BUILD_DIR")"; fi
|
||||
- if $COV; then raco cover -s main -s test -s doc -f codecov -f html -d ~/coverage . || true; fi
|
||||
# TODO: add an option to cover to run the "outer" module too, not just the submodules.
|
||||
# TODO: deploy the coverage info.
|
11
LICENSE.txt
Normal file
11
LICENSE.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
chain-module-begin
|
||||
Copyright (c) 2017 georges
|
||||
|
||||
This package is distributed under the GNU Lesser General Public
|
||||
License (LGPL). This means that you can link chain-module-begin into proprietary
|
||||
applications, provided you follow the rules stated in the LGPL. You
|
||||
can also modify this package; if you distribute a modified version,
|
||||
you must distribute it under the terms of the LGPL, which in
|
||||
particular means that you must release the source code for the
|
||||
modified software. See http://www.gnu.org/copyleft/lesser.html
|
||||
for more information.
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
chain-module-begin
|
||||
==================
|
||||
README text here.
|
11
info.rkt
Normal file
11
info.rkt
Normal file
|
@ -0,0 +1,11 @@
|
|||
#lang info
|
||||
(define collection "chain-module-begin")
|
||||
(define deps '("base"
|
||||
"rackunit-lib"
|
||||
"debug-scopes"))
|
||||
(define build-deps '("scribble-lib"
|
||||
"racket-doc"))
|
||||
(define scribblings '(("scribblings/chain-module-begin.scrbl" ())))
|
||||
(define pkg-desc "Use this to build meta-languages, where a #%module-begin expands to the #%module-begin of another user-specified language.")
|
||||
(define version "0.1")
|
||||
(define pkg-authors '("Georges Dupéron"))
|
29
main.rkt
Normal file
29
main.rkt
Normal file
|
@ -0,0 +1,29 @@
|
|||
#lang racket/base
|
||||
|
||||
(provide chain-module-begin)
|
||||
|
||||
(require (for-syntax racket/base
|
||||
syntax/parse
|
||||
debug-scopes/named-scopes/exptime))
|
||||
|
||||
(define-syntax continue
|
||||
(syntax-parser
|
||||
[(_ whole-ctx lang lang-modbeg . body)
|
||||
#:with ({~literal #%plain-module-begin} . expanded-body)
|
||||
(local-expand (datum->syntax #'whole-ctx
|
||||
`(,#'lang-modbeg . ,#'body)
|
||||
#'whole-ctx)
|
||||
'module-begin
|
||||
'())
|
||||
(define new-scope (make-module-like-named-scope
|
||||
(format "nested-lang-~a" (syntax-e #'lang))))
|
||||
(new-scope #`(begin . expanded-body))]))
|
||||
|
||||
(define-syntax chain-module-begin
|
||||
(syntax-parser
|
||||
[{~and whole (_ lang . body)}
|
||||
#:with lang-modbeg (datum->syntax #'lang '#%module-begin #'lang)
|
||||
#:with whole-ctx (datum->syntax #'whole 'ctx #'whole)
|
||||
#'(#%plain-module-begin
|
||||
(require lang)
|
||||
(continue whole-ctx lang lang-modbeg . body))]))
|
73
scribblings/chain-module-begin.scrbl
Normal file
73
scribblings/chain-module-begin.scrbl
Normal file
|
@ -0,0 +1,73 @@
|
|||
#lang scribble/manual
|
||||
@require[@for-label[chain-module-begin
|
||||
racket/base]]
|
||||
|
||||
@title{Chaining module languages}
|
||||
@author[@author+email["Georges Dupéron" "georges.duperon@gmail.com"]]
|
||||
|
||||
@defmodule[chain-module-begin]
|
||||
|
||||
This package is experimental. Later versions may break backward-compatibility.
|
||||
|
||||
@defform[(chain-module-begin lang . body)]{
|
||||
This macro is intended to be used as the result of a @racket[#%module-begin]
|
||||
macro. It chain-calls the @racket[#%module-begin] of @racket[lang]. This makes
|
||||
it possible for a @racket[#%module-begin] to perform some changes on its body,
|
||||
and then chain-call the @racket[#%module-begin] of a user-specified language.
|
||||
|
||||
As an example here is the definition for a no-op language, which simply takes a
|
||||
(possibly improper) list of languages to chain, and calls the next one:
|
||||
|
||||
@racketblock[
|
||||
(module the-meta-lang racket/base
|
||||
(provide (rename-out [new-#%module-begin #%module-begin]))
|
||||
|
||||
(require chain-module-begin
|
||||
(for-syntax racket/base
|
||||
syntax/parse))
|
||||
|
||||
(define-syntax (new-#%module-begin stx)
|
||||
(syntax-parse stx
|
||||
[(_ {~or next-lang:id (next-lang:id . chain₊)} . body)
|
||||
(define maybe-chain₊ (if (attribute chain₊)
|
||||
`(,#'chain₊)
|
||||
'()))
|
||||
(define new-form `(,#'chain-module-begin ,#'next-lang ,@maybe-chain₊
|
||||
. ,(transform-body #'body)))
|
||||
(datum->syntax stx new-form stx stx)]))
|
||||
|
||||
(define-for-syntax (transform-body body)
|
||||
(code:comment "identity transformation:")
|
||||
body))]
|
||||
|
||||
This language could then be used as follows:
|
||||
|
||||
@racketblock[
|
||||
(module b the-meta-lang typed/racket
|
||||
(define x : Number 123))]
|
||||
|
||||
Given two other meta-language built in the same way and provided by
|
||||
@racketid[meta-two] and @racketid[meta-three], it would be possible
|
||||
to chain the three languages as follows:
|
||||
|
||||
@racketblock[
|
||||
(module b the-lang (meta-two meta-three . typed/racket)
|
||||
(define x : Number 123))]
|
||||
|
||||
The @racket[chain-module-begin] macro produces the following syntax:
|
||||
|
||||
@racketblock[(#%plain-module-begin
|
||||
(require lang)
|
||||
(continue . internal-args))]
|
||||
|
||||
where @racket[(continue . _internal-args)] fully expands
|
||||
@racket[(#%module-begin . body)], where @racket[#%module-begin] is the one
|
||||
provided by @racket[lang], and produces the following syntax:
|
||||
|
||||
@racketblock[(begin . _expanded-body)]
|
||||
|
||||
An extra scope is added to the whole @racket[(begin . _expanded-body)] form,
|
||||
so that a @racket[#%require] form within the @racket[_expanded-body] may
|
||||
shadow bindings provided by @racket[lang], just as @racket[require] forms
|
||||
normally have the possibility to shadow bindings provided by the @(hash-lang)
|
||||
language.}
|
Loading…
Reference in New Issue
Block a user