#generation #generator #code-generation #code

code_generator

A code generator (Currently only targets C)

15 releases

0.1.15 Aug 12, 2024
0.1.14 Aug 9, 2024
0.1.7 Jul 30, 2024

#634 in Development tools

Download history 162/week @ 2024-07-18 532/week @ 2024-07-25 357/week @ 2024-08-01 574/week @ 2024-08-08 37/week @ 2024-08-15

1,032 downloads per month

MIT license

54KB
1K SLoC

Code Generator

  • This project is not stabilized. There will be many breaking changes before it is stabilized.
  • The goal of this project is to be able to generate code, and be able to easily change the formatting of the generated code as needed.
  • This library makes it easier to reuse code generation code since it is context aware.
  • This library currently only supports C, but I would like to support multiple target languages.

TODO:

  • Support more types of code generation (switch, do/while, etc.)
  • Support more languages. Currently the language is fairly hard coded. Not sure if that can be abstracted.
  • Unit tests
  • Documentation

Limitations

  • I don't believe it would be possible to work backwards with the existing architecture of the project. This library could not parse code, and do anything with it without a major rework.

lib.rs:

This generator is designed to allow easy reuse of code generation

Example

This example shows how the same structure can be generated into two different formats.

#
let code = CodeSet::new(vec![
    Box::new(String::from("#include \"test.h\"")),
    Box::new(String::from("")),
    Box::new(String::from("")),
    Box::new(Function::new(FunctionSignature::new(
            Name::new("MyReturnTypeOne"),
            Name::new("MyFunctionNameOne"),
            vec![
                (Name::new("ParamTypeOne"), Name::new("ParamNameOne")),
                (Name::new("ParamTypeTwo"), Name::new("ParamNameTwo")),
                (Name::new("ParamTypeThree"), Name::new("ParamNameThree")),
            ]
        ),
        CodeBody::new(vec![
            Box::new(IfStatement::new(
                    Name::new_with_type("ParamNameThree", NameType::Member),
                CodeBody::new(vec![
                    Box::new(ForLoop::new(
                        String::from("ParamTypeTwo i = 0"),
                        String::from("i < param_name_two"),
                        String::from("i++"),
                        vec![
                            Box::new(String::from("printf(\"ParamOne: {}\\n\", param_name_one);"))
                        ]
                    ))
                ])
            ))
        ])
    )),
    Box::new(String::from("")),
]);

let mut info = CodeGenerationInfo::from_style(CodeStyle::KnR);
info.set_new_line_type(NewLineType::Nl);
assert_eq!(
"#include \"test.h\"


MyReturnTypeOne my_function_name_one(ParamTypeOne param_name_one, ParamTypeTwo param_name_two, ParamTypeThree param_name_three) {
    if (param_name_three) {
        for (ParamTypeTwo i = 0; i < param_name_two; i++) {
            printf(\"ParamOne: {}\\n\", param_name_one);
        }
    }
}
", format!("{}", code.display(info)));

let mut info = CodeGenerationInfo::from_style(CodeStyle::Allman);
info.set_new_line_type(NewLineType::Nl);
assert_eq!(
"#include \"test.h\"


MyReturnTypeOne my_function_name_one(ParamTypeOne param_name_one, ParamTypeTwo param_name_two, ParamTypeThree param_name_three)
{
    if (param_name_three)
    {
        for (ParamTypeTwo i = 0; i < param_name_two; i++)
        {
            printf(\"ParamOne: {}\\n\", param_name_one);
        }
    }
}
", format!("{}", code.display(info)));



Because the output format is not dependent on the input data structure, it is very easy to make code generation modular. Any pieces of generated code that share structure, can share a generator.

No runtime deps