molecule_codegen/generator/languages/c/
mod.rs1use 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}