finish codeparser improvements

pip_cmg now works with new nested entities approach
Getters now can access to bitfields
This commit is contained in:
2025-09-18 05:54:31 +03:00
parent af02684dc5
commit 7083b2c32b
15 changed files with 244 additions and 157 deletions

View File

@@ -120,15 +120,15 @@ struct PIP_EXPORT FunctionInfo {
//! \~english Class or struct information //! \~english Class or struct information
//! \~russian Информация о классе или структуре //! \~russian Информация о классе или структуре
struct PIP_EXPORT ClassInfo { struct PIP_EXPORT ClassInfo {
ClassInfo() { has_name = true; } ClassInfo() { is_anonymous = false; }
//! \~english Custom PIMETA content //! \~english Custom PIMETA content
//! \~russian Произвольное содержимое PIMETA //! \~russian Произвольное содержимое PIMETA
MetaMap meta; MetaMap meta;
//! \~english Has name or not //! \~english Anonymous or not
//! \~russian Имеет или нет имя //! \~russian Анонимный или нет
bool has_name; bool is_anonymous;
//! \~english Type //! \~english Type
//! \~russian Тип //! \~russian Тип
@@ -294,61 +294,67 @@ private:
NO_COPY_CLASS(__Storage__) NO_COPY_CLASS(__Storage__)
}; };
class PIP_EXPORT __StorageAccess__ { class PIP_EXPORT
public: __StorageAccess__{public:
//! \~english Getter for single storage of PICodeInfo::ClassInfo, access by name //! \~english Getter for single storage of PICodeInfo::ClassInfo, access by name
//! \~russian Доступ к единому хранилищу PICodeInfo::ClassInfo, доступ по имени //! \~russian Доступ к единому хранилищу PICodeInfo::ClassInfo, доступ по имени
static const PIMap<PIConstChars, PICodeInfo::ClassInfo *> & classes() { return *(__Storage__::instance()->classesInfo); } static const PIMap<PIConstChars, PICodeInfo::ClassInfo *> & classes(){return *(__Storage__::instance()->classesInfo);
} // namespace PICodeInfo
//! \~english Getter for single storage of PICodeInfo::EnumInfo, access by name //! \~english Getter for single storage of PICodeInfo::EnumInfo, access by name
//! \~russian Доступ к единому хранилищу хранилище PICodeInfo::EnumInfo, доступ по имени //! \~russian Доступ к единому хранилищу хранилище PICodeInfo::EnumInfo, доступ по имени
static const PIMap<PIConstChars, PICodeInfo::EnumInfo *> & enums() { return *(__Storage__::instance()->enumsInfo); } static const PIMap<PIConstChars, PICodeInfo::EnumInfo *> & enums() {
return *(__Storage__::instance()->enumsInfo);
}
static const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> & accessValueFunctions() { static const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> & accessValueFunctions() {
return *(__Storage__::instance()->accessValueFunctions); return *(__Storage__::instance()->accessValueFunctions);
} }
static const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> & accessTypeFunctions() { static const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> & accessTypeFunctions() {
return *(__Storage__::instance()->accessTypeFunctions); return *(__Storage__::instance()->accessTypeFunctions);
} }
}; }
;
#define PICODEINFO PICodeInfo::__StorageAccess__ #define PICODEINFO PICodeInfo::__StorageAccess__
class PIP_EXPORT ClassInfoInterface { class PIP_EXPORT
public: ClassInfoInterface{public: const PIMap<PIConstChars, PICodeInfo::ClassInfo *> * operator->() const DEPRECATEDM("use PICODEINFO::classes()"){
const PIMap<PIConstChars, PICodeInfo::ClassInfo *> * operator->() const DEPRECATEDM("use PICODEINFO::classes()") { return __Storage__::instance() -> classesInfo;
return __Storage__::instance()->classesInfo; }
} }
}; ;
static ClassInfoInterface classesInfo; static ClassInfoInterface classesInfo;
class PIP_EXPORT EnumsInfoInterface { class PIP_EXPORT
public: EnumsInfoInterface{public: const PIMap<PIConstChars, PICodeInfo::EnumInfo *> * operator->() const DEPRECATEDM("use PICODEINFO::enums()"){
const PIMap<PIConstChars, PICodeInfo::EnumInfo *> * operator->() const DEPRECATEDM("use PICODEINFO::enums()") { return __Storage__::instance() -> enumsInfo;
return __Storage__::instance()->enumsInfo; }
} }
}; ;
static EnumsInfoInterface enumsInfo; static EnumsInfoInterface enumsInfo;
class PIP_EXPORT AccessValueFunctionInterface { class PIP_EXPORT AccessValueFunctionInterface{
public: public: const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * operator->()
const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * operator->() const DEPRECATEDM("use PICODEINFO::accessValueFunctions()") { const DEPRECATEDM("use PICODEINFO::accessValueFunctions()"){
return __Storage__::instance()->accessValueFunctions; return __Storage__::instance() -> accessValueFunctions;
} }
}; }
;
static AccessValueFunctionInterface accessValueFunctions; static AccessValueFunctionInterface accessValueFunctions;
class PIP_EXPORT AccessTypeFunctionInterface { class PIP_EXPORT AccessTypeFunctionInterface{
public: public: const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * operator->()
const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * operator->() const DEPRECATEDM("use PICODEINFO::accessTypeFunctions()") { const DEPRECATEDM("use PICODEINFO::accessTypeFunctions()"){
return __Storage__::instance()->accessTypeFunctions; return __Storage__::instance() -> accessTypeFunctions;
} }
}; }
;
static AccessTypeFunctionInterface accessTypeFunctions; static AccessTypeFunctionInterface accessTypeFunctions;

View File

@@ -611,14 +611,14 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc)
Visibility vis = cur_def_vis; Visibility vis = cur_def_vis;
cur_def_vis = (is_class ? Private : Public); cur_def_vis = (is_class ? Private : Public);
PIString cn = cd.mid(6).trim(); PIString cn = cd.mid(6).trim();
bool has_name = !cn.isEmpty(); bool is_anonymous = cn.isEmpty();
if (cn.isEmpty()) cn = PIStringAscii("<unnamed_") + PIString::fromNumber(anon_num++) + '>'; if (cn.isEmpty()) cn = PIStringAscii("<unnamed_") + PIString::fromNumber(anon_num++) + '>';
// piCout << "found " << typename_ << cn; // piCout << "found " << typename_ << cn;
Entity * e = new Entity(); Entity * e = new Entity();
e->meta = meta; e->meta = meta;
e->name = cur_namespace + cn; e->name = cur_namespace + cn;
e->type = typename_; e->type = typename_;
e->has_name = has_name; e->is_anonymous = is_anonymous;
e->parents = parents; e->parents = parents;
e->visibility = vis; e->visibility = vis;
e->file = cur_file; e->file = cur_file;
@@ -651,7 +651,6 @@ PICodeParser::Entity * PICodeParser::parseClass(Entity * parent, PIString & fc,
} }
// piCout << "found class <****\n" << fc << "\n****>"; // piCout << "found class <****\n" << fc << "\n****>";
if (ce) { if (ce) {
if (parent) parent->children << ce;
ce->parent_scope = parent; ce->parent_scope = parent;
} }
int ps = -1; int ps = -1;
@@ -693,7 +692,7 @@ PICodeParser::Entity * PICodeParser::parseClass(Entity * parent, PIString & fc,
fc.takeSymbol(); fc.takeSymbol();
continue; continue;
} }
tmp = fc.takeLeft(fc.find('{')); tmp = fc.takeLeft(fc.find('{')).trim();
stmp = fc.takeRange('{', '}'); stmp = fc.takeRange('{', '}');
stmp = cw + ' ' + tmp + '{' + stmp + '}'; stmp = cw + ' ' + tmp + '{' + stmp + '}';
auto new_entity = parseClass(ce, stmp, false); auto new_entity = parseClass(ce, stmp, false);
@@ -706,17 +705,15 @@ PICodeParser::Entity * PICodeParser::parseClass(Entity * parent, PIString & fc,
if (fc.takeSymbol() == ";") break; if (fc.takeSymbol() == ";") break;
} while (var.isNotEmpty()); } while (var.isNotEmpty());
if (new_entity) { if (new_entity) {
if (vars.isNotEmpty()) {
ce->children.removeAll(new_entity);
Member me; Member me;
me.visibility = cur_def_vis; me.visibility = cur_def_vis;
me.type = new_entity->name; me.type = new_entity->name;
if (tmp.isEmpty() && vars.isEmpty()) vars = {""};
for (const auto & v: vars) { for (const auto & v: vars) {
me.name = v; me.name = v;
ce->members << me; ce->members << me;
} }
} }
}
// piCout << "!!! <" << vars; // piCout << "!!! <" << vars;
continue; continue;
} }
@@ -1261,7 +1258,7 @@ void PICodeParser::replaceMeta(PIString & dn) {
PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) { PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) {
for (auto * e: entities) for (auto * e: entities)
if (e->name == en) return e; if (e->name == en) return e;
return 0; return nullptr;
} }

