implement $$byte, $$word, $$long, $$bitfield

This commit is contained in:
Wolfgang Thaller 2014-10-14 00:11:21 +02:00
parent 959846f093
commit c93cb8feae
6 changed files with 81 additions and 11 deletions

View File

@ -136,6 +136,8 @@ ExprPtr IdentifierExpr::lookup(ResourceCompiler *ctx)
int IdentifierExpr::evaluateInt(ResourceCompiler *ctx)
{
if(ctx->isPrePass())
return 0;
return lookup(ctx)->evaluateInt(ctx);
}
@ -186,3 +188,24 @@ std::string UnimplementedExpr::evaluateString(ResourceCompiler *ctx)
std::cerr << msg << std::endl;
return "";
}
PeekExpr::PeekExpr(ExprPtr addr, ExprPtr offset, ExprPtr size)
: addr(addr), offset(offset), size(size)
{
}
PeekExpr::PeekExpr(ExprPtr addr, int size)
: addr(addr),
offset(std::make_shared<IntExpr>(0)),
size(std::make_shared<IntExpr>(size))
{
}
int PeekExpr::evaluateInt(ResourceCompiler *ctx)
{
int p = addr->evaluateInt(ctx) + offset->evaluateInt(ctx);
int s = size->evaluateInt(ctx);
return ctx->peek(p, s);
}

View File

@ -148,5 +148,15 @@ public:
virtual std::string evaluateString(ResourceCompiler *ctx);
};
class PeekExpr : public Expression
{
ExprPtr addr;
ExprPtr offset;
ExprPtr size;
public:
PeekExpr(ExprPtr addr, ExprPtr offset, ExprPtr size);
PeekExpr(ExprPtr addr, int size);
virtual int evaluateInt(ResourceCompiler *ctx);
};
#endif // EXPRESSION_H

View File

@ -41,6 +41,37 @@ void ResourceCompiler::write(int nBits, int value)
//currentOffset += nBits;
}
int ResourceCompiler::peek(int bitPos, int size)
{
int bytePos = bitPos / 8;
int endBytePos = (bitPos + size - 1) / 8 + 1;
unsigned bitPosInByte = bitPos % 8;
unsigned outPos = 32 - size;
unsigned val = 0;
for(int i = bytePos; i != endBytePos; ++i)
{
unsigned byte;
if(i < data.size())
byte = data[i];
else if(i < prePassData.size())
byte = prePassData[i];
else
byte = 0;
unsigned read = byte << (bitPosInByte + 24);
val |= (read >> outPos);
outPos += 8 - bitPosInByte;
bitPosInByte = 0;
}
return val;
}
ExprPtr ResourceCompiler::lookupIdentifier(std::string name, const Subscripts &sub)
{
if(currentField)
@ -70,10 +101,13 @@ void ResourceCompiler::compile()
if(verboseFlag) std::cout << "(first pass)\n";
currentOffset = 0;
data.clear();
prePass = true;
typeDefinition->compile(body, this, true);
if(verboseFlag) std::cout << "(second pass)\n";
currentOffset = 0;
data.clear();
prePassData = std::move(data);
data.clear(); // ###
prePass = false;
typeDefinition->compile(body, this, false);
if(verboseFlag) std::cout << "(done)\n";

View File

@ -31,10 +31,12 @@ class ResourceCompiler
Field* currentField;
Subscripts currentSubscripts;
std::vector<unsigned char> data;
std::vector<unsigned char> data, prePassData;
bool verboseFlag;
void beginArrayScope(std::string& arrayName, int index);
bool prePass;
public:
ResourceCompiler(TypeDefinitionPtr type, CompoundExprPtr body, bool verboseFlag);
@ -44,6 +46,8 @@ public:
void write(int nBits, int value);
int tell() { return currentOffset; }
int peek(int bitPos, int size);
ExprPtr lookupIdentifier(std::string name, const Subscripts& sub = Subscripts());
void defineLabel(const std::string& name);
@ -52,6 +56,8 @@ public:
int getArrayCount(const std::string& arrayName);
int getArrayIndex(const std::string& arrayName);
bool isPrePass() { return prePass; }
class FieldScope
{
ResourceCompiler *compiler;

View File

@ -169,11 +169,8 @@ void SimpleField::compileInt(ExprPtr expr, ResourceCompiler *compiler, bool preP
}
int actualValue = 0;
if(!prePass)
{
ResourceCompiler::FieldScope scope(compiler, this);
actualValue = (value ? value : expr)->evaluateInt(compiler);
}
ResourceCompiler::FieldScope scope(compiler, this);
actualValue = (value ? value : expr)->evaluateInt(compiler);
compiler->write(bitSize, actualValue);
}

View File

@ -371,13 +371,13 @@ expression8 : INTLIT { $$ = std::make_shared<IntExpr>($1); }
| "$$arrayindex" "(" identifier_expression ")"
{ $$ = std::make_shared<ArrayIndexExpr>($identifier_expression); }
| "$$bitfield" "(" expression "," expression "," expression ")"
{ $$ = std::make_shared<UnimplementedExpr>("$$bitfield"); }
{ $$ = std::make_shared<PeekExpr>($3, $5, $7); }
| "$$word" "(" expression ")"
{ $$ = std::make_shared<UnimplementedExpr>("$$word"); }
{ $$ = std::make_shared<PeekExpr>($3, 16); }
| "$$byte" "(" expression ")"
{ $$ = std::make_shared<UnimplementedExpr>("$$byte"); }
{ $$ = std::make_shared<PeekExpr>($3, 8); }
| "$$long" "(" expression ")"
{ $$ = std::make_shared<UnimplementedExpr>("$$long"); }
{ $$ = std::make_shared<PeekExpr>($3, 32); }
;
%type <IdentifierExprPtr> identifier_expression;