4 * Created on: Sep 11, 2012
10 #include "Interpreter.h"
27 Compiler::Compiler(const Interpreter &intp)
30 int headerSize(4 + (5 * sizeof(int)) + (intp.Values().size() * 2 * sizeof(int)));
32 exportsOffset = headerSize + Remaining(headerSize, 16);
33 int exportsSize(intp.ExportedIdentifiers().size() * sizeof(Export));
35 externalsOffset = exportsOffset + exportsSize + Remaining(exportsSize, 16);
36 int externalsSize(intp.PostponedDefinitions().size() * sizeof(External));
38 exportStringsOffset = externalsOffset + externalsSize + Remaining(externalsSize, 16);
39 int exportStringsSize(0);
40 for (set<string>::const_iterator i(intp.ExportedIdentifiers().begin()), end(intp.ExportedIdentifiers().end()); i != end; ++i) {
41 exportStringsSize += i->size() + 1;
44 externalStringsOffset = exportStringsOffset + exportStringsSize + Remaining(exportStringsSize, 16);
45 int externalStringsSize(0);
46 for(vector<Interpreter::PostponedDefinition>::const_iterator i(intp.PostponedDefinitions().begin()), end(intp.PostponedDefinitions().end()); i != end; ++i) {
47 externalStringsSize += std::strlen(i->identifier) + 1;
50 imagesOffset = externalStringsOffset + externalStringsSize + Remaining(externalStringsSize, 16);
51 int imagesSize(intp.Images().size() * sizeof(ImageProperties));
52 for (map<string, SDL_Surface *>::const_iterator i(intp.Images().begin()), end(intp.Images().end()); i != end; ++i) {
53 imagesSize += i->second->w * i->second->h * i->second->format->BytesPerPixel;
56 objectsOffset = imagesOffset + imagesSize + Remaining(imagesSize, 16);
58 for (map<int, vector<void *> >::const_iterator i(intp.Values().begin()), end(intp.Values().end()); i != end; ++i) {
59 const TypeDescription &td(TypeDescription::Get(i->first));
60 objectOffsets[i->first] = objectsOffset + objectsSize;
61 objectsSize += td.Size() * i->second.size();
62 objectsSize += Remaining(objectsSize, 16);
66 void Compiler::Write(ostream &out) {
73 WriteExportStrings(out);
75 WriteExternalStrings(out);
83 void Compiler::WriteHeader(ostream &out) {
84 Write(out, "L2O\n", 4);
85 Write(out, reinterpret_cast<const char *>(&exportsOffset), sizeof(int));
86 Write(out, reinterpret_cast<const char *>(&externalsOffset), sizeof(int));
87 Write(out, reinterpret_cast<const char *>(&externalStringsOffset), sizeof(int));
88 Write(out, reinterpret_cast<const char *>(&exportStringsOffset), sizeof(int));
89 Write(out, reinterpret_cast<const char *>(&imagesOffset), sizeof(int));
90 Write(out, reinterpret_cast<const char *>(&objectsOffset), sizeof(int));
91 for(map<int, vector<void *> >::const_iterator i(intp.Values().begin()), end(intp.Values().end()); i != end; ++i) {
92 Write(out, reinterpret_cast<const char *>(&i->first), sizeof(int));
93 int typeOffset(TypeOffset(i->first));
94 Write(out, reinterpret_cast<const char *>(&typeOffset), sizeof(int));
98 void Compiler::WriteExports(ostream &out) {
99 int nameOffset(externalStringsOffset);
100 for (set<string>::const_iterator i(intp.ExportedIdentifiers().begin()), end(intp.ExportedIdentifiers().end()); i != end; ++i) {
101 const Interpreter::ParsedDefinition &dfn(intp.GetDefinition(*i));
103 exp.nameOffset = nameOffset;
104 exp.typeId = dfn.type;
105 exp.dataOffset = ObjectOffset(dfn.type, dfn.id);
106 Write(out, reinterpret_cast<char *>(&exp), sizeof(Export));
107 nameOffset += i->size() + 1;
111 void Compiler::WriteExternals(ostream &out) {
112 int nameOffset(exportStringsOffset);
113 for(vector<Interpreter::PostponedDefinition>::const_iterator i(intp.PostponedDefinitions().begin()), end(intp.PostponedDefinitions().end()); i != end; ++i) {
115 ext.nameOffset = nameOffset;
116 ext.referenceOffset = ReferenceOffset(i->type, i->id, i->offset);
117 ext.inlined = i->inlined ? 1 : 0;
118 Write(out, reinterpret_cast<char *>(&ext), sizeof(External));
119 nameOffset += std::strlen(i->identifier) + 1;
123 void Compiler::WriteExportStrings(ostream &out) {
124 for (set<string>::const_iterator i(intp.ExportedIdentifiers().begin()), end(intp.ExportedIdentifiers().end()); i != end; ++i) {
125 Write(out, i->c_str(), i->size() + 1);
129 void Compiler::WriteExternalStrings(ostream &out) {
130 for(vector<Interpreter::PostponedDefinition>::const_iterator i(intp.PostponedDefinitions().begin()), end(intp.PostponedDefinitions().end()); i != end; ++i) {
131 Write(out, i->identifier, std::strlen(i->identifier) + 1);
135 void Compiler::WriteImages(ostream &out) {
136 for (map<string, SDL_Surface *>::const_iterator i(intp.Images().begin()), end(intp.Images().end()); i != end; ++i) {
138 ip.flags = i->second->flags;
139 ip.width = i->second->w;
140 ip.height = i->second->h;
141 ip.depth = i->second->format->BitsPerPixel;
142 ip.rmask = i->second->format->Rmask;
143 ip.gmask = i->second->format->Gmask;
144 ip.bmask = i->second->format->Bmask;
145 ip.amask = i->second->format->Amask;
146 Write(out, reinterpret_cast<char *>(&ip), sizeof(ImageProperties));
147 SDL_LockSurface(i->second);
148 Write(out, reinterpret_cast<char *>(i->second->pixels), ip.width * ip.height * i->second->format->BytesPerPixel);
149 // TODO: store palette too?
150 SDL_UnlockSurface(i->second);
154 void Compiler::WriteObjects(ostream &out) {
155 for (map<int, vector<void *> >::const_iterator i(intp.Values().begin()), end(intp.Values().end()); i != end; ++i) {
156 const TypeDescription &td(TypeDescription::Get(i->first));
157 for (vector<void *>::const_iterator j(i->second.begin()), jend(i->second.end()); j != jend; ++j) {
158 Write(out, reinterpret_cast<char *>(*j), td.Size());
165 void Compiler::Write(ostream &out, const char *data, int amount) {
166 out.write(data, amount);
170 void Compiler::Pad(ostream &out, int to) {
171 for (int remaining(Remaining(cursor, to)); remaining > 0; --remaining) {
177 int Compiler::Remaining(int value, int alignment) {
178 int have(value % alignment);
179 return (have > 0) ? (16 - have) : 0;
183 int Compiler::ReferenceOffset(int typeId, int objectId, std::ptrdiff_t fieldOffset) const {
184 return ObjectOffset(typeId, objectId) + fieldOffset;
187 int Compiler::ObjectOffset(int typeId, int objectId) const {
188 const TypeDescription &td(TypeDescription::Get(typeId));
189 return TypeOffset(typeId) + (td.Size() * objectId);
192 int Compiler::TypeOffset(int typeId) const {
193 return objectOffsets.at(typeId);