mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-29 12:50:35 +00:00
Rez: add some error reporting
This commit is contained in:
parent
2a86126dad
commit
3da8beb96f
@ -56,6 +56,8 @@ add_library(RezLib
|
|||||||
ResourceCompiler.h
|
ResourceCompiler.h
|
||||||
|
|
||||||
ResSpec.h
|
ResSpec.h
|
||||||
|
|
||||||
|
Diagnostic.h Diagnostic.cc
|
||||||
)
|
)
|
||||||
target_link_libraries(RezLib ResourceFiles ${Boost_LIBRARIES})
|
target_link_libraries(RezLib ResourceFiles ${Boost_LIBRARIES})
|
||||||
|
|
||||||
|
17
Rez/Diagnostic.cc
Normal file
17
Rez/Diagnostic.cc
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include "Diagnostic.h"
|
||||||
|
|
||||||
|
Diagnostic::Diagnostic()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Diagnostic::Diagnostic(Severity sev, std::string msg, yy::location loc)
|
||||||
|
: severity(sev), message(msg), location(loc)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Diagnostic &d)
|
||||||
|
{
|
||||||
|
return out << d.location << ": " << d.message;
|
||||||
|
}
|
31
Rez/Diagnostic.h
Normal file
31
Rez/Diagnostic.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef DIAGNOSTIC_H
|
||||||
|
#define DIAGNOSTIC_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iosfwd>
|
||||||
|
#include "location.hh"
|
||||||
|
|
||||||
|
class Diagnostic
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Severity
|
||||||
|
{
|
||||||
|
warning,
|
||||||
|
error,
|
||||||
|
fatalError
|
||||||
|
};
|
||||||
|
|
||||||
|
Diagnostic();
|
||||||
|
Diagnostic(Severity sev, std::string msg, yy::location loc);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Severity severity;
|
||||||
|
std::string message;
|
||||||
|
yy::location location;
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream&, const Diagnostic&);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream&, const Diagnostic&);
|
||||||
|
|
||||||
|
#endif // DIAGNOSTIC_H
|
@ -3,21 +3,29 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include "Diagnostic.h"
|
||||||
|
|
||||||
int Expression::evaluateInt(ResourceCompiler *ctx)
|
int Expression::evaluateInt(ResourceCompiler *ctx)
|
||||||
{
|
{
|
||||||
throw TypeError();
|
error(ctx, "Expected an integer or integer expression here.");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Expression::evaluateString(ResourceCompiler *ctx)
|
std::string Expression::evaluateString(ResourceCompiler *ctx)
|
||||||
{
|
{
|
||||||
throw TypeError();
|
error(ctx, "Expected a string or string expression here.");
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression::~Expression()
|
Expression::~Expression()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Expression::error(ResourceCompiler *ctx, std::string err)
|
||||||
|
{
|
||||||
|
ctx->problem(Diagnostic(Diagnostic::Severity::error, err, location));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
StringExpr::~StringExpr()
|
StringExpr::~StringExpr()
|
||||||
{
|
{
|
||||||
@ -80,8 +88,8 @@ int BinaryExpr::evaluateInt(ResourceCompiler *ctx)
|
|||||||
case BinaryOp::DIVIDE:
|
case BinaryOp::DIVIDE:
|
||||||
return a->evaluateInt(ctx) / b->evaluateInt(ctx);
|
return a->evaluateInt(ctx) / b->evaluateInt(ctx);
|
||||||
default:
|
default:
|
||||||
throw TypeError();
|
error(ctx, "Expected an integer or integer expression here.");
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,8 +100,8 @@ std::string BinaryExpr::evaluateString(ResourceCompiler *ctx)
|
|||||||
case BinaryOp::CONCAT:
|
case BinaryOp::CONCAT:
|
||||||
return a->evaluateString(ctx) + b->evaluateString(ctx);
|
return a->evaluateString(ctx) + b->evaluateString(ctx);
|
||||||
default:
|
default:
|
||||||
throw TypeError();
|
error(ctx, "Expected a string or string expression here.");
|
||||||
break;
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,14 +119,14 @@ int UnaryExpr::evaluateInt(ResourceCompiler *ctx)
|
|||||||
case UnaryOp::COMPLEMENT:
|
case UnaryOp::COMPLEMENT:
|
||||||
return ~a->evaluateInt(ctx);
|
return ~a->evaluateInt(ctx);
|
||||||
default:
|
default:
|
||||||
throw TypeError();
|
error(ctx, "Expected an integer or integer expression here.");
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IdentifierExpr::IdentifierExpr(std::string id)
|
IdentifierExpr::IdentifierExpr(std::string id, yy::location loc)
|
||||||
: id(id)
|
: Expression(loc), id(id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +141,8 @@ ExprPtr IdentifierExpr::lookup(ResourceCompiler *ctx)
|
|||||||
for(auto arg : arguments)
|
for(auto arg : arguments)
|
||||||
sub.addSubscript(arg->evaluateInt(ctx));
|
sub.addSubscript(arg->evaluateInt(ctx));
|
||||||
ExprPtr val = ctx->lookupIdentifier(id, sub);
|
ExprPtr val = ctx->lookupIdentifier(id, sub);
|
||||||
assert(val);
|
if(!val)
|
||||||
|
error(ctx, "Identifier \"" + id + "\" is not defined.");
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,17 +150,23 @@ int IdentifierExpr::evaluateInt(ResourceCompiler *ctx)
|
|||||||
{
|
{
|
||||||
if(ctx->isPrePass())
|
if(ctx->isPrePass())
|
||||||
return 0;
|
return 0;
|
||||||
return lookup(ctx)->evaluateInt(ctx);
|
if(ExprPtr e = lookup(ctx))
|
||||||
|
return e->evaluateInt(ctx);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string IdentifierExpr::evaluateString(ResourceCompiler *ctx)
|
std::string IdentifierExpr::evaluateString(ResourceCompiler *ctx)
|
||||||
{
|
{
|
||||||
return lookup(ctx)->evaluateString(ctx);
|
if(ExprPtr e = lookup(ctx))
|
||||||
|
return e->evaluateString(ctx);
|
||||||
|
else
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CaseExpr::CaseExpr(const std::string &tag, CompoundExprPtr expr)
|
CaseExpr::CaseExpr(const std::string &tag, CompoundExprPtr expr, yy::location loc)
|
||||||
: tag(tag), expr(expr)
|
: Expression(loc), tag(tag), expr(expr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,15 +208,16 @@ std::string UnimplementedExpr::evaluateString(ResourceCompiler *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PeekExpr::PeekExpr(ExprPtr addr, ExprPtr offset, ExprPtr size)
|
PeekExpr::PeekExpr(ExprPtr addr, ExprPtr offset, ExprPtr size, yy::location loc)
|
||||||
: addr(addr), offset(offset), size(size)
|
: Expression(loc), addr(addr), offset(offset), size(size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PeekExpr::PeekExpr(ExprPtr addr, int size)
|
PeekExpr::PeekExpr(ExprPtr addr, int size, yy::location loc)
|
||||||
: addr(addr),
|
: Expression(loc),
|
||||||
offset(std::make_shared<IntExpr>(0)),
|
addr(addr),
|
||||||
size(std::make_shared<IntExpr>(size))
|
offset(std::make_shared<IntExpr>(0,loc)),
|
||||||
|
size(std::make_shared<IntExpr>(size,loc))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "location.hh"
|
||||||
|
|
||||||
class ResourceCompiler;
|
class ResourceCompiler;
|
||||||
|
|
||||||
class Expression;
|
class Expression;
|
||||||
@ -33,16 +35,22 @@ class TypeError
|
|||||||
class Expression
|
class Expression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
yy::location location;
|
||||||
|
|
||||||
|
Expression(yy::location loc) : location(loc) {}
|
||||||
|
|
||||||
virtual int evaluateInt(ResourceCompiler *ctx);
|
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||||
virtual std::string evaluateString(ResourceCompiler *ctx);
|
virtual std::string evaluateString(ResourceCompiler *ctx);
|
||||||
virtual ~Expression();
|
virtual ~Expression();
|
||||||
|
|
||||||
|
void error(ResourceCompiler *ctx, std::string err);
|
||||||
};
|
};
|
||||||
|
|
||||||
class StringExpr : public Expression
|
class StringExpr : public Expression
|
||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
public:
|
public:
|
||||||
StringExpr(const std::string& str) : str(str) {}
|
StringExpr(const std::string& str, yy::location loc) : Expression(loc), str(str) {}
|
||||||
~StringExpr();
|
~StringExpr();
|
||||||
virtual std::string evaluateString(ResourceCompiler *ctx);
|
virtual std::string evaluateString(ResourceCompiler *ctx);
|
||||||
};
|
};
|
||||||
@ -51,7 +59,7 @@ class IntExpr : public Expression
|
|||||||
{
|
{
|
||||||
int val;
|
int val;
|
||||||
public:
|
public:
|
||||||
IntExpr(int val) : val(val) {}
|
IntExpr(int val, yy::location loc) : Expression(loc), val(val) {}
|
||||||
~IntExpr();
|
~IntExpr();
|
||||||
|
|
||||||
virtual int evaluateInt(ResourceCompiler *ctx);
|
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||||
@ -61,6 +69,8 @@ class CompoundExpr : public Expression
|
|||||||
{
|
{
|
||||||
std::vector<ExprPtr> items;
|
std::vector<ExprPtr> items;
|
||||||
public:
|
public:
|
||||||
|
CompoundExpr(yy::location loc) : Expression(loc) {}
|
||||||
|
|
||||||
void addItem(ExprPtr item);
|
void addItem(ExprPtr item);
|
||||||
ExprPtr getItem(int i) const { return items[i]; }
|
ExprPtr getItem(int i) const { return items[i]; }
|
||||||
int size() const { return items.size(); }
|
int size() const { return items.size(); }
|
||||||
@ -74,7 +84,7 @@ class CaseExpr : public Expression
|
|||||||
CompoundExprPtr expr;
|
CompoundExprPtr expr;
|
||||||
friend class SwitchField;
|
friend class SwitchField;
|
||||||
public:
|
public:
|
||||||
CaseExpr(const std::string& tag, CompoundExprPtr expr);
|
CaseExpr(const std::string& tag, CompoundExprPtr expr, yy::location loc);
|
||||||
};
|
};
|
||||||
|
|
||||||
class BinaryExpr : public Expression
|
class BinaryExpr : public Expression
|
||||||
@ -82,8 +92,8 @@ class BinaryExpr : public Expression
|
|||||||
BinaryOp op;
|
BinaryOp op;
|
||||||
ExprPtr a, b;
|
ExprPtr a, b;
|
||||||
public:
|
public:
|
||||||
BinaryExpr(BinaryOp op, ExprPtr a, ExprPtr b)
|
BinaryExpr(BinaryOp op, ExprPtr a, ExprPtr b, yy::location loc)
|
||||||
: op(op), a(a), b(b) {}
|
: Expression(loc), op(op), a(a), b(b) {}
|
||||||
~BinaryExpr();
|
~BinaryExpr();
|
||||||
|
|
||||||
virtual int evaluateInt(ResourceCompiler *ctx);
|
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||||
@ -95,8 +105,8 @@ class UnaryExpr : public Expression
|
|||||||
UnaryOp op;
|
UnaryOp op;
|
||||||
ExprPtr a;
|
ExprPtr a;
|
||||||
public:
|
public:
|
||||||
UnaryExpr(UnaryOp op, ExprPtr a)
|
UnaryExpr(UnaryOp op, ExprPtr a, yy::location loc)
|
||||||
: op(op), a(a) {}
|
: Expression(loc), op(op), a(a) {}
|
||||||
~UnaryExpr();
|
~UnaryExpr();
|
||||||
|
|
||||||
virtual int evaluateInt(ResourceCompiler *ctx);
|
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||||
@ -107,7 +117,7 @@ class IdentifierExpr : public Expression
|
|||||||
public:
|
public:
|
||||||
std::string id;
|
std::string id;
|
||||||
std::vector<ExprPtr> arguments;
|
std::vector<ExprPtr> arguments;
|
||||||
IdentifierExpr(std::string id);
|
IdentifierExpr(std::string id, yy::location loc);
|
||||||
|
|
||||||
void addArgument(ExprPtr e);
|
void addArgument(ExprPtr e);
|
||||||
ExprPtr lookup(ResourceCompiler *ctx);
|
ExprPtr lookup(ResourceCompiler *ctx);
|
||||||
@ -119,7 +129,7 @@ class CountOfExpr : public Expression
|
|||||||
{
|
{
|
||||||
IdentifierExprPtr arg;
|
IdentifierExprPtr arg;
|
||||||
public:
|
public:
|
||||||
CountOfExpr(IdentifierExprPtr arg) : arg(arg) {}
|
CountOfExpr(IdentifierExprPtr arg, yy::location loc) : Expression(loc), arg(arg) {}
|
||||||
virtual int evaluateInt(ResourceCompiler *ctx);
|
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -127,7 +137,7 @@ class ArrayIndexExpr : public Expression
|
|||||||
{
|
{
|
||||||
IdentifierExprPtr arg;
|
IdentifierExprPtr arg;
|
||||||
public:
|
public:
|
||||||
ArrayIndexExpr(IdentifierExprPtr arg) : arg(arg) {}
|
ArrayIndexExpr(IdentifierExprPtr arg, yy::location loc) : Expression(loc), arg(arg) {}
|
||||||
virtual int evaluateInt(ResourceCompiler *ctx);
|
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -135,7 +145,7 @@ class ReadExpr : public Expression
|
|||||||
{
|
{
|
||||||
ExprPtr arg;
|
ExprPtr arg;
|
||||||
public:
|
public:
|
||||||
ReadExpr(ExprPtr arg) : arg(arg) {}
|
ReadExpr(ExprPtr arg, yy::location loc) : Expression(loc), arg(arg) {}
|
||||||
virtual std::string evaluateString(ResourceCompiler *ctx);
|
virtual std::string evaluateString(ResourceCompiler *ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -143,7 +153,7 @@ class UnimplementedExpr : public Expression
|
|||||||
{
|
{
|
||||||
std::string msg;
|
std::string msg;
|
||||||
public:
|
public:
|
||||||
UnimplementedExpr(std::string msg) : msg(msg) {}
|
UnimplementedExpr(std::string msg, yy::location loc) : Expression(loc), msg(msg) {}
|
||||||
virtual int evaluateInt(ResourceCompiler *ctx);
|
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||||
virtual std::string evaluateString(ResourceCompiler *ctx);
|
virtual std::string evaluateString(ResourceCompiler *ctx);
|
||||||
};
|
};
|
||||||
@ -154,8 +164,8 @@ class PeekExpr : public Expression
|
|||||||
ExprPtr offset;
|
ExprPtr offset;
|
||||||
ExprPtr size;
|
ExprPtr size;
|
||||||
public:
|
public:
|
||||||
PeekExpr(ExprPtr addr, ExprPtr offset, ExprPtr size);
|
PeekExpr(ExprPtr addr, ExprPtr offset, ExprPtr size, yy::location loc);
|
||||||
PeekExpr(ExprPtr addr, int size);
|
PeekExpr(ExprPtr addr, int size, yy::location loc);
|
||||||
virtual int evaluateInt(ResourceCompiler *ctx);
|
virtual int evaluateInt(ResourceCompiler *ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
#include "ResourceCompiler.h"
|
#include "ResourceCompiler.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "ResourceDefinitions.h"
|
#include "ResourceDefinitions.h"
|
||||||
|
#include "RezWorld.h"
|
||||||
|
#include "Diagnostic.h"
|
||||||
|
|
||||||
ResourceCompiler::ResourceCompiler(
|
ResourceCompiler::ResourceCompiler(
|
||||||
TypeDefinitionPtr type, CompoundExprPtr body, bool verboseFlag)
|
RezWorld& world, TypeDefinitionPtr type, CompoundExprPtr body, bool verboseFlag)
|
||||||
: typeDefinition(type),
|
: world(world),
|
||||||
|
typeDefinition(type),
|
||||||
body(body),
|
body(body),
|
||||||
currentField(nullptr)
|
currentField(nullptr)
|
||||||
{
|
{
|
||||||
@ -99,14 +102,14 @@ ExprPtr ResourceCompiler::lookupIdentifier(std::string name, const Subscripts &s
|
|||||||
if(p != labelValues.end())
|
if(p != labelValues.end())
|
||||||
return p->second;
|
return p->second;
|
||||||
|
|
||||||
std::cerr << "ID lookup failed: " << name << std::endl;
|
//std::cerr << "ID lookup failed: " << name << std::endl;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCompiler::defineLabel(const std::string &name)
|
void ResourceCompiler::defineLabel(const std::string &name)
|
||||||
{
|
{
|
||||||
labelValues[std::make_pair(name,currentSubscripts)] = std::make_shared<IntExpr>(currentOffset);
|
labelValues[std::make_pair(name,currentSubscripts)] = std::make_shared<IntExpr>(currentOffset, yy::location());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCompiler::compile()
|
void ResourceCompiler::compile()
|
||||||
@ -142,6 +145,11 @@ int ResourceCompiler::getArrayIndex(const std::string &arrayName)
|
|||||||
return curArrayIndices[arrayName];
|
return curArrayIndices[arrayName];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceCompiler::problem(Diagnostic d)
|
||||||
|
{
|
||||||
|
world.problem(d);
|
||||||
|
}
|
||||||
|
|
||||||
void ResourceCompiler::beginArrayScope(std::string &arrayName, int index)
|
void ResourceCompiler::beginArrayScope(std::string &arrayName, int index)
|
||||||
{
|
{
|
||||||
if(arrayName != "")
|
if(arrayName != "")
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
#include "ResourceDefinitions.h"
|
#include "ResourceDefinitions.h"
|
||||||
|
|
||||||
class Field;
|
class Field;
|
||||||
|
class RezWorld;
|
||||||
|
class Diagnostic;
|
||||||
|
|
||||||
class Subscripts
|
class Subscripts
|
||||||
{
|
{
|
||||||
@ -45,6 +46,7 @@ public:
|
|||||||
|
|
||||||
class ResourceCompiler : public BinaryOutput
|
class ResourceCompiler : public BinaryOutput
|
||||||
{
|
{
|
||||||
|
RezWorld& world;
|
||||||
TypeDefinitionPtr typeDefinition;
|
TypeDefinitionPtr typeDefinition;
|
||||||
CompoundExprPtr body;
|
CompoundExprPtr body;
|
||||||
std::map<std::pair<std::string, Subscripts>, ExprPtr> labelValues;
|
std::map<std::pair<std::string, Subscripts>, ExprPtr> labelValues;
|
||||||
@ -53,13 +55,9 @@ class ResourceCompiler : public BinaryOutput
|
|||||||
Field* currentField;
|
Field* currentField;
|
||||||
Subscripts currentSubscripts;
|
Subscripts currentSubscripts;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void beginArrayScope(std::string& arrayName, int index);
|
void beginArrayScope(std::string& arrayName, int index);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ResourceCompiler(TypeDefinitionPtr type, CompoundExprPtr body, bool verboseFlag);
|
ResourceCompiler(RezWorld& world, TypeDefinitionPtr type, CompoundExprPtr body, bool verboseFlag);
|
||||||
|
|
||||||
|
|
||||||
ExprPtr lookupIdentifier(std::string name, const Subscripts& sub = Subscripts());
|
ExprPtr lookupIdentifier(std::string name, const Subscripts& sub = Subscripts());
|
||||||
|
|
||||||
@ -87,6 +85,8 @@ public:
|
|||||||
: compiler(compiler) { compiler->beginArrayScope(arrayName, index); }
|
: compiler(compiler) { compiler->beginArrayScope(arrayName, index); }
|
||||||
~ArrayScope() { compiler->currentSubscripts.popSubscript(); }
|
~ArrayScope() { compiler->currentSubscripts.popSubscript(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void problem(Diagnostic d);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,14 +20,15 @@ FieldList::~FieldList()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldList::addField(FieldPtr field)
|
void FieldList::addField(FieldPtr field, yy::location loc)
|
||||||
{
|
{
|
||||||
|
field->location = loc;
|
||||||
fields.push_back(field);
|
fields.push_back(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldList::addLabel(std::string name)
|
void FieldList::addLabel(std::string name, yy::location loc)
|
||||||
{
|
{
|
||||||
addField(std::make_shared<LabelField>(name));
|
addField(std::make_shared<LabelField>(name), loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldList::compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass)
|
void FieldList::compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass)
|
||||||
@ -52,9 +53,9 @@ void SimpleField::addNamedValue(std::string n)
|
|||||||
{
|
{
|
||||||
if(lastNamedValue)
|
if(lastNamedValue)
|
||||||
addNamedValue(n, std::make_shared<BinaryExpr>(
|
addNamedValue(n, std::make_shared<BinaryExpr>(
|
||||||
BinaryOp::PLUS, lastNamedValue, std::make_shared<IntExpr>(1)));
|
BinaryOp::PLUS, lastNamedValue, std::make_shared<IntExpr>(1, yy::location()), yy::location()));
|
||||||
else
|
else
|
||||||
addNamedValue(n, std::make_shared<IntExpr>(0));
|
addNamedValue(n, std::make_shared<IntExpr>(0, yy::location()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleField::addNamedValue(std::string n, ExprPtr val)
|
void SimpleField::addNamedValue(std::string n, ExprPtr val)
|
||||||
@ -200,8 +201,12 @@ void SimpleField::compileCompound(ExprPtr expr, ResourceCompiler *compiler, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
CompoundExprPtr compound = std::dynamic_pointer_cast<CompoundExpr>(val);
|
CompoundExprPtr compound = std::dynamic_pointer_cast<CompoundExpr>(val);
|
||||||
|
if(!compound || compound->size() != count)
|
||||||
|
{
|
||||||
|
expr->error(compiler, std::string("expected ") + (type == Type::rect ? "rect {t,l,b,r}." : "point {v,h}."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
assert(compound);
|
assert(compound);
|
||||||
|
|
||||||
assert(compound->size() == count);
|
assert(compound->size() == count);
|
||||||
|
|
||||||
for(int i = 0; i < count; i++)
|
for(int i = 0; i < count; i++)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "Expression.h"
|
#include "Expression.h"
|
||||||
#include "ResType.h"
|
#include "ResType.h"
|
||||||
|
|
||||||
|
#include "location.hh"
|
||||||
|
|
||||||
class TypeSpec
|
class TypeSpec
|
||||||
{
|
{
|
||||||
@ -44,6 +45,8 @@ class ResourceCompiler;
|
|||||||
class Field
|
class Field
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
yy::location location;
|
||||||
|
|
||||||
virtual bool needsValue() { return true; }
|
virtual bool needsValue() { return true; }
|
||||||
|
|
||||||
virtual void compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass) = 0;
|
virtual void compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass) = 0;
|
||||||
@ -129,8 +132,8 @@ protected:
|
|||||||
std::vector<FieldPtr> fields;
|
std::vector<FieldPtr> fields;
|
||||||
public:
|
public:
|
||||||
virtual ~FieldList();
|
virtual ~FieldList();
|
||||||
void addField(FieldPtr field);
|
void addField(FieldPtr field, yy::location loc);
|
||||||
void addLabel(std::string name);
|
void addLabel(std::string name, yy::location loc);
|
||||||
|
|
||||||
virtual void compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass);
|
virtual void compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass);
|
||||||
};
|
};
|
||||||
|
@ -198,9 +198,9 @@ type_spec : res_type { $$ = TypeSpec($res_type); }
|
|||||||
;
|
;
|
||||||
|
|
||||||
field_definitions : %empty
|
field_definitions : %empty
|
||||||
| field_definitions IDENTIFIER ":" { world.fieldLists.top()->addLabel($2); }
|
| field_definitions IDENTIFIER ":" { world.fieldLists.top()->addLabel($2, @2); }
|
||||||
| field_definitions ";"
|
| field_definitions ";"
|
||||||
| field_definitions field_definition ";" { world.fieldLists.top()->addField($2); }
|
| field_definitions field_definition ";" { world.fieldLists.top()->addField($2, @2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
%type <FieldPtr> field_definition;
|
%type <FieldPtr> field_definition;
|
||||||
@ -328,71 +328,71 @@ switch_case : "case" IDENTIFIER ":"
|
|||||||
|
|
||||||
|
|
||||||
value : expression { $$ = $1; }
|
value : expression { $$ = $1; }
|
||||||
| "{" resource_body "}" { $$ = $2; }
|
| "{" resource_body "}" { $$ = $2; $$->location = @0; }
|
||||||
| string_expression { $$ = $1; }
|
| string_expression { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
expression : expression1 { $$ = $1; }
|
expression : expression1 { $$ = $1; }
|
||||||
| expression "^" expression1 { $$ = std::make_shared<BinaryExpr>(BinaryOp::XOR, $1, $3); }
|
| expression "^" expression1 { $$ = std::make_shared<BinaryExpr>(BinaryOp::XOR, $1, $3, @0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
expression1 : expression2 { $$ = $1; }
|
expression1 : expression2 { $$ = $1; }
|
||||||
| expression1 "&" expression2 { $$ = std::make_shared<BinaryExpr>(BinaryOp::AND, $1, $3); }
|
| expression1 "&" expression2 { $$ = std::make_shared<BinaryExpr>(BinaryOp::AND, $1, $3, @0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
expression2 : expression3 { $$ = $1; }
|
expression2 : expression3 { $$ = $1; }
|
||||||
| expression2 "|" expression3 { $$ = std::make_shared<BinaryExpr>(BinaryOp::OR, $1, $3); }
|
| expression2 "|" expression3 { $$ = std::make_shared<BinaryExpr>(BinaryOp::OR, $1, $3, @0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
expression3 : expression4 { $$ = $1; }
|
expression3 : expression4 { $$ = $1; }
|
||||||
| expression3 "==" expression4 { $$ = std::make_shared<BinaryExpr>(BinaryOp::EQUAL, $1, $3); }
|
| expression3 "==" expression4 { $$ = std::make_shared<BinaryExpr>(BinaryOp::EQUAL, $1, $3, @0); }
|
||||||
| expression3 "!=" expression4 { $$ = std::make_shared<BinaryExpr>(BinaryOp::NOTEQUAL, $1, $3); }
|
| expression3 "!=" expression4 { $$ = std::make_shared<BinaryExpr>(BinaryOp::NOTEQUAL, $1, $3, @0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
expression4 : expression5 { $$ = $1; }
|
expression4 : expression5 { $$ = $1; }
|
||||||
| expression4 ">>" expression5 { $$ = std::make_shared<BinaryExpr>(BinaryOp::SHIFTRIGHT, $1, $3); }
|
| expression4 ">>" expression5 { $$ = std::make_shared<BinaryExpr>(BinaryOp::SHIFTRIGHT, $1, $3, @0); }
|
||||||
| expression4 "<<" expression5 { $$ = std::make_shared<BinaryExpr>(BinaryOp::SHIFTLEFT, $1, $3); }
|
| expression4 "<<" expression5 { $$ = std::make_shared<BinaryExpr>(BinaryOp::SHIFTLEFT, $1, $3, @0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
expression5 : expression6 { $$ = $1; }
|
expression5 : expression6 { $$ = $1; }
|
||||||
| expression5 "+" expression6 { $$ = std::make_shared<BinaryExpr>(BinaryOp::PLUS, $1, $3); }
|
| expression5 "+" expression6 { $$ = std::make_shared<BinaryExpr>(BinaryOp::PLUS, $1, $3, @0); }
|
||||||
| expression5 "-" expression6 { $$ = std::make_shared<BinaryExpr>(BinaryOp::MINUS, $1, $3); }
|
| expression5 "-" expression6 { $$ = std::make_shared<BinaryExpr>(BinaryOp::MINUS, $1, $3, @0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
expression6 : expression7 { $$ = $1; }
|
expression6 : expression7 { $$ = $1; }
|
||||||
| expression6 "*" expression7 { $$ = std::make_shared<BinaryExpr>(BinaryOp::MULTIPLY, $1, $3); }
|
| expression6 "*" expression7 { $$ = std::make_shared<BinaryExpr>(BinaryOp::MULTIPLY, $1, $3, @0); }
|
||||||
| expression6 "/" expression7 { $$ = std::make_shared<BinaryExpr>(BinaryOp::DIVIDE, $1, $3); }
|
| expression6 "/" expression7 { $$ = std::make_shared<BinaryExpr>(BinaryOp::DIVIDE, $1, $3, @0); }
|
||||||
;
|
;
|
||||||
expression7 : expression8 { $$ = $1; }
|
expression7 : expression8 { $$ = $1; }
|
||||||
| "-" expression7 { $$ = std::make_shared<UnaryExpr>(UnaryOp::MINUS, $2); }
|
| "-" expression7 { $$ = std::make_shared<UnaryExpr>(UnaryOp::MINUS, $2, @0); }
|
||||||
| "+" expression7 { $$ = $2; }
|
| "+" expression7 { $$ = $2; }
|
||||||
| "~" expression7 { $$ = std::make_shared<UnaryExpr>(UnaryOp::COMPLEMENT, $2); }
|
| "~" expression7 { $$ = std::make_shared<UnaryExpr>(UnaryOp::COMPLEMENT, $2, @0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
expression8 : INTLIT { $$ = std::make_shared<IntExpr>($1); }
|
expression8 : INTLIT { $$ = std::make_shared<IntExpr>($1, @1); }
|
||||||
| CHARLIT { $$ = std::make_shared<IntExpr>($1); }
|
| CHARLIT { $$ = std::make_shared<IntExpr>($1, @1); }
|
||||||
|
|
||||||
| identifier_expression { $$ = $1; }
|
| identifier_expression { $$ = $1; }
|
||||||
| "(" expression ")" { $$ = $2; }
|
| "(" expression ")" { $$ = $2; }
|
||||||
|
|
||||||
| "$$countof" "(" identifier_expression ")"
|
| "$$countof" "(" identifier_expression ")"
|
||||||
{ $$ = std::make_shared<CountOfExpr>($identifier_expression); }
|
{ $$ = std::make_shared<CountOfExpr>($identifier_expression, @0); }
|
||||||
| "$$arrayindex" "(" identifier_expression ")"
|
| "$$arrayindex" "(" identifier_expression ")"
|
||||||
{ $$ = std::make_shared<ArrayIndexExpr>($identifier_expression); }
|
{ $$ = std::make_shared<ArrayIndexExpr>($identifier_expression, @0); }
|
||||||
| "$$bitfield" "(" expression "," expression "," expression ")"
|
| "$$bitfield" "(" expression "," expression "," expression ")"
|
||||||
{ $$ = std::make_shared<PeekExpr>($3, $5, $7); }
|
{ $$ = std::make_shared<PeekExpr>($3, $5, $7, @0); }
|
||||||
| "$$word" "(" expression ")"
|
| "$$word" "(" expression ")"
|
||||||
{ $$ = std::make_shared<PeekExpr>($3, 16); }
|
{ $$ = std::make_shared<PeekExpr>($3, 16, @0); }
|
||||||
| "$$byte" "(" expression ")"
|
| "$$byte" "(" expression ")"
|
||||||
{ $$ = std::make_shared<PeekExpr>($3, 8); }
|
{ $$ = std::make_shared<PeekExpr>($3, 8, @0); }
|
||||||
| "$$long" "(" expression ")"
|
| "$$long" "(" expression ")"
|
||||||
{ $$ = std::make_shared<PeekExpr>($3, 32); }
|
{ $$ = std::make_shared<PeekExpr>($3, 32, @0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
%type <IdentifierExprPtr> identifier_expression;
|
%type <IdentifierExprPtr> identifier_expression;
|
||||||
identifier_expression : IDENTIFIER { $$ = std::make_shared<IdentifierExpr>($1); }
|
identifier_expression : IDENTIFIER { $$ = std::make_shared<IdentifierExpr>($1, @1); }
|
||||||
| IDENTIFIER
|
| IDENTIFIER
|
||||||
{ world.functionCalls.push(std::make_shared<IdentifierExpr>($1)); }
|
{ world.functionCalls.push(std::make_shared<IdentifierExpr>($1, @1)); }
|
||||||
"[" function_argument_list1 "]"
|
"[" function_argument_list1 "]"
|
||||||
{ $$ = world.functionCalls.top(); world.functionCalls.pop(); }
|
{ $$ = world.functionCalls.top(); world.functionCalls.pop(); }
|
||||||
;
|
;
|
||||||
@ -407,7 +407,7 @@ function_argument_list1 : expression
|
|||||||
%type <ExprPtr> string_expression string_expression1;
|
%type <ExprPtr> string_expression string_expression1;
|
||||||
string_expression : string_expression1 { $$ = $1; }
|
string_expression : string_expression1 { $$ = $1; }
|
||||||
| string_expression string_expression1
|
| string_expression string_expression1
|
||||||
{ $$ = std::make_shared<BinaryExpr>(BinaryOp::CONCAT, $1, $2); }
|
{ $$ = std::make_shared<BinaryExpr>(BinaryOp::CONCAT, $1, $2, @0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
%type <std::string> stringlit;
|
%type <std::string> stringlit;
|
||||||
@ -415,14 +415,14 @@ stringlit : STRINGLIT { $$ = $1; }
|
|||||||
| DOLLAR STRINGLIT { $$ = fromHex($2); }
|
| DOLLAR STRINGLIT { $$ = fromHex($2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
string_expression1 : stringlit { $$ = std::make_shared<StringExpr>($1); }
|
string_expression1 : stringlit { $$ = std::make_shared<StringExpr>($1, @1); }
|
||||||
| "$$read" "(" string_expression ")"
|
| "$$read" "(" string_expression ")"
|
||||||
{ $$ = std::make_shared<ReadExpr>($string_expression); }
|
{ $$ = std::make_shared<ReadExpr>($string_expression, @0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
resource : "resource" res_spec "{" resource_body "}"
|
resource : "resource" res_spec "{" resource_body "}"
|
||||||
{
|
{
|
||||||
world.addResource($res_spec, $resource_body);
|
world.addResource($res_spec, $resource_body, @0);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -439,23 +439,23 @@ resource_attributes : %empty { $$ = [](ResSpec s){ return s; }; }
|
|||||||
;
|
;
|
||||||
|
|
||||||
%type <CompoundExprPtr> resource_body resource_body1;
|
%type <CompoundExprPtr> resource_body resource_body1;
|
||||||
resource_body : %empty { $$ = std::make_shared<CompoundExpr>(); }
|
resource_body : %empty { $$ = std::make_shared<CompoundExpr>(@0); }
|
||||||
| resource_body1 { $$ = $1; }
|
| resource_body1 { $$ = $1; $$->location = @1; }
|
||||||
;
|
;
|
||||||
resource_body1 : resource_item { $$ = std::make_shared<CompoundExpr>(); $$->addItem($1); }
|
resource_body1 : resource_item { $$ = std::make_shared<CompoundExpr>(@1); $$->addItem($1); }
|
||||||
| resource_body1 "," resource_item { $$ = $1; $$->addItem($3); }
|
| resource_body1 "," resource_item { $$ = $1; $$->addItem($3); }
|
||||||
| resource_body1 ";" resource_item { $$ = $1; $$->addItem($3); }
|
| resource_body1 ";" resource_item { $$ = $1; $$->addItem($3); }
|
||||||
| resource_body1 ";" { $$ = $1; }
|
| resource_body1 ";" { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
resource_item : value { $$ = $1; }
|
resource_item : value { $$ = $1; }
|
||||||
| IDENTIFIER "{" resource_body "}" { $$ = std::make_shared<CaseExpr>($IDENTIFIER, $resource_body); }
|
| IDENTIFIER "{" resource_body "}" { $$ = std::make_shared<CaseExpr>($IDENTIFIER, $resource_body, @0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
data : "data" res_spec "{" string_expression "}"
|
data : "data" res_spec "{" string_expression "}"
|
||||||
{
|
{
|
||||||
world.addData($res_spec, $string_expression->evaluateString(nullptr));
|
world.addData($res_spec, $string_expression->evaluateString(nullptr), @0);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "Diagnostic.h"
|
||||||
|
|
||||||
RezWorld::RezWorld()
|
RezWorld::RezWorld()
|
||||||
: verboseFlag(false)
|
: verboseFlag(false)
|
||||||
{
|
{
|
||||||
@ -14,7 +16,7 @@ void RezWorld::addTypeDefinition(TypeSpec spec, TypeDefinitionPtr type)
|
|||||||
types[spec] = type;
|
types[spec] = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDefinitionPtr RezWorld::getTypeDefinition(ResType type, int id)
|
TypeDefinitionPtr RezWorld::getTypeDefinition(ResType type, int id, yy::location loc)
|
||||||
{
|
{
|
||||||
auto p = types.find(TypeSpec(type, id));
|
auto p = types.find(TypeSpec(type, id));
|
||||||
if(p != types.end())
|
if(p != types.end())
|
||||||
@ -22,24 +24,31 @@ TypeDefinitionPtr RezWorld::getTypeDefinition(ResType type, int id)
|
|||||||
p = types.find(TypeSpec(type));
|
p = types.find(TypeSpec(type));
|
||||||
if(p != types.end())
|
if(p != types.end())
|
||||||
return p->second;
|
return p->second;
|
||||||
|
problem(Diagnostic(Diagnostic::Severity::error, "Can't find type definition for '" + std::string(type) + "'", loc));
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RezWorld::addResource(ResSpec spec, CompoundExprPtr body)
|
void RezWorld::addResource(ResSpec spec, CompoundExprPtr body, yy::location loc)
|
||||||
{
|
{
|
||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
std::cout << "RESOURCE " << spec.type() << "(" << spec.id() << ", " << "\"" << spec.name() << "\"" << spec.attr() << ")" << std::endl;
|
std::cout << "RESOURCE " << spec.type() << "(" << spec.id() << ", " << "\"" << spec.name() << "\"" << spec.attr() << ")" << std::endl;
|
||||||
TypeDefinitionPtr def = getTypeDefinition(spec.type(), spec.id());
|
TypeDefinitionPtr def = getTypeDefinition(spec.type(), spec.id(), loc);
|
||||||
ResourceCompiler compiler(def, body, verboseFlag);
|
|
||||||
|
ResourceCompiler compiler(*this, def, body, verboseFlag);
|
||||||
compiler.compile();
|
compiler.compile();
|
||||||
|
|
||||||
resources.addResource(Resource(spec.type(), spec.id(), compiler.resourceData(), spec.name(), spec.attr()));
|
resources.addResource(Resource(spec.type(), spec.id(), compiler.resourceData(), spec.name(), spec.attr()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RezWorld::addData(ResSpec spec, const std::string &data)
|
void RezWorld::addData(ResSpec spec, const std::string &data, yy::location loc)
|
||||||
{
|
{
|
||||||
if(verboseFlag)
|
if(verboseFlag)
|
||||||
std::cout << "DATA " << spec.type() << "(" << spec.id() << ", " << "\"" << spec.name() << "\"" << spec.attr() << ")" << std::endl;
|
std::cout << "DATA " << spec.type() << "(" << spec.id() << ", " << "\"" << spec.name() << "\"" << spec.attr() << ")" << std::endl;
|
||||||
resources.addResource(Resource(spec.type(), spec.id(), data, spec.name(), spec.attr()));
|
resources.addResource(Resource(spec.type(), spec.id(), data, spec.name(), spec.attr()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RezWorld::problem(Diagnostic d)
|
||||||
|
{
|
||||||
|
std::cerr << d << std::endl;
|
||||||
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include "ResourceFork.h"
|
#include "ResourceFork.h"
|
||||||
#include "ResSpec.h"
|
#include "ResSpec.h"
|
||||||
|
|
||||||
|
class Diagnostic;
|
||||||
|
|
||||||
class RezWorld
|
class RezWorld
|
||||||
{
|
{
|
||||||
friend class RezParser;
|
friend class RezParser;
|
||||||
@ -19,18 +21,21 @@ class RezWorld
|
|||||||
std::stack<SwitchFieldPtr> switches;
|
std::stack<SwitchFieldPtr> switches;
|
||||||
|
|
||||||
Resources resources;
|
Resources resources;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RezWorld();
|
RezWorld();
|
||||||
void addTypeDefinition(TypeSpec spec, TypeDefinitionPtr type);
|
void addTypeDefinition(TypeSpec spec, TypeDefinitionPtr type);
|
||||||
|
|
||||||
TypeDefinitionPtr getTypeDefinition(ResType type, int id);
|
TypeDefinitionPtr getTypeDefinition(ResType type, int id, yy::location loc);
|
||||||
|
|
||||||
void addResource(ResSpec spec, CompoundExprPtr body);
|
void addResource(ResSpec spec, CompoundExprPtr body, yy::location loc);
|
||||||
void addData(ResSpec spec, const std::string& data);
|
void addData(ResSpec spec, const std::string& data, yy::location loc);
|
||||||
|
|
||||||
Resources& getResources() { return resources; }
|
Resources& getResources() { return resources; }
|
||||||
|
|
||||||
bool verboseFlag;
|
bool verboseFlag;
|
||||||
|
|
||||||
|
void problem(Diagnostic d);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user