X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=src%2Floader%2FInterpreter.cpp;h=8b54fc177913de18a1266f885cc8e959b6eb4eef;hb=587a9fc38235475f1c25424bee3e3aeb892a25e2;hp=7dcb41e969c0de829f87ef56c67896e0c0dfc82a;hpb=cc3d698b8c1ad09d7a3f9e3f28bc84e0ac1735ea;p=l2e.git diff --git a/src/loader/Interpreter.cpp b/src/loader/Interpreter.cpp index 7dcb41e..8b54fc1 100644 --- a/src/loader/Interpreter.cpp +++ b/src/loader/Interpreter.cpp @@ -1,6 +1,7 @@ #include "Interpreter.h" #include "ParsedSource.h" +#include "TypeDescription.h" #include "../battle/Hero.h" #include "../battle/Monster.h" #include "../battle/PartyLayout.h" @@ -40,7 +41,7 @@ using graphics::Gauge; using graphics::ComplexAnimation; using graphics::SimpleAnimation; using graphics::Sprite; -using geometry::Vector; +using math::Vector; using std::make_pair; using std::set; using std::string; @@ -127,10 +128,9 @@ void Interpreter::ReadLiteral(const Definition &dfn) { void Interpreter::ReadLiteral(int typeId, int id, char *object, const Literal &literal) { switch (literal.GetType()) { case Literal::ARRAY_VALUES: - throw Error("named value arrays are not supported, sorry"); - break; case Literal::ARRAY_PROPS: - throw Error("named property list arrays are not supported, sorry"); + case Literal::ARRAY_IDENTS: + throw Error("named arrays are not supported, sorry"); break; case Literal::BOOLEAN: new (object) bool(literal.GetBoolean()); @@ -177,10 +177,9 @@ void *Interpreter::GetObject(int typeId, const Value &v) { int typeId(0), id(0); switch (v.GetLiteral().GetType()) { case Literal::ARRAY_VALUES: - throw Error("cannot copy value arrays, sorry"); - break; case Literal::ARRAY_PROPS: - throw Error("cannot copy property list arrays, sorry"); + case Literal::ARRAY_IDENTS: + throw Error("cannot copy arrays, sorry"); break; case Literal::BOOLEAN: { @@ -287,28 +286,56 @@ void Interpreter::ReadObject(int typeId, int id, char *object, const PropertyLis char *dest(object + fd.Offset()); if (fd.IsAggregate()) { int arraySize(i->second->GetLiteral().ArraySize()); - char *aggregate(alloc.Alloc(fieldType.Size() * arraySize)); - char *iter(aggregate); + size_t memberSize = fd.IsReferenced() ? sizeof(char *) : fieldType.Size(); + char *aggregate = alloc.Alloc(arraySize * memberSize); + char *iter = aggregate; if (i->second->GetLiteral().GetType() == Literal::ARRAY_PROPS) { const vector &list(i->second->GetLiteral().GetPropertyLists()); - for (vector::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += fieldType.Size()) { - fieldType.Construct(iter); - ReadObject(fieldType.TypeId(), -1, iter, **j); + for (vector::const_iterator j(list.begin()), end(list.end()); + j != end; ++j, iter += memberSize) { + char *member; + if (fd.IsReferenced()) { + member = alloc.Alloc(fieldType.Size()); + *reinterpret_cast(iter) = member; + } else { + member = iter; + } + fieldType.Construct(member); + ReadObject(fieldType.TypeId(), -1, member, **j); } - } else { + } else if (i->second->GetLiteral().GetType() == Literal::ARRAY_VALUES) { const vector &list(i->second->GetLiteral().GetValues()); - for (vector::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += fieldType.Size()) { - fieldType.Construct(iter); - ReadLiteral(fieldType.TypeId(), -1, iter, (*j)->GetLiteral()); + for (vector::const_iterator j(list.begin()), end(list.end()); + j != end; ++j, iter += memberSize) { + char *member; + if (fd.IsReferenced()) { + member = alloc.Alloc(fieldType.Size()); + *reinterpret_cast(iter) = member; + } else { + member = iter; + } + fieldType.Construct(member); + ReadLiteral(fieldType.TypeId(), -1, member, (*j)->GetLiteral()); } - } - if (fd.IsReferenced()) { - std::memcpy(dest, &aggregate, sizeof(char *)); - dest += sizeof(char *); - std::memcpy(dest, &arraySize, sizeof(int)); } else { - throw Error("aggregate type fields must be referenced"); + if (!fd.IsReferenced()) { + // TODO: implement inline identifier arrays + throw std::runtime_error("inline identifier arrays not implemented (yet)"); + } + const vector &list(i->second->GetLiteral().GetIdentifiers()); + for (vector::const_iterator j(list.begin()), end(list.end()); + j != end; ++j, iter += memberSize) { + if (source.IsDefined(*j)) { + *reinterpret_cast(iter) + = GetObject(fd.TypeId(), *j); + } else { + Postpone(iter, *j, fd.TypeId(), false); + } + } } + std::memcpy(dest, &aggregate, sizeof(char *)); + dest += sizeof(char *); + std::memcpy(dest, &arraySize, sizeof(int)); } else if (i->second->IsLiteral() && !fd.IsReferenced()) { // inline literals if (i->second->GetLiteral().IsObject()) { @@ -328,7 +355,7 @@ void Interpreter::ReadObject(int typeId, int id, char *object, const PropertyLis } } } else { - Postpone(typeId, id, fd.Offset(), i->second->GetIdentifier(), fd.TypeId(), !fd.IsReferenced()); + Postpone(object, i->second->GetIdentifier(), fd.TypeId(), !fd.IsReferenced(), fd.IsAggregate()); } } td.Load(object); @@ -833,11 +860,17 @@ bool Interpreter::CanLink(const Value &v) const { return v.IsLiteral() || source.IsDefined(v.GetIdentifier()); } -void Interpreter::Postpone(int type, int id, std::ptrdiff_t offset, const std::string &identifier, int linkedType, bool inlined) { +void Interpreter::Postpone( + char *dest, + const std::string &identifier, + int type, + bool inlined, + bool aggregate) { char *str(alloc.Alloc(identifier.size() + 1)); std::memcpy(str, identifier.c_str(), identifier.size()); str[identifier.size()] = '\0'; - postponedDefinitions.push_back(PostponedDefinition(type, id, offset, str, linkedType, inlined)); + postponedDefinitions.push_back( + PostponedDefinition(dest, str, type, inlined, aggregate)); }