Skip to content

Commit

Permalink
feat!: Support implicit modules for all decorators and turn builtins …
Browse files Browse the repository at this point in the history
…into implicit module (#476)

Closes #463.

BREAKING CHANGE: The `GuppyModule` argument is now optional for all
decorators and no longer the first positional argument. Removed the
explicit module objects `builtins`, `quantum`, and `angle`.

---------

Co-authored-by: Alan Lawrence <alan.lawrence@cambridgequantum.com>
  • Loading branch information
mark-koch and acl-cqc authored Sep 16, 2024
1 parent 0b0b1af commit cc8a424
Show file tree
Hide file tree
Showing 69 changed files with 596 additions and 516 deletions.
223 changes: 163 additions & 60 deletions guppylang/decorator.py

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion guppylang/ipython_inspect.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Tools for inspecting source code when running in IPython."""

import ast
from typing import NamedTuple, cast
from typing import Any, NamedTuple, cast


def is_running_ipython() -> bool:
Expand Down Expand Up @@ -54,3 +54,11 @@ def find_ipython_def(name: str) -> IPythonDef | None:
cell_name = f"In [{len(cell_sources) - i}]"
return IPythonDef(node, cell_name, cell_source)
return None


def get_ipython_globals() -> dict[str, Any]:
"""Returns the globals of the current IPython kernel."""
try:
return get_ipython().user_ns # type: ignore[name-defined, no-any-return]
except NameError:
raise RuntimeError("Not running in IPython") from None
1 change: 1 addition & 0 deletions guppylang/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from guppylang.definition.ty import TypeDef
from guppylang.error import GuppyError, pretty_errors

PyClass = type
PyFunc = Callable[..., Any]
PyFuncDefOrDecl = tuple[bool, PyFunc]

Expand Down
36 changes: 16 additions & 20 deletions guppylang/prelude/angles.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@
from hugr import val as hv

from guppylang.decorator import guppy
from guppylang.module import GuppyModule
from guppylang.prelude._internal.checker import CoercingChecker
from guppylang.prelude._internal.compiler.angle import AngleOpCompiler
from guppylang.prelude.builtins import nat

angles = GuppyModule("angles")


_hugr_angle_type = ht.Opaque("angle", ht.TypeBound.Copyable, [], "tket2.quantum")


Expand All @@ -32,68 +28,68 @@ def _hugr_angle_value(numerator: int, log_denominator: int) -> hv.Value:
)


pi = guppy.constant(angles, "pi", ty="angle", value=_hugr_angle_value(1, 1))
pi = guppy.constant("pi", ty="angle", value=_hugr_angle_value(1, 1))


@guppy.type(angles, _hugr_angle_type)
@guppy.type(_hugr_angle_type)
class angle:
"""The type of angles represented as dyadic rational multiples of 2π."""

@guppy.custom(angles, AngleOpCompiler("afromrad"), CoercingChecker())
@guppy.custom(AngleOpCompiler("afromrad"), CoercingChecker())
def __new__(radians: float) -> "angle": ...

@guppy.custom(angles, AngleOpCompiler("aadd"))
@guppy.custom(AngleOpCompiler("aadd"))
def __add__(self: "angle", other: "angle") -> "angle": ...

@guppy.custom(angles, AngleOpCompiler("asub"))
@guppy.custom(AngleOpCompiler("asub"))
def __sub__(self: "angle", other: "angle") -> "angle": ...

@guppy.custom(angles, AngleOpCompiler("aneg"))
@guppy.custom(AngleOpCompiler("aneg"))
def __neg__(self: "angle") -> "angle": ...

@guppy.custom(angles, AngleOpCompiler("atorad"))
@guppy.custom(AngleOpCompiler("atorad"))
def __float__(self: "angle") -> float: ...

@guppy.custom(angles, AngleOpCompiler("aeq"))
@guppy.custom(AngleOpCompiler("aeq"))
def __eq__(self: "angle", other: "angle") -> bool: ...

@guppy(angles)
@guppy
@no_type_check
def __mul__(self: "angle", other: int) -> "angle":
if other < 0:
return self._nat_mul(nat(other))
else:
return -self._nat_mul(nat(other))

@guppy(angles)
@guppy
@no_type_check
def __rmul__(self: "angle", other: int) -> "angle":
return self * other

@guppy(angles)
@guppy
@no_type_check
def __truediv__(self: "angle", other: int) -> "angle":
if other < 0:
return self._nat_div(nat(other))
else:
return -self._nat_div(nat(other))

@guppy.custom(angles, AngleOpCompiler("amul"))
@guppy.custom(AngleOpCompiler("amul"))
def _nat_mul(self: "angle", other: nat) -> "angle": ...

@guppy.custom(angles, AngleOpCompiler("aneg"))
@guppy.custom(AngleOpCompiler("aneg"))
def _nat_div(self: "angle", other: nat) -> "angle": ...

@guppy.custom(angles, AngleOpCompiler("aparts"))
@guppy.custom(AngleOpCompiler("aparts"))
def _parts(self: "angle") -> tuple[nat, nat]: ...

@guppy(angles)
@guppy
@no_type_check
def numerator(self: "angle") -> nat:
numerator, _ = self._parts()
return numerator

@guppy(angles)
@guppy
@no_type_check
def log_denominator(self: "angle") -> nat:
_, log_denominator = self._parts()
Expand Down
Loading

0 comments on commit cc8a424

Please sign in to comment.