Source code for m2isar.backends.isa_manual.visitor

# SPDX-License-Identifier: Apache-2.0
#
# This file is part of the M2-ISA-R project: https://github.com/tum-ei-eda/M2-ISA-R
#
# Copyright (C) 2022
# Chair of Electrical Design Automation
# Technical University of Munich

"""Visitor for traversing the behavior in the metamodel and generating the CoreDSL2 syntax."""

from m2isar.metamodel import arch, behav
from m2isar.metamodel.utils.ExprVisitor import ExprVisitor
from functools import singledispatchmethod

# pylint: disable=unused-argument


[docs] class ISAmanualVisitor(ExprVisitor): """Visitor for generating ISA manual CoreDSL2-like behavior text.""" @singledispatchmethod
[docs] def generate(self, expr: behav.BaseNode, context=None): raise NotImplementedError(f"No visit method implemented for type {type(expr).__name__} in {type(self).__name__}")
@generate.register
[docs] def _(self, expr: behav.Operation, writer): if len(expr.statements) > 1: writer.enter_block() for stmt in expr.statements: self.generate(stmt, writer) if not isinstance(stmt, (behav.Conditional, behav.Operation)): writer.write_line(";") if len(expr.statements) > 1: writer.leave_block()
@generate.register def _(self, expr: behav.BinaryOperation, writer): self.generate(expr.left, writer) writer.write(f" {expr.op.value} ") self.generate(expr.right, writer) @generate.register def _(self, expr: behav.SliceOperation, writer): self.generate(expr.expr, writer) writer.write("[") self.generate(expr.left, writer) writer.write(":") self.generate(expr.right, writer) writer.write("]") @generate.register def _(self, expr: behav.ConcatOperation, writer): self.generate(expr.left, writer) writer.write(" :: ") self.generate(expr.right, writer) @generate.register def _(self, expr: behav.IntLiteral, writer): writer.write(expr.value) @generate.register def _(self, expr: behav.IntLiteral, writer): writer.write(expr.value) @generate.register def _(self, expr: behav.ScalarDefinition, writer): writer.write_type(expr.scalar.data_type, expr.scalar.size) writer.write(" ") writer.write(expr.scalar.name) if expr.scalar.value: writer.write(" = ") writer.write(expr.scalar.value) @generate.register def _(self, expr: behav.Break, writer): writer.write_line("break;") @generate.register def _(self, expr: behav.Assignment, writer): self.generate(expr.target, writer) writer.write(" = ") self.generate(expr.expr, writer) @generate.register def _(self, expr: behav.Conditional, writer): for i, stmt in enumerate(expr.stmts): if i == 0: writer.write("if (") self.generate(expr.conds[i], writer) writer.write(")") elif 0 < i < len(expr.conds): writer.write("else if(") self.generate(expr.conds[i], writer) writer.write(")") else: writer.write("else") writer.enter_block() self.generate(stmt, writer) if not isinstance(stmt, (behav.Conditional, behav.Operation)): writer.write_line(";") nl = len(expr.stmts) > i writer.leave_block(nl=nl) @generate.register def _(self, expr: behav.Loop, writer): writer.write("while (") self.generate(expr.cond, writer) writer.write(")") writer.enter_block() for stmt in expr.stmts: self.generate(stmt, writer) writer.leave_block() @generate.register def _(self, expr: behav.Ternary, writer): self.generate(expr.cond, writer) writer.write(" ? ") self.generate(expr.then_expr, writer) writer.write(" : ") self.generate(expr.else_expr, writer) @generate.register def _(self, expr: behav.Return, writer): writer.write("return") if expr.expr is not None: writer.write(" ") self.generate(expr.expr, writer) @generate.register def _(self, expr: behav.UnaryOperation, writer): writer.write(expr.op.value) self.generate(expr.right, writer) @generate.register def _(self, expr: behav.NamedReference, writer): writer.write(expr.reference.name) if isinstance(expr.reference, (arch.Constant, arch.Memory, arch.Scalar)): pass @generate.register def _(self, expr: behav.IndexedReference, writer): writer.write(expr.reference.name) writer.write("[") self.generate(expr.index, writer) writer.write("]") @generate.register def _(self, expr: behav.TypeConv, writer): writer.write("(") writer.write_type(expr.data_type, expr.size) writer.write(")") writer.write("(") self.generate(expr.expr, writer) writer.write(")") @generate.register def _(self, expr: behav.Callable, writer): ref = expr.ref_or_name if isinstance(ref, arch.Function): writer.write(ref.name) else: raise NotImplementedError writer.write("(") for i, stmt in enumerate(expr.args): self.generate(stmt, writer) if i < len(expr.args) - 1: writer.write(", ") writer.write(")") @generate.register def _(self, expr: behav.Group, writer): writer.write("(") self.generate(expr.expr, writer) writer.write(")")