# ==================================================================================================================== #
# __ ___ _ ____ _ __ __ _ _ #
# _ __ _ \ \ / / | | | _ \| | | \/ | ___ __| | ___| | #
# | '_ \| | | \ \ / /| |_| | | | | | | |\/| |/ _ \ / _` |/ _ \ | #
# | |_) | |_| |\ V / | _ | |_| | |___| | | | (_) | (_| | __/ | #
# | .__/ \__, | \_/ |_| |_|____/|_____|_| |_|\___/ \__,_|\___|_| #
# |_| |___/ #
# ==================================================================================================================== #
# Authors: #
# Patrick Lehmann #
# #
# License: #
# ==================================================================================================================== #
# Copyright 2017-2023 Patrick Lehmann - Boetzingen, Germany #
# Copyright 2016-2017 Patrick Lehmann - Dresden, Germany #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. #
# You may obtain a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
# #
# SPDX-License-Identifier: Apache-2.0 #
# ==================================================================================================================== #
#
"""
This module contains parts of an abstract document language model for VHDL.
All declarations for literals, aggregates, operators forming an expressions.
"""
from typing import Tuple, List, Iterable
from pyTooling.Decorators import export
from pyVHDLModel.Base import ModelEntity, ExpressionUnion, Direction
from pyVHDLModel.Symbol import Symbol
@export
class BaseExpression(ModelEntity):
"""A ``BaseExpression`` is a base-class for all expressions."""
@export
class Literal(BaseExpression):
"""A ``Literal`` is a base-class for all literals."""
@export
class NullLiteral(Literal):
[docs] def __str__(self) -> str:
return "null"
@export
class EnumerationLiteral(Literal):
_value: str
def __init__(self, value: str):
super().__init__()
self._value = value
@property
def Value(self) -> str:
return self._value
[docs] def __str__(self) -> str:
return self._value
@export
class NumericLiteral(Literal):
"""A ``NumericLiteral`` is a base-class for all numeric literals."""
@export
class IntegerLiteral(NumericLiteral):
_value: int
def __init__(self, value: int):
super().__init__()
self._value = value
@property
def Value(self) -> int:
return self._value
[docs] def __str__(self) -> str:
return str(self._value)
@export
class FloatingPointLiteral(NumericLiteral):
_value: float
def __init__(self, value: float):
super().__init__()
self._value = value
@property
def Value(self) -> float:
return self._value
[docs] def __str__(self) -> str:
return str(self._value)
@export
class PhysicalLiteral(NumericLiteral):
_unitName: str
def __init__(self, unitName: str):
super().__init__()
self._unitName = unitName
@property
def UnitName(self) -> str:
return self._unitName
def __str__(self) -> str:
return f"{self._value} {self._unitName}"
@export
class PhysicalIntegerLiteral(PhysicalLiteral):
_value: int
def __init__(self, value: int, unitName: str):
super().__init__(unitName)
self._value = value
@property
def Value(self) -> int:
return self._value
@export
class PhysicalFloatingLiteral(PhysicalLiteral):
_value: float
def __init__(self, value: float, unitName: str):
super().__init__(unitName)
self._value = value
@property
def Value(self) -> float:
return self._value
@export
class CharacterLiteral(Literal):
_value: str
def __init__(self, value: str):
super().__init__()
self._value = value
@property
def Value(self) -> str:
return self._value
[docs] def __str__(self) -> str:
return str(self._value)
@export
class StringLiteral(Literal):
_value: str
def __init__(self, value: str):
super().__init__()
self._value = value
@property
def Value(self) -> str:
return self._value
[docs] def __str__(self) -> str:
return "\"" + self._value + "\""
@export
class BitStringLiteral(Literal):
_value: str
def __init__(self, value: str):
super().__init__()
self._value = value
@property
def Value(self) -> str:
return self._value
def __str__(self) -> str:
return "\"" + self._value + "\""
@export
class ParenthesisExpression: #(Protocol):
@property
def Operand(self) -> ExpressionUnion:
return None
@export
class UnaryExpression(BaseExpression):
"""A ``UnaryExpression`` is a base-class for all unary expressions."""
_FORMAT: Tuple[str, str]
_operand: ExpressionUnion
def __init__(self, operand: ExpressionUnion):
super().__init__()
self._operand = operand
# operand._parent = self # FIXME: operand is provided as None
@property
def Operand(self):
return self._operand
def __str__(self) -> str:
return f"{self._FORMAT[0]}{self._operand!s}{self._FORMAT[1]}"
@export
class NegationExpression(UnaryExpression):
_FORMAT = ("-", "")
@export
class IdentityExpression(UnaryExpression):
_FORMAT = ("+", "")
@export
class InverseExpression(UnaryExpression):
_FORMAT = ("not ", "")
@export
class AbsoluteExpression(UnaryExpression):
_FORMAT = ("abs ", "")
@export
class TypeConversion(UnaryExpression):
pass
@export
class SubExpression(UnaryExpression, ParenthesisExpression):
_FORMAT = ("(", ")")
@export
class BinaryExpression(BaseExpression):
"""A ``BinaryExpression`` is a base-class for all binary expressions."""
_FORMAT: Tuple[str, str, str]
_leftOperand: ExpressionUnion
_rightOperand: ExpressionUnion
def __init__(self, leftOperand: ExpressionUnion, rightOperand: ExpressionUnion):
super().__init__()
self._leftOperand = leftOperand
leftOperand._parent = self
self._rightOperand = rightOperand
rightOperand._parent = self
@property
def LeftOperand(self):
return self._leftOperand
@property
def RightOperand(self):
return self._rightOperand
def __str__(self) -> str:
return "{leftOperator}{leftOperand!s}{middleOperator}{rightOperand!s}{rightOperator}".format(
leftOperator=self._FORMAT[0],
leftOperand=self._leftOperand,
middleOperator=self._FORMAT[1],
rightOperand=self._rightOperand,
rightOperator=self._FORMAT[2],
)
@export
class RangeExpression(BinaryExpression):
_direction: Direction
@property
def Direction(self) -> Direction:
return self._direction
@export
class AscendingRangeExpression(RangeExpression):
_direction = Direction.To
_FORMAT = ("", " to ", "")
@export
class DescendingRangeExpression(RangeExpression):
_direction = Direction.DownTo
_FORMAT = ("", " downto ", "")
@export
class AddingExpression(BinaryExpression):
"""A ``AddingExpression`` is a base-class for all adding expressions."""
@export
class AdditionExpression(AddingExpression):
_FORMAT = ("", " + ", "")
@export
class SubtractionExpression(AddingExpression):
_FORMAT = ("", " - ", "")
@export
class ConcatenationExpression(AddingExpression):
_FORMAT = ("", " & ", "")
@export
class MultiplyingExpression(BinaryExpression):
"""A ``MultiplyingExpression`` is a base-class for all multiplying expressions."""
@export
class MultiplyExpression(MultiplyingExpression):
_FORMAT = ("", " * ", "")
@export
class DivisionExpression(MultiplyingExpression):
_FORMAT = ("", " / ", "")
@export
class RemainderExpression(MultiplyingExpression):
_FORMAT = ("", " rem ", "")
@export
class ModuloExpression(MultiplyingExpression):
_FORMAT = ("", " mod ", "")
@export
class ExponentiationExpression(MultiplyingExpression):
_FORMAT = ("", "**", "")
@export
class LogicalExpression(BinaryExpression):
"""A ``LogicalExpression`` is a base-class for all logical expressions."""
@export
class AndExpression(LogicalExpression):
_FORMAT = ("", " and ", "")
@export
class NandExpression(LogicalExpression):
_FORMAT = ("", " nand ", "")
@export
class OrExpression(LogicalExpression):
_FORMAT = ("", " or ", "")
@export
class NorExpression(LogicalExpression):
_FORMAT = ("", " nor ", "")
@export
class XorExpression(LogicalExpression):
_FORMAT = ("", " xor ", "")
@export
class XnorExpression(LogicalExpression):
_FORMAT = ("", " xnor ", "")
@export
class RelationalExpression(BinaryExpression):
"""A ``RelationalExpression`` is a base-class for all shifting expressions."""
@export
class EqualExpression(RelationalExpression):
_FORMAT = ("", " = ", "")
@export
class UnequalExpression(RelationalExpression):
_FORMAT = ("", " /= ", "")
@export
class GreaterThanExpression(RelationalExpression):
_FORMAT = ("", " > ", "")
@export
class GreaterEqualExpression(RelationalExpression):
_FORMAT = ("", " >= ", "")
@export
class LessThanExpression(RelationalExpression):
_FORMAT = ("", " < ", "")
@export
class LessEqualExpression(RelationalExpression):
_FORMAT = ("", " <= ", "")
@export
class MatchingRelationalExpression(RelationalExpression):
pass
@export
class MatchingEqualExpression(MatchingRelationalExpression):
_FORMAT = ("", " ?= ", "")
@export
class MatchingUnequalExpression(MatchingRelationalExpression):
_FORMAT = ("", " ?/= ", "")
@export
class MatchingGreaterThanExpression(MatchingRelationalExpression):
_FORMAT = ("", " ?> ", "")
@export
class MatchingGreaterEqualExpression(MatchingRelationalExpression):
_FORMAT = ("", " ?>= ", "")
@export
class MatchingLessThanExpression(MatchingRelationalExpression):
_FORMAT = ("", " ?< ", "")
@export
class MatchingLessEqualExpression(MatchingRelationalExpression):
_FORMAT = ("", " ?<= ", "")
@export
class ShiftExpression(BinaryExpression):
"""A ``ShiftExpression`` is a base-class for all shifting expressions."""
@export
class ShiftLogicExpression(ShiftExpression):
pass
@export
class ShiftArithmeticExpression(ShiftExpression):
pass
@export
class RotateExpression(ShiftExpression):
pass
@export
class ShiftRightLogicExpression(ShiftLogicExpression):
_FORMAT = ("", " srl ", "")
@export
class ShiftLeftLogicExpression(ShiftLogicExpression):
_FORMAT = ("", " sll ", "")
@export
class ShiftRightArithmeticExpression(ShiftArithmeticExpression):
_FORMAT = ("", " sra ", "")
@export
class ShiftLeftArithmeticExpression(ShiftArithmeticExpression):
_FORMAT = ("", " sla ", "")
@export
class RotateRightExpression(RotateExpression):
_FORMAT = ("", " ror ", "")
@export
class RotateLeftExpression(RotateExpression):
_FORMAT = ("", " rol ", "")
@export
class QualifiedExpression(BaseExpression, ParenthesisExpression):
_operand: ExpressionUnion
_subtype: Symbol
def __init__(self, subtype: Symbol, operand: ExpressionUnion):
super().__init__()
self._operand = operand
operand._parent = self
self._subtype = subtype
subtype._parent = self
@property
def Operand(self):
return self._operand
@property
def Subtyped(self):
return self._subtype
[docs] def __str__(self) -> str:
return f"{self._subtype}'({self._operand!s})"
@export
class TernaryExpression(BaseExpression):
"""A ``TernaryExpression`` is a base-class for all ternary expressions."""
_FORMAT: Tuple[str, str, str, str]
_firstOperand: ExpressionUnion
_secondOperand: ExpressionUnion
_thirdOperand: ExpressionUnion
def __init__(self):
super().__init__()
# FIXME: parameters and initializers are missing !!
@property
def FirstOperand(self):
return self._firstOperand
@property
def SecondOperand(self):
return self._secondOperand
@property
def ThirdOperand(self):
return self._thirdOperand
def __str__(self) -> str:
return "{beforeFirstOperator}{firstOperand!s}{beforeSecondOperator}{secondOperand!s}{beforeThirdOperator}{thirdOperand!s}{lastOperator}".format(
beforeFirstOperator=self._FORMAT[0],
firstOperand=self._firstOperand,
beforeSecondOperator=self._FORMAT[1],
secondOperand=self._secondOperand,
beforeThirdOperator=self._FORMAT[2],
thirdOperand=self._thirdOperand,
lastOperator=self._FORMAT[4],
)
@export
class WhenElseExpression(TernaryExpression):
_FORMAT = ("", " when ", " else ", "")
@export
class FunctionCall(BaseExpression):
pass
@export
class Allocation(BaseExpression):
pass
@export
class SubtypeAllocation(Allocation):
_subtype: Symbol
def __init__(self, subtype: Symbol):
super().__init__()
self._subtype = subtype
subtype._parent = self
@property
def Subtype(self) -> Symbol:
return self._subtype
[docs] def __str__(self) -> str:
return f"new {self._subtype!s}"
@export
class QualifiedExpressionAllocation(Allocation):
_qualifiedExpression: QualifiedExpression
def __init__(self, qualifiedExpression: QualifiedExpression):
super().__init__()
self._qualifiedExpression = qualifiedExpression
qualifiedExpression._parent = self
@property
def QualifiedExpression(self) -> QualifiedExpression:
return self._qualifiedExpression
[docs] def __str__(self) -> str:
return f"new {self._qualifiedExpression!s}"
@export
class AggregateElement(ModelEntity):
"""A ``AggregateElement`` is a base-class for all aggregate elements."""
_expression: ExpressionUnion
def __init__(self, expression: ExpressionUnion):
super().__init__()
self._expression = expression
expression._parent = self
@property
def Expression(self):
return self._expression
@export
class SimpleAggregateElement(AggregateElement):
[docs] def __str__(self) -> str:
return str(self._expression)
@export
class IndexedAggregateElement(AggregateElement):
_index: int
def __init__(self, index: ExpressionUnion, expression: ExpressionUnion):
super().__init__(expression)
self._index = index
@property
def Index(self) -> int:
return self._index
[docs] def __str__(self) -> str:
return f"{self._index!s} => {self._expression!s}"
@export
class RangedAggregateElement(AggregateElement):
_range: 'Range'
def __init__(self, rng: 'Range', expression: ExpressionUnion):
super().__init__(expression)
self._range = rng
rng._parent = self
@property
def Range(self) -> 'Range':
return self._range
[docs] def __str__(self) -> str:
return f"{self._range!s} => {self._expression!s}"
@export
class NamedAggregateElement(AggregateElement):
_name: Symbol
def __init__(self, name: Symbol, expression: ExpressionUnion):
super().__init__(expression)
self._name = name
name._parent = self
@property
def Name(self) -> Symbol:
return self._name
[docs] def __str__(self) -> str:
return "{name!s} => {value!s}".format(
name=self._name,
value=self._expression,
)
@export
class OthersAggregateElement(AggregateElement):
[docs] def __str__(self) -> str:
return "others => {value!s}".format(
value=self._expression,
)
@export
class Aggregate(BaseExpression):
_elements: List[AggregateElement]
def __init__(self, elements: Iterable[AggregateElement]):
super().__init__()
self._elements = []
for element in elements:
self._elements.append(element)
element._parent = self
@property
def Elements(self) -> List[AggregateElement]:
return self._elements
[docs] def __str__(self) -> str:
choices = [str(element) for element in self._elements]
return "({choices})".format(
choices=", ".join(choices)
)