# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""Facility for symbolically referencing type variables.
Type variables are instances of the TypeVar class, which is uniqued by name.
An "expando" accessor `TV` is provided that generates a named TypeVar for
any attribute access:
>>> TV.T
TypeVar(T)
>>> TV.T is TV.U
False
>>> TV.T is TV.T
True
"""
from enum import Enum
from typing import Dict
__all__ = [
"TypeVar",
"TV",
# Predefined types.
"I32",
"I64",
"F32",
"F64",
# TypeVar aliases.
"T",
"U",
"V",
]
class TypeVar:
"""A replaceable type variable.
Type variables are uniqued by name.
"""
ALL_TYPEVARS = dict() # type: Dict[str, "TypeVar"]
def __new__(cls, name: str):
existing = cls.ALL_TYPEVARS.get(name)
if existing is not None:
return existing
new = super().__new__(cls)
new.name = name
cls.ALL_TYPEVARS[name] = new
return new
def __repr__(self):
return f"TypeVar({self.name})"
@classmethod
def create_expando(cls):
"""Create an expando class that creates unique type vars on attr access."""
class ExpandoTypeVars:
def __getattr__(self, n):
return cls(n)
return ExpandoTypeVars()
# Expando access via TV.foo
TV = TypeVar.create_expando()
# Predefined types.
I32 = TV.I32
I64 = TV.I64
F32 = TV.F32
F64 = TV.F64
# Some common type name aliases.
T = TV.T
U = TV.U
V = TV.V