mirror of
https://github.com/autc04/Retro68.git
synced 2025-08-05 08:26:10 +00:00
Rez: switch
This commit is contained in:
@@ -125,3 +125,9 @@ int IdentifierExpr::evaluateInt(ResourceCompiler *ctx)
|
|||||||
return val->evaluateInt(ctx);
|
return val->evaluateInt(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CaseExpr::CaseExpr(const std::string &tag, CompoundExprPtr expr)
|
||||||
|
: tag(tag), expr(expr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@@ -9,9 +9,11 @@ class ResourceCompiler;
|
|||||||
class Expression;
|
class Expression;
|
||||||
class CompoundExpr;
|
class CompoundExpr;
|
||||||
class IdentifierExpr;
|
class IdentifierExpr;
|
||||||
|
class CaseExpr;
|
||||||
typedef std::shared_ptr<Expression> ExprPtr;
|
typedef std::shared_ptr<Expression> ExprPtr;
|
||||||
typedef std::shared_ptr<CompoundExpr> CompoundExprPtr;
|
typedef std::shared_ptr<CompoundExpr> CompoundExprPtr;
|
||||||
typedef std::shared_ptr<IdentifierExpr> IdentifierExprPtr;
|
typedef std::shared_ptr<IdentifierExpr> IdentifierExprPtr;
|
||||||
|
typedef std::shared_ptr<CaseExpr> CaseExprPtr;
|
||||||
|
|
||||||
|
|
||||||
enum class BinaryOp
|
enum class BinaryOp
|
||||||
@@ -64,6 +66,15 @@ public:
|
|||||||
~CompoundExpr();
|
~CompoundExpr();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CaseExpr : public Expression
|
||||||
|
{
|
||||||
|
std::string tag;
|
||||||
|
CompoundExprPtr expr;
|
||||||
|
friend class SwitchField;
|
||||||
|
public:
|
||||||
|
CaseExpr(const std::string& tag, CompoundExprPtr expr);
|
||||||
|
};
|
||||||
|
|
||||||
class BinaryExpr : public Expression
|
class BinaryExpr : public Expression
|
||||||
{
|
{
|
||||||
BinaryOp op;
|
BinaryOp op;
|
||||||
|
@@ -181,3 +181,20 @@ void LabelField::compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass)
|
|||||||
{
|
{
|
||||||
compiler->defineLabel(name);
|
compiler->defineLabel(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SwitchField::addCase(const std::string name, FieldListPtr alternative)
|
||||||
|
{
|
||||||
|
cases[name] = alternative;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwitchField::compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass)
|
||||||
|
{
|
||||||
|
CaseExprPtr caseExpr = std::dynamic_pointer_cast<CaseExpr>(expr);
|
||||||
|
assert(caseExpr);
|
||||||
|
|
||||||
|
FieldListPtr caseDefinition = cases[caseExpr->tag];
|
||||||
|
assert(caseDefinition);
|
||||||
|
|
||||||
|
caseDefinition->compile(caseExpr->expr, compiler, prePass);
|
||||||
|
}
|
||||||
|
@@ -137,6 +137,16 @@ public:
|
|||||||
};
|
};
|
||||||
typedef std::shared_ptr<ArrayField> ArrayFieldPtr;
|
typedef std::shared_ptr<ArrayField> ArrayFieldPtr;
|
||||||
|
|
||||||
|
class SwitchField : public Field
|
||||||
|
{
|
||||||
|
std::map<std::string, FieldListPtr> cases;
|
||||||
|
public:
|
||||||
|
void addCase(const std::string name, FieldListPtr alternative);
|
||||||
|
|
||||||
|
virtual void compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass);
|
||||||
|
};
|
||||||
|
typedef std::shared_ptr<SwitchField> SwitchFieldPtr;
|
||||||
|
|
||||||
class TypeDefinition : public FieldList
|
class TypeDefinition : public FieldList
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
@@ -157,7 +157,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 { $$ = $1; }
|
| array_definition { $$ = $1; }
|
||||||
| switch_definition { $$ = nullptr; }
|
| switch_definition { $$ = $1; }
|
||||||
| fill_statement { $$ = nullptr; }
|
| fill_statement { $$ = nullptr; }
|
||||||
| align_statement { $$ = nullptr; }
|
| align_statement { $$ = nullptr; }
|
||||||
;
|
;
|
||||||
@@ -240,13 +240,31 @@ field_attribute : "hex" { $$ = SimpleField::Attrs::hex; }
|
|||||||
| "literal" { $$ = SimpleField::Attrs::literal; }
|
| "literal" { $$ = SimpleField::Attrs::literal; }
|
||||||
;
|
;
|
||||||
|
|
||||||
switch_definition: "switch" "{"
|
%type <FieldPtr> switch_definition;
|
||||||
|
switch_definition:
|
||||||
|
"switch"
|
||||||
|
{ world.switches.push(std::make_shared<SwitchField>()); }
|
||||||
|
"{"
|
||||||
switch_cases
|
switch_cases
|
||||||
"}" ;
|
"}"
|
||||||
|
{
|
||||||
|
$$ = world.switches.top();
|
||||||
|
world.switches.pop();
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
switch_cases : %empty | switch_cases switch_case ;
|
switch_cases : %empty | switch_cases switch_case ;
|
||||||
|
|
||||||
switch_case : "case" IDENTIFIER ":" field_definitions ;
|
switch_case : "case" IDENTIFIER ":"
|
||||||
|
{
|
||||||
|
world.fieldLists.push(std::make_shared<FieldList>());
|
||||||
|
}
|
||||||
|
field_definitions
|
||||||
|
{
|
||||||
|
world.switches.top()->addCase($IDENTIFIER, world.fieldLists.top());
|
||||||
|
world.fieldLists.pop();
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
value : expression { $$ = $1; }
|
value : expression { $$ = $1; }
|
||||||
| "{" resource_body "}" { $$ = $2; }
|
| "{" resource_body "}" { $$ = $2; }
|
||||||
@@ -340,7 +358,7 @@ resource_body1 : resource_item { $$ = std::make_shared<CompoundExpr>(); $$->addI
|
|||||||
;
|
;
|
||||||
|
|
||||||
resource_item : value { $$ = $1; }
|
resource_item : value { $$ = $1; }
|
||||||
| IDENTIFIER "{" resource_body "}" // ###
|
| IDENTIFIER "{" resource_body "}" { $$ = std::make_shared<CaseExpr>($IDENTIFIER, $resource_body); }
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
@@ -13,6 +13,7 @@ class RezWorld
|
|||||||
std::map<TypeSpec, TypeDefinitionPtr> types;
|
std::map<TypeSpec, TypeDefinitionPtr> types;
|
||||||
std::stack<FieldListPtr> fieldLists;
|
std::stack<FieldListPtr> fieldLists;
|
||||||
std::stack<IdentifierExprPtr> functionCalls;
|
std::stack<IdentifierExprPtr> functionCalls;
|
||||||
|
std::stack<SwitchFieldPtr> switches;
|
||||||
public:
|
public:
|
||||||
RezWorld();
|
RezWorld();
|
||||||
void addTypeDefinition(TypeSpec spec, TypeDefinitionPtr type);
|
void addTypeDefinition(TypeSpec spec, TypeDefinitionPtr type);
|
||||||
|
Reference in New Issue
Block a user