Skip to content

Commit

Permalink
Declaration element
Browse files Browse the repository at this point in the history
- New declaration element.
- Refactoring existing code base to use explicit declaration calls.
  • Loading branch information
cogu committed Jan 26, 2024
1 parent 80dabbf commit 8fa1770
Show file tree
Hide file tree
Showing 20 changed files with 654 additions and 249 deletions.
3 changes: 0 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
{
"python.linting.pylintEnabled": true,
"python.linting.enabled": true,
"python.testing.unittestArgs": [
"-v",
"-s",
Expand All @@ -17,5 +15,4 @@
"--max-line-length=120",
"--ignore=D101,D102,D107,D200,D205,D400,D401"
],
"python.linting.flake8Enabled": false,
}
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,27 @@

Notable changes.

## Unreleased

### Removed

* StuctRef (struct references).

### Added

* Declaration element
* Constructor for `Function` takes an optional params argument.

### Changed

* Variables, functions, structs are no longer implicitly declared.
* Use explicit element `Declaration` for all declarations.
* Method `FunctionCall.add_arg` renamed to `FunctionCall.append`.

## [v0.3.1]

### Added

* Support struct declaratios and struct references

## [v0.3.0]
Expand Down
73 changes: 70 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ code = C.sequence()
code.append(C.sysinclude("stdio.h"))
code.append(C.blank())
char_ptr_type = C.type("char", pointer=True)
code.append(C.function("main", "int").make_param("argc", "int").make_param("argv", char_ptr_type, pointer=True))
code.append(C.declaration(C.function("main", "int", params=[C.variable("argc", "int"),
C.variable("argv", char_ptr_type, pointer=True)
])))
main_body = C.block()
main_body.append(C.statement(C.func_call("printf", C.str_literal(r"Hello World\n"))))
main_body.append(C.statement(C.func_return(0)))
Expand All @@ -31,7 +33,7 @@ print(writer.write_str(code))
}
```
Same code example but with slighty modified formatting style:
Here's the same example again but this time we change the formatting style of the output:
- Opening brace on same line
- Pointer alignment to the right
Expand All @@ -44,7 +46,9 @@ code = C.sequence()
code.append(C.sysinclude("stdio.h"))
code.append(C.blank())
char_ptr_type = C.type("char", pointer=True)
code.append(C.function("main", "int").make_param("argc", "int").make_param("argv", char_ptr_type, pointer=True))
code.append(C.declaration(C.function("main", "int", params=[C.variable("argc", "int"),
C.variable("argv", char_ptr_type, pointer=True)
])))
main_body = C.block()
main_body.append(C.statement(C.func_call("printf", C.str_literal(r"Hello World\n"))))
main_body.append(C.statement(C.func_return(0)))
Expand All @@ -64,6 +68,69 @@ print(writer.write_str(code))
}
```
## Important update about declarations
Starting from version 0.3.1 you need to wrap functions, variables, structs and typedefs inside `C.declaraton` to actually declare them.
Before v0.3.1 these elements were implicitly declared when encountered in the code sequence.
Not using `C.declaration` will only print the name when used on variables, functions or typedefs. For structs it will have the following meaning:
* without declaration: Will only forward declare the struct type.
* With declaration: Will fully declare the struct and its members.
Example:
```python
import cfile
C = cfile.CFactory()
code = C.sequence()
mystruct = C.struct("mystruct",
members=[C.struct_member("field_1", "int"),
C.struct_member("field_2", "int")])
code.append(C.statement(mystruct)) # Forward declaration
code.append(C.blank())
code.append(C.statement(C.declaration(mystruct))) # Struct declaration
writer = cfile.Writer(cfile.StyleOptions())
print(writer.write_str(code))
```

```C
struct mystruct;

struct mystruct
{
int field_1;
int field_2;
};
```

When declaring typedefs of structs you can wrap the struct declaration inside the declaration of the typedef.

Example:

```python
import cfile

C = cfile.CFactory()

code = C.sequence()
mystruct = C.struct("mystruct",
members=[C.struct_member("field_1", "int"),
C.struct_member("field_2", "int")])
code.append(C.statement(C.declaration(C.typedef("mystruct_t", C.declaration(mystruct)))))
writer = cfile.Writer(cfile.StyleOptions(break_before_braces=cfile.BreakBeforeBraces.ATTACH))
print(writer.write_str(code))
```

```C
typedef struct mystruct {
int field_1;
int field_2;
} mystruct_t;
```

## Requires

Python 3.10+ (Needed for modern type hinting support).
Expand Down
4 changes: 3 additions & 1 deletion doc/cfile.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
cfile
=====

C code generator for python.
C code generator for python.

TBD.
File renamed without changes.
File renamed without changes.
13 changes: 13 additions & 0 deletions examples/forward_declared_struct.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import cfile

C = cfile.CFactory()

