this repo has no description
at fixPythonPipStalling 200 lines 4.5 kB view raw
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}