View File

@@ -100,7 +100,7 @@ public:
struct PIP_EXPORT Entity { struct PIP_EXPORT Entity {
Entity() { Entity() {
visibility = Global; visibility = Global;
has_name = true; is_anonymous = false;
size = 0; size = 0;
parent_scope = 0; parent_scope = 0;
} }
@@ -110,10 +110,9 @@ public:
PIString file; PIString file;
Visibility visibility; Visibility visibility;
int size; int size;
bool has_name; bool is_anonymous;
Entity * parent_scope; Entity * parent_scope;
PIVector<Entity *> parents; PIVector<Entity *> parents;
PIVector<Entity *> children;
PIVector<Member> functions; PIVector<Member> functions;
PIVector<Member> members; PIVector<Member> members;
PIVector<Typedef> typedefs; PIVector<Typedef> typedefs;

View File

@@ -225,17 +225,20 @@ bool PIVariant::operator==(const PIVariant & v) const {
PIVariant::Type PIVariant::typeFromName(const PIString & tname) { PIVariant::Type PIVariant::typeFromName(const PIString & tname) {
PIString s = tname.trimmed().toLowerCase().replaceAll(" ", ""); PIString s = tname.trimmed().toLowerCase().replaceAll(" ", "");
if (s == "bool" || s == "boolean") return PIVariant::pivBool; if (s == "bool" || s == "boolean") return PIVariant::pivBool;
if (s == "char" || s == "sbyte") return PIVariant::pivChar; if (s == "char" || s == "sbyte" || s == "int8_t") return PIVariant::pivChar;
if (s == "short" || s == "shortint" || s == "signedshort" || s == "signedshortint" || s == "sword") return PIVariant::pivShort; if (s == "short" || s == "shortint" || s == "signedshort" || s == "signedshortint" || s == "sword" || s == "int16_t")
if (s == "int" || s == "signed" || s == "signedint") return PIVariant::pivInt; return PIVariant::pivShort;
if (s == "int" || s == "signed" || s == "signedint" || s == "int32_t") return PIVariant::pivInt;
if (s == "long" || s == "longint" || s == "signedlong" || s == "signedlongint" || s == "sdword") return PIVariant::pivInt; if (s == "long" || s == "longint" || s == "signedlong" || s == "signedlongint" || s == "sdword") return PIVariant::pivInt;
if (s == "llong" || s == "longlong" || s == "longlongint" || s == "signedlonglong" || s == "signedlonglongint" || s == "sqword") if (s == "llong" || s == "longlong" || s == "longlongint" || s == "signedlonglong" || s == "signedlonglongint" || s == "sqword" ||
s == "int64_t")
return PIVariant::pivLLong; return PIVariant::pivLLong;
if (s == "uchar" || s == "byte") return PIVariant::pivUChar; if (s == "uchar" || s == "byte" || s == "uint8_t") return PIVariant::pivUChar;
if (s == "ushort" || s == "unsignedshort" || s == "unsignedshortint" || s == "word") return PIVariant::pivUShort; if (s == "ushort" || s == "unsignedshort" || s == "unsignedshortint" || s == "word" || s == "uint16_t") return PIVariant::pivUShort;
if (s == "uint" || s == "unsigned" || s == "unsignedint") return PIVariant::pivUInt; if (s == "uint" || s == "unsigned" || s == "unsignedint" || s == "uint32_t") return PIVariant::pivUInt;
if (s == "ulong" || s == "unsignedlong" || s == "unsignedlongint" || s == "dword") return PIVariant::pivUInt; if (s == "ulong" || s == "unsignedlong" || s == "unsignedlongint" || s == "dword") return PIVariant::pivUInt;
if (s == "ullong" || s == "unsignedlonglong" || s == "unsignedlonglongint" || s == "qword") return PIVariant::pivULLong; if (s == "ullong" || s == "unsignedlonglong" || s == "unsignedlonglongint" || s == "qword" || s == "uint64_t")
return PIVariant::pivULLong;
if (s == "float") return PIVariant::pivFloat; if (s == "float") return PIVariant::pivFloat;
if (s == "double" || s == "real") return PIVariant::pivDouble; if (s == "double" || s == "real") return PIVariant::pivDouble;
if (s == "ldouble" || s == "longdouble") return PIVariant::pivLDouble; if (s == "ldouble" || s == "longdouble") return PIVariant::pivLDouble;

View File

@@ -126,3 +126,8 @@ PIString toCName(const PIString & s) {
ret.replaceAll("__", "_"); ret.replaceAll("__", "_");
return ret; return ret;
} }
PICodeParser::Entity * findEntity(Runtime & rt, const PIString & type) {
return rt.parser.findEntityByName(type);
}

View File

@@ -35,5 +35,6 @@ void usage();
void help(); void help();
PIString toCName(const PIString & s); PIString toCName(const PIString & s);
PICodeParser::Entity * findEntity(Runtime & rt, const PIString & type);
#endif #endif

View File

@@ -22,14 +22,52 @@
#include "stream.h" #include "stream.h"
void writeGetterTypeMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PISet<int> used_id;
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue;
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
writeGetterTypeMembers(rt, type, var_prefix + m.name);
continue;
}
}
rt.ts << "\tif (strcmp(name, \"" << var_prefix << m.name << "\") == 0) return \"" << m.type;
// if (m.isBitfield()) rt.ts << ":" << m.bits;
rt.ts << "\";\n";
}
}
void writeGetterValueMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PISet<int> used_id;
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue;
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
writeGetterValueMembers(rt, type, var_prefix + m.name);
continue;
}
}
rt.ts << "\tif (strcmp(name, \"" << var_prefix << m.name << "\") == 0) {";
if (m.isBitfield()) {
rt.ts << "ret = piSerialize(static_cast<" << m.type << ">(o->" << var_prefix << m.name << "));";
} else
rt.ts << "serialize(ret, o->" << var_prefix << m.name << ");";
rt.ts << " return ret;}\n";
}
}
void makeGetterType(Runtime & rt, const PICodeParser::Entity * e) { void makeGetterType(Runtime & rt, const PICodeParser::Entity * e) {
if (!needClassStream(e)) return; if (!needClassStream(e)) return;
rt.ts << "\nconst char * getterType" << toCName(e->name) << "(const char * name) {\n"; rt.ts << "\nconst char * getterType" << toCName(e->name) << "(const char * name) {\n";
rt.ts << "\tif (!name) return \"\";\n"; rt.ts << "\tif (!name) return \"\";\n";
for (const PICodeParser::Member & m: e->members) { writeGetterTypeMembers(rt, e);
if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue;
rt.ts << "\tif (strcmp(name, \"" << m.name << "\") == 0) return \"" << m.type << "\";\n";
}
rt.ts << "\treturn \"\";\n}\n"; rt.ts << "\treturn \"\";\n}\n";
} }
@@ -40,9 +78,6 @@ void makeGetterValue(Runtime & rt, const PICodeParser::Entity * e) {
rt.ts << "\tPIByteArray ret;\n"; rt.ts << "\tPIByteArray ret;\n";
rt.ts << "\tif (!p || !name) return ret;\n"; rt.ts << "\tif (!p || !name) return ret;\n";
rt.ts << "\t" << e->name << " * o = (" << e->name << "*)p;\n"; rt.ts << "\t" << e->name << " * o = (" << e->name << "*)p;\n";
for (const PICodeParser::Member & m: e->members) { writeGetterValueMembers(rt, e);
if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue;
rt.ts << "\tif (strcmp(name, \"" << m.name << "\") == 0) {serialize(ret, o->" << m.name << "); return ret;}\n";
}
rt.ts << "\treturn ret;\n}\n"; rt.ts << "\treturn ret;\n}\n";
} }