code = C.sequence()
mystruct = C.struct("mystruct",
members=[C.struct_member("field_1", "int"),
C.struct_member("field_2", "int")])
code.append(C.statement(mystruct)) # Forward declaration
code.append(C.blank())
code.append(C.statement(C.declaration(mystruct))) # Struct declaration
writer = cfile.Writer(cfile.StyleOptions())
print(writer.write_str(code))
4 changes: 3 additions & 1 deletion examples/hello_world.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
code.append(C.sysinclude("stdio.h"))
code.append(C.blank())
char_ptr_type = C.type("char", pointer=True)
code.append(C.function("main", "int").make_param("argc", "int").make_param("argv", char_ptr_type, pointer=True))
code.append(C.declaration(C.function("main", "int", params=[C.variable("argc", "int"),
C.variable("argv", char_ptr_type, pointer=True)
])))
main_body = C.block()
main_body.append(C.statement(C.func_call("printf", C.str_literal(r"Hello World\n"))))
main_body.append(C.statement(C.func_return(0)))
Expand Down
7 changes: 5 additions & 2 deletions examples/hello_world2.py → examples/hello_world_styled.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Simple hello world with non-default formatting style
Simple hello world with formatting style
Style:
- new-line after opening brace
- pointer aligns to the right
"""
Expand All @@ -12,7 +13,9 @@
code.append(C.sysinclude("stdio.h"))
code.append(C.blank())
char_ptr_type = C.type("char", pointer=True)
code.append(C.function("main", "int").make_param("argc", "int").make_param("argv", char_ptr_type, pointer=True))
code.append(C.declaration(C.function("main", "int", params=[C.variable("argc", "int"),
C.variable("argv", char_ptr_type, pointer=True)
])))
main_body = C.block()
main_body.append(C.statement(C.func_call("printf", C.str_literal(r"Hello World\n"))))
main_body.append(C.statement(C.func_return(0)))
Expand Down
21 changes: 21 additions & 0 deletions examples/struct_initializer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
Typedef of a struct then declare a variable of that struct with initializer.
Style:
- new-line after opening brace
"""
import cfile

C = cfile.CFactory()
code = C.sequence()
struct = C.struct("mystruct",
members=[C.struct_member("field_1", "int"),
C.struct_member("field_2", "int")])
struct_type = C.typedef("my_struct_t", C.declaration(struct))
code.append(C.statement(C.declaration(struct_type)))
code.append(C.blank())
code.append(C.statement(C.declaration(C.variable("instance", struct_type), [0, 0])))

writer = cfile.Writer(cfile.StyleOptions(break_before_braces=cfile.BreakBeforeBraces.ATTACH))
print(writer.write_str(code))
10 changes: 6 additions & 4 deletions examples/typedef_header.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Example of header file with type declaration
Example header file with some type declarations
"""
import cfile

Expand All @@ -18,18 +18,20 @@
code.append(C.blank())
code.append(C.sysinclude("stdint.h"))
code.append(C.blank())
code.append([C.statement(C.struct_ref("os_task_tag")), C.line_comment("Forward declaration")])
os_task_tag = C.struct("os_task_tag")
code.append([C.statement(os_task_tag), C.line_comment("Forward declaration")])
code.append(C.blank())
struct = C.struct("os_alarm_cfg_tag",
members=[C.struct_member("taskPtr", C.struct_ref("os_task_tag", pointer=True)),
members=[C.struct_member("taskPtr", os_task_tag, pointer=True),
C.struct_member("eventMask", "uint32_t"),
C.struct_member("initDelayMs", "uint32_t"),
C.struct_member("periodMs", "uint32_t")])
code.append(C.statement(C.typedef("os_alarm_cfg_t", struct)))
code.append(C.statement(C.declaration(C.typedef("os_alarm_cfg_t", C.declaration(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))
41 changes: 41 additions & 0 deletions examples/typedef_header_styled.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
Example header file with some type declaration and formatting style
- new-line after opening brace
- pointer aligns to the right
"""
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())
os_task_tag = C.struct("os_task_tag")
code.append([C.statement(os_task_tag), C.line_comment("Forward declaration")])
code.append(C.blank())
struct = C.struct("os_alarm_cfg_tag",
members=[C.struct_member("taskPtr", os_task_tag, pointer=True),
C.struct_member("eventMask", "uint32_t"),
C.struct_member("initDelayMs", "uint32_t"),
C.struct_member("periodMs", "uint32_t")])
code.append(C.statement(C.declaration(C.typedef("os_alarm_cfg_t", C.declaration(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)])
style = cfile.StyleOptions(break_before_braces=cfile.BreakBeforeBraces.ATTACH,
pointer_alignment=cfile.Alignment.RIGHT)
writer = cfile.Writer(style)
print(writer.write_str(code))
11 changes: 11 additions & 0 deletions examples/typedef_struct.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import cfile

C = cfile.CFactory()

code = C.sequence()
mystruct = C.struct("mystruct",
members=[C.struct_member("field_1", "int"),
C.struct_member("field_2", "int")])
code.append(C.statement(C.declaration(C.typedef("mystruct_t", C.declaration(mystruct)))))
writer = cfile.Writer(cfile.StyleOptions(break_before_braces=cfile.BreakBeforeBraces.ATTACH))
print(writer.write_str(code))
15 changes: 15 additions & 0 deletions examples/variables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
Variable declarations and access
"""
import cfile

C = cfile.CFactory()
code = C.sequence()
var1 = C.variable("var1", "int")
var2 = C.variable("var2", "int")
code.append(C.statement(C.declaration(var1))) # int var1;
code.append(C.statement(C.declaration(var2, 0))) # int var2 = 0;
code.append(C.statement(var1)) # var1;
code.append(C.statement(C.assignment(var1, 0))) # var1 = 0;
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.1"
version = "0.3.2a1"
description = "A C code generator written in Python 3"
readme = "README.md"
requires-python = ">=3.10"
Expand Down
Loading

0 comments on commit 8fa1770

Please sign in to comment.