Source code for pyVHDLModel.Expression

# ==================================================================================================================== #
#             __     ___   _ ____  _     __  __           _      _                                                     #
#   _ __  _   \ \   / / | | |  _ \| |   |  \/  | ___   __| | ___| |                                                    #
#  | '_ \| | | \ \ / /| |_| | | | | |   | |\/| |/ _ \ / _` |/ _ \ |                                                    #
#  | |_) | |_| |\ 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) )