pivariant, enum, tiny format

This commit is contained in:
2022-12-13 21:44:06 +03:00
parent 9d9357b0ca
commit c74ba871cd
15 changed files with 1914 additions and 851 deletions

View File

@@ -20,6 +20,7 @@
#include "picli.h"
#include "picodeparser.h"
#include "piiostream.h"
#include <iostream>
using namespace PICoutManipulators;
@@ -102,6 +103,10 @@ void help() {
piCout << help_string;
}
void printError(const PIString & msg) {
std::cerr << msg.data() << std::endl;
}
PIString toCName(const PIString &s) {
PIString ret(s.trimmed());
@@ -231,13 +236,14 @@ void makeEnumInfo(PIIOTextStream & ts, const PICodeParser::Enum * e) {
}
void writeClassStreamMembersOut(PIIOTextStream & ts, const PICodeParser::Entity * e, int & cnt, bool simple) {
bool writeClassStreamMembersOut(PIIOTextStream & ts, const PICodeParser::Entity * e, int & cnt, bool simple) {
PIVector<PICodeParser::Member> ml;
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue;
ml << m;
}
bool is_union = e->type == "union";
PISet<int> used_id;
for (const PICodeParser::Member & m: ml) {
if (is_union && m.isBitfield())
continue;
@@ -245,6 +251,10 @@ void writeClassStreamMembersOut(PIIOTextStream & ts, const PICodeParser::Entity
++cnt;
if (m.meta.contains("id"))
cnt = m.meta.value("id").toInt();
if (used_id[cnt]) {
printError("Error with \"" + e->name + "\" stream operator: ID " + PIString::fromNumber(cnt) + " already used");
return false;
}
if (m.dims.isEmpty()) {
if (simple) {
ts << "\ts << ";
@@ -275,21 +285,23 @@ void writeClassStreamMembersOut(PIIOTextStream & ts, const PICodeParser::Entity
if (is_union)
break;
}
if (is_union) return;
if (is_union) return true;
for (const PICodeParser::Entity * ce: e->children) {
if (ce->has_name) continue;
writeClassStreamMembersOut(ts, ce, cnt, simple);
if (!writeClassStreamMembersOut(ts, ce, cnt, simple)) return false;
}
return true;
}
void writeClassStreamMembersIn(PIIOTextStream & ts, const PICodeParser::Entity * e, int & cnt, bool simple) {
bool writeClassStreamMembersIn(PIIOTextStream & ts, const PICodeParser::Entity * e, int & cnt, bool simple) {
PIVector<PICodeParser::Member> ml;
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue;
ml << m;
}
bool is_union = e->type == "union";
PISet<int> used_id;
for (const PICodeParser::Member & m: ml) {
if (is_union && m.isBitfield())
continue;
@@ -297,6 +309,11 @@ void writeClassStreamMembersIn(PIIOTextStream & ts, const PICodeParser::Entity *
++cnt;
if (m.meta.contains("id"))
cnt = m.meta.value("id").toInt();
if (used_id[cnt]) {
printError("Error with \"" + e->name + "\" stream operator: ID " + PIString::fromNumber(cnt) + " already used");
return false;
}
used_id << cnt;
if (m.dims.isEmpty()) {
bool is_enum = parser.isEnum(m.type);
if (simple) {
@@ -339,11 +356,12 @@ void writeClassStreamMembersIn(PIIOTextStream & ts, const PICodeParser::Entity *
if (is_union)
break;
}
if (is_union) return;
if (is_union) return true;
for (const PICodeParser::Entity * ce: e->children) {
if (ce->has_name) continue;
writeClassStreamMembersIn(ts, ce, cnt, simple);
if (!writeClassStreamMembersIn(ts, ce, cnt, simple)) return false;
}
return true;
}
@@ -359,14 +377,14 @@ bool needClassStream(const PICodeParser::Entity * e) {
}
void makeClassStream(PIIOTextStream & ts, const PICodeParser::Entity * e) {
if (!needClassStream(e)) return;
bool makeClassStream(PIIOTextStream & ts, const PICodeParser::Entity * e) {
if (!needClassStream(e)) return true;
bool simple = e->meta.contains("simple-stream");
ts << "\nBINARY_STREAM_WRITE(" << e->name << ") {\n";
if (!simple)
ts << "\tPIChunkStream cs;\n";
int cnt = 0;
writeClassStreamMembersOut(ts, e, cnt, simple);
if (!writeClassStreamMembersOut(ts, e, cnt, simple)) return false;
if (!simple)
ts << "\ts << cs.data();\n";
ts << "\treturn s;\n}\n";
@@ -379,10 +397,11 @@ void makeClassStream(PIIOTextStream & ts, const PICodeParser::Entity * e) {
ts << "\t\tswitch (cs.read()) {\n";
}
cnt = 0;
writeClassStreamMembersIn(ts, e, cnt, simple);
if (!writeClassStreamMembersIn(ts, e, cnt, simple)) return false;
if (!simple)
ts << "\t\t}\n\t}\n";
ts << "\treturn s;\n}\n";
return true;
}
@@ -507,7 +526,8 @@ bool writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool met
for (const PICodeParser::Entity * e: parser.entities) {
if (!e->has_name || e->name.startsWith("_PI") ||
!(e->visibility == PICodeParser::Global || e->visibility == PICodeParser::Public)) continue;
makeClassStream(ts, e);
if (!makeClassStream(ts, e))
return false;
}
}
if (meta || enums || getters) {