View File

@@ -22,6 +22,8 @@
#include "common.h" #include "common.h"
void writeGetterTypeMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {});
void writeGetterValueMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {});
void makeGetterType(Runtime & rt, const PICodeParser::Entity * e); void makeGetterType(Runtime & rt, const PICodeParser::Entity * e);
void makeGetterValue(Runtime & rt, const PICodeParser::Entity * e); void makeGetterValue(Runtime & rt, const PICodeParser::Entity * e);

View File

@@ -22,7 +22,8 @@
#include "pitranslator.h" #include "pitranslator.h"
bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e) { bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PIVector<PICodeParser::Member> ml; PIVector<PICodeParser::Member> ml;
for (const PICodeParser::Member & m: e->members) { for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue; if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue;
@@ -30,12 +31,19 @@ bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e) {
} }
bool is_union = e->type == "union"; bool is_union = e->type == "union";
for (const PICodeParser::Member & m: ml) { for (const PICodeParser::Member & m: ml) {
if (is_union && m.isBitfield()) continue; if (m.isBitfield()) continue;
if (m.attributes[PICodeParser::Static]) continue; if (m.attributes[PICodeParser::Static]) continue;
if (m.meta.value("id") == "-") continue; if (m.meta.value("id") == "-") continue;
// if (m.meta.contains("id")) cnt = m.meta.value("id").toInt(); // if (m.meta.contains("id")) cnt = m.meta.value("id").toInt();
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
writeClassJSONMembersOut(rt, type, var_prefix + m.name);
continue;
}
}
if (m.dims.isEmpty()) { if (m.dims.isEmpty()) {
rt.ts << "\tret[\"" << m.name << "\"] = piSerializeJSON(v." << m.name << ");\n"; rt.ts << "\tret[\"" << var_prefix << m.name << "\"] = piSerializeJSON(v." << var_prefix << m.name << ");\n";
} else { } else {
PIString ptype = m.type.left(m.type.find('[')).trim(); PIString ptype = m.type.left(m.type.find('[')).trim();
PIString size = m.dims[0]; PIString size = m.dims[0];
@@ -43,21 +51,22 @@ bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e) {
size += " * "; size += " * ";
size += m.dims[i]; size += m.dims[i];
} }
rt.ts << "\tret[\"" << m.name << "\"] = piSerializeJSON(PIVector<" << ptype << " >((const " << ptype << " *)(v." << m.name rt.ts << "\tret[\"" << var_prefix << m.name << "\"] = piSerializeJSON(PIVector<" << ptype << " >((const " << ptype << " *)(v."
<< "), " << size << "));\n"; << var_prefix << m.name << "), " << size << "));\n";
} }
if (is_union) break; if (is_union) break;
} }
if (is_union) return true; if (is_union) return true;
for (const PICodeParser::Entity * ce: e->children) { /*for (const PICodeParser::Entity * ce: e->children) {
if (ce->has_name) continue; if (!ce->is_anonymous) continue;
if (!writeClassJSONMembersOut(rt, ce)) return false; if (!writeClassJSONMembersOut(rt, ce)) return false;
} }*/
return true; return true;
} }
bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e) { bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PIVector<PICodeParser::Member> ml; PIVector<PICodeParser::Member> ml;
for (const PICodeParser::Member & m: e->members) { for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue; if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue;
@@ -66,12 +75,19 @@ bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e) {
bool is_union = e->type == "union"; bool is_union = e->type == "union";
PISet<int> used_id; PISet<int> used_id;
for (const PICodeParser::Member & m: ml) { for (const PICodeParser::Member & m: ml) {
if (is_union && m.isBitfield()) continue; if (m.isBitfield()) continue;
if (m.attributes[PICodeParser::Static]) continue; if (m.attributes[PICodeParser::Static]) continue;
if (m.meta.value("id") == "-") continue; if (m.meta.value("id") == "-") continue;
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
writeClassJSONMembersIn(rt, type, var_prefix + m.name);
continue;
}
}
// if (m.meta.contains("id")) cnt = m.meta.value("id").toInt(); // if (m.meta.contains("id")) cnt = m.meta.value("id").toInt();
if (m.dims.isEmpty()) { if (m.dims.isEmpty()) {
rt.ts << "\tpiDeserializeJSON(v." << m.name << ", js[\"" << m.name << "\"]);\n"; rt.ts << "\tpiDeserializeJSON(v." << var_prefix << m.name << ", js[\"" << var_prefix << m.name << "\"]);\n";
} else { } else {
PIString ptype = m.type.left(m.type.find('[')).trim(); PIString ptype = m.type.left(m.type.find('[')).trim();
PIString size = m.dims[0]; PIString size = m.dims[0];
@@ -80,19 +96,19 @@ bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e) {
size += m.dims[i]; size += m.dims[i];
} }
rt.ts << "\t{\n\t\tPIVector<" << ptype << " > d;\n"; rt.ts << "\t{\n\t\tPIVector<" << ptype << " > d;\n";
rt.ts << "\t\tpiDeserializeJSON(d, js[\"" << m.name << "\"]);\n"; rt.ts << "\t\tpiDeserializeJSON(d, js[\"" << var_prefix << m.name << "\"]);\n";
rt.ts << "\t\tint cnt = piMini(d.size_s(), " << size << ");\n"; rt.ts << "\t\tint cnt = piMini(d.size_s(), " << size << ");\n";
rt.ts << "\t\tfor (int i = 0; i < cnt; ++i)\n"; rt.ts << "\t\tfor (int i = 0; i < cnt; ++i)\n";
rt.ts << "\t\t\t((" << ptype << " *)(v." << m.name << "))[i] = d[i];\n"; rt.ts << "\t\t\t((" << ptype << " *)(v." << var_prefix << m.name << "))[i] = d[i];\n";
rt.ts << "\t}\n"; rt.ts << "\t}\n";
} }
if (is_union) break; if (is_union) break;
} }
if (is_union) return true; if (is_union) return true;
for (const PICodeParser::Entity * ce: e->children) { /*for (const PICodeParser::Entity * ce: e->children) {
if (ce->has_name) continue; if (!ce->is_anonymous) continue;
if (!writeClassJSONMembersIn(rt, ce)) return false; if (!writeClassJSONMembersIn(rt, ce)) return false;
} }*/
return true; return true;
} }

