From 4c8dc2c2436e4b6f6bae5e6faf180c6f9f57f824 Mon Sep 17 00:00:00 2001 From: Cervenka Dusan Date: Wed, 13 Nov 2024 11:44:27 +0100 Subject: [PATCH] Added switch support Signed-off-by: Cervenka Dusan --- src/cfile/core.py | 48 ++++++++++++++++++++++++++++++++++++++++++++ src/cfile/factory.py | 8 ++++++++ src/cfile/writer.py | 38 +++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) diff --git a/src/cfile/core.py b/src/cfile/core.py index 5115432..1f05dc0 100644 --- a/src/cfile/core.py +++ b/src/cfile/core.py @@ -511,3 +511,51 @@ class Block(Sequence): """ A sequence wrapped in braces """ +class SwitchCase(Block): + """ + A sequence for switch case wrapped in braces + """ + + def __init__(self, cases: list[int | EnumMember] | None = None): + """ + Empty values means default + """ + super().__init__() + + if cases == None: + self.cases = [] + elif isinstance(cases, list): + self.cases: list[int | EnumMember] = list(cases) + else: + raise TypeError('Invalid argument type for "cases"') + + +class Switch(Element): + """ + A sequence for switch case wrapped in braces + """ + + def __init__(self, switchVar: str | Variable, cases: list[SwitchCase] | None = None): + super().__init__() + + if switchVar == "" or not (isinstance(switchVar, str) or isinstance(switchVar, Variable)): + raise ValueError("switchVar cannot be empty and check data type") + + self.switchVar = switchVar + + if cases == None: + self.cases = [] + elif isinstance(cases, list): + self.cases: list[SwitchCase] = list(cases) + else: + raise TypeError('Invalid argument type for "cases"') + + def append(self, case: SwitchCase) -> None: + """ + Appends new element to the conditions definition + """ + if not isinstance(case, SwitchCase): + raise TypeError(f'Invalid type, expected "SwitchCase", got {str(type(case))}') + self.cases.append(case) + + diff --git a/src/cfile/factory.py b/src/cfile/factory.py index 71a609e..7ecbcd7 100644 --- a/src/cfile/factory.py +++ b/src/cfile/factory.py @@ -227,3 +227,11 @@ def declaration(self, """New declaration""" return core.Declaration(element, init_value) + + def switch_case(self, cases: list[int | core.EnumMember] | None = None) -> core.SwitchCase: + + return core.SwitchCase(cases) + + def switch(self, switchVar: str | core.Variable, cases: list[core.SwitchCase] | None = None) -> core.Switch: + + return core.Switch(switchVar, cases) diff --git a/src/cfile/writer.py b/src/cfile/writer.py index e842e8f..b84497a 100644 --- a/src/cfile/writer.py +++ b/src/cfile/writer.py @@ -123,6 +123,7 @@ def __init__(self, style: c_style.StyleOptions) -> None: "IfndefDirective": self._write_ifndef_directive, "EndifDirective": self._write_endif_directive, "Extern": self._write_extern, + "Switch": self._write_switch, } self.last_element = ElementType.NONE @@ -182,6 +183,8 @@ def _write_sequence(self, sequence: core.Sequence) -> None: self._start_line() self._write_line_comment(elem) self._eol() + elif isinstance(elem, core.Switch): + self._write_switch(elem) elif isinstance(elem, core.Block): self._start_line() self._write_block(elem) @@ -709,3 +712,38 @@ def _write_endif_directive(self, elem: core.EndifDirective) -> None: def _write_extern(self, elem: core.Extern) -> None: self._write(f'extern "{elem.language}"') self.last_element = ElementType.DIRECTIVE + + def _write_switch(self, elem: core.Switch): + defaultCase = None + self._start_line() + if type(elem.switchVar) == core.Variable: + self._write(f"switch({elem.switchVar.name}){{") + else: + self._write(f"switch({elem.switchVar}){{") + self._eol() + self._indent() + for case in elem.cases: + if not case.cases: + if defaultCase == None: + defaultCase = case + continue + else: + raise ValueError("Empty case (default) can be defined only once.") + firstCase = False + for condition in case.cases: + if not firstCase: + firstCase = True + else: + self._write_line("") + self._eol() + self._start_line() + self._write(f"case {condition if type(condition) == type(int) else condition.name}:") + self._write_block(case) + if defaultCase: + self._start_line() + self._write(f"default:") + self._write_block(defaultCase) + self._dedent() + self._start_line() + self._write("}") + self._eol()