Coverage for pyVHDLModel/Expression.py: 80%

453 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-20 22:13 +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. 

34 

35All declarations for literals, aggregates, operators forming an expressions. 

36""" 

37from typing import Tuple, List, Iterable, Union 

38 

39from pyTooling.Decorators import export, readonly 

40 

41from pyVHDLModel.Base import ModelEntity, Direction, Range 

42from pyVHDLModel.Symbol import Symbol 

43 

44 

45ExpressionUnion = Union[ 

46 'BaseExpression', 

47 'QualifiedExpression', 

48 'FunctionCall', 

49 'TypeConversion', 

50 # ConstantOrSymbol, TODO: ObjectSymbol 

51 'Literal', 

52] 

53 

54 

55@export 

56class BaseExpression(ModelEntity): 

57 """A ``BaseExpression`` is a base-class for all expressions.""" 

58 

59 

60@export 

61class Literal(BaseExpression): 

62 """A ``Literal`` is a base-class for all literals.""" 

63 

64 

65@export 

66class NullLiteral(Literal): 

67 def __str__(self) -> str: 

68 return "null" 

69 

70 

71@export 

72class EnumerationLiteral(Literal): 

73 _value: str 

74 

75 def __init__(self, value: str, parent: ModelEntity = None) -> None: 

76 super().__init__(parent) 

77 

78 self._value = value 

79 

80 @readonly 

81 def Value(self) -> str: 

82 return self._value 

83 

84 def __str__(self) -> str: 

85 return self._value 

86 

87 

88@export 

89class NumericLiteral(Literal): 

90 """A ``NumericLiteral`` is a base-class for all numeric literals.""" 

91 

92 

93@export 

94class IntegerLiteral(NumericLiteral): 

95 _value: int 

96 

97 def __init__(self, value: int) -> None: 

98 super().__init__() 

99 self._value = value 

100 

101 @readonly 

102 def Value(self) -> int: 

103 return self._value 

104 

105 def __str__(self) -> str: 

106 return str(self._value) 

107 

108 

109@export 

110class FloatingPointLiteral(NumericLiteral): 

111 _value: float 

112 

113 def __init__(self, value: float) -> None: 

114 super().__init__() 

115 self._value = value 

116 

117 @readonly 

118 def Value(self) -> float: 

119 return self._value 

120 

121 def __str__(self) -> str: 

122 return str(self._value) 

123 

124 

125@export 

126class PhysicalLiteral(NumericLiteral): 

127 _unitName: str 

128 

129 def __init__(self, unitName: str) -> None: 

130 super().__init__() 

131 self._unitName = unitName 

132 

133 @readonly 

134 def UnitName(self) -> str: 

135 return self._unitName 

136 

137 def __str__(self) -> str: 

138 return f"{self._value} {self._unitName}" 

139 

140 

141@export 

142class PhysicalIntegerLiteral(PhysicalLiteral): 

143 _value: int 

144 

145 def __init__(self, value: int, unitName: str) -> None: 

146 super().__init__(unitName) 

147 self._value = value 

148 

149 @readonly 

150 def Value(self) -> int: 

151 return self._value 

152 

153 

154@export 

155class PhysicalFloatingLiteral(PhysicalLiteral): 

156 _value: float 

157 

158 def __init__(self, value: float, unitName: str) -> None: 

159 super().__init__(unitName) 

160 self._value = value 

161 

162 @readonly 

163 def Value(self) -> float: 

164 return self._value 

165 

166 

167@export 

168class CharacterLiteral(Literal): 

169 _value: str 

170 

171 def __init__(self, value: str) -> None: 

172 super().__init__() 

173 self._value = value 

174 

175 @readonly 

176 def Value(self) -> str: 

177 return self._value 

178 

179 def __str__(self) -> str: 

180 return str(self._value) 

181 

182 

183@export 

184class StringLiteral(Literal): 

185 _value: str 

186 

187 def __init__(self, value: str) -> None: 

188 super().__init__() 

189 self._value = value 

190 

191 @readonly 

192 def Value(self) -> str: 

193 return self._value 

194 

195 def __str__(self) -> str: 

196 return "\"" + self._value + "\"" 

197 

198 

199@export 

200class BitStringLiteral(Literal): 

201 _value: str 

202 

203 def __init__(self, value: str) -> None: 

204 super().__init__() 

205 self._value = value 

206 

207 @readonly 

208 def Value(self) -> str: 

209 return self._value 

210 

211 def __str__(self) -> str: 

212 return "\"" + self._value + "\"" 

213 

214 

215@export 

216class ParenthesisExpression: #(Protocol): 

217 __slots__ = () # FIXME: use ExtendedType? 

218 

219 @readonly 

220 def Operand(self) -> ExpressionUnion: 

221 return None 

222 

223 

224@export 

225class UnaryExpression(BaseExpression): 

226 """A ``UnaryExpression`` is a base-class for all unary expressions.""" 

227 

228 _FORMAT: Tuple[str, str] 

229 _operand: ExpressionUnion 

230 

231 def __init__(self, operand: ExpressionUnion, parent: ModelEntity = None) -> None: 

232 super().__init__(parent) 

233 

234 self._operand = operand 

235 # operand._parent = self # FIXME: operand is provided as None 

236 

237 @readonly 

238 def Operand(self): 

239 return self._operand 

240 

241 def __str__(self) -> str: 

242 return f"{self._FORMAT[0]}{self._operand!s}{self._FORMAT[1]}" 

243 

244 

245@export 

246class NegationExpression(UnaryExpression): 

247 _FORMAT = ("-", "") 

248 

249 

250@export 

251class IdentityExpression(UnaryExpression): 

252 _FORMAT = ("+", "") 

253 

254 

255@export 

256class InverseExpression(UnaryExpression): 

257 _FORMAT = ("not ", "") 

258 

259 

260@export 

261class UnaryAndExpression(UnaryExpression): 

262 _FORMAT = ("and ", "") 

263 

264 

265@export 

266class UnaryNandExpression(UnaryExpression): 

267 _FORMAT = ("nand ", "") 

268 

269 

270@export 

271class UnaryOrExpression(UnaryExpression): 

272 _FORMAT = ("or ", "") 

273 

274 

275@export 

276class UnaryNorExpression(UnaryExpression): 

277 _FORMAT = ("nor ", "") 

278 

279 

280@export 

281class UnaryXorExpression(UnaryExpression): 

282 _FORMAT = ("xor ", "") 

283 

284 

285@export 

286class UnaryXnorExpression(UnaryExpression): 

287 _FORMAT = ("xnor ", "") 

288 

289 

290@export 

291class AbsoluteExpression(UnaryExpression): 

292 _FORMAT = ("abs ", "") 

293 

294 

295@export 

296class TypeConversion(UnaryExpression): 

297 pass 

298 

299 

300@export 

301class SubExpression(UnaryExpression, ParenthesisExpression): 

302 _FORMAT = ("(", ")") 

303 

304 

305@export 

306class BinaryExpression(BaseExpression): 

307 """A ``BinaryExpression`` is a base-class for all binary expressions.""" 

308 

309 _FORMAT: Tuple[str, str, str] 

310 _leftOperand: ExpressionUnion 

311 _rightOperand: ExpressionUnion 

312 

313 def __init__(self, leftOperand: ExpressionUnion, rightOperand: ExpressionUnion, parent: ModelEntity = None) -> None: 

314 super().__init__(parent) 

315 

316 self._leftOperand = leftOperand 

317 leftOperand._parent = self 

318 

319 self._rightOperand = rightOperand 

320 rightOperand._parent = self 

321 

322 @property 

323 def LeftOperand(self): 

324 return self._leftOperand 

325 

326 @property 

327 def RightOperand(self): 

328 return self._rightOperand 

329 

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 ) 

338 

339 

340@export 

341class RangeExpression(BinaryExpression): 

342 _direction: Direction 

343 

344 @property 

345 def Direction(self) -> Direction: 

346 return self._direction 

347 

348 

349@export 

350class AscendingRangeExpression(RangeExpression): 

351 _direction = Direction.To 

352 _FORMAT = ("", " to ", "") 

353 

354 

355@export 

356class DescendingRangeExpression(RangeExpression): 

357 _direction = Direction.DownTo 

358 _FORMAT = ("", " downto ", "") 

359 

360 

361@export 

362class AddingExpression(BinaryExpression): 

363 """A ``AddingExpression`` is a base-class for all adding expressions.""" 

364 

365 

366@export 

367class AdditionExpression(AddingExpression): 

368 _FORMAT = ("", " + ", "") 

369 

370 

371@export 

372class SubtractionExpression(AddingExpression): 

373 _FORMAT = ("", " - ", "") 

374 

375 

376@export 

377class ConcatenationExpression(AddingExpression): 

378 _FORMAT = ("", " & ", "") 

379 

380 

381@export 

382class MultiplyingExpression(BinaryExpression): 

383 """A ``MultiplyingExpression`` is a base-class for all multiplying expressions.""" 

384 

385 

386@export 

387class MultiplyExpression(MultiplyingExpression): 

388 _FORMAT = ("", " * ", "") 

389 

390 

391@export 

392class DivisionExpression(MultiplyingExpression): 

393 _FORMAT = ("", " / ", "") 

394 

395 

396@export 

397class RemainderExpression(MultiplyingExpression): 

398 _FORMAT = ("", " rem ", "") 

399 

400 

401@export 

402class ModuloExpression(MultiplyingExpression): 

403 _FORMAT = ("", " mod ", "") 

404 

405 

406@export 

407class ExponentiationExpression(MultiplyingExpression): 

408 _FORMAT = ("", "**", "") 

409 

410 

411@export 

412class LogicalExpression(BinaryExpression): 

413 """A ``LogicalExpression`` is a base-class for all logical expressions.""" 

414 

415 

416@export 

417class AndExpression(LogicalExpression): 

418 _FORMAT = ("", " and ", "") 

419 

420 

421@export 

422class NandExpression(LogicalExpression): 

423 _FORMAT = ("", " nand ", "") 

424 

425 

426@export 

427class OrExpression(LogicalExpression): 

428 _FORMAT = ("", " or ", "") 

429 

430 

431@export 

432class NorExpression(LogicalExpression): 

433 _FORMAT = ("", " nor ", "") 

434 

435 

436@export 

437class XorExpression(LogicalExpression): 

438 _FORMAT = ("", " xor ", "") 

439 

440 

441@export 

442class XnorExpression(LogicalExpression): 

443 _FORMAT = ("", " xnor ", "") 

444 

445 

446@export 

447class RelationalExpression(BinaryExpression): 

448 """A ``RelationalExpression`` is a base-class for all shifting expressions.""" 

449 

450 

451@export 

452class EqualExpression(RelationalExpression): 

453 _FORMAT = ("", " = ", "") 

454 

455 

456@export 

457class UnequalExpression(RelationalExpression): 

458 _FORMAT = ("", " /= ", "") 

459 

460 

461@export 

462class GreaterThanExpression(RelationalExpression): 

463 _FORMAT = ("", " > ", "") 

464 

465 

466@export 

467class GreaterEqualExpression(RelationalExpression): 

468 _FORMAT = ("", " >= ", "") 

469 

470 

471@export 

472class LessThanExpression(RelationalExpression): 

473 _FORMAT = ("", " < ", "") 

474 

475 

476@export 

477class LessEqualExpression(RelationalExpression): 

478 _FORMAT = ("", " <= ", "") 

479 

480 

481@export 

482class MatchingRelationalExpression(RelationalExpression): 

483 pass 

484 

485 

486@export 

487class MatchingEqualExpression(MatchingRelationalExpression): 

488 _FORMAT = ("", " ?= ", "") 

489 

490 

491@export 

492class MatchingUnequalExpression(MatchingRelationalExpression): 

493 _FORMAT = ("", " ?/= ", "") 

494 

495 

496@export 

497class MatchingGreaterThanExpression(MatchingRelationalExpression): 

498 _FORMAT = ("", " ?> ", "") 

499 

500 

501@export 

502class MatchingGreaterEqualExpression(MatchingRelationalExpression): 

503 _FORMAT = ("", " ?>= ", "") 

504 

505 

506@export 

507class MatchingLessThanExpression(MatchingRelationalExpression): 

508 _FORMAT = ("", " ?< ", "") 

509 

510 

511@export 

512class MatchingLessEqualExpression(MatchingRelationalExpression): 

513 _FORMAT = ("", " ?<= ", "") 

514 

515 

516@export 

517class ShiftExpression(BinaryExpression): 

518 """A ``ShiftExpression`` is a base-class for all shifting expressions.""" 

519 

520 

521@export 

522class ShiftLogicExpression(ShiftExpression): 

523 pass 

524 

525 

526@export 

527class ShiftArithmeticExpression(ShiftExpression): 

528 pass 

529 

530 

531@export 

532class RotateExpression(ShiftExpression): 

533 pass 

534 

535 

536@export 

537class ShiftRightLogicExpression(ShiftLogicExpression): 

538 _FORMAT = ("", " srl ", "") 

539 

540 

541@export 

542class ShiftLeftLogicExpression(ShiftLogicExpression): 

543 _FORMAT = ("", " sll ", "") 

544 

545 

546@export 

547class ShiftRightArithmeticExpression(ShiftArithmeticExpression): 

548 _FORMAT = ("", " sra ", "") 

549 

550 

551@export 

552class ShiftLeftArithmeticExpression(ShiftArithmeticExpression): 

553 _FORMAT = ("", " sla ", "") 

554 

555 

556@export 

557class RotateRightExpression(RotateExpression): 

558 _FORMAT = ("", " ror ", "") 

559 

560 

561@export 

562class RotateLeftExpression(RotateExpression): 

563 _FORMAT = ("", " rol ", "") 

564 

565 

566@export 

567class QualifiedExpression(BaseExpression, ParenthesisExpression): 

568 _operand: ExpressionUnion 

569 _subtype: Symbol 

570 

571 def __init__(self, subtype: Symbol, operand: ExpressionUnion, parent: ModelEntity = None) -> None: 

572 super().__init__(parent) 

573 

574 self._operand = operand 

575 operand._parent = self 

576 

577 self._subtype = subtype 

578 subtype._parent = self 

579 

580 @property 

581 def Operand(self): 

582 return self._operand 

583 

584 @property 

585 def Subtyped(self): 

586 return self._subtype 

587 

588 def __str__(self) -> str: 

589 return f"{self._subtype}'({self._operand!s})" 

590 

591 

592@export 

593class TernaryExpression(BaseExpression): 

594 """A ``TernaryExpression`` is a base-class for all ternary expressions.""" 

595 

596 _FORMAT: Tuple[str, str, str, str] 

597 _firstOperand: ExpressionUnion 

598 _secondOperand: ExpressionUnion 

599 _thirdOperand: ExpressionUnion 

600 

601 def __init__(self, parent: ModelEntity = None) -> None: 

602 super().__init__(parent) 

603 

604 # FIXME: parameters and initializers are missing !! 

605 

606 @property 

607 def FirstOperand(self): 

608 return self._firstOperand 

609 

610 @property 

611 def SecondOperand(self): 

612 return self._secondOperand 

613 

614 @property 

615 def ThirdOperand(self): 

616 return self._thirdOperand 

617 

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 ) 

628 

629 

630@export 

631class WhenElseExpression(TernaryExpression): 

632 _FORMAT = ("", " when ", " else ", "") 

633 

634 

635@export 

636class FunctionCall(BaseExpression): 

637 pass 

638 

639 

640@export 

641class Allocation(BaseExpression): 

642 pass 

643 

644 

645@export 

646class SubtypeAllocation(Allocation): 

647 _subtype: Symbol 

648 

649 def __init__(self, subtype: Symbol, parent: ModelEntity = None) -> None: 

650 super().__init__(parent) 

651 

652 self._subtype = subtype 

653 subtype._parent = self 

654 

655 @property 

656 def Subtype(self) -> Symbol: 

657 return self._subtype 

658 

659 def __str__(self) -> str: 

660 return f"new {self._subtype!s}" 

661 

662 

663@export 

664class QualifiedExpressionAllocation(Allocation): 

665 _qualifiedExpression: QualifiedExpression 

666 

667 def __init__(self, qualifiedExpression: QualifiedExpression, parent: ModelEntity = None) -> None: 

668 super().__init__(parent) 

669 

670 self._qualifiedExpression = qualifiedExpression 

671 qualifiedExpression._parent = self 

672 

673 @property 

674 def QualifiedExpression(self) -> QualifiedExpression: 

675 return self._qualifiedExpression 

676 

677 def __str__(self) -> str: 

678 return f"new {self._qualifiedExpression!s}" 

679 

680 

681@export 

682class AggregateElement(ModelEntity): 

683 """A ``AggregateElement`` is a base-class for all aggregate elements.""" 

684 

685 _expression: ExpressionUnion 

686 

687 def __init__(self, expression: ExpressionUnion, parent: ModelEntity = None) -> None: 

688 super().__init__(parent) 

689 

690 self._expression = expression 

691 expression._parent = self 

692 

693 @property 

694 def Expression(self): 

695 return self._expression 

696 

697 

698@export 

699class SimpleAggregateElement(AggregateElement): 

700 def __str__(self) -> str: 

701 return str(self._expression) 

702 

703 

704@export 

705class IndexedAggregateElement(AggregateElement): 

706 _index: int 

707 

708 def __init__(self, index: ExpressionUnion, expression: ExpressionUnion, parent: ModelEntity = None) -> None: 

709 super().__init__(expression, parent) 

710 

711 self._index = index 

712 

713 @property 

714 def Index(self) -> int: 

715 return self._index 

716 

717 def __str__(self) -> str: 

718 return f"{self._index!s} => {self._expression!s}" 

719 

720 

721@export 

722class RangedAggregateElement(AggregateElement): 

723 _range: Range 

724 

725 def __init__(self, rng: Range, expression: ExpressionUnion, parent: ModelEntity = None) -> None: 

726 super().__init__(expression, parent) 

727 

728 self._range = rng 

729 rng._parent = self 

730 

731 @property 

732 def Range(self) -> Range: 

733 return self._range 

734 

735 def __str__(self) -> str: 

736 return f"{self._range!s} => {self._expression!s}" 

737 

738 

739@export 

740class NamedAggregateElement(AggregateElement): 

741 _name: Symbol 

742 

743 def __init__(self, name: Symbol, expression: ExpressionUnion, parent: ModelEntity = None) -> None: 

744 super().__init__(expression, parent) 

745 

746 self._name = name 

747 name._parent = self 

748 

749 @property 

750 def Name(self) -> Symbol: 

751 return self._name 

752 

753 def __str__(self) -> str: 

754 return "{name!s} => {value!s}".format( 

755 name=self._name, 

756 value=self._expression, 

757 ) 

758 

759 

760@export 

761class OthersAggregateElement(AggregateElement): 

762 def __str__(self) -> str: 

763 return "others => {value!s}".format( 

764 value=self._expression, 

765 ) 

766 

767 

768@export 

769class Aggregate(BaseExpression): 

770 _elements: List[AggregateElement] 

771 

772 def __init__(self, elements: Iterable[AggregateElement], parent: ModelEntity = None) -> None: 

773 super().__init__(parent) 

774 

775 self._elements = [] 

776 for element in elements: 

777 self._elements.append(element) 

778 element._parent = self 

779 

780 @property 

781 def Elements(self) -> List[AggregateElement]: 

782 return self._elements 

783 

784 def __str__(self) -> str: 

785 choices = [str(element) for element in self._elements] 

786 return "({choices})".format( 

787 choices=", ".join(choices) 

788 )