Linea: line oriented reader
William Hatch <william@hatch.uno>
Note that you canโt represent any arbitrary s-expression with Linea, but you can represent a very useful subset of them.
1 Stability
Everything documented here is stable unless it says otherwise.
2 Linea Guide
TODO
Explanation of inner/outer reading, readtable modifications, #%symbol defaults.
TL;DR
#lang linea "my-lang-bindings.rkt"
finwe feanor fingolfin finarfin
beren (and) \
luthien tinuviel
(huan (vs) werewolf-sauron)
manwe orome {
varda yavanna
aule (mandos
nienna #{ulmo tulkas})
melkor
}
(module <some-file-name> "my-lang-bindings.rkt"
(#%module-begin
(#%linea-line finwe feanor fingolfin finarfin)
(#%linea-line beren (and) luthien tinuviel)
(#%linea-s-exp (huan (vs) werewold-sauron))
(#%linea-line
manwe
orome
(#%linea-expressions-begin
(#%linea-line varda yavanna)
(#%linea-line aule (mandos
nienna
(#%hash-braces
(#%linea-expressions-begin
(#%linea-line ulmo tulkas)))))
(#%linea-line melkor)))))
2.1 Line Macros
Line macros are designed to give lines of code flexible meaning. They are similar to Racketโs treatment of S-expressions with macros and #%app.
Just like the macro expander will check whether the first element of a form is bound as a macro, #%linea-line checks if the first element of a line is a line macro. Just like the macro expander inserts #%app if there is not an explicit macro use, #%linea-line inserts #%linea-default-line-macro.
One major difference is that line macros are specially marked with prop:line-macro, because the macros that you want to override S-expression meaning and line meaning are not necessarily the same. The define-line-macro form defines line macros that also work as a normal macro (and execute the same syntax transformer), but that is not required.
3 Linea Reference
3.1 linea/defaults
TODO: #%hash-braces โ currently #%hash-braces are not defined by default, but they are defined if you (require rash/demo/setup)...
syntax
(#%linea-expressions-begin e ...)
syntax
(#%linea-line starter e ...)
syntax
(#%linea-s-exp e)
syntax
The identifier #%linea-default-line-macro is the default that is inserted when no explicit line macro is used. But by default it just raises an error. This is configured with with-default-line-macro.
Donโt count on the name being the same at any future time. Donโt set it yourself. Use with-default-line-macro.
3.2 linea/line-macro
syntax
(define-line-macro name transformer)
;; in a language like Rash that uses the Linea reader... (require (for-syntax racket/base syntax/parse)) (define-line-macro basic-app (syntax-parser [(_ e ...) #'(#%app e ...)])) basic-app println "hello world" (define-line-macro my-for (syntax-parser [(_ i:id (~datum in) from:id ... (~datum do) body:expr) #'(for ([i (list 'from ...)]) body)])) my-for f in file1.txt file2.txt do { basic-app println f }
Use with-default-line-macro to set it for a region of code.
line-macro
(with-default-line-macro new-default-line-macro body ...)
(with-default-line-macro basic-app { displayln "Oh hi" displayln "what's up?" }) ;; or with-default-line-macro basic-app { displayln "Oh hi" displayln "what's up?" }
line-macro
(splicing-with-default-line-macro new-default-line-macro body ...)
3.3 linea/line-macro-prop
syntax class
The property should hold a procedure that takes a struct instance as its first argument and a syntax object as its second argument.
(struct my-line-macro-struct (transformer) #:property prop:line-macro (ฮป (inst . args) (apply (my-line-macro-struct-transformer inst) args)))
procedure
(line-macro? x) โ any/c
x : any/c
3.4 #lang linea
#lang linea | package: linea |
#lang racket/base (require linea/defaults linea/line-macro (for-syntax racket/base syntax/parse)) (define-line-macro print-quoted-list (syntax-parser [(_ e ...) #'(println '(e ...))])) (provide (all-from-out linea/defaults linea/line-macro racket/base) print-quoted-list)
#lang linea "mylang.rkt" ;; prints '(a b c) print-quoted-list a b c with-default-line-macro print-quoted-list { ;; prints '(hello world) hello world }
Be sure that the module you name at the top-level provides a binding for #%linea-line, #%linea-s-exp, and #%linea-expressions-begin, in addition to other #% identifiers that a module needs (eg. #%module-begin, #%app, ...).
3.5 linea/read
TODO:
linea-read-syntax
linea-read
make-linea-read-funcs
readtable-add-linea-escape
default-linea-s-exp-readtable
default-linea-line-readtable
default-linea-line-avoid-list
current-linea-s-exp-readtable
current-linea-line-readtable
current-linea-line-avoid-list
4 Code and License
The code is available on github.
This library is licensed under the terms of the MIT license and the Apache version 2.0 license, at your option.