this repo has no description
1#include "ResourceCompiler.h"
2#include <iostream>
3#include "ResourceDefinitions.h"
4#include "RezWorld.h"
5#include "Diagnostic.h"
6
7ResourceCompiler::ResourceCompiler(
8 RezWorld& world, TypeDefinitionPtr type, CompoundExprPtr body, bool verboseFlag)
9 : world(world),
10 typeDefinition(type),
11 body(body),
12 currentField(nullptr)
13{
14 this->verboseFlag = verboseFlag;
15}
16
17BinaryOutput::BinaryOutput()
18 : verboseFlag(false)
19{
20 reset(true);
21}
22
23void BinaryOutput::reset(bool prePass)
24{
25 currentOffset = 0;
26 if(!prePass)
27 prePassData = std::move(data);
28 data.clear();
29 this->prePass = prePass;
30}
31
32std::string BinaryOutput::resourceData()
33{
34 return std::string(data.begin(), data.end());
35}
36
37void BinaryOutput::write(int nBits, int value)
38{
39 if(verboseFlag)
40 std::cout << "[" << nBits << " bits] = " << std::hex << value << std::dec << std::endl;
41
42 unsigned mask = 1 << (nBits-1);
43
44 for(int i = 0; i < nBits; i++)
45 {
46 bool bit = (value & mask) != 0;
47
48 if(currentOffset % 8 == 0)
49 data.push_back(bit ? 0x80 : 0);
50 else if(bit)
51 data.back() |= (0x80 >> (currentOffset % 8));
52 ++currentOffset;
53
54 mask >>= 1;
55 }
56
57 //currentOffset += nBits;
58}
59
60int BinaryOutput::peek(int bitPos, int size)
61{
62 unsigned bytePos = bitPos / 8;
63 unsigned endBytePos = (bitPos + size - 1) / 8 + 1;
64
65 unsigned bitPosInByte = bitPos % 8;
66 unsigned outPos = 32 - size;
67
68 unsigned val = 0;
69
70 for(unsigned i = bytePos; i != endBytePos; ++i)
71 {
72 unsigned byte;
73 if(i < data.size())
74 byte = data[i];
75 else if(i < prePassData.size())
76 byte = prePassData[i];
77 else
78 byte = 0;
79
80 unsigned read = byte << (bitPosInByte + 24);
81 val |= (read >> outPos);
82
83 outPos += 8 - bitPosInByte;
84
85 bitPosInByte = 0;
86 }
87
88 return val;
89}
90
91ExprPtr ResourceCompiler::lookupIdentifier(std::string name, const Subscripts &sub)
92{
93 if(currentField)
94 {
95 if(ExprPtr val = currentField->lookupNamedValue(name))
96 {
97 return val;
98 }
99 }
100
101 auto p = labelValues.find(std::make_pair(name, sub));
102 if(p != labelValues.end())
103 return p->second;
104
105 //std::cerr << "ID lookup failed: " << name << std::endl;
106
107 return nullptr;
108}
109
110void ResourceCompiler::defineLabel(const std::string &name)
111{
112 labelValues[std::make_pair(name,currentSubscripts)] = std::make_shared<IntExpr>(currentOffset, yy::location());
113}
114
115void ResourceCompiler::compile()
116{
117 if(verboseFlag) std::cout << "(first pass)\n";
118 reset(true);
119 typeDefinition->compile(body, this, true);
120 if(verboseFlag) std::cout << "(second pass)\n";
121
122 reset(false);
123 typeDefinition->compile(body, this, false);
124 if(verboseFlag) std::cout << "(done)\n";
125}
126
127int ResourceCompiler::getArrayCount(const std::string &name)
128{
129 Subscripts sub = currentSubscripts;
130 for(;;)
131 {
132 auto p = arrayCounts.find(std::make_pair(name, sub));
133 if(p != arrayCounts.end())
134 return p->second;
135
136
137 if(sub.empty())
138 return 0; /* ### */
139 sub.popSubscript();
140 }
141}
142
143int ResourceCompiler::getArrayIndex(const std::string &arrayName)
144{
145 return curArrayIndices[arrayName];
146}
147
148void ResourceCompiler::problem(Diagnostic d)
149{
150 if(!prePass)
151 world.problem(d);
152}
153
154void ResourceCompiler::beginArrayScope(std::string &arrayName, int index)
155{
156 if(arrayName != "")
157 {
158 curArrayIndices[arrayName] = index;
159 int& count = arrayCounts[std::make_pair(arrayName, currentSubscripts)];
160 if(count < index)
161 count = index;
162 arrayCounts[std::make_pair(arrayName, Subscripts())] = count;
163 //std::cout << "count for " << arrayName << " is " << count << std::endl;
164 }
165 currentSubscripts.addSubscript(index);
166}
167
168Subscripts::Subscripts()
169{
170}
171
172Subscripts::~Subscripts()
173{
174}
175
176void Subscripts::addSubscript(int x)
177{
178 subscripts.push_back(x);
179}
180
181void Subscripts::popSubscript()
182{
183 subscripts.pop_back();
184}
185
186bool Subscripts::operator<(const Subscripts &other) const
187{
188 if(subscripts.size() < other.subscripts.size())
189 return true;
190 if(other.subscripts.size() < subscripts.size())
191 return false;
192 for(int i = 0, n = subscripts.size(); i < n; i++)
193 {
194 if(subscripts[i] < other.subscripts[i])
195 return true;
196 else if(subscripts[i] > other.subscripts[i])
197 return false;
198 }
199 return false;
200}