molecule_codegen/generator/languages/c/
mod.rs

1use std::io;
2
3use case::CaseExt;
4
5use crate::{ast, C_API_VERSION_MIN, VERSION};
6
7#[macro_use]
8mod utilities;
9
10mod import;
11
12mod builder;
13mod reader;
14
15use self::{builder::GenBuilder, import::GenImport, reader::GenReader};
16
17pub(crate) struct Generator;
18
19impl Generator {
20    fn title<W: io::Write>(writer: &mut W, title: &str) -> io::Result<()> {
21        writeln!(writer, "/*")?;
22        writeln!(writer, " * {}", title)?;
23        writeln!(writer, " */")?;
24        writeln!(writer)
25    }
26
27    fn ifndef<W: io::Write>(o: &mut W, name: &str) -> io::Result<()> {
28        let n = name.to_snake().to_uppercase();
29        let api_decorator = utilities::API_DECORATOR;
30        w!(o, "#ifndef {}_H                                        ", n);
31        w!(o, "#define {}_H                                        ", n);
32        w!(o, "                                                       ");
33        w!(o, "#ifdef __cplusplus                                     ");
34        w!(o, "extern \"C\" {{                                        ");
35        w!(o, "#endif /* __cplusplus */                               ");
36        w!(o, "                                                       ");
37        w!(o, "#ifndef {}                              ", api_decorator);
38        w!(o, "#define __DEFINE_MOLECULE_API_DECORATOR_{}          ", n);
39        w!(o, "#define {}                              ", api_decorator);
40        w!(o, "#endif /* {} */                         ", api_decorator);
41        Ok(())
42    }
43
44    fn endif<W: io::Write>(o: &mut W, name: &str) -> io::Result<()> {
45        let n = name.to_snake().to_uppercase();
46        let api_decorator = utilities::API_DECORATOR;
47        w!(o, "                                                       ");
48        w!(o, "#ifdef __DEFINE_MOLECULE_API_DECORATOR_{}           ", n);
49        w!(o, "#undef {}                               ", api_decorator);
50        w!(o, "#undef __DEFINE_MOLECULE_API_DECORATOR_{}           ", n);
51        w!(o, "#endif /* __DEFINE_MOLECULE_API_DECORATOR_{} */     ", n);
52        w!(o, "                                                       ");
53        w!(o, "#ifdef __cplusplus                                     ");
54        w!(o, "}}                                                     ");
55        w!(o, "#endif /* __cplusplus */                               ");
56        w!(o, "                                                       ");
57        w!(o, "#endif /* {}_H */                                   ", n);
58        Ok(())
59    }
60
61    fn define_version<W: io::Write>(o: &mut W) -> io::Result<()> {
62        let molc_ver = semver::Version::parse(VERSION)
63            .map(|v| (v.major * 1000 + v.minor) * 1000 + v.patch)
64            .unwrap();
65        let api_ver_min = semver::Version::parse(C_API_VERSION_MIN)
66            .map(|v| (v.major * 1000 + v.minor) * 1000 + v.patch)
67            .unwrap();
68        w!(o, "#define MOLECULEC_VERSION {}                 ", molc_ver);
69        w!(o, "#define MOLECULE_API_VERSION_MIN {}       ", api_ver_min);
70        Ok(())
71    }
72}
73
74impl super::LanguageGenerator for Generator {
75    fn generate<W: io::Write>(writer: &mut W, ast: &ast::Ast) -> io::Result<()> {
76        writeln!(writer, "// Generated by Molecule {}", VERSION)?;
77        writeln!(writer)?;
78        Self::define_version(writer)?;
79        writeln!(writer)?;
80        writeln!(writer, r#"#include "molecule_reader.h""#)?;
81        writeln!(writer, r#"#include "molecule_builder.h""#)?;
82        writeln!(writer)?;
83        Self::ifndef(writer, ast.namespace())?;
84        let imports = ast.imports();
85        if !imports.is_empty() {
86            writeln!(writer)?;
87            for import in imports {
88                import.gen_import(writer)?;
89            }
90        }
91        writeln!(writer)?;
92        Self::title(writer, "Reader APIs")?;
93        for decl in ast.major_decls() {
94            decl.gen_reader_interfaces(writer)?;
95        }
96        writeln!(writer)?;
97        Self::title(writer, "Builder APIs")?;
98        for decl in ast.major_decls() {
99            decl.gen_builder_interfaces(writer)?;
100        }
101        writeln!(writer)?;
102        Self::title(writer, "Default Value")?;
103        writeln!(writer, r#"#define ____ 0x00"#)?;
104        writeln!(writer)?;
105        for decl in ast.major_decls() {
106            decl.gen_default(writer)?;
107        }
108        writeln!(writer)?;
109        writeln!(writer, r#"#undef ____"#)?;
110        writeln!(writer)?;
111        Self::title(writer, "Reader Functions")?;
112        for decl in ast.major_decls() {
113            decl.gen_reader_functions(writer)?;
114        }
115        writeln!(writer)?;
116        Self::title(writer, "Builder Functions")?;
117        for decl in ast.major_decls() {
118            decl.gen_builder_functions(writer)?;
119        }
120        Self::endif(writer, ast.namespace())?;
121        Ok(())
122    }
123}