1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# 4# Copyright (C) 2024 Antmicro 5# 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18# SPDX-License-Identifier: Apache-2.0 19 20from typing import Iterable 21from peakrdl_renode.csharp.ast import CodeCC, CodeGenerator, Expr, Node, Type 22from itertools import chain 23from .ast import * 24 25class GT(BinaryOp): 26 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 27 super().__init__('>', lhs, rhs, Type.bool, **kwargs) 28 29class LT(BinaryOp): 30 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 31 super().__init__('<', lhs, rhs, Type.bool, **kwargs) 32 33class GTE(BinaryOp): 34 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 35 super().__init__('>=', lhs, rhs, Type.bool, **kwargs) 36 37class LTE(BinaryOp): 38 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 39 super().__init__('<=', lhs, rhs, Type.bool, **kwargs) 40 41class EQ(BinaryOp): 42 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 43 super().__init__('==', lhs, rhs, Type.bool, **kwargs) 44 45class NEQ(BinaryOp): 46 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 47 super().__init__('!=', lhs, rhs, Type.bool, **kwargs) 48 49class Add(BinaryOp): 50 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 51 super().__init__('+', lhs, rhs, lhs.type, **kwargs) 52 53class Sub(BinaryOp): 54 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 55 super().__init__('-', lhs, rhs, lhs.type, **kwargs) 56 57class Mul(BinaryOp): 58 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 59 super().__init__('*', lhs, rhs, lhs.type, **kwargs) 60 61class Div(BinaryOp): 62 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 63 super().__init__('/', lhs, rhs, lhs.type, **kwargs) 64 65class SHL(BinaryOp): 66 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 67 if lhs.type.width is None: raise RuntimeError('Invalid operand for bitshift') 68 ty_ = lhs.type if lhs.type.width >= 32 else Type.int 69 super().__init__('<<', lhs, rhs, ty_, **kwargs) 70 71class SHR(BinaryOp): 72 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 73 if lhs.type.width is None: raise RuntimeError('Invalid operand for bitshift') 74 ty_ = lhs.type if lhs.type.width >= 32 else Type.int 75 super().__init__('>>', lhs, rhs, ty_, **kwargs) 76 77class USHR(BinaryOp): 78 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 79 if lhs.type.width is None: raise RuntimeError('Invalid operand for bitshift') 80 ty_ = lhs.type if lhs.type.width >= 32 else Type.int 81 super().__init__('>>>', lhs, rhs, ty_, **kwargs) 82 83class AND(BinaryOp): 84 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 85 super().__init__('&', lhs, rhs, lhs.type, **kwargs) 86 87class OR(BinaryOp): 88 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 89 super().__init__('|', lhs, rhs, lhs.type, **kwargs) 90 91class LAND(BinaryOp): 92 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 93 super().__init__('&&', lhs, rhs, Type.bool, **kwargs) 94 95class LOR(BinaryOp): 96 def __init__(self, lhs: Expr, rhs: Expr, **kwargs): 97 super().__init__('||', lhs, rhs, Type.bool, **kwargs) 98 99class Cond(Expr): 100 def __init__(self, cond: Expr, then_: Expr, else_: Expr, **kwargs): 101 super().__init__(then_.type, **kwargs) 102 103 self.cond = cond 104 self.then_ = then_ 105 self.else_ = else_ 106 107 cond.parent = (self, 'cond') 108 then_.parent = (self, 'then_') 109 else_.parent = (self, 'else_') 110 111 def children(self) -> Iterable[Node]: 112 return [self.cond, self.then_, self.else_] 113 114 def tokenize(self, cg: CodeGenerator) -> Iterable[str | CodeCC]: 115 return chain( 116 self.emit_comment_tokens(inline=True), 117 self.cond.tokenize(cg), 118 [' ? '], 119 self.then_.tokenize(cg), 120 [' : '], 121 self.else_.tokenize(cg) 122 ) 123