View File

@@ -22,8 +22,8 @@
#include "common.h" #include "common.h"
bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e); bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {});
bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e); bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {});
bool needClassJSON(const PICodeParser::Entity * e); bool needClassJSON(const PICodeParser::Entity * e);
bool makeClassJSON(Runtime & rt, const PICodeParser::Entity * e); bool makeClassJSON(Runtime & rt, const PICodeParser::Entity * e);

View File

@@ -67,7 +67,7 @@ bool writeModel(PICodeParser & parser,
if (getters) { if (getters) {
ts << "\n\n// Getter funtions\n"; ts << "\n\n// Getter funtions\n";
for (const PICodeParser::Entity * e: parser.entities) { for (const PICodeParser::Entity * e: parser.entities) {
if (!e->has_name || e->name.startsWith("_PI")) continue; if (e->is_anonymous || e->name.startsWith("_PI")) continue;
makeGetterType(rt, e); makeGetterType(rt, e);
makeGetterValue(rt, e); makeGetterValue(rt, e);
} }
@@ -95,7 +95,7 @@ bool writeModel(PICodeParser & parser,
if (meta) { if (meta) {
ts << "\n\n// Classes\n"; ts << "\n\n// Classes\n";
for (const PICodeParser::Entity * e: parser.entities) { for (const PICodeParser::Entity * e: parser.entities) {
if (e->name.startsWith("_PI")) continue; if (e->name.startsWith("_PI") || e->is_anonymous) continue;
makeClassInfo(rt, e); makeClassInfo(rt, e);
} }
} }
@@ -108,7 +108,7 @@ bool writeModel(PICodeParser & parser,
ts << "\n// Getters\n"; ts << "\n// Getters\n";
for (const PICodeParser::Entity * e: parser.entities) { for (const PICodeParser::Entity * e: parser.entities) {
if (!needClassStream(e)) continue; if (!needClassStream(e)) continue;
if (!e->has_name || e->name.startsWith("_PI")) continue; if (e->is_anonymous || e->name.startsWith("_PI")) continue;
ts << "\tci_avf[\"" << e->name << "\"] = getterValue" << toCName(e->name) << ";\n"; ts << "\tci_avf[\"" << e->name << "\"] = getterValue" << toCName(e->name) << ";\n";
ts << "\tci_atf[\"" << e->name << "\"] = getterType" << toCName(e->name) << ";\n"; ts << "\tci_atf[\"" << e->name << "\"] = getterType" << toCName(e->name) << ";\n";
} }
@@ -125,7 +125,7 @@ bool writeModel(PICodeParser & parser,
if (meta) { if (meta) {
ts << "\n// Classes clean\n"; ts << "\n// Classes clean\n";
for (const PICodeParser::Entity * e: parser.entities) { for (const PICodeParser::Entity * e: parser.entities) {
if (e->name.startsWith("_PI")) continue; if (e->name.startsWith("_PI") || e->is_anonymous) continue;
ts << "\tpiDeleteSafety(ci_ci[\"" << e->name << "\"]);\n"; ts << "\tpiDeleteSafety(ci_ci[\"" << e->name << "\"]);\n";
ts << "\tci_ins->classesInfo->remove(\"" << e->name << "\");\n"; ts << "\tci_ins->classesInfo->remove(\"" << e->name << "\");\n";
} }
@@ -143,7 +143,7 @@ bool writeModel(PICodeParser & parser,
ts << "\n// Getters clean\n"; ts << "\n// Getters clean\n";
for (const PICodeParser::Entity * e: parser.entities) { for (const PICodeParser::Entity * e: parser.entities) {
if (!needClassStream(e)) continue; if (!needClassStream(e)) continue;
if (!e->has_name || e->name.startsWith("_PI")) continue; if (e->is_anonymous || e->name.startsWith("_PI")) continue;
ts << "\tci_avf.remove(\"" << e->name << "\");\n"; ts << "\tci_avf.remove(\"" << e->name << "\");\n";
ts << "\tci_atf.remove(\"" << e->name << "\");\n"; ts << "\tci_atf.remove(\"" << e->name << "\");\n";
} }
@@ -173,7 +173,7 @@ bool writeModel(PICodeParser & parser,
if (streams) { if (streams) {
ts << "\n\n// Stream operators\n"; ts << "\n\n// Stream operators\n";
for (const PICodeParser::Entity * e: parser.entities) { for (const PICodeParser::Entity * e: parser.entities) {
if (!e->has_name || e->name.startsWith("_PI") || if (e->is_anonymous || e->name.startsWith("_PI") ||
!(e->visibility == PICodeParser::Global || e->visibility == PICodeParser::Public)) !(e->visibility == PICodeParser::Global || e->visibility == PICodeParser::Public))
continue; continue;
if (!makeClassStream(rt, e)) return false; if (!makeClassStream(rt, e)) return false;
@@ -182,7 +182,7 @@ bool writeModel(PICodeParser & parser,
if (json) { if (json) {
ts << "\n\n// JSON serialization\n"; ts << "\n\n// JSON serialization\n";
for (const PICodeParser::Entity * e: parser.entities) { for (const PICodeParser::Entity * e: parser.entities) {
if (!e->has_name || e->name.startsWith("_PI") || if (e->is_anonymous || e->name.startsWith("_PI") ||
!(e->visibility == PICodeParser::Global || e->visibility == PICodeParser::Public)) !(e->visibility == PICodeParser::Global || e->visibility == PICodeParser::Public))
continue; continue;
if (!makeClassJSON(rt, e)) return false; if (!makeClassJSON(rt, e)) return false;

View File

@@ -20,27 +20,17 @@
#include "metainfo.h" #include "metainfo.h"
void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e) { void writeClassInfoMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) {
rt.ts << "\n\t{\n\tClassInfo * ci = new ClassInfo();\n"; if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
rt.ts << "\tci->type = \"" << e->type << "\";\n";
rt.ts << "\tci->name = \"" << e->name << "\";\n";
rt.ts << "\tci->has_name = " << (e->has_name ? "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";
for (const PICodeParser::Member & m: e->members) { for (const PICodeParser::Member & m: e->members) {
rt.ts << "\tti = TypeInfo(\"" << m.name << "\", \"" << m.type << "\""; 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) { if (m.attributes != 0) {
bool fir = true; bool fir = true;
rt.ts << ", "; rt.ts << ", ";
@@ -97,6 +87,29 @@ void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e) {
} }
rt.ts << "\tci->variables << ti;\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; PIString arg;
bool has_fi = false; bool has_fi = false;
for (const PICodeParser::Member & m: e->functions) { for (const PICodeParser::Member & m: e->functions) {

View File

@@ -22,6 +22,7 @@
#include "common.h" #include "common.h"
void writeClassInfoMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {});
void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e); void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e);
#endif #endif

View File

@@ -22,7 +22,8 @@
#include "pitranslator.h" #include "pitranslator.h"
bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple) { bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PIVector<PICodeParser::Member> ml; PIVector<PICodeParser::Member> ml;
for (const PICodeParser::Member & m: e->members) { for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue; if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue;
@@ -31,9 +32,16 @@ bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, in
bool is_union = e->type == "union"; bool is_union = e->type == "union";
PISet<int> used_id; PISet<int> used_id;
for (const PICodeParser::Member & m: ml) { for (const PICodeParser::Member & m: ml) {
if (is_union && m.isBitfield()) continue; if (m.isBitfield()) continue;
if (m.attributes[PICodeParser::Static]) continue; if (m.attributes[PICodeParser::Static]) continue;
if (m.meta.value("id") == "-") continue; if (m.meta.value("id") == "-") continue;
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
if (!writeClassStreamMembersOut(rt, type, cnt, simple, var_prefix + m.name)) return false;
continue;
}
}
++cnt; ++cnt;
if (m.meta.contains("id")) cnt = m.meta.value("id").toInt(); if (m.meta.contains("id")) cnt = m.meta.value("id").toInt();
if (used_id[cnt]) { if (used_id[cnt]) {
@@ -44,11 +52,11 @@ bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, in
if (simple) { if (simple) {
rt.ts << "\ts << "; rt.ts << "\ts << ";
if (rt.parser.isEnum(m.type)) rt.ts << "(int)"; if (rt.parser.isEnum(m.type)) rt.ts << "(int)";
rt.ts << "v." << m.name << ";\n"; rt.ts << "v." << var_prefix << m.name << ";\n";
} else { } else {
rt.ts << "\tcs.add(" << cnt << ", "; rt.ts << "\tcs.add(" << cnt << ", ";
if (rt.parser.isEnum(m.type)) rt.ts << "(int)"; if (rt.parser.isEnum(m.type)) rt.ts << "(int)";
rt.ts << "v." << m.name << ");\n"; rt.ts << "v." << var_prefix << m.name << ");\n";
} }
} else { } else {
PIString ptype = m.type.left(m.type.find('[')).trim(); PIString ptype = m.type.left(m.type.find('[')).trim();
@@ -59,24 +67,22 @@ bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, in
} }
if (simple) { if (simple) {
rt.ts << "\tfor (int i = 0; i < " << size << "; ++i)\n"; rt.ts << "\tfor (int i = 0; i < " << size << "; ++i)\n";
rt.ts << "\t\ts << ((const " << ptype << " *)(v." << m.name << "))[i];\n"; rt.ts << "\t\ts << ((const " << ptype << " *)(" << "v." << var_prefix << m.name << "))[i];\n";
} else { } else {
rt.ts << "\tcs << cs.chunk(" << cnt << ", PIVector<" << ptype << " >((const " << ptype << " *)(v." << m.name << "), "; rt.ts << "\tcs << cs.chunk(" << cnt << ", PIVector<" << ptype << " >((const " << ptype << " *)(" << "v." << var_prefix
<< m.name << "), ";
rt.ts << size << "));\n"; rt.ts << size << "));\n";
} }
} }
if (is_union) break; if (is_union) break;
} }
if (is_union) return true; if (is_union) return true;
for (const PICodeParser::Entity * ce: e->children) {
if (ce->has_name) continue;
if (!writeClassStreamMembersOut(rt, ce, cnt, simple)) return false;
}
return true; return true;
} }
bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple) { bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PIVector<PICodeParser::Member> ml; PIVector<PICodeParser::Member> ml;
for (const PICodeParser::Member & m: e->members) { for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue; if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue;
@@ -85,9 +91,16 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int
bool is_union = e->type == "union"; bool is_union = e->type == "union";
PISet<int> used_id; PISet<int> used_id;
for (const PICodeParser::Member & m: ml) { for (const PICodeParser::Member & m: ml) {
if (is_union && m.isBitfield()) continue; if (m.isBitfield()) continue;
if (m.attributes[PICodeParser::Static]) continue; if (m.attributes[PICodeParser::Static]) continue;
if (m.meta.value("id") == "-") continue; if (m.meta.value("id") == "-") continue;
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
if (!writeClassStreamMembersIn(rt, type, cnt, simple, var_prefix + m.name)) return false;
continue;
}
}
++cnt; ++cnt;
if (m.meta.contains("id")) cnt = m.meta.value("id").toInt(); if (m.meta.contains("id")) cnt = m.meta.value("id").toInt();
if (used_id[cnt]) { if (used_id[cnt]) {
@@ -104,8 +117,8 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int
if (is_enum) if (is_enum)
rt.ts << "i;"; rt.ts << "i;";
else else
rt.ts << "v." << m.name << ";"; rt.ts << "v." << var_prefix << m.name << ";";
if (is_enum) rt.ts << " v." << m.name << " = (" << m.type << ")i;}"; if (is_enum) rt.ts << " v. << var_prefix" << m.name << " = (" << m.type << ")i;}";
rt.ts << "\n"; rt.ts << "\n";
} else { } else {
rt.ts << "\t\tcase " << cnt << ":"; rt.ts << "\t\tcase " << cnt << ":";
@@ -114,9 +127,9 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int
if (is_enum) if (is_enum)
rt.ts << "i"; rt.ts << "i";
else else
rt.ts << "v." << m.name; rt.ts << "v." << var_prefix << m.name;
rt.ts << ");"; rt.ts << ");";
if (is_enum) rt.ts << " v." << m.name << " = (" << m.type << ")i;}"; if (is_enum) rt.ts << " v." << var_prefix << m.name << " = (" << m.type << ")i;}";
rt.ts << " break;\n"; rt.ts << " break;\n";
} }
} else { } else {
@@ -128,12 +141,12 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int
} }
if (simple) { if (simple) {
rt.ts << "\tfor (int i = 0; i < " << size << "; ++i)\n"; rt.ts << "\tfor (int i = 0; i < " << size << "; ++i)\n";
rt.ts << "\t\ts >> ((" << ptype << " *)(v." << m.name << "))[i];\n"; rt.ts << "\t\ts >> ((" << ptype << " *)(" << "v." << var_prefix << m.name << "))[i];\n";
} else { } else {
rt.ts << "\t\tcase " << cnt << ": {\n\t\t\tPIVector<" << ptype << " > d; cs.get(d);\n"; rt.ts << "\t\tcase " << cnt << ": {\n\t\t\tPIVector<" << ptype << " > d; cs.get(d);\n";
rt.ts << "\t\t\tint cnt = piMini(d.size_s(), " << size << ");\n"; rt.ts << "\t\t\tint cnt = piMini(d.size_s(), " << size << ");\n";
rt.ts << "\t\t\tfor (int i = 0; i < cnt; ++i)\n"; rt.ts << "\t\t\tfor (int i = 0; i < cnt; ++i)\n";
rt.ts << "\t\t\t\t((" << ptype << " *)(v." << m.name << "))[i] = d[i];\n"; rt.ts << "\t\t\t\t((" << ptype << " *)(" << "v." << var_prefix << m.name << "))[i] = d[i];\n";
rt.ts << "\t\t\t}\n"; rt.ts << "\t\t\t}\n";
rt.ts << "\t\t\tbreak;\n"; rt.ts << "\t\t\tbreak;\n";
} }
@@ -141,10 +154,6 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int
if (is_union) break; if (is_union) break;
} }
if (is_union) return true; if (is_union) return true;
for (const PICodeParser::Entity * ce: e->children) {
if (ce->has_name) continue;
if (!writeClassStreamMembersIn(rt, ce, cnt, simple)) return false;
}
return true; return true;
} }

View File

@@ -22,8 +22,8 @@
#include "common.h" #include "common.h"
bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple); bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple, PIString var_prefix = {});
bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple); bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple, PIString var_prefix = {});
bool needClassStream(const PICodeParser::Entity * e); bool needClassStream(const PICodeParser::Entity * e);
bool makeClassStream(Runtime & rt, const PICodeParser::Entity * e); bool makeClassStream(Runtime & rt, const PICodeParser::Entity * e);