mirror of
https://github.com/autc04/Retro68.git
synced 2024-12-09 20:50:17 +00:00
primitive array support
This commit is contained in:
parent
e5d2ab752a
commit
523a68d3de
@ -61,7 +61,9 @@ class CompoundExpr : public Expression
|
||||
std::vector<ExprPtr> items;
|
||||
public:
|
||||
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();
|
||||
};
|
||||
|
||||
|
@ -101,3 +101,41 @@ void SimpleField::compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +108,18 @@ public:
|
||||
};
|
||||
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
|
||||
{
|
||||
};
|
||||
|
@ -156,7 +156,7 @@ field_definitions : %empty
|
||||
|
||||
%type <FieldPtr> field_definition;
|
||||
field_definition: simple_field_definition { $$ = $1; }
|
||||
| array_definition { $$ = nullptr; }
|
||||
| array_definition { $$ = $1; }
|
||||
| switch_definition { $$ = nullptr; }
|
||||
| fill_statement { $$ = nullptr; }
|
||||
| align_statement { $$ = nullptr; }
|
||||
@ -207,13 +207,25 @@ align_statement : "align" fill_unit;
|
||||
|
||||
fill_unit : "bit" | "byte" | "word" | "long";
|
||||
|
||||
|
||||
array_definition: array_attributes "array" array_name_opt array_count_opt "{" field_definitions "}" ;
|
||||
%type <FieldPtr> array_definition;
|
||||
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_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" ;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user