Skip to content

Commit

Permalink
Add basic struct support
Browse files Browse the repository at this point in the history
  • Loading branch information
cogu committed Oct 15, 2023
1 parent 2083e1c commit 5cf8532
Show file tree
Hide file tree
Showing 11 changed files with 321 additions and 74 deletions.
26 changes: 26 additions & 0 deletions examples/cpp_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""
Header example with include guard and C++ language check
"""
import cfile

C = cfile.CFactory()

INCLUDE_GUARD_TEXT = "INCLUDE_GUARD_H"

code = C.sequence()
code.append(C.ifndef(INCLUDE_GUARD_TEXT))
code.append(C.define(INCLUDE_GUARD_TEXT))
code.append(C.blank())
code.append(C.ifndef("__cplusplus"))
code.append(C.line(C.extern("C")))
code.append(C.line("{"))
code.append(C.endif())
code.append(C.blank())
code.append(C.line_comment(" PLACEHOLDER"))
code.append(C.blank())
code.append(C.ifndef("__cplusplus"))
code.append(C.line("}"))
code.append([C.endif(), C.line_comment(" __cplusplus")])
code.append([C.endif(), C.line_comment(" " + INCLUDE_GUARD_TEXT)])
writer = cfile.Writer(cfile.StyleOptions())
print(writer.write_str(code))
25 changes: 25 additions & 0 deletions examples/cpp_check2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""
Same as cpp_check.py but places the "extern" brace on the same line as extern declaration
"""
import cfile

C = cfile.CFactory()

INCLUDE_GUARD_TEXT = "INCLUDE_GUARD_H"

code = C.sequence()
code.append(C.ifndef(INCLUDE_GUARD_TEXT))
code.append(C.define(INCLUDE_GUARD_TEXT))
code.append(C.blank())
code.append(C.ifndef("__cplusplus"))
code.append([C.extern("C"), "{"])
code.append(C.endif())
code.append(C.blank())
code.append(C.line_comment(" PLACEHOLDER"))
code.append(C.blank())
code.append(C.ifndef("__cplusplus"))
code.append(C.line("}"))
code.append([C.endif(), C.line_comment(" __cplusplus")])
code.append([C.endif(), C.line_comment(" " + INCLUDE_GUARD_TEXT)])
writer = cfile.Writer(cfile.StyleOptions())
print(writer.write_str(code))
25 changes: 0 additions & 25 deletions examples/header_file.py

This file was deleted.

24 changes: 0 additions & 24 deletions examples/header_file2.py

This file was deleted.

30 changes: 30 additions & 0 deletions examples/typedef_header.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""
Example of header file with type declaration
"""
import cfile

C = cfile.CFactory()

INCLUDE_GUARD_TEXT = "INCLUDE_GUARD_H"

code = C.sequence()
code.append(C.ifndef(INCLUDE_GUARD_TEXT))
code.append(C.define(INCLUDE_GUARD_TEXT))
code.append(C.blank())
code.append(C.ifndef("__cplusplus"))
code.append(C.line(C.extern("C")))
code.append(C.line("{"))
code.append(C.endif(adjust=1))
code.append(C.blank())
code.append(C.sysinclude("stdint.h"))
code.append(C.blank())
struct = C.struct("heap_tag", members=[C.struct_member("pItem", "void", pointer=True),
C.struct_member("u32Value", "uint32_t")])
code.append(C.statement(C.typedef("heap_t", struct)))
code.append(C.blank())
code.append(C.ifndef("__cplusplus"))
code.append(C.line("}"))
code.append([C.endif(), C.line_comment(" __cplusplus")])
code.append([C.endif(), C.line_comment(" " + INCLUDE_GUARD_TEXT)])
writer = cfile.Writer(cfile.StyleOptions())
print(writer.write_str(code))
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "cfile"
version = "0.3.0"
version = "0.3.1a1"
description = "A C code generator written in Python 3"
readme = "README.md"
requires-python = ">=3.10"
Expand Down
70 changes: 66 additions & 4 deletions src/cfile/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,75 @@ def qualifier(self, name) -> bool:
raise KeyError(name)


class StructMember(Element):
"""
Struct element. This is similar to Variable
but doesn't support type qualifier such as static
or extern
"""
def __init__(self,
name: str,
data_type: Union[str, Type, "Struct"],
const: bool = False, # Pointer qualifier only
pointer: bool = False,
array: int | None = None) -> None:
self.name = name
self.const = const
self.pointer = pointer
self.array = array
if isinstance(data_type, Type):
self.data_type = data_type
elif isinstance(data_type, str):
self.data_type = Type(data_type)
else:
raise TypeError(str(type(data_type)))


class Struct(Element):
"""
A struct definition
"""
def __init__(self, name: str, members: StructMember | list[StructMember] | None = None) -> None:
self.name = name
self.members: list[StructMember] = []
if members is not None:
if isinstance(members, StructMember):
self.append(members)
elif isinstance(members, list):
for member in members:
self.append(member)
else:
raise TypeError('Invalid argument type for "elements"')

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

def make_member(self,
name: str,
data_type: str | Type,
const: bool = False, # Pointer qualifier only
pointer: bool = False,
array: int | None = None) -> StructMember:
"""
Creates a new StructMember and appends it to the list of elements
"""
member = StructMember(name, data_type, const, pointer, array)
self.members.append(member)
return member


class Variable(Element):
"""
Variable declaration
"""
def __init__(self,
name: str,
data_type: str | Type,
data_type: str | Type | Struct,
const: bool = False, # Only used as pointer qualifier
pointer: bool = False,
extern: bool = False,
Expand All @@ -178,7 +240,7 @@ def __init__(self,
self.extern = extern
self.static = static
self.array = array
if isinstance(data_type, Type):
if isinstance(data_type, (Type, Struct)):
self.data_type = data_type
elif isinstance(data_type, str):
self.data_type = Type(data_type)
Expand Down Expand Up @@ -208,15 +270,15 @@ class TypeDef(Element):
"""
def __init__(self,
name: str,
data_type: str | Type,
data_type: str | Type | Struct,
const: bool = False, # Only used as pointer qualifier
pointer: bool = False,
array: int | None = None) -> None:
self.name = name
self.const = const
self.pointer = pointer
self.array = array
if isinstance(data_type, Type):
if isinstance(data_type, (Type, Struct)):
self.data_type = data_type
elif isinstance(data_type, str):
self.data_type = Type(data_type)
Expand Down
28 changes: 24 additions & 4 deletions src/cfile/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def block(self) -> core.Block():

def function(self,
name: str,
return_type: str | core.Type | None = None,
return_type: str | core.Type | core.Struct | None = None,
static: bool = False,
const: bool = False, # This is not const of the return type
extern: bool = False) -> core.Function:
Expand All @@ -126,7 +126,7 @@ def function(self,
return core.Function(name, return_type, static, const, extern)

def type(self,
type_ref: str | core.Type,
type_ref: str | core.Type | core.Struct,
const: bool = False,
pointer: bool = False,
volatile: bool = False,
Expand All @@ -136,9 +136,29 @@ def type(self,
"""
return core.Type(type_ref, const, pointer, volatile, array)

def struct_member(self,
name: str,
data_type: str | core.Type | core.Struct,
const: bool = False, # Pointer qualifier only
pointer: bool = False,
array: int | None = None) -> core.StructMember:
"""
New StructMember
"""
return core.StructMember(name, data_type, const, pointer, array)

def struct(self,
name: str,
members: core.StructMember | list[core.StructMember] | None = None
) -> core.Variable:
"""
New Struct
"""
return core.Struct(name, members)

def variable(self,
name: str,
data_type: str | core.Type,
data_type: str | core.Type | core.Struct,
const: bool = False, # Only used as pointer qualifier
pointer: bool = False,
extern: bool = False,
Expand All @@ -151,7 +171,7 @@ def variable(self,

def typedef(self,
name: str,
data_type: str | core.Type,
data_type: str | core.Type | core.Struct,
const: bool = False, # Only used as pointer qualifier
pointer: bool = False,
array: int | None = None) -> None:
Expand Down
6 changes: 5 additions & 1 deletion src/cfile/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ def make(cls, break_before_braces: BreakBeforeBraces) -> "BraceWrapping":

class StyleOptions:
"""
Format style selection
Format style options
Default format style:
* Indentation: 4 spaces
* Always break for spaces (ALLMAN style)
"""
def __init__(self,
break_before_braces: BreakBeforeBraces = BreakBeforeBraces.ALLMAN,
Expand Down
Loading

0 comments on commit 5cf8532

Please sign in to comment.