hissp.reader module#
The Lissp language reader and associated helper functions.
The reader is organized as a lexer and parser. The parser is extensible with Lissp reader macros. The lexer is not extensible, and doesn’t do much more than pull tokens from a relatively simple regex and track its position for error messages.
- hissp.reader.GENSYM_BYTES = 5#
The number of bytes gensym
$#
hashes have.The default 5 bytes (40 bits) should be more than sufficient space to eliminate collisions with typical usage, but for unusual applications, hash length can be increased, up to a maximum of 32 bytes. (16 would have more space than a
uuid.uuid4
.)Each hash character encodes 5 bits (base32 encoding), so 40-bit hashes typically take 8 characters.
- hissp.reader.ENTUPLE = ('lambda', (':', ':*', ' _'), ' _')#
Used by the template macro to make tuples.
To avoid creating a dependency on Hissp, by default, templates spell out the entuple implementation every time, but you can override this by setting some other value here.
- hissp.reader.DROP = <object object>#
The sentinel value returned by the discard macro
_#
, which the reader skips over when parsing. Reader macros can have read-time side effects with no Hissp output by returning this. (Not recommended.)
- exception hissp.reader.SoftSyntaxError[source]#
Bases:
SyntaxError
A syntax error that could be corrected with more lines of input.
When the REPL encounters this when attempting to evaluate a form, it will ask for more lines, rather than aborting with an error.
- class hissp.reader.Lexer(code: str, file: str = '<?>')[source]#
Bases:
Iterator
The tokenizer for the Lissp language.
Most of the actual tokenizing is done by the regex. The Lexer adds some position tracking to that to help with error messages.
- class hissp.reader.Comment(token)[source]#
Bases:
object
Parsed object for a comment token (line comment block).
The reader normally discards these, but reader macros can use them.
- class hissp.reader.Kwarg(k, v)[source]#
Bases:
object
Contains a read-time keyword argument for reader macros.
Normally made with kwarg tags, but can be constructed directly.
- class hissp.reader.Lissp(qualname='__main__', ns=None, evaluate=False, filename='<?>')[source]#
Bases:
object
The parser for the Lissp language.
Wraps around a Hissp compiler instance. Parses Lissp tokens into Hissp syntax trees.
- position(index=None)[source]#
Get the
filename
,lineno
,offset
andtext
for aSyntaxError
, from theLexer
given toparse
.
- parse_macro(tag: str, form)[source]#
Apply a reader macro to a form.
The built-in reader macros are handled here. They are
'
`
(backtick)template quote (starts a
template
)_#
.#
inject (evaluate at read time and use resulting object)
Plus the three built-in template helper macros, which are only valid inside a template.
,
unquote
,@
splice unquote
$#
The built-in macros are reserved by the reader and cannot be reassigned.
- gensym(form: str)[source]#
Generate a symbol unique to the current template. Re-munges any $’s as a gensym hash, or adds it as a prefix if there aren’t any. Gensym hashes are deterministic for reproducible builds. Inputs are the code string being read, the current
__name__
(defaults to “__main__” if not found) and a count of templates read so far.
- hissp.reader.is_hissp_string(form) bool [source]#
Determines if form would directly represent a string in Hissp.
Allows “readerless mode”-style strings: (‘quote’,’foo’,) and any string literal in a Hissp-level str: ‘“foo”’ (including the “(‘foo’)” form produced by the Lissp reader).
Macros often produce strings in one of these forms, via
'
orrepr
on a string object.
- hissp.reader.is_lissp_string(form) bool [source]#
Determines if form could have been read from a Lissp string literal.
It’s not enough to check if the form has a string type. Several token types such as control words, symbols, and Python injections, read in as strings. Macros may need to distinguish these cases.
- hissp.reader.is_string_literal(form) bool | None [source]#
Determines if
ast.literal_eval
on form produces a string.False if it produces something else or None if it raises Exception.
- hissp.reader.is_qualifiable(symbol)[source]#
Determines if symbol can be qualified with a module.
Can’t be
quote
,__import__
, any Python reserved word, a prefix auto-gensym, already qualified, method syntax, or a module handle; and must be a valid identifier or attribute identifier.
- hissp.reader.transpile(package: str | None, *modules: str)[source]#
Transpiles the named Python modules from Lissp.
A .lissp file of the same name must be present in the module’s location. The Python modules are overwritten. Missing modules are created. If the package is “” or
None
,transpile
writes non- packaged modules to the current working directory instead.
- hissp.reader.transpile_packaged(resource: str, package: str)[source]#
Locates & transpiles a packaged .lissp resource file to .py.
- hissp.reader.transpile_file(path: Path | str, package: str | None = None)[source]#
Transpiles a single .lissp file to .py in the same location.
Code in .lissp files is executed upon compilation. This is necessary because macro definitions can alter the compilation of subsequent top-level forms. A packaged Lissp file must know its package at compile time to handle templates and macros correctly.
After the .py file is written,
__file__
will be set to it, if it doesn’t exist already.