#include "Interpreter.h"
#include "ParsedSource.h"
+#include "TypeDescription.h"
#include "../battle/Hero.h"
#include "../battle/Monster.h"
#include "../battle/PartyLayout.h"
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;
char *dest(object + fd.Offset());
if (fd.IsAggregate()) {
int arraySize(i->second->GetLiteral().ArraySize());
- char *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) {
- aggregate = alloc.Alloc(fieldType.Size() * arraySize);
- char *iter = aggregate;
const vector<PropertyList *> &list(i->second->GetLiteral().GetPropertyLists());
- for (vector<PropertyList *>::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<PropertyList *>::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<char **>(iter) = member;
+ } else {
+ member = iter;
+ }
+ fieldType.Construct(member);
+ ReadObject(fieldType.TypeId(), -1, member, **j);
}
} else if (i->second->GetLiteral().GetType() == Literal::ARRAY_VALUES) {
- aggregate = alloc.Alloc(fieldType.Size() * arraySize);
- char *iter = aggregate;
const vector<Value *> &list(i->second->GetLiteral().GetValues());
- for (vector<Value *>::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<Value *>::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<char **>(iter) = member;
+ } else {
+ member = iter;
+ }
+ fieldType.Construct(member);
+ ReadLiteral(fieldType.TypeId(), -1, member, (*j)->GetLiteral());
}
} else {
- aggregate = alloc.Alloc(sizeof(char *) * arraySize);
- char *iter = aggregate;
+ if (!fd.IsReferenced()) {
+ // TODO: implement inline identifier arrays
+ throw std::runtime_error("inline identifier arrays not implemented (yet)");
+ }
const vector<string> &list(i->second->GetLiteral().GetIdentifiers());
- for (vector<string>::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += sizeof(void *)) {
+ for (vector<string>::const_iterator j(list.begin()), end(list.end());
+ j != end; ++j, iter += memberSize) {
if (source.IsDefined(*j)) {
*reinterpret_cast<void **>(iter)
= GetObject(fd.TypeId(), *j);
} else {
- Postpone(typeId, id, fd.Offset() + (iter - aggregate), *j, fd.TypeId(), false);
+ Postpone(iter, *j, fd.TypeId(), false);
}
}
}
- 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");
- }
+ 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()) {
}
}
} 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);
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));
}