mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-26 06:49:33 +00:00
implement $$byte, $$word, $$long, $$bitfield
This commit is contained in:
parent
959846f093
commit
c93cb8feae
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user