Skip to content

Commit

Permalink
WIP: Excise Extra
Browse files Browse the repository at this point in the history
  • Loading branch information
gilch committed Dec 22, 2023
1 parent 8eb0222 commit 0a61028
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 319 deletions.
200 changes: 0 additions & 200 deletions docs/lissp_whirlwind_tour.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1886,203 +1886,3 @@ Lissp Whirlwind Tour
;; Statement injections work at the top level only.
#> .#"from operator import *" ;All your operator are belong to us.
>>> from operator import *

;;;; 15.4 Extra (!), the Final Builtin Reader Macro

;;; Reader macros have one primary argument, but additional arguments
;;; can be passed in with the extra macro !. A tag consumes the next
;;; parsed object, and if it's an Extra, consumes one again. Thus,
;;; extras must be written between the tag and primary, but because
;;; they're often optional refinements, which are easier to define as
;;; trailing optional parameters in Python functions, they get passed in
;;; after the primary.

#> (setattr _macro_ 'L\# en#list) ; (help _macro_.en\#)
#..
>>> setattr(
... _macro_,
... 'LQzHASH_',
... (lambda *_Qz6RFWTTVXz_xs:
... list(
... _Qz6RFWTTVXz_xs)))


#> L#primary
>>> ['primary']
['primary']

#> L#!1 primary
>>> ['primary', 1]
['primary', 1]


;; Alias can work on reader macros too!
#> (hissp.._macro_.alias M: hissp.._macro_)
>>> # hissp.._macro_.alias
... # hissp.macros.._macro_.defmacro
... # hissp.macros.._macro_.let
... (lambda _QzAW22OE5Kz_fn=(lambda _QzARAQTXTEz_prime,_QzARAQTXTEz_reader=None,*_QzARAQTXTEz_args:(
... 'Aliases ``hissp.._macro_`` as ``MQzCOLON_#``.',
... # hissp.macros.._macro_.ifQz_else
... (lambda b,c,a:c()if b else a())(
... _QzARAQTXTEz_reader,
... (lambda :
... __import__('builtins').getattr(
... __import__('hissp')._macro_,
... ('{}{}').format(
... _QzARAQTXTEz_reader,
... # hissp.macros.._macro_.ifQz_else
... (lambda b,c,a:c()if b else a())(
... 'hissp.._macro_'.endswith(
... '._macro_'),
... (lambda :'QzHASH_'),
... (lambda :('')))))(
... _QzARAQTXTEz_prime,
... *_QzARAQTXTEz_args)),
... (lambda :
... ('{}.{}').format(
... 'hissp.._macro_',
... _QzARAQTXTEz_prime))))[-1]):(
... __import__('builtins').setattr(
... _QzAW22OE5Kz_fn,
... '__doc__',
... 'Aliases ``hissp.._macro_`` as ``MQzCOLON_#``.'),
... __import__('builtins').setattr(
... _QzAW22OE5Kz_fn,
... '__qualname__',
... ('.').join(
... ('_macro_',
... 'MQzCOLON_QzHASH_',))),
... __import__('builtins').setattr(
... __import__('operator').getitem(
... __import__('builtins').globals(),
... '_macro_'),
... 'MQzCOLON_QzHASH_',
... _QzAW22OE5Kz_fn))[-1])()

#> M:#!b"Read-time b# via alias." ;Extra arg for alias with (!)
>>> b'Read-time b# via alias.'
b'Read-time b# via alias.'


#> L# !1 !2 primary ;Note the order!
>>> ['primary', 1, 2]
['primary', 1, 2]

#> .#(en#list "primary" 1 2) ;Inject. Note the order.
>>> ['primary', 1, 2]
['primary', 1, 2]


#> !1 ;! is for a single Extra.
>>> __import__('pickle').loads( # Extra([1])
... b'ccopyreg\n'
... b'_reconstructor\n'
... b'(chissp.reader\n'
... b'Extra\n'
... b'cbuiltins\n'
... b'tuple\n'
... b'(I1\n'
... b'ttR.'
... )
Extra([1])

#> hissp.reader..Extra#(: :? 0 :* (1 2 3)) ; but Extra can have multiple elements.
>>> __import__('pickle').loads( # Extra([':', ':?', 0, ':*', (1, 2, 3)])
... b'ccopyreg\n'
... b'_reconstructor\n'
... b'(chissp.reader\n'
... b'Extra\n'
... b'cbuiltins\n'
... b'tuple\n'
... b'(V:\n'
... b'V:?\n'
... b'I0\n'
... b'V:*\n'
... b'(I1\n'
... b'I2\n'
... b'I3\n'
... b'tttR.'
... )
Extra([':', ':?', 0, ':*', (1, 2, 3)])

#> !!!1 2 3 ;Extras can have extras.
>>> __import__('pickle').loads( # Extra([1, 2, 3])
... b'ccopyreg\n'
... b'_reconstructor\n'
... b'(chissp.reader\n'
... b'Extra\n'
... b'cbuiltins\n'
... b'tuple\n'
... b'(I1\n'
... b'I2\n'
... b'I3\n'
... b'ttR.'
... )
Extra([1, 2, 3])


#> L#!: !:* !(0 1 2) !:? !3 primary ;Unpacking works like calls.
>>> ['primary', 0, 1, 2, 3]
['primary', 0, 1, 2, 3]

#> L#!0 !: !:* !(1 2 3)primary ;Same effect.
>>> ['primary', 0, 1, 2, 3]
['primary', 0, 1, 2, 3]

#> L#hissp.reader..Extra#(0 : :* (1 2 3))primary ;Same effect.
>>> ['primary', 0, 1, 2, 3]
['primary', 0, 1, 2, 3]


#> (setattr _macro_ 'E\# hissp.reader..Extra)
>>> setattr(
... _macro_,
... 'EQzHASH_',
... __import__('hissp.reader',fromlist='?').Extra)


#> L# !0 E#(1 2) !3 primary ;Same effect.
>>> ['primary', 0, 1, 2, 3]
['primary', 0, 1, 2, 3]

#> L#E#(0 : :* (1 2 3))primary ;Same effect.
>>> ['primary', 0, 1, 2, 3]
['primary', 0, 1, 2, 3]


;; Kwargs also work like calls.
#> builtins..dict#()
>>> {}
{}

#> builtins..dict#!: !spam !1 !foo !2 !:** !.#(dict : eggs 3 bar 4)()
>>> {'spam': 1, 'foo': 2, 'eggs': 3, 'bar': 4}
{'spam': 1, 'foo': 2, 'eggs': 3, 'bar': 4}

#> builtins..dict#E#(: spam 1 foo 2 :** .#(dict : eggs 3 bar 4))()
>>> {'spam': 1, 'foo': 2, 'eggs': 3, 'bar': 4}
{'spam': 1, 'foo': 2, 'eggs': 3, 'bar': 4}

#> builtins..dict#!: !!spam 1 !!foo 2 !!:** .#(dict : eggs 3 bar 4)()
>>> {'spam': 1, 'foo': 2, 'eggs': 3, 'bar': 4}
{'spam': 1, 'foo': 2, 'eggs': 3, 'bar': 4}


;; Yeah, you can nest these if you have to.
#> L# !x
#.. !L# !1 L# !A
#.. inner
#.. !y
#..outer
>>> ['outer', 'x', [['inner', 'A'], 1], 'y']
['outer', 'x', [['inner', 'A'], 1], 'y']


;; The compiler will evaluate tuples no matter how the reader produces them.
#> builtins..tuple#L# !"Hello" !"World!" print
>>> print(
... ('Hello'),
... ('World!'))
Hello World!
Loading

0 comments on commit 0a61028

Please sign in to comment.