Coverage for pyVHDLModel/Expression.py: 80%
453 statements
« prev ^ index » next coverage.py v7.6.7, created at 2024-11-22 22:15 +0000
« prev ^ index » next coverage.py v7.6.7, created at 2024-11-22 22:15 +0000
1# ==================================================================================================================== #
2# __ ___ _ ____ _ __ __ _ _ #
3# _ __ _ \ \ / / | | | _ \| | | \/ | ___ __| | ___| | #
4# | '_ \| | | \ \ / /| |_| | | | | | | |\/| |/ _ \ / _` |/ _ \ | #
5# | |_) | |_| |\ V / | _ | |_| | |___| | | | (_) | (_| | __/ | #
6# | .__/ \__, | \_/ |_| |_|____/|_____|_| |_|\___/ \__,_|\___|_| #
7# |_| |___/ #
8# ==================================================================================================================== #
9# Authors: #
10# Patrick Lehmann #
11# #
12# License: #
13# ==================================================================================================================== #
14# Copyright 2017-2024 Patrick Lehmann - Boetzingen, Germany #
15# Copyright 2016-2017 Patrick Lehmann - Dresden, Germany #
16# #
17# Licensed under the Apache License, Version 2.0 (the "License"); #
18# you may not use this file except in compliance with the License. #
19# You may obtain a copy of the License at #
20# #
21# http://www.apache.org/licenses/LICENSE-2.0 #
22# #
23# Unless required by applicable law or agreed to in writing, software #
24# distributed under the License is distributed on an "AS IS" BASIS, #
25# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
26# See the License for the specific language governing permissions and #
27# limitations under the License. #
28# #
29# SPDX-License-Identifier: Apache-2.0 #
30# ==================================================================================================================== #
31#
32"""
33This module contains parts of an abstract document language model for VHDL.
35All declarations for literals, aggregates, operators forming an expressions.
36"""
37from typing import Tuple, List, Iterable, Union
39from pyTooling.Decorators import export, readonly
41from pyVHDLModel.Base import ModelEntity, Direction, Range
42from pyVHDLModel.Symbol import Symbol
45ExpressionUnion = Union[
46 'BaseExpression',
47 'QualifiedExpression',
48 'FunctionCall',
49 'TypeConversion',
50 # ConstantOrSymbol, TODO: ObjectSymbol
51 'Literal',
52]
55@export
56class BaseExpression(ModelEntity):
57 """A ``BaseExpression`` is a base-class for all expressions."""
60@export
61class Literal(BaseExpression):
62 """A ``Literal`` is a base-class for all literals."""
65@export
66class NullLiteral(Literal):
67 def __str__(self) -> str:
68 return "null"
71@export
72class EnumerationLiteral(Literal):
73 _value: str
75 def __init__(self, value: str, parent: ModelEntity = None) -> None:
76 super().__init__(parent)
78 self._value = value
80 @readonly
81 def Value(self) -> str:
82 return self._value
84 def __str__(self) -> str:
85 return self._value
88@export
89class NumericLiteral(Literal):
90 """A ``NumericLiteral`` is a base-class for all numeric literals."""
93@export
94class IntegerLiteral(NumericLiteral):
95 _value: int
97 def __init__(self, value: int) -> None:
98 super().__init__()
99 self._value = value
101 @readonly
102 def Value(self) -> int:
103 return self._value
105 def __str__(self) -> str:
106 return str(self._value)
109@export
110class FloatingPointLiteral(NumericLiteral):
111 _value: float
113 def __init__(self, value: float) -> None:
114 super().__init__()
115 self._value = value
117 @readonly
118 def Value(self) -> float:
119 return self._value
121 def __str__(self) -> str:
122 return str(self._value)
125@export
126class PhysicalLiteral(NumericLiteral):
127 _unitName: str
129 def __init__(self, unitName: str) -> None:
130 super().__init__()
131 self._unitName = unitName
133 @readonly
134 def UnitName(self) -> str:
135 return self._unitName
137 def __str__(self) -> str:
138 return f"{self._value} {self._unitName}"
141@export
142class PhysicalIntegerLiteral(PhysicalLiteral):
143 _value: int
145 def __init__(self, value: int, unitName: str) -> None:
146 super().__init__(unitName)
147 self._value = value
149 @readonly
150 def Value(self) -> int:
151 return self._value
154@export
155class PhysicalFloatingLiteral(PhysicalLiteral):
156 _value: float
158 def __init__(self, value: float, unitName: str) -> None:
159 super().__init__(unitName)
160 self._value = value
162 @readonly
163 def Value(self) -> float:
164 return self._value
167@export
168class CharacterLiteral(Literal):
169 _value: str
171 def __init__(self, value: str) -> None:
172 super().__init__()
173 self._value = value
175 @readonly
176 def Value(self) -> str:
177 return self._value
179 def __str__(self) -> str:
180 return str(self._value)
183@export
184class StringLiteral(Literal):
185 _value: str
187 def __init__(self, value: str) -> None:
188 super().__init__()
189 self._value = value
191 @readonly
192 def Value(self) -> str:
193 return self._value
195 def __str__(self) -> str:
196 return "\"" + self._value + "\""
199@export
200class BitStringLiteral(Literal):
201 _value: str
203 def __init__(self, value: str) -> None:
204 super().__init__()
205 self._value = value
207 @readonly
208 def Value(self) -> str:
209 return self._value
211 def __str__(self) -> str:
212 return "\"" + self._value + "\""
215@export
216class ParenthesisExpression: #(Protocol):
217 __slots__ = () # FIXME: use ExtendedType?
219 @readonly
220 def Operand(self) -> ExpressionUnion:
221 return None
224@export
225class UnaryExpression(BaseExpression):
226 """A ``UnaryExpression`` is a base-class for all unary expressions."""
228 _FORMAT: Tuple[str, str]
229 _operand: ExpressionUnion
231 def __init__(self, operand: ExpressionUnion, parent: ModelEntity = None) -> None:
232 super().__init__(parent)
234 self._operand = operand
235 # operand._parent = self # FIXME: operand is provided as None
237 @readonly
238 def Operand(self):
239 return self._operand
241 def __str__(self) -> str:
242 return f"{self._FORMAT[0]}{self._operand!s}{self._FORMAT[1]}"
245@export
246class NegationExpression(UnaryExpression):
247 _FORMAT = ("-", "")
250@export
251class IdentityExpression(UnaryExpression):
252 _FORMAT = ("+", "")
255@export
256class InverseExpression(UnaryExpression):
257 _FORMAT = ("not ", "")
260@export
261class UnaryAndExpression(UnaryExpression):
262 _FORMAT = ("and ", "")
265@export
266class UnaryNandExpression(UnaryExpression):
267 _FORMAT = ("nand ", "")
270@export
271class UnaryOrExpression(UnaryExpression):
272 _FORMAT = ("or ", "")
275@export
276class UnaryNorExpression(UnaryExpression):
277 _FORMAT = ("nor ", "")
280@export
281class UnaryXorExpression(UnaryExpression):
282 _FORMAT = ("xor ", "")
285@export
286class UnaryXnorExpression(UnaryExpression):
287 _FORMAT = ("xnor ", "")
290@export
291class AbsoluteExpression(UnaryExpression):
292 _FORMAT = ("abs ", "")
295@export
296class TypeConversion(UnaryExpression):
297 pass
300@export
301class SubExpression(UnaryExpression, ParenthesisExpression):
302 _FORMAT = ("(", ")")
305@export
306class BinaryExpression(BaseExpression):
307 """A ``BinaryExpression`` is a base-class for all binary expressions."""
309 _FORMAT: Tuple[str, str, str]
310 _leftOperand: ExpressionUnion
311 _rightOperand: ExpressionUnion
313 def __init__(self, leftOperand: ExpressionUnion, rightOperand: ExpressionUnion, parent: ModelEntity = None) -> None:
314 super().__init__(parent)
316 self._leftOperand = leftOperand
317 leftOperand._parent = self
319 self._rightOperand = rightOperand
320 rightOperand._parent = self
322 @property
323 def LeftOperand(self):
324 return self._leftOperand
326 @property
327 def RightOperand(self):
328 return self._rightOperand
330 def __str__(self) -> str:
331 return "{leftOperator}{leftOperand!s}{middleOperator}{rightOperand!s}{rightOperator}".format(
332 leftOperator=self._FORMAT[0],
333 leftOperand=self._leftOperand,
334 middleOperator=self._FORMAT[1],
335 rightOperand=self._rightOperand,
336 rightOperator=self._FORMAT[2],
337 )
340@export
341class RangeExpression(BinaryExpression):
342 _direction: Direction
344 @property
345 def Direction(self) -> Direction:
346 return self._direction
349@export
350class AscendingRangeExpression(RangeExpression):
351 _direction = Direction.To
352 _FORMAT = ("", " to ", "")
355@export
356class DescendingRangeExpression(RangeExpression):
357 _direction = Direction.DownTo
358 _FORMAT = ("", " downto ", "")
361@export
362class AddingExpression(BinaryExpression):
363 """A ``AddingExpression`` is a base-class for all adding expressions."""
366@export
367class AdditionExpression(AddingExpression):
368 _FORMAT = ("", " + ", "")
371@export
372class SubtractionExpression(AddingExpression):
373 _FORMAT = ("", " - ", "")
376@export
377class ConcatenationExpression(AddingExpression):
378 _FORMAT = ("", " & ", "")
381@export
382class MultiplyingExpression(BinaryExpression):
383 """A ``MultiplyingExpression`` is a base-class for all multiplying expressions."""
386@export
387class MultiplyExpression(MultiplyingExpression):
388 _FORMAT = ("", " * ", "")
391@export
392class DivisionExpression(MultiplyingExpression):
393 _FORMAT = ("", " / ", "")
396@export
397class RemainderExpression(MultiplyingExpression):
398 _FORMAT = ("", " rem ", "")
401@export
402class ModuloExpression(MultiplyingExpression):
403 _FORMAT = ("", " mod ", "")
406@export
407class ExponentiationExpression(MultiplyingExpression):
408 _FORMAT = ("", "**", "")
411@export
412class LogicalExpression(BinaryExpression):
413 """A ``LogicalExpression`` is a base-class for all logical expressions."""
416@export
417class AndExpression(LogicalExpression):
418 _FORMAT = ("", " and ", "")
421@export
422class NandExpression(LogicalExpression):
423 _FORMAT = ("", " nand ", "")
426@export
427class OrExpression(LogicalExpression):
428 _FORMAT = ("", " or ", "")
431@export
432class NorExpression(LogicalExpression):
433 _FORMAT = ("", " nor ", "")
436@export
437class XorExpression(LogicalExpression):
438 _FORMAT = ("", " xor ", "")
441@export
442class XnorExpression(LogicalExpression):
443 _FORMAT = ("", " xnor ", "")
446@export
447class RelationalExpression(BinaryExpression):
448 """A ``RelationalExpression`` is a base-class for all shifting expressions."""
451@export
452class EqualExpression(RelationalExpression):
453 _FORMAT = ("", " = ", "")
456@export
457class UnequalExpression(RelationalExpression):
458 _FORMAT = ("", " /= ", "")
461@export
462class GreaterThanExpression(RelationalExpression):
463 _FORMAT = ("", " > ", "")
466@export
467class GreaterEqualExpression(RelationalExpression):
468 _FORMAT = ("", " >= ", "")
471@export
472class LessThanExpression(RelationalExpression):
473 _FORMAT = ("", " < ", "")
476@export
477class LessEqualExpression(RelationalExpression):
478 _FORMAT = ("", " <= ", "")
481@export
482class MatchingRelationalExpression(RelationalExpression):
483 pass
486@export
487class MatchingEqualExpression(MatchingRelationalExpression):
488 _FORMAT = ("", " ?= ", "")
491@export
492class MatchingUnequalExpression(MatchingRelationalExpression):
493 _FORMAT = ("", " ?/= ", "")
496@export
497class MatchingGreaterThanExpression(MatchingRelationalExpression):
498 _FORMAT = ("", " ?> ", "")
501@export
502class MatchingGreaterEqualExpression(MatchingRelationalExpression):
503 _FORMAT = ("", " ?>= ", "")
506@export
507class MatchingLessThanExpression(MatchingRelationalExpression):
508 _FORMAT = ("", " ?< ", "")
511@export
512class MatchingLessEqualExpression(MatchingRelationalExpression):
513 _FORMAT = ("", " ?<= ", "")
516@export
517class ShiftExpression(BinaryExpression):
518 """A ``ShiftExpression`` is a base-class for all shifting expressions."""
521@export
522class ShiftLogicExpression(ShiftExpression):
523 pass
526@export
527class ShiftArithmeticExpression(ShiftExpression):
528 pass
531@export
532class RotateExpression(ShiftExpression):
533 pass
536@export
537class ShiftRightLogicExpression(ShiftLogicExpression):
538 _FORMAT = ("", " srl ", "")
541@export
542class ShiftLeftLogicExpression(ShiftLogicExpression):
543 _FORMAT = ("", " sll ", "")
546@export
547class ShiftRightArithmeticExpression(ShiftArithmeticExpression):
548 _FORMAT = ("", " sra ", "")
551@export
552class ShiftLeftArithmeticExpression(ShiftArithmeticExpression):
553 _FORMAT = ("", " sla ", "")
556@export
557class RotateRightExpression(RotateExpression):
558 _FORMAT = ("", " ror ", "")
561@export
562class RotateLeftExpression(RotateExpression):
563 _FORMAT = ("", " rol ", "")
566@export
567class QualifiedExpression(BaseExpression, ParenthesisExpression):
568 _operand: ExpressionUnion
569 _subtype: Symbol
571 def __init__(self, subtype: Symbol, operand: ExpressionUnion, parent: ModelEntity = None) -> None:
572 super().__init__(parent)
574 self._operand = operand
575 operand._parent = self
577 self._subtype = subtype
578 subtype._parent = self
580 @property
581 def Operand(self):
582 return self._operand
584 @property
585 def Subtyped(self):
586 return self._subtype
588 def __str__(self) -> str:
589 return f"{self._subtype}'({self._operand!s})"
592@export
593class TernaryExpression(BaseExpression):
594 """A ``TernaryExpression`` is a base-class for all ternary expressions."""
596 _FORMAT: Tuple[str, str, str, str]
597 _firstOperand: ExpressionUnion
598 _secondOperand: ExpressionUnion
599 _thirdOperand: ExpressionUnion
601 def __init__(self, parent: ModelEntity = None) -> None:
602 super().__init__(parent)
604 # FIXME: parameters and initializers are missing !!
606 @property
607 def FirstOperand(self):
608 return self._firstOperand
610 @property
611 def SecondOperand(self):
612 return self._secondOperand
614 @property
615 def ThirdOperand(self):
616 return self._thirdOperand
618 def __str__(self) -> str:
619 return "{beforeFirstOperator}{firstOperand!s}{beforeSecondOperator}{secondOperand!s}{beforeThirdOperator}{thirdOperand!s}{lastOperator}".format(
620 beforeFirstOperator=self._FORMAT[0],
621 firstOperand=self._firstOperand,
622 beforeSecondOperator=self._FORMAT[1],
623 secondOperand=self._secondOperand,
624 beforeThirdOperator=self._FORMAT[2],
625 thirdOperand=self._thirdOperand,
626 lastOperator=self._FORMAT[4],
627 )
630@export
631class WhenElseExpression(TernaryExpression):
632 _FORMAT = ("", " when ", " else ", "")
635@export
636class FunctionCall(BaseExpression):
637 pass
640@export
641class Allocation(BaseExpression):
642 pass
645@export
646class SubtypeAllocation(Allocation):
647 _subtype: Symbol
649 def __init__(self, subtype: Symbol, parent: ModelEntity = None) -> None:
650 super().__init__(parent)
652 self._subtype = subtype
653 subtype._parent = self
655 @property
656 def Subtype(self) -> Symbol:
657 return self._subtype
659 def __str__(self) -> str:
660 return f"new {self._subtype!s}"
663@export
664class QualifiedExpressionAllocation(Allocation):
665 _qualifiedExpression: QualifiedExpression
667 def __init__(self, qualifiedExpression: QualifiedExpression, parent: ModelEntity = None) -> None:
668 super().__init__(parent)
670 self._qualifiedExpression = qualifiedExpression
671 qualifiedExpression._parent = self
673 @property
674 def QualifiedExpression(self) -> QualifiedExpression:
675 return self._qualifiedExpression
677 def __str__(self) -> str:
678 return f"new {self._qualifiedExpression!s}"
681@export
682class AggregateElement(ModelEntity):
683 """A ``AggregateElement`` is a base-class for all aggregate elements."""
685 _expression: ExpressionUnion
687 def __init__(self, expression: ExpressionUnion, parent: ModelEntity = None) -> None:
688 super().__init__(parent)
690 self._expression = expression
691 expression._parent = self
693 @property
694 def Expression(self):
695 return self._expression
698@export
699class SimpleAggregateElement(AggregateElement):
700 def __str__(self) -> str:
701 return str(self._expression)
704@export
705class IndexedAggregateElement(AggregateElement):
706 _index: int
708 def __init__(self, index: ExpressionUnion, expression: ExpressionUnion, parent: ModelEntity = None) -> None:
709 super().__init__(expression, parent)
711 self._index = index
713 @property
714 def Index(self) -> int:
715 return self._index
717 def __str__(self) -> str:
718 return f"{self._index!s} => {self._expression!s}"
721@export
722class RangedAggregateElement(AggregateElement):
723 _range: Range
725 def __init__(self, rng: Range, expression: ExpressionUnion, parent: ModelEntity = None) -> None:
726 super().__init__(expression, parent)
728 self._range = rng
729 rng._parent = self
731 @property
732 def Range(self) -> Range:
733 return self._range
735 def __str__(self) -> str:
736 return f"{self._range!s} => {self._expression!s}"
739@export
740class NamedAggregateElement(AggregateElement):
741 _name: Symbol
743 def __init__(self, name: Symbol, expression: ExpressionUnion, parent: ModelEntity = None) -> None:
744 super().__init__(expression, parent)
746 self._name = name
747 name._parent = self
749 @property
750 def Name(self) -> Symbol:
751 return self._name
753 def __str__(self) -> str:
754 return "{name!s} => {value!s}".format(
755 name=self._name,
756 value=self._expression,
757 )
760@export
761class OthersAggregateElement(AggregateElement):
762 def __str__(self) -> str:
763 return "others => {value!s}".format(
764 value=self._expression,
765 )
768@export
769class Aggregate(BaseExpression):
770 _elements: List[AggregateElement]
772 def __init__(self, elements: Iterable[AggregateElement], parent: ModelEntity = None) -> None:
773 super().__init__(parent)
775 self._elements = []
776 for element in elements:
777 self._elements.append(element)
778 element._parent = self
780 @property
781 def Elements(self) -> List[AggregateElement]:
782 return self._elements
784 def __str__(self) -> str:
785 choices = [str(element) for element in self._elements]
786 return "({choices})".format(
787 choices=", ".join(choices)
788 )