primitive array support

This commit is contained in:
Wolfgang Thaller 2014-10-07 20:44:40 +02:00
parent e5d2ab752a
commit 523a68d3de
4 changed files with 70 additions and 6 deletions

View File

@ -61,7 +61,9 @@ class CompoundExpr : public Expression
std::vector<ExprPtr> items; std::vector<ExprPtr> items;
public: public:
void addItem(ExprPtr item); void addItem(ExprPtr item);
ExprPtr getItem(int i) { return items[i]; } ExprPtr getItem(int i) const { return items[i]; }
int size() const { return items.size(); }
~CompoundExpr(); ~CompoundExpr();
}; };

View File

@ -101,3 +101,41 @@ void SimpleField::compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass
compiler->write(bitSize, actualValue); compiler->write(bitSize, actualValue);
} }
ArrayField::ArrayField(std::string name, ExprPtr count)
: name(name), arrayCount(count)
{
}
void ArrayField::compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass)
{
CompoundExprPtr compound = std::dynamic_pointer_cast<CompoundExpr>(expr);
assert(compound);
int i = 0;
int n = compound->size();
int iterations = 0;
while(i < n)
{
++iterations;
for(FieldPtr f : fields)
{
if(f->needsValue())
{
assert(i < n);
f->compile(compound->getItem(i++), compiler, prePass);
}
else
f->compile(nullptr, compiler, prePass);
}
}
if(arrayCount)
{
int expected = arrayCount->evaluateInt(compiler);
assert(expected == iterations);
}
}

View File

@ -108,6 +108,18 @@ public:
}; };
typedef std::shared_ptr<FieldList> FieldListPtr; typedef std::shared_ptr<FieldList> FieldListPtr;
class ArrayField : public FieldList
{
std::string name;
ExprPtr arrayCount;
public:
ArrayField(std::string name /* or empty */, ExprPtr count /* may be null*/);
virtual void compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass);
};
typedef std::shared_ptr<ArrayField> ArrayFieldPtr;
class TypeDefinition : public FieldList class TypeDefinition : public FieldList
{ {
}; };

View File

@ -156,7 +156,7 @@ field_definitions : %empty
%type <FieldPtr> field_definition; %type <FieldPtr> field_definition;
field_definition: simple_field_definition { $$ = $1; } field_definition: simple_field_definition { $$ = $1; }
| array_definition { $$ = nullptr; } | array_definition { $$ = $1; }
| switch_definition { $$ = nullptr; } | switch_definition { $$ = nullptr; }
| fill_statement { $$ = nullptr; } | fill_statement { $$ = nullptr; }
| align_statement { $$ = nullptr; } | align_statement { $$ = nullptr; }
@ -207,13 +207,25 @@ align_statement : "align" fill_unit;
fill_unit : "bit" | "byte" | "word" | "long"; fill_unit : "bit" | "byte" | "word" | "long";
%type <FieldPtr> array_definition;
array_definition: array_attributes "array" array_name_opt array_count_opt "{" field_definitions "}" ; array_definition:
array_attributes "array" array_name_opt array_count_opt
{
ArrayFieldPtr af = std::make_shared<ArrayField>($array_name_opt, $array_count_opt);
world.fieldLists.push(af);
}
"{" field_definitions "}"
{
$$ = world.fieldLists.top();
world.fieldLists.pop();
}
;
array_count : "[" expression "]" { $$ = $2; } array_count : "[" expression "]" { $$ = $2; }
array_count_opt : %empty { $$ = nullptr; } | array_count; array_count_opt : %empty { $$ = nullptr; } | array_count { $$ = $1; };
array_name_opt : %empty | IDENTIFIER ; %type <std::string> array_name_opt;
array_name_opt : %empty { $$ = ""; } | IDENTIFIER { $$ = $1; } ;
array_attributes: %empty | "wide" ; array_attributes: %empty | "wide" ;