# 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
import antlr4
import antlr4.error.ErrorListener
import numpy as np
from m2isar.metamodel import arch, type_info, behav
from typing import Union
from ... import M2SyntaxError
from .parser_gen import CoreDSL2Lexer, CoreDSL2Parser
[docs]
RADIX = {
'b': 2,
'h': 16,
'd': 10,
'o': 8
}
[docs]
SHORTHANDS = {
"char": 8,
"short": 16,
"int": 32,
"long": 64
}
[docs]
SIGNEDNESS = {
"signed": True,
"unsigned": False
}
[docs]
BOOLCONST = {
"true": 1,
"false": 0
}
[docs]
class MyErrorListener(antlr4.error.ErrorListener.ErrorListener):
def __init__(self, filename=None) -> None:
[docs]
self.filename = filename
super().__init__()
[docs]
def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e):
raise M2SyntaxError(f"Syntax error in file {self.filename}, line {line}, column {column}: {msg}")
[docs]
def make_parser(filename):
input_stream = antlr4.FileStream(filename)
lexer = CoreDSL2Lexer(input_stream)
stream = antlr4.CommonTokenStream(lexer)
parser = CoreDSL2Parser(stream)
error_handler = MyErrorListener(filename)
parser.removeErrorListeners()
parser.addErrorListener(error_handler)
return parser
### Infer Type Size (required to be constant for now at compile time)
[docs]
def infer_shape_from_type(ty: Union[type_info.PrimitiveType, type_info.ArrayType], shape : list[int]) -> list[int]:
if isinstance(ty, type_info.ArrayType):
shape.append(arch.get_const_or_val(ty.length))
infer_shape_from_type(ty.element_type, shape)
elif isinstance(ty, type_info.PrimitiveType):
return
## Infer the type of the innermost Element (No Array anymore ...)
[docs]
def infer_simple_type(ty: Union[type_info.PrimitiveType, type_info.ArrayType]) -> type_info.PrimitiveType:
if isinstance(ty, type_info.ArrayType):
return infer_simple_type(ty.element_type)
elif isinstance(ty, type_info.PrimitiveType):
return ty
[docs]
def literal_tree_to_values(expr):
if isinstance(expr, behav.Literal):
return expr.value
if isinstance(expr, (list, tuple)):
return [literal_tree_to_values(x) for x in expr]
raise TypeError(f"Expected Literal or nested list, got {type(expr)}")
[docs]
def create_np_array_from_literal_array(values: list[behav.Literal], ty: type_info.ArrayType):
shape = []
infer_shape_from_type(ty, shape)
values = literal_tree_to_values(values)
return np.array(values)