Files
pip/utils/code_model_generator/metainfo.cpp
peri4 7083b2c32b finish codeparser improvements
pip_cmg now works with new nested entities approach
Getters now can access to bitfields
2025-09-18 05:54:31 +03:00

168 lines
5.0 KiB
C++

/*
PIP - Platform Independent Primitives
Code model generator
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "metainfo.h"
void writeClassInfoMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
for (const PICodeParser::Member & m: e->members) {
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
writeClassInfoMembers(rt, type, var_prefix + m.name);
continue;
}
}
rt.ts << "\tti = TypeInfo(\"" << var_prefix << m.name << "\", \"" << m.type << "\"";
if (m.attributes != 0) {
bool fir = true;
rt.ts << ", ";
if (m.attributes[PICodeParser::Const]) {
if (fir)
fir = false;
else
rt.ts << " | ";
rt.ts << "Const";
}
if (m.attributes[PICodeParser::Static]) {
if (fir)
fir = false;
else
rt.ts << " | ";
rt.ts << "Static";
}
if (m.attributes[PICodeParser::Mutable]) {
if (fir)
fir = false;
else
rt.ts << " | ";
rt.ts << "Mutable";
}
if (m.attributes[PICodeParser::Volatile]) {
if (fir)
fir = false;
else
rt.ts << " | ";
rt.ts << "Volatile";
}
if (m.attributes[PICodeParser::Inline]) {
if (fir)
fir = false;
else
rt.ts << " | ";
rt.ts << "Inline";
}
if (m.attributes[PICodeParser::Virtual]) {
if (fir)
fir = false;
else
rt.ts << " | ";
rt.ts << "Virtual";
}
} else {
if (m.isBitfield()) rt.ts << ", 0";
}
if (m.isBitfield()) rt.ts << ", " << m.bits;
rt.ts << ");\n";
if (!m.meta.isEmpty()) {
for (PICodeParser::MetaMap::const_iterator i = m.meta.begin(); i != m.meta.end(); ++i)
rt.ts << "\tti.meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n";
}
rt.ts << "\tci->variables << ti;\n";
}
}
void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e) {
rt.ts << "\n\t{\n\tClassInfo * ci = new ClassInfo();\n";
rt.ts << "\tci->type = \"" << e->type << "\";\n";
rt.ts << "\tci->name = \"" << e->name << "\";\n";
// rt.ts << "\tci->is_anonymous = " << (e->is_anonymous ? "true" : "false") << ";\n";
if (!e->meta.isEmpty()) {
auto i = e->meta.makeIterator();
while (i.next())
rt.ts << "\tci->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n";
}
rt.ts << "\tci_ci[ci->name] = ci;\n";
if (e->parent_scope) {
rt.ts << "\tpci = "
<< "ci_ci.value(\"" << e->parent_scope->name << "\", 0);\n";
rt.ts << "\tif (pci) pci->children_info << ci;\n";
}
for (const PICodeParser::Entity * p: e->parents)
rt.ts << "\tci->parents << \"" << p->name << "\";\n";
if (!e->members.isEmpty()) rt.ts << "\n\tTypeInfo ti;\n";
writeClassInfoMembers(rt, e);
PIString arg;
bool has_fi = false;
for (const PICodeParser::Member & m: e->functions) {
if (e->name.findCWord(m.name) >= 0) continue;
if (!has_fi) rt.ts << "\n\tFunctionInfo * fi;\n";
has_fi = true;
rt.ts << "\tci->functions.push_back(FunctionInfo()); fi = &(ci->functions.back());\n";
rt.ts << "\tfi->name = \"" << m.name << "\";";
rt.ts << " fi->return_type = TypeInfo(\"\", \"" << m.type << "\"";
if (m.attributes[PICodeParser::Const] || m.attributes[PICodeParser::Static]) {
bool fir = true;
rt.ts << ", ";
if (m.attributes[PICodeParser::Const]) {
if (fir)
fir = false;
else
rt.ts << " | ";
rt.ts << "Const";
}
if (m.attributes[PICodeParser::Static]) {
if (fir)
fir = false;
else
rt.ts << " | ";
rt.ts << "Static";
}
}
rt.ts << ");\n";
// piCout << "write func" << m.name;
for (const PIString & a: m.arguments_full) {
// piCout << "write arg" << a;
rt.ts << "\tfi->arguments << TypeInfo(";
arg = a;
bool con = false;
arg.prepend(" ");
if (arg.find(" const ") >= 0) {
arg.replaceAll(" const ", " ");
con = true;
}
arg.trim();
int i = 0;
for (i = arg.size_s() - 1; i > 0; --i)
if (!_isCChar(arg[i]) && !(arg[i].isDigit())) break;
rt.ts << "\"" << arg.takeRight(arg.size_s() - i - 1).trim() << "\", ";
rt.ts << "\"" << arg.trim() << "\"";
if (con) rt.ts << ", Const";
rt.ts << ");\n";
}
if (!m.meta.isEmpty()) {
for (PICodeParser::MetaMap::const_iterator i = m.meta.begin(); i != m.meta.end(); ++i)
rt.ts << "\tfi->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n";
}
}
rt.ts << "\n\t}";
}