Rez: fill and align

This commit is contained in:
Wolfgang Thaller 2014-10-08 01:37:28 +02:00
parent e0ab85c1c4
commit 50eb0f5373
5 changed files with 78 additions and 5 deletions

View File

@ -37,6 +37,7 @@ public:
void reserve(int nBits) { write(nBits, 0); }
void write(int nBits, int value);
int tell() { return currentOffset; }
ExprPtr lookupIdentifier(std::string name, const Subscripts& sub = Subscripts());

View File

@ -252,3 +252,46 @@ void SwitchField::compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass
caseDefinition->compile(caseExpr->expr, compiler, prePass);
}
FillAlignField::FillAlignField(FillAlignField::Type type, bool isAlign, ExprPtr count)
: type(type), isAlign(isAlign), count(count)
{
}
bool FillAlignField::needsValue()
{
return false;
}
void FillAlignField::compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass)
{
int bitSize;
switch(type)
{
case Type::bit: bitSize = 1; break;
case Type::nibble: bitSize = 4; break;
case Type::byte: bitSize = 8; break;
case Type::word: bitSize = 16; break;
case Type::long_: bitSize = 32; break;
}
int actualCount = 1;
if(count)
actualCount = count->evaluateInt(compiler);
for(int i = 0; i < actualCount; i++)
{
int n;
if(isAlign)
{
int mask = bitSize - 1;
int pos = compiler->tell();
n = ((pos + mask) & ~mask) - pos;
}
else
n = bitSize;
compiler->write(n, 0);
}
}

View File

@ -97,6 +97,22 @@ private:
};
typedef std::shared_ptr<SimpleField> SimpleFieldPtr;
class FillAlignField : public Field
{
public:
enum class Type
{
bit, nibble, byte, word, long_
};
FillAlignField(Type type, bool isAlign, ExprPtr count = ExprPtr());
virtual bool needsValue();
virtual void compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass);
private:
Type type;
ExprPtr count;
bool isAlign;
};
inline SimpleField::Attrs operator|(SimpleField::Attrs a, SimpleField::Attrs b)
{

View File

@ -117,6 +117,7 @@ RezSymbol RezLexer::nextToken()
KEYWORD(LITERAL, "literal"),
KEYWORD(BOOLEAN, "boolean"),
KEYWORD(BIT, "bit"),
KEYWORD(NIBBLE, "nibble"),
KEYWORD(BYTE, "byte"),
KEYWORD(CHAR, "char"),
KEYWORD(WORD, "word"),

View File

@ -57,6 +57,7 @@
%token BOOLEAN "boolean";
%token BIT "bit";
%token NIBBLE "nibble";
%token BYTE "byte";
%token CHAR "char";
%token WORD "word";
@ -158,8 +159,8 @@ field_definitions : %empty
field_definition: simple_field_definition { $$ = $1; }
| array_definition { $$ = $1; }
| switch_definition { $$ = $1; }
| fill_statement { $$ = nullptr; }
| align_statement { $$ = nullptr; }
| fill_statement { $$ = $1; }
| align_statement { $$ = $1; }
;
%type <SimpleFieldPtr> simple_field_definition;
@ -202,10 +203,21 @@ simpletype : "boolean" { $$ = SimpleField::Type::boolean; }
| "bitstring" { $$ = SimpleField::Type::bitstring; }
;
fill_statement : "fill" fill_unit array_count_opt;
align_statement : "align" fill_unit;
%type <FieldPtr> fill_statement align_statement;
fill_statement : "fill" fill_unit array_count_opt
{ $$ = std::make_shared<FillAlignField>($fill_unit, false, $array_count_opt); }
;
align_statement : "align" fill_unit
{ $$ = std::make_shared<FillAlignField>($fill_unit, true); }
;
fill_unit : "bit" | "byte" | "word" | "long";
%type <FillAlignField::Type> fill_unit;
fill_unit : "bit" { $$ = FillAlignField::Type::bit; }
| "nibble" { $$ = FillAlignField::Type::nibble; }
| "byte" { $$ = FillAlignField::Type::byte; }
| "word" { $$ = FillAlignField::Type::word; }
| "long" { $$ = FillAlignField::Type::long_; }
;
%type <FieldPtr> array_definition;
array_definition: