from hdlConvertorAst.hdlAst import HdlOpType, HdlValueId, HdlValueInt, \
HdlOp
from hdlConvertorAst.py_ver_compatibility import is_str
from hdlConvertorAst.to.common import ToHdlCommon, ASSOCIATIVITY,\
ASSIGN_OPERATORS_SYMBOLS_C
from hdlConvertorAst.to.hdlUtils import iter_with_last
from hdlConvertorAst.to.verilog.expr import ASSIGN_OPERATORS, ToVerilog2005Expr
L = ASSOCIATIVITY.L_TO_R
R = ASSOCIATIVITY.R_TO_L
[docs]class ToSystemcExpr(ToHdlCommon):
# https://en.cppreference.com/w/cpp/language/operator_precedence
OP_PRECEDENCE = {
HdlOpType.DOUBLE_COLON: (1, L),
HdlOpType.INCR_POST: (2, L),
HdlOpType.DECR_POST: (2, L),
HdlOpType.TYPE_OF: (2, L),
HdlOpType.CALL: (2, L),
HdlOpType.INDEX: (3, L),
HdlOpType.DOT: (2, L),
HdlOpType.ARROW: (2, L),
HdlOpType.PARAMETRIZATION: (2, L),
HdlOpType.INCR_PRE: (3, R),
HdlOpType.DECR_PRE: (3, R),
HdlOpType.MINUS_UNARY: (3, R),
HdlOpType.PLUS_UNARY: (3, R),
HdlOpType.NEG_LOG: (3, R),
HdlOpType.NEG: (3, R),
HdlOpType.REFERENCE: (3, R),
HdlOpType.DIV: (5, L),
HdlOpType.MUL: (5, L),
HdlOpType.MOD: (5, L),
HdlOpType.ADD: (6, L),
HdlOpType.SUB: (6, L),
HdlOpType.SLL: (7, L),
HdlOpType.SRL: (7, L),
HdlOpType.GT: (9, L),
HdlOpType.LT: (9, L),
HdlOpType.GE: (9, L),
HdlOpType.LE: (9, L),
HdlOpType.NE: (10, L),
HdlOpType.EQ: (10, L),
HdlOpType.AND: (11, L),
HdlOpType.XOR: (12, L),
HdlOpType.OR: (13, L),
HdlOpType.AND_LOG: (14, L),
HdlOpType.OR_LOG: (15, L),
HdlOpType.TERNARY: (16, R),
}
OP_PRECEDENCE.update({
k: (16, R) for k in ASSIGN_OPERATORS
})
GENERIC_UNARY_OPS = {
HdlOpType.NEG_LOG: "!",
HdlOpType.NEG: "~",
HdlOpType.MINUS_UNARY: "-",
HdlOpType.PLUS_UNARY: "+",
HdlOpType.INCR_PRE: "++",
HdlOpType.DECR_PRE: "--",
}
GENERIC_UNARY_OPS_POSTFIX = ToVerilog2005Expr.GENERIC_UNARY_OPS_POSTFIX
GENERIC_BIN_OPS = {
HdlOpType.DOUBLE_COLON: "::",
HdlOpType.AND: " & ",
HdlOpType.OR: " | ",
HdlOpType.XOR: " ^ ",
HdlOpType.EQ: ' == ',
HdlOpType.NE: " != ",
HdlOpType.MUL: " * ",
HdlOpType.DIV: " / ",
HdlOpType.POW: " ** ",
HdlOpType.MOD: " % ",
HdlOpType.SLL: " << ",
HdlOpType.SRL: " >> ",
}
GENERIC_BIN_OPS.update(ToHdlCommon.GENERIC_BIN_OPS)
GENERIC_BIN_OPS.update(ASSIGN_OPERATORS_SYMBOLS_C)
[docs] def visit_HdlValueInt(self, o):
"""
:type o: HdlValueInt
"""
w = self.out.write
if o.bits is None:
w(str(o.val))
else:
if o.base is None:
w(str(o.val))
else:
b = o.base
if isinstance(o.val, int):
if b == 2:
f = "0b{0:b}"
elif b == 8:
f = "0o{0:o}"
elif b == 16:
f = "0x{0:x}"
else:
raise NotImplementedError(b)
w(f.format(o.val))
else:
if b == 2:
f = '"0b{0}"'
elif b == 8:
f = '"0o{0}"'
elif b == 16:
f = '"0x{0}"'
else:
raise NotImplementedError(b)
w(f.format(o.val.upper()))
[docs] def visit_iHdlExpr(self, o):
"""
:type o: iHdlExpr
"""
w = self.out.write
if isinstance(o, HdlValueId):
w(o.val)
elif is_str(o):
w('"%s"' % o)
elif isinstance(o, HdlValueInt):
self.visit_HdlValueInt(o)
elif isinstance(o, (list, tuple)):
with_nl = len(o) > 3
if isinstance(o, list):
begin = "{"
end = "}"
else:
begin = "("
end = ")"
w(begin)
for elem in o:
self.visit_iHdlExpr(elem)
if with_nl:
w(", \n")
else:
w(", ")
w(end)
elif isinstance(o, HdlOp):
self.visit_HdlOp(o)
elif o is None:
w("nullptr")
else:
raise NotImplementedError(o.__class__, o)
return True
[docs] def visit_HdlOp(self, op):
"""
:type o: HdlOp
"""
w = self.out.write
o = op.fn
if o == HdlOpType.RISING:
self._visit_operand(op.ops[0], 0, op, False, False)
w(".pos()")
elif o == HdlOpType.FALLING:
self._visit_operand(op.ops[0], 0, op, False, False)
w(".neg()")
elif o == HdlOpType.PARAMETRIZATION:
self._visit_operand(op.ops[0], 0, op, False, False)
w("<")
for last, _o in iter_with_last(op.ops[1:]):
self.visit_iHdlExpr(_o)
if not last:
w(", ")
w(">")
else:
ToHdlCommon.visit_HdlOp(self, op)
return True