You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pollen/main-helper.rkt

87 lines
3.4 KiB
Racket

#lang racket
(require racket/contract/region)
(require (for-syntax racket/rerequire pollen/tools pollen/world))
(require pollen/tools pollen/world)
(provide (except-out (all-defined-out) top~)
(rename-out (top~ #%top)))
(module+ test (require rackunit))
(define-syntax-rule (top~ . id)
(λ x `(id ,@x)))
(define-syntax (bound/c stx)
(syntax-case stx ()
[(_ x)
(if (identifier-binding #'x )
#'x
#'(#%top . x))]))
(define-for-syntax (put-file-in-require-form file)
`(file ,(->string file)))
(define-syntax (require-and-provide-extras stx)
(define project-require-files (get-project-require-files))
(if project-require-files
(let ([files-in-require-form (map put-file-in-require-form project-require-files)])
(datum->syntax stx `(begin
(require ,@files-in-require-form)
(provide (all-from-out ,@files-in-require-form)))))
; if no files to import, do nothing
#'(begin)))
(define-syntax (require-extras stx)
(define project-require-files (get-project-require-files))
(if project-require-files
(let ([files-in-require-form (map put-file-in-require-form project-require-files)])
(datum->syntax stx `(begin
(require ,@files-in-require-form))))
; if no files to import, do nothing
#'(begin)))
;; here = path of this file, relative to current directory.
;; We want to make this identifier behave as a runtime function
;; This requires two steps.
;; First, define the underlying function as syntax-rule
(define-syntax (get-here-path stx)
(datum->syntax stx
'(begin
;; Even though begin permits defines,
;; This macro might be used in an expression context,
;; whereupon define would cause an error.
;; Therefore, best to use let.
(let* ([ccr (current-contract-region)] ; trick for getting current module name
[hp (cond
;; if contract-region is called from within submodule,
;; you get a list
;; in which case, just grab the path from the front
[(list? ccr) (car ccr)]
;; file isn't yet saved in drracket
[(equal? 'pollen-lang-module ccr) 'nowhere]
[else ccr])])
;; pass complete path back as here value (as string)
;; Why not relative to current-directory?
;; Because current-directory can't be parameterized
;; so raises possibility of inconsistent values.
;; Whereas the complete path is unambiguous,
;; and can be made relative by the caller (or otherwise altered).
(->string hp)))))
;; todo: update tests
;(module+ test
; (check-equal? (get-here) "main-helper.rkt"))
; Second step: apply a separate syntax transform to the identifier itself
; We can't do this in one step, because if the macro goes from identifier to function definition,
; The macro processor will evaluate the body at compile-time, not at runtime.
(define-syntax here-path (λ(stx) (datum->syntax stx '(get-here-path))))
;; todo: update test
;(module+ test
; (check-equal? here "main-helper.rkt"))