Skip to content

Commit

Permalink
Added enums working in declaration assignment.
Browse files Browse the repository at this point in the history
Signed-off-by: Cervenka Dusan <[email protected]>
  • Loading branch information
Hadatko committed Nov 7, 2024
1 parent f3811d5 commit 9decef9
Show file tree
Hide file tree
Showing 3 changed files with 402 additions and 122 deletions.
242 changes: 182 additions & 60 deletions src/cfile/core.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
cfile core
"""
from typing import Union, Any
from typing import Any, Self


class Element:
Expand Down Expand Up @@ -145,7 +145,7 @@ class Type(DataType):
Data type
"""
def __init__(self,
base_type: Union[str, "Type"],
base_type: str | Self,
const: bool = False,
pointer: bool = False,
volatile: bool = False,
Expand Down Expand Up @@ -185,10 +185,13 @@ class Enum(DataType):
A enum definition
"""

def __init__(self, name: str, members: list[EnumMember] = [], attributes: list[str] = []) -> None:
def __init__(self, name: str, members: list[EnumMember] | None = None, attributes: list[str] | None = None) -> None:
super().__init__(name)
if isinstance(members, list):
self.members: list[EnumMember] = members.copy()

if members == None:
self.members = []
elif isinstance(members, list):
self.members = list(members)
enumValue = -1
for enum in self.members:
if enum.value == None:
Expand All @@ -197,8 +200,14 @@ def __init__(self, name: str, members: list[EnumMember] = [], attributes: list[s
else:
enumValue = enum.value
else:
raise TypeError('Invalid argument type for "elements"')
self.attributes = attributes.copy()
raise TypeError('Invalid argument type for "members"')

if attributes == None:
self.attributes = []
elif isinstance(attributes, list):
self.attributes: list[str] = list(attributes)
else:
raise TypeError('Invalid argument type for "attributes"')

def append(self, member: EnumMember) -> None:
"""
Expand Down Expand Up @@ -236,13 +245,22 @@ class Struct(DataType):
"""
A struct definition
"""
def __init__(self, name: str = "", members: list[StructMember] = [], attributes: list[str] = []) -> None:
def __init__(self, name: str = "", members: list[StructMember] | None = None, attributes: list[str] | None = None) -> None:
super().__init__(name)
if isinstance(members, list):
self.members: list[StructMember] = members.copy()

if members == None:
self.members = []
elif isinstance(members, list):
self.members: list[StructMember] = list(members)
else:
raise TypeError('Invalid argument type for "elements"')
self.attributes = attributes.copy()
raise TypeError('Invalid argument type for "members"')

if attributes == None:
self.attributes = []
elif isinstance(attributes, list):
self.attributes: list[str] = list(attributes)
else:
raise TypeError('Invalid argument type for "attributes"')

def append(self, member: StructMember) -> None:
"""
Expand All @@ -266,46 +284,32 @@ def make_member(self,
return member


class TypeDef(DataType):
"""
Type definition (typedef)
"""
def __init__(self,
name: str,
base_type: Union[str, "DataType", "Declaration"],
const: bool = False,
pointer: bool = False,
volatile: bool = False,
array: int | None = None) -> None:
super().__init__(name)
self.const = const
self.volatile = volatile
class UnionMember(Element):
def __init__(self, name: str, data_type: DataType, pointer: bool = False, array: int | None = None):
self.name = name
self.data_type = data_type
self.pointer = pointer
self.array = array
self.base_type: DataType | Declaration
if isinstance(base_type, DataType):
self.base_type = base_type
elif isinstance(base_type, str):
self.base_type = Type(base_type)
elif isinstance(base_type, Declaration):
if not isinstance(base_type.element, DataType):
err_msg = f'base_type: Declaration must declare a type, not {str(type(base_type.element))}'
self.base_type = base_type


class Union(DataType):
def __init__(self, name: str, members: list[UnionMember] | None = None):
self.name = name

if members == None:
self.members = []
elif isinstance(members, list):
self.members: list[UnionMember] = list(members)
else:
err_msg = 'base_type: Invalid type, expected "str" | "DataType" | "Declaration",'
err_msg += ' got {str(type(base_type))}'
raise TypeError(err_msg)
raise TypeError('Invalid argument type for "members"')

def qualifier(self, name) -> bool:
def append(self, member: UnionMember) -> None:
"""
Returns the status of named qualifier
Appends new element to the struct definition
"""
if name == "const":
return self.const
if name == "volatile":
return self.volatile
else:
raise KeyError(name)
if not isinstance(member, UnionMember):
raise TypeError(f'Invalid type, expected "UnionMember", got {str(type(member))}')
self.members.append(member)


class Variable(Element):
Expand Down Expand Up @@ -357,7 +361,7 @@ def __init__(self,
static: bool = False,
const: bool = False, # const function (as seen in C++)
extern: bool = False,
params: list[Variable] = []) -> None:
params: list[Variable] | None = None) -> None:
self.name = name
self.static = static
self.const = const
Expand All @@ -370,7 +374,11 @@ def __init__(self,
self.return_type = Type("void")
else:
raise TypeError(str(type(return_type)))
self.params = params.copy()

if isinstance(params, list):
self.params: list[Variable] = list(params)
else:
raise TypeError('Invalid argument type for "params"')

def append(self, param: Variable) -> "Function":
"""
Expand Down Expand Up @@ -403,7 +411,7 @@ class Declaration(Element):
- Function
"""
def __init__(self,
element: Union[Variable, Function, DataType],
element: Variable | Function | DataType,
init_value: Any | None = None) -> None:
if isinstance(element, (Variable, Function, DataType)):
self.element = element
Expand Down Expand Up @@ -451,6 +459,8 @@ def __init__(self,
self.expression = "true" if expression else "false"
elif isinstance(expression, (int, float)):
self.expression = str(expression)
elif isinstance(expression, EnumMember):
self.expression = expression.name
elif isinstance(expression, (str, Element)):
self.expression = expression
else:
Expand Down Expand Up @@ -513,7 +523,7 @@ class Sequence:
A sequence of statements, comments or whitespace
"""
def __init__(self) -> None:
self.elements: list[Union[Comment, Statement, "Sequence"]] = []
self.elements: list[Comment | Statement | "Sequence"] = []

def __len__(self) -> int:
return len(self.elements)
Expand Down Expand Up @@ -542,20 +552,132 @@ class Block(Sequence):
"""


class ConditionType(Enum):
IF = 0
ELSE_IF = 1
ELSE = 2
class Condition(Block):
"""
A sequence for condition wrapped in braces
"""

def __init__(self, condition: str):
super().__init__()
self.condition = condition


class Condition(Block):
class Conditions(Element):
"""
A condition wrapped in braces
"""
def __init__(self, condition: str = "", type: ConditionType = ConditionType.ELSE):

def __init__(self, conditions: list[Condition] | None = None):
super().__init__()
self.condition = condition
self.type = type

if (condition and type == ConditionType.ELSE) or (not condition and type != ConditionType.ELSE):
raise Exception("Condition and type didn't match")
if conditions == None:
self.conditions = []
elif isinstance(conditions, list):
self.conditions: list[Condition] = list(conditions)
else:
raise TypeError('Invalid argument type for "conditions"')

def append(self, member: Condition) -> None:
"""
Appends new element to the conditions definition
"""
if not isinstance(member, Condition):
raise TypeError(f'Invalid type, expected "Condition", got {str(type(member))}')
self.conditions.append(member)


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 ")

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)


class Break(Element):
"""
Adding break into block
"""


class TypeDef(DataType):
"""
Type definition (typedef)
"""

def __init__(self,
name: str,
base_type: str | DataType | Declaration,
const: bool = False,
pointer: bool = False,
volatile: bool = False,
array: int | None = None) -> None:
super().__init__(name)
self.const = const
self.volatile = volatile
self.pointer = pointer
self.array = array
self.base_type: DataType | Declaration
if isinstance(base_type, DataType):
self.base_type = base_type
elif isinstance(base_type, str):
self.base_type = Type(base_type)
elif isinstance(base_type, Declaration):
if not isinstance(base_type.element, DataType):
err_msg = f'base_type: Declaration must declare a type, not {str(type(base_type.element))}'
self.base_type = base_type
else:
err_msg = 'base_type: Invalid type, expected "str" | "DataType" | "Declaration",'
err_msg += ' got {str(type(base_type))}'
raise TypeError(err_msg)

def qualifier(self, name) -> bool:
"""
Returns the status of named qualifier
"""
if name == "const":
return self.const
if name == "volatile":
return self.volatile
else:
raise KeyError(name)
Loading

0 comments on commit 9decef9

Please sign in to comment.