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 tag
s.
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: dozens of gensyms in the same scope would have a less than a one-in-a-billion chance of collision, even assuming they all have the same suffix. (Even 3 bytes gets that number down to around one in ten thousand.)
For unusual applications (if more than dozens of gensyms are expected in a shared scope, or one in a billion is still too high), hash length can be increased, up to a maximum of 32 bytes.
Even 8 bytes is enough space for a hundred thousand gensyms in the same scope with similar collision probability, or dozens with a one-in-quadrillion chance, which is probably lower than the risk of a hardware failure. Itâs unlikely youâll ever need more than 16 bytes, which has more space than
uuid.uuid4
.Each hash character encodes 5 bits (
Base32
), so a multiple of 5 is recommended, although 3, 8, or 13 bytes are also fairly efficient for their size:bytes
bits
chars
example
3
24
5
Qzthink__G
5
40
8
Qzthinking__G
8
64
13
Qzinvestigation__G
10
80
16
Qzincomprehensible__G
13
104
21
Qzelectroencephalograph__G
15
120
24
Qzmagneticresonanceimaging__G
16
128
26
Qzpositronemissiontomography__G
- 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: str)[source]#
Bases:
object
Parsed object
class for acomment token
(line comment block).The reader normally discards these, but they can be
tag
arguments.
- class hissp.reader.Kwarg(k: str, v: Any)[source]#
Bases:
NamedTuple
Contains a read-time keyword argument for a
tag
.Normally made with a
kwarg token
, but can be constructed directly.
- class hissp.reader.Lissp(qualname: str = '__main__', env: dict[str, Any] | None = None, evaluate: bool = False, filename: str = '<?>')[source]#
Bases:
object
The Lissp Reader
Wraps around a Hissp compiler instance and creates a Lissp parser.
- class hissp.reader.Parser(lissp: Lissp, tokens: Lexer)[source]#
Bases:
Iterator
The parser for the Lissp language.
Parses Lissp tokens into Hissp syntax trees.
The
special tag
s are handled here. They are'
`
(backtick)template quote
(starts atemplate
)_#
.#
inject tag
(evaluate at read time)Plus the three built-in template helpers, which are only valid inside a template.
,
,@
$#
And finally, the
stararg token
special tags*=
and**=
.Special tags are reserved by the reader and cannot be reassigned.
- position(index: int | None = None) tuple[str, int, int, str] [source]#
Get the
filename
,lineno
,offset
andtext
for aSyntaxError
, from theLexer
given toparse
.
- static bare(v: str)[source]#
Preprocesses a
bare token
. Handles escapes and munging.
- hissp.reader.is_hissp_string(form: object) TypeGuard[str | tuple[Literal['quote'], str]] [source]#
Determines if form would directly represent a string in Hissp. (A
Hissp string
.)Allows
readerless mode
-style strings:('quote','foo',)
and anystring literal fragment
:'"foo"'
(including the"('foo')"
form produced by the Lissp reader).Macros often produce strings in one of these forms, via
quote
orrepr
on a string object.
- hissp.reader.is_lissp_unicode(form: object) TypeGuard[str] [source]#
Determines if form could have been read from a Lissp
Unicode token
.Itâs not enough to check if the form has a string type. Several token types such as a
control token
,symbol token
, orfragment token
, read in as astr atom
. Macros may need to distinguish these cases.
- hissp.reader.is_string_literal(form: object) TypeGuard[str] [source]#
Determines if
ast.literal_eval
on form produces a string. (Astring literal fragment
.)
- hissp.reader.is_qualifiable(symbol: str) bool [source]#
Determines if symbol can be qualified with a module.
Canât be
quote
,__import__
, any Python reserved word, a prefix auto-gensym
, fully qualified, method syntax, or amodule handle
; and must be a valid identifier or attribute identifier.
- hissp.reader.transpile(package: str | None, *modules: str) None [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 ââ orNone
,transpile
writes non- packaged modules to the current working directory instead.
- hissp.reader.transpile_packaged(resource: str, package: str) None [source]#
Locates & transpiles a packaged
.lissp
resource file to.py
.
- hissp.reader.transpile_file(path: Path | str, package: str | None = 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.