mirror of
https://github.com/autc04/Retro68.git
synced 2025-02-18 02:30:48 +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)
|
int IdentifierExpr::evaluateInt(ResourceCompiler *ctx)
|
||||||
{
|
{
|
||||||
|
if(ctx->isPrePass())
|
||||||
|
return 0;
|
||||||
return lookup(ctx)->evaluateInt(ctx);
|
return lookup(ctx)->evaluateInt(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,3 +188,24 @@ std::string UnimplementedExpr::evaluateString(ResourceCompiler *ctx)
|
|||||||
std::cerr << msg << std::endl;
|
std::cerr << msg << std::endl;
|
||||||
return "";
|
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);
|
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
|
#endif // EXPRESSION_H
|
||||||
|
@ -41,6 +41,37 @@ void ResourceCompiler::write(int nBits, int value)
|
|||||||
//currentOffset += nBits;
|
//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)
|
ExprPtr ResourceCompiler::lookupIdentifier(std::string name, const Subscripts &sub)
|
||||||
{
|
{
|
||||||
if(currentField)
|
if(currentField)
|
||||||
@ -70,10 +101,13 @@ void ResourceCompiler::compile()
|
|||||||
if(verboseFlag) std::cout << "(first pass)\n";
|
if(verboseFlag) std::cout << "(first pass)\n";
|
||||||
currentOffset = 0;
|
currentOffset = 0;
|
||||||
data.clear();
|
data.clear();
|
||||||
|
prePass = true;
|
||||||
typeDefinition->compile(body, this, true);
|
typeDefinition->compile(body, this, true);
|
||||||
if(verboseFlag) std::cout << "(second pass)\n";
|
if(verboseFlag) std::cout << "(second pass)\n";
|
||||||
currentOffset = 0;
|
currentOffset = 0;
|
||||||
data.clear();
|
prePassData = std::move(data);
|
||||||
|
data.clear(); // ###
|
||||||
|
prePass = false;
|
||||||
typeDefinition->compile(body, this, false);
|
typeDefinition->compile(body, this, false);
|
||||||
if(verboseFlag) std::cout << "(done)\n";
|
if(verboseFlag) std::cout << "(done)\n";
|
||||||
|
|
||||||
|
@ -31,10 +31,12 @@ class ResourceCompiler
|
|||||||
Field* currentField;
|
Field* currentField;
|
||||||
Subscripts currentSubscripts;
|
Subscripts currentSubscripts;
|
||||||
|
|
||||||
std::vector<unsigned char> data;
|
std::vector<unsigned char> data, prePassData;
|
||||||
bool verboseFlag;
|
bool verboseFlag;
|
||||||
|
|
||||||
void beginArrayScope(std::string& arrayName, int index);
|
void beginArrayScope(std::string& arrayName, int index);
|
||||||
|
|
||||||
|
bool prePass;
|
||||||
public:
|
public:
|
||||||
ResourceCompiler(TypeDefinitionPtr type, CompoundExprPtr body, bool verboseFlag);
|
ResourceCompiler(TypeDefinitionPtr type, CompoundExprPtr body, bool verboseFlag);
|
||||||
|
|
||||||
@ -44,6 +46,8 @@ public:
|
|||||||
void write(int nBits, int value);
|
void write(int nBits, int value);
|
||||||
int tell() { return currentOffset; }
|
int tell() { return currentOffset; }
|
||||||
|
|
||||||
|
int peek(int bitPos, int size);
|
||||||
|
|
||||||
ExprPtr lookupIdentifier(std::string name, const Subscripts& sub = Subscripts());
|
ExprPtr lookupIdentifier(std::string name, const Subscripts& sub = Subscripts());
|
||||||
|
|
||||||
void defineLabel(const std::string& name);
|
void defineLabel(const std::string& name);
|
||||||
@ -52,6 +56,8 @@ public:
|
|||||||
int getArrayCount(const std::string& arrayName);
|
int getArrayCount(const std::string& arrayName);
|
||||||
int getArrayIndex(const std::string& arrayName);
|
int getArrayIndex(const std::string& arrayName);
|
||||||
|
|
||||||
|
bool isPrePass() { return prePass; }
|
||||||
|
|
||||||
class FieldScope
|
class FieldScope
|
||||||
{
|
{
|
||||||
ResourceCompiler *compiler;
|
ResourceCompiler *compiler;
|
||||||
|
@ -169,11 +169,8 @@ void SimpleField::compileInt(ExprPtr expr, ResourceCompiler *compiler, bool preP
|
|||||||
}
|
}
|
||||||
|
|
||||||
int actualValue = 0;
|
int actualValue = 0;
|
||||||
if(!prePass)
|
|
||||||
{
|
|
||||||
ResourceCompiler::FieldScope scope(compiler, this);
|
ResourceCompiler::FieldScope scope(compiler, this);
|
||||||
actualValue = (value ? value : expr)->evaluateInt(compiler);
|
actualValue = (value ? value : expr)->evaluateInt(compiler);
|
||||||
}
|
|
||||||
|
|
||||||
compiler->write(bitSize, actualValue);
|
compiler->write(bitSize, actualValue);
|
||||||
}
|
}
|
||||||
|
@ -371,13 +371,13 @@ expression8 : INTLIT { $$ = std::make_shared<IntExpr>($1); }
|
|||||||
| "$$arrayindex" "(" identifier_expression ")"
|
| "$$arrayindex" "(" identifier_expression ")"
|
||||||
{ $$ = std::make_shared<ArrayIndexExpr>($identifier_expression); }
|
{ $$ = std::make_shared<ArrayIndexExpr>($identifier_expression); }
|
||||||
| "$$bitfield" "(" expression "," expression "," expression ")"
|
| "$$bitfield" "(" expression "," expression "," expression ")"
|
||||||
{ $$ = std::make_shared<UnimplementedExpr>("$$bitfield"); }
|
{ $$ = std::make_shared<PeekExpr>($3, $5, $7); }
|
||||||
| "$$word" "(" expression ")"
|
| "$$word" "(" expression ")"
|
||||||
{ $$ = std::make_shared<UnimplementedExpr>("$$word"); }
|
{ $$ = std::make_shared<PeekExpr>($3, 16); }
|
||||||
| "$$byte" "(" expression ")"
|
| "$$byte" "(" expression ")"
|
||||||
{ $$ = std::make_shared<UnimplementedExpr>("$$byte"); }
|
{ $$ = std::make_shared<PeekExpr>($3, 8); }
|
||||||
| "$$long" "(" expression ")"
|
| "$$long" "(" expression ")"
|
||||||
{ $$ = std::make_shared<UnimplementedExpr>("$$long"); }
|
{ $$ = std::make_shared<PeekExpr>($3, 32); }
|
||||||
;
|
;
|
||||||
|
|
||||||
%type <IdentifierExprPtr> identifier_expression;
|
%type <IdentifierExprPtr> identifier_expression;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user