Skip to content

Commit

Permalink
Merge pull request #270 from gilch/macro-mistakes
Browse files Browse the repository at this point in the history
Macro mistakes
  • Loading branch information
gilch authored Nov 10, 2024
2 parents 72e199f + 0021e5d commit 5f85883
Show file tree
Hide file tree
Showing 16 changed files with 5,247 additions and 1,066 deletions.
4 changes: 2 additions & 2 deletions docs/command_line_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ For example, using `hissp.reader.transpile`, a package name, and module names,

.. code-block:: console
$ alias lisspt="lissp -c '(hissp..transpile : :* [##1:] sys..argv)'"
$ alias lisspt="lissp -c '(H#transpile : :* [##1:] sys..argv)'"
$ lisspt pkg foo # Transpiles pkg/foo.lissp to pkg/foo.py in a package context.
$ lisspt pkg.sub foo # Transpiles pkg/sub/foo.lissp to .py in subpackage context.
$ lisspt "" foo bar # foo.lissp, bar.lissp to foo.py, bar.py without a package.
Expand All @@ -54,7 +54,7 @@ or using `hissp.reader.transpile_file`, a file name, and a package name,

.. code-block:: console
$ alias lissptf="lissp -c '(hissp.reader..transpile_file : :* [##1:] sys..argv)'"
$ alias lissptf="lissp -c '(H#reader.transpile_file : :* [##1:] sys..argv)'"
$ lissptf spam.lissp # Transpile a single file without a package.
$ cd pkg
$ lissptf eggs.lissp pkg # must declare the package name
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,4 @@
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]

intersphinx_mapping = {"python": ("https://docs.python.org/3", None)}
intersphinx_mapping = {"python": ("https://docs.python.org/3.10", None)}
56 changes: 46 additions & 10 deletions docs/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ Glossary
`Injection` of a Python statement is only valid at the top level.

doorstop
A `discarded item` used to "hold open" a bracket trail.
Typically ``_#/`` in Lissp,
but may be a `Unicode token` with a comment.
A `discarded item` used to "hold open" a bracket trail
or avoid a ``))`` in line.
Any discarded item used this way is functionally a doorstop,
but, in Lissp, the typical style starts with ``_#/``
and may continue with a label of what form the next ``)`` is closing,
like ``_#/foo``, similar to XML tags.

abstract syntax tree
ast
Expand Down Expand Up @@ -125,7 +128,9 @@ Glossary

atom
A `form` that is either the empty tuple ``()`` or not of type `tuple`.
`is_atomic` tests for atoms.
Atoms are the leaf elements of Hissp's syntax trees,
while non-empty tuples are the nodes.
`is_node` tests for the non-leaves, so its negation tests for atoms.

form
An object meant for evaluation;
Expand Down Expand Up @@ -165,6 +170,33 @@ Glossary
not linked-lists or vectors,
hence “params tuple” when written with a tuple.

standard
nonstandard
The standard language is a disciplined subset with full generality.
Standard (`readerless mode`) Hissp uses `str atom`\ s only for
`control word`\ s and `symbol`\ s
(which include imports and attribute access)
and avoids other `Python injection`\ s.
Standard Lissp also uses `str atom`\ s for `string literal fragment`\ s.
(Standard readerless mode instead compiles string literals exclusively
via the quote `special form`, or nested in `set`, `dict`, or `list` `atom`\ s.)
Other Python injections are considered nonstandard.
Nonstandard constructions should be used sparingly and with care.
Metaprograms are not necessarily expected to handle nonstandard Python injections,
because that would require processing the much more complicated language
of Python expressions, but not all nonstandard injections are problematic.
The bundled tags and macros mostly avoid nonstandard injections in expansions,
but (with the notable exception of `mix`)
allow them where they would be no worse than an opaque
`fully-qualified identifier`,
or in a few cases where the user writes part of the injection.
Standard Hissp also avoids importing the ``hissp`` package outside of
metaprograms (and direct helpers not otherwise called) to preserve the
`standalone property`.
Standard atom types are those the compiler has a literal notation for.
Use of nonstandard types can result in a `pickle expression` or a crash
during compilation (if the atom is unpickleable).

injection
Either a `Python injection` or a `Hissp injection`, depending on context.

Expand All @@ -178,22 +210,22 @@ Glossary
making them less useful or risking errors.
However, the compiler only targets a subset of Python expressions.
Injection transcends that limitation.
Injection of identifiers is considered standard in Hissp,
Injection of identifiers is considered `standard` in Hissp,
so is not discourarged.
A Lissp `Unicode token` reads as a `string literal fragment`,
rather than as a `quote`\ d `str atom`,
making them an example of injection as well.
This usage is standard in Lissp.
This usage is `standard` in Lissp.

hissp injection
Any `atom` of non-standard type (or the use thereof),
Any `atom` of `nonstandard` type (or the use thereof),
i.e., anything the compiler doesn't have a literal notation for,
which it would have to attempt to emit as a `pickle expression`.
This includes instances of standard types without a literal notation
(e.g., `float` is a standard type, but `math.nan` has no literal)
or collections containing nonstandard elements or cycles.
A macroexpansion may be an injection.
Besides macroexpansions, in readerless mode,
A `macro expansion` may be an injection.
Besides macro expansions, in readerless mode,
this almost always requires the use of non-literal notation,
(i.e., notation not accepted by `ast.literal_eval`).
In Lissp, this almost always requires the use of a `tagging token`.
Expand Down Expand Up @@ -266,10 +298,14 @@ Glossary
a type of `str atom` used for identifiers.

symbol
A `module handle` or a `Python fragment` containing an identifier.
A `module handle` or a `Python fragment` containing an
`identifier<str.isidentifier>`.
(Possibly with `qualification`.)
A symbol is always a `str atom`.
`is_symbol` tests for symbols.
Some identifiers are `reserved<keyword.iskeyword>` in Python and
can't be used as variable/attribute names
(`not`, `None`, `class`, etc.) These still count as symbols.

munging
The process of replacing characters invalid in a Python identifier
Expand Down
44 changes: 26 additions & 18 deletions docs/lissp_whirlwind_tour.rst
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,9 @@ Lissp Whirlwind Tour
;; only meant for use at read time, but they're allowed to survive to
;; run time for debugging purposes.
#> spam=eggs
>>> # Kwarg('spam', 'eggs')
... __import__('pickle').loads(b'ccopy_reg\n_reconstructor\n(chissp.reader\nKwarg\nc__builtin__\nobject\nNtR(dVk\nVspam\nsVv\nVeggs\nsb.')
Kwarg('spam', 'eggs')
>>> # Kwarg(k='spam', v='eggs')
... __import__('pickle').loads(b'ccopy_reg\n_reconstructor\n(chissp.reader\nKwarg\nc__builtin__\ntuple\n(Vspam\nVeggs\nttR.')
Kwarg(k='spam', v='eggs')


;; use ; for a COMMENT TOKEN (like this one)
Expand Down Expand Up @@ -531,8 +531,8 @@ Lissp Whirlwind Tour
'QzDIGITxFOUR_2'

#> '\.
>>> 'QzFULLxSTOP_'
'QzFULLxSTOP_'
>>> 'QzDOT_'
'QzDOT_'

#> '\\
>>> 'QzBSOL_'
Expand Down Expand Up @@ -1532,17 +1532,20 @@ Lissp Whirlwind Tour
('operator..add', 1, ('operator..add', 2, 3))


;; Five of the helpers are predicates for inspecting code.
;; Some of the helpers are predicates for inspecting code.
#> (pprint..pp
#.. (list
#.. (itertools..starmap
#.. (lambda xy (|| x y.__name__))
#.. (filter (lambda x (|x[1]| |x[0]|))
#.. (itertools..product '(:control symbol "string" 'quoted () 1 '2)
#.. (|| hissp..is_atomic
#.. hissp..is_control
#.. (itertools..product '(:control re. "string" 'quoted () 1 '2)
#.. (|| hissp..is_control
#.. hissp..is_import
#.. hissp..is_node
#.. hissp..is_str
#.. hissp..is_symbol
#.. hissp..is_hissp_string
#.. hissp..is_lissp_unicode
#.. hissp..is_string_literal))))))
>>> __import__('pprint').pp(
... list(
Expand All @@ -1559,7 +1562,7 @@ Lissp Whirlwind Tour
... ),
... __import__('itertools').product(
... (':control',
... 'symbol',
... 're.',
... "('string')",
... ('quote',
... 'quoted',),
Expand All @@ -1568,21 +1571,26 @@ Lissp Whirlwind Tour
... ('quote',
... (2),),),
... (
... __import__('hissp').is_atomic,
... __import__('hissp').is_control,
... __import__('hissp').is_import,
... __import__('hissp').is_node,
... __import__('hissp').is_str,
... __import__('hissp').is_symbol,
... __import__('hissp').is_hissp_string,
... __import__('hissp').is_lissp_unicode,
... __import__('hissp').is_string_literal))))))
[(':control', 'is_atomic'),
(':control', 'is_control'),
('symbol', 'is_atomic'),
('symbol', 'is_symbol'),
("('string')", 'is_atomic'),
[(':control', 'is_control'),
(':control', 'is_str'),
('re.', 'is_import'),
('re.', 'is_str'),
('re.', 'is_symbol'),
("('string')", 'is_str'),
("('string')", 'is_hissp_string'),
("('string')", 'is_lissp_unicode'),
("('string')", 'is_string_literal'),
(('quote', 'quoted'), 'is_node'),
(('quote', 'quoted'), 'is_hissp_string'),
((), 'is_atomic'),
(1, 'is_atomic')]
(('quote', 2), 'is_node')]


;; Macros only work as invocations, not arguments!
Expand Down
Loading

0 comments on commit 5f85883

Please sign in to comment.