2014-10-07 18:15:46 +00:00
|
|
|
#include "ResourceCompiler.h"
|
|
|
|
#include <iostream>
|
2014-10-07 22:41:40 +00:00
|
|
|
#include "ResourceDefinitions.h"
|
2014-10-07 18:15:46 +00:00
|
|
|
|
2014-10-09 20:15:13 +00:00
|
|
|
ResourceCompiler::ResourceCompiler(
|
|
|
|
TypeDefinitionPtr type, CompoundExprPtr body, bool verboseFlag)
|
|
|
|
: typeDefinition(type),
|
|
|
|
body(body),
|
|
|
|
currentOffset(0),
|
|
|
|
currentField(nullptr),
|
|
|
|
verboseFlag(verboseFlag)
|
2014-10-07 18:15:46 +00:00
|
|
|
{
|
2014-10-07 22:41:40 +00:00
|
|
|
|
2014-10-07 18:15:46 +00:00
|
|
|
}
|
|
|
|
|
2014-10-08 00:52:34 +00:00
|
|
|
std::string ResourceCompiler::resourceData()
|
|
|
|
{
|
|
|
|
return std::string(data.begin(), data.end());
|
|
|
|
}
|
|
|
|
|
2014-10-07 18:15:46 +00:00
|
|
|
void ResourceCompiler::write(int nBits, int value)
|
|
|
|
{
|
2014-10-09 20:15:13 +00:00
|
|
|
if(verboseFlag)
|
|
|
|
std::cout << "[" << nBits << " bits] = " << std::hex << value << std::dec << std::endl;
|
2014-10-08 00:52:34 +00:00
|
|
|
|
|
|
|
unsigned mask = 1 << (nBits-1);
|
|
|
|
|
|
|
|
for(int i = 0; i < nBits; i++)
|
|
|
|
{
|
|
|
|
bool bit = (value & mask) != 0;
|
|
|
|
|
|
|
|
if(currentOffset % 8 == 0)
|
|
|
|
data.push_back(bit ? 0x80 : 0);
|
|
|
|
else if(bit)
|
|
|
|
data.back() |= (0x80 >> (currentOffset % 8));
|
|
|
|
++currentOffset;
|
|
|
|
|
|
|
|
mask >>= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//currentOffset += nBits;
|
2014-10-07 22:41:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ExprPtr ResourceCompiler::lookupIdentifier(std::string name, const Subscripts &sub)
|
|
|
|
{
|
|
|
|
if(currentField)
|
|
|
|
{
|
|
|
|
if(ExprPtr val = currentField->lookupNamedValue(name))
|
2014-10-08 00:52:34 +00:00
|
|
|
{
|
2014-10-07 22:41:40 +00:00
|
|
|
return val;
|
2014-10-08 00:52:34 +00:00
|
|
|
}
|
2014-10-07 22:41:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto p = labelValues.find(std::make_pair(name, sub));
|
|
|
|
if(p != labelValues.end())
|
|
|
|
return p->second;
|
|
|
|
|
2014-10-09 20:15:13 +00:00
|
|
|
std::cerr << "ID lookup failed: " << name << std::endl;
|
2014-10-08 00:52:34 +00:00
|
|
|
|
2014-10-07 22:41:40 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ResourceCompiler::defineLabel(const std::string &name)
|
|
|
|
{
|
|
|
|
labelValues[std::make_pair(name,currentSubscripts)] = std::make_shared<IntExpr>(currentOffset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ResourceCompiler::compile()
|
|
|
|
{
|
2014-10-09 20:15:13 +00:00
|
|
|
if(verboseFlag) std::cout << "(first pass)\n";
|
2014-10-07 22:41:40 +00:00
|
|
|
currentOffset = 0;
|
2014-10-08 00:52:34 +00:00
|
|
|
data.clear();
|
2014-10-07 22:41:40 +00:00
|
|
|
typeDefinition->compile(body, this, true);
|
2014-10-09 20:15:13 +00:00
|
|
|
if(verboseFlag) std::cout << "(second pass)\n";
|
2014-10-07 22:41:40 +00:00
|
|
|
currentOffset = 0;
|
2014-10-08 00:52:34 +00:00
|
|
|
data.clear();
|
2014-10-07 22:41:40 +00:00
|
|
|
typeDefinition->compile(body, this, false);
|
2014-10-09 20:15:13 +00:00
|
|
|
if(verboseFlag) std::cout << "(done)\n";
|
2014-10-07 22:41:40 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int ResourceCompiler::getArrayCount(const std::string &name)
|
|
|
|
{
|
|
|
|
Subscripts sub = currentSubscripts;
|
|
|
|
for(;;)
|
|
|
|
{
|
|
|
|
auto p = arrayCounts.find(std::make_pair(name, sub));
|
|
|
|
if(p != arrayCounts.end())
|
|
|
|
return p->second;
|
|
|
|
|
|
|
|
|
|
|
|
if(sub.empty())
|
|
|
|
return 0; /* ### */
|
|
|
|
sub.popSubscript();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int ResourceCompiler::getArrayIndex(const std::string &arrayName)
|
|
|
|
{
|
|
|
|
return curArrayIndices[arrayName];
|
|
|
|
}
|
|
|
|
|
|
|
|
void ResourceCompiler::beginArrayScope(std::string &arrayName, int index)
|
|
|
|
{
|
|
|
|
if(arrayName != "")
|
|
|
|
{
|
|
|
|
curArrayIndices[arrayName] = index;
|
|
|
|
int& count = arrayCounts[std::make_pair(arrayName, currentSubscripts)];
|
|
|
|
if(count < index)
|
|
|
|
count = index;
|
|
|
|
arrayCounts[std::make_pair(arrayName, Subscripts())] = count;
|
|
|
|
//std::cout << "count for " << arrayName << " is " << count << std::endl;
|
|
|
|
}
|
|
|
|
currentSubscripts.addSubscript(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
Subscripts::Subscripts()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Subscripts::~Subscripts()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Subscripts::addSubscript(int x)
|
|
|
|
{
|
|
|
|
subscripts.push_back(x);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Subscripts::popSubscript()
|
|
|
|
{
|
|
|
|
subscripts.pop_back();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Subscripts::operator<(const Subscripts &other) const
|
|
|
|
{
|
|
|
|
if(subscripts.size() < other.subscripts.size())
|
|
|
|
return true;
|
|
|
|
if(other.subscripts.size() < subscripts.size())
|
|
|
|
return false;
|
|
|
|
for(int i = 0, n = subscripts.size(); i < n; i++)
|
|
|
|
{
|
|
|
|
if(subscripts[i] < other.subscripts[i])
|
|
|
|
return true;
|
|
|
|
else if(subscripts[i] > other.subscripts[i])
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return false;
|
2014-10-07 18:15:46 +00:00
|
|
|
}
|