Skip to content

Commit

Permalink
Cache compiled modules
Browse files Browse the repository at this point in the history
This is required for defonce.

`transpile` will also set `__file__`.
  • Loading branch information
gilch committed Sep 24, 2023
1 parent 2073a37 commit e672348
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 18 deletions.
16 changes: 8 additions & 8 deletions docs/lissp_whirlwind_tour.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1643,7 +1643,7 @@ Lissp Whirlwind Tour
... ('(print "Hello from spam!")\n(.update (globals) : x 42)'))
53

#> (hissp.reader..transpile __package__ 'spam 'eggs) ; Side effects on compilation
#> (hissp.reader..transpile __package__ 'spam 'eggs) ;Side effects on compilation.
>>> __import__('hissp.reader',fromlist='?').transpile(
... __package__,
... 'spam',
Expand All @@ -1652,20 +1652,20 @@ Lissp Whirlwind Tour
Hello World!


#> spam..x ; and import!
>>> __import__('spam').x
Hello from spam!
42

#> spam..x ;Python caches imports.
#> spam..x ;Python caches compiler's imports,
>>> __import__('spam').x
42

#> eggs.
>>> __import__('eggs')
Hello World!
<module 'eggs' from ...>

#> (importlib..reload spam.) ; but side effects happen on reload.
>>> __import__('importlib').reload(
... __import__('spam'))
Hello from spam!
<module 'spam' from ...>


#> (any (map (lambda f (os..remove f)) ;Cleanup.
#.. '(eggs.lissp spam.lissp spam.py eggs.py)))
Expand Down
15 changes: 8 additions & 7 deletions src/hissp/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
from contextlib import contextmanager, suppress
from contextvars import ContextVar
from functools import wraps
from itertools import chain, takewhile, starmap
from itertools import chain, starmap, takewhile
from pprint import pformat
from traceback import format_exc
from types import ModuleType
from typing import Iterable, List, NewType, Tuple, TypeVar, Union
from typing import Any, Dict, Iterable, List, NewType, Tuple, TypeVar, Union
from warnings import warn

PAIR_WORDS = {":*": "*", ":**": "**", ":?": ""}
Expand Down Expand Up @@ -95,16 +95,17 @@ def __init__(self, qualname="__main__", ns=None, evaluate=True):
self.abort = None

@staticmethod
def new_ns(name, doc=None, package=None):
"""Creates and initializes a dict namespace like a module,
with the given `__name__`, ``__doc__``, and `__package__`;
``__builtins__``; an empty ``__annotations__``; and whatever
else Python currently adds to new module objects.
def new_ns(name, doc=None, package=None) -> Dict[str, Any]:
"""Imports the named module, creating it if necessary.
Returns the module's ``__dict__``.
"""
mod = ModuleType(name, doc)
mod.__annotations__ = {}
mod.__package__ = package
mod.__builtins__ = builtins
if name != "__main__":
mod = sys.modules.setdefault(name, mod)
return vars(mod)

def compile(self, forms: Iterable) -> str:
Expand Down
10 changes: 7 additions & 3 deletions src/hissp/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from pathlib import Path, PurePath
from pprint import pformat
from threading import Lock
from typing import Any, Iterable, Iterator, NewType, Optional, Tuple, Union, List
from typing import Any, Dict, Iterable, Iterator, List, NewType, Optional, Tuple, Union

import hissp.compiler as C
from hissp.compiler import Compiler, readerless
Expand Down Expand Up @@ -218,7 +218,7 @@ def reinit(self):
self._p = 0

@property
def ns(self):
def ns(self) -> Dict[str, Any]:
"""The wrapped `Compiler`'s ``ns``."""
return self.compiler.ns

Expand Down Expand Up @@ -603,9 +603,13 @@ def transpile_file(path: Union[Path, str], package: Optional[str] = None):
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.
"""
path = Path(path).resolve(strict=True)
qualname = f"{package or ''}{'.' if package else ''}{PurePath(path.name).stem}"
L = Lissp(qualname=qualname, evaluate=True, filename=str(path))
python = L.compile(re.sub(r"^#!.*\n", "", path.read_text("utf8")))
path.with_suffix(".py").write_text(python, "utf8")
(py := path.with_suffix(".py")).write_text(python, "utf8")
L.ns.setdefault("__file__", str(py))

0 comments on commit e672348

Please sign in to comment.