Skip to content

Commit

Permalink
Represent arithmetic negation by class
Browse files Browse the repository at this point in the history
Ref. eng/recordflux/RecordFlux#1395
  • Loading branch information
treiher committed Feb 14, 2024
1 parent 71e53d9 commit 2b71b3a
Show file tree
Hide file tree
Showing 9 changed files with 335 additions and 203 deletions.
81 changes: 45 additions & 36 deletions rflx/ada.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,25 @@ def rflx_expr(self) -> expr.Not:
return expr.Not(self.expression.rflx_expr())


class Neg(Expr):
def __init__(self, expression: Expr) -> None:
super().__init__()
self.expression = expression

def __neg__(self) -> Expr:
return self.expression

def _update_str(self) -> None:
self._str = intern(f"(-{self.parenthesized(self.expression)})")

@property
def precedence(self) -> Precedence:
return Precedence.HIGHEST_PRECEDENCE_OPERATOR

def rflx_expr(self) -> expr.Neg:
return expr.Neg(self.expression.rflx_expr())


class BinExpr(Expr):
def __init__(self, left: Expr, right: Expr) -> None:
super().__init__()
Expand Down Expand Up @@ -224,7 +243,7 @@ class Add(AssExpr):
def _update_str(self) -> None:
self._str = str(self.terms[0])
for t in self.terms[1:]:
if (isinstance(t, Number) and t.value < 0) or (isinstance(t, Name) and t.negative):
if (isinstance(t, Number) and t.value < 0) or isinstance(t, Neg):
self._str += f" - {self.parenthesized(-t)}"
else:
self._str += f"{self.symbol}{self.parenthesized(t)}"
Expand Down Expand Up @@ -310,13 +329,12 @@ def symbol(self) -> str:


class Name(Expr):
def __init__(self, negative: bool = False) -> None:
def __init__(self) -> None:
super().__init__()
self.negative = negative
self._update_str()

def _update_str(self) -> None:
self._str = intern(f"(-{self._representation})" if self.negative else self._representation)
self._str = intern(self._representation)

@property
@abstractmethod
Expand All @@ -331,7 +349,7 @@ def precedence(self) -> Precedence:
class Literal(Name):
def __init__(self, identifier: StrID) -> None:
self.identifier = ID(identifier)
super().__init__(negative=False)
super().__init__()

@property
def _representation(self) -> str:
Expand All @@ -346,12 +364,12 @@ def rflx_expr(self) -> expr.Literal:


class Variable(Name):
def __init__(self, identifier: StrID, negative: bool = False) -> None:
def __init__(self, identifier: StrID) -> None:
self.identifier = ID(identifier)
super().__init__(negative)
super().__init__()

def __neg__(self) -> Variable:
return self.__class__(self.identifier, not self.negative)
def __neg__(self) -> Neg:
return Neg(self)

@property
def _representation(self) -> str:
Expand All @@ -371,24 +389,24 @@ def rflx_expr(self) -> expr.Variable:


class Attribute(Name):
def __init__(self, prefix: Union[StrID, Expr], negative: bool = False) -> None:
def __init__(self, prefix: Union[StrID, Expr]) -> None:
if isinstance(prefix, ID):
prefix = Variable(prefix)
if isinstance(prefix, str):
prefix = Variable(prefix)

self.prefix: Expr = prefix
super().__init__(negative)
super().__init__()

def __neg__(self) -> Attribute:
return self.__class__(self.prefix, not self.negative)
def __neg__(self) -> Neg:
return Neg(self)

@property
def _representation(self) -> str:
return f"{self.prefix}'{self.__class__.__name__}"

def rflx_expr(self) -> expr.Attribute:
result = getattr(expr, self.__class__.__name__)(self.prefix.rflx_expr(), self.negative)
result = getattr(expr, self.__class__.__name__)(self.prefix.rflx_expr())
assert isinstance(result, expr.Attribute)
return result

Expand Down Expand Up @@ -462,7 +480,6 @@ def __init__(
self,
prefix: Union[StrID, Expr],
expression: Expr,
negative: bool = False, # noqa: ARG002
) -> None:
self.expression = expression
super().__init__(prefix)
Expand Down Expand Up @@ -523,13 +540,13 @@ class Update(NamedAttributeExpr):

@invariant(lambda self: len(self.elements) > 0)
class Indexed(Name):
def __init__(self, prefix: Expr, *elements: Expr, negative: bool = False) -> None:
def __init__(self, prefix: Expr, *elements: Expr) -> None:
self.prefix = prefix
self.elements = list(elements)
super().__init__(negative)
super().__init__()

def __neg__(self) -> Indexed:
return self.__class__(self.prefix, *self.elements, negative=not self.negative)
def __neg__(self) -> Neg:
return Neg(self)

@property
def _representation(self) -> str:
Expand All @@ -539,7 +556,6 @@ def rflx_expr(self) -> expr.Indexed:
return expr.Indexed(
self.prefix.rflx_expr(),
*[e.rflx_expr() for e in self.elements],
negative=self.negative,
)


Expand All @@ -548,21 +564,20 @@ def __init__(
self,
prefix: Expr,
selector: StrID,
negative: bool = False,
) -> None:
self.prefix = prefix
self.selector = ID(selector)
super().__init__(negative)
super().__init__()

def __neg__(self) -> Selected:
return self.__class__(self.prefix, self.selector, not self.negative)
def __neg__(self) -> Neg:
return Neg(self)

@property
def _representation(self) -> str:
return f"{self.prefix}.{self.selector}"

def rflx_expr(self) -> expr.Selected:
return expr.Selected(self.prefix.rflx_expr(), self.selector, self.negative)
return expr.Selected(self.prefix.rflx_expr(), self.selector)


class Call(Name):
Expand All @@ -571,20 +586,14 @@ def __init__(
identifier: StrID,
arguments: Optional[Sequence[Expr]] = None,
named_arguments: Optional[Mapping[ID, Expr]] = None,
negative: bool = False,
) -> None:
self.identifier = ID(identifier)
self.arguments = arguments or []
self.named_arguments = named_arguments or {}
super().__init__(negative)

def __neg__(self) -> Call:
return self.__class__(
self.identifier,
self.arguments,
self.named_arguments,
not self.negative,
)
super().__init__()

def __neg__(self) -> Neg:
return Neg(self)

@property
def _representation(self) -> str:
Expand All @@ -600,7 +609,7 @@ def _representation(self) -> str:

def rflx_expr(self) -> expr.Call:
assert not self.named_arguments
return expr.Call(self.identifier, [a.rflx_expr() for a in self.arguments], self.negative)
return expr.Call(self.identifier, [a.rflx_expr() for a in self.arguments])


class Slice(Name):
Expand Down
Loading

0 comments on commit 2b71b3a

Please sign in to comment.