diff --git a/Rez/CMakeLists.txt b/Rez/CMakeLists.txt index 0c7a08f08a..0bb65a0885 100644 --- a/Rez/CMakeLists.txt +++ b/Rez/CMakeLists.txt @@ -56,6 +56,8 @@ add_library(RezLib ResourceCompiler.h ResSpec.h + + Diagnostic.h Diagnostic.cc ) target_link_libraries(RezLib ResourceFiles ${Boost_LIBRARIES}) diff --git a/Rez/Diagnostic.cc b/Rez/Diagnostic.cc new file mode 100644 index 0000000000..3d8d2ab107 --- /dev/null +++ b/Rez/Diagnostic.cc @@ -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; +} diff --git a/Rez/Diagnostic.h b/Rez/Diagnostic.h new file mode 100644 index 0000000000..3e0b442089 --- /dev/null +++ b/Rez/Diagnostic.h @@ -0,0 +1,31 @@ +#ifndef DIAGNOSTIC_H +#define DIAGNOSTIC_H + +#include +#include +#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 diff --git a/Rez/Expression.cc b/Rez/Expression.cc index 636f6e8547..808d0557be 100644 --- a/Rez/Expression.cc +++ b/Rez/Expression.cc @@ -3,21 +3,29 @@ #include #include #include +#include "Diagnostic.h" int Expression::evaluateInt(ResourceCompiler *ctx) { - throw TypeError(); + error(ctx, "Expected an integer or integer expression here."); + return 0; } std::string Expression::evaluateString(ResourceCompiler *ctx) { - throw TypeError(); + error(ctx, "Expected a string or string expression here."); + return ""; } Expression::~Expression() { } +void Expression::error(ResourceCompiler *ctx, std::string err) +{ + ctx->problem(Diagnostic(Diagnostic::Severity::error, err, location)); +} + StringExpr::~StringExpr() { @@ -80,8 +88,8 @@ int BinaryExpr::evaluateInt(ResourceCompiler *ctx) case BinaryOp::DIVIDE: return a->evaluateInt(ctx) / b->evaluateInt(ctx); default: - throw TypeError(); - break; + error(ctx, "Expected an integer or integer expression here."); + return 0; } } @@ -92,8 +100,8 @@ std::string BinaryExpr::evaluateString(ResourceCompiler *ctx) case BinaryOp::CONCAT: return a->evaluateString(ctx) + b->evaluateString(ctx); default: - throw TypeError(); - break; + error(ctx, "Expected a string or string expression here."); + return ""; } } @@ -111,14 +119,14 @@ int UnaryExpr::evaluateInt(ResourceCompiler *ctx) case UnaryOp::COMPLEMENT: return ~a->evaluateInt(ctx); default: - throw TypeError(); - break; + error(ctx, "Expected an integer or integer expression here."); + return 0; } } -IdentifierExpr::IdentifierExpr(std::string id) - : id(id) +IdentifierExpr::IdentifierExpr(std::string id, yy::location loc) + : Expression(loc), id(id) { } @@ -133,7 +141,8 @@ ExprPtr IdentifierExpr::lookup(ResourceCompiler *ctx) for(auto arg : arguments) sub.addSubscript(arg->evaluateInt(ctx)); ExprPtr val = ctx->lookupIdentifier(id, sub); - assert(val); + if(!val) + error(ctx, "Identifier \"" + id + "\" is not defined."); return val; } @@ -141,17 +150,23 @@ int IdentifierExpr::evaluateInt(ResourceCompiler *ctx) { if(ctx->isPrePass()) 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) { - return lookup(ctx)->evaluateString(ctx); + if(ExprPtr e = lookup(ctx)) + return e->evaluateString(ctx); + else + return ""; } -CaseExpr::CaseExpr(const std::string &tag, CompoundExprPtr expr) - : tag(tag), expr(expr) +CaseExpr::CaseExpr(const std::string &tag, CompoundExprPtr expr, yy::location loc) + : Expression(loc), tag(tag), expr(expr) { } @@ -193,15 +208,16 @@ std::string UnimplementedExpr::evaluateString(ResourceCompiler *ctx) } -PeekExpr::PeekExpr(ExprPtr addr, ExprPtr offset, ExprPtr size) - : addr(addr), offset(offset), size(size) +PeekExpr::PeekExpr(ExprPtr addr, ExprPtr offset, ExprPtr size, yy::location loc) + : Expression(loc), addr(addr), offset(offset), size(size) { } -PeekExpr::PeekExpr(ExprPtr addr, int size) - : addr(addr), - offset(std::make_shared(0)), - size(std::make_shared(size)) +PeekExpr::PeekExpr(ExprPtr addr, int size, yy::location loc) + : Expression(loc), + addr(addr), + offset(std::make_shared(0,loc)), + size(std::make_shared(size,loc)) { } diff --git a/Rez/Expression.h b/Rez/Expression.h index 0300ec6aec..f9572a250c 100644 --- a/Rez/Expression.h +++ b/Rez/Expression.h @@ -4,6 +4,8 @@ #include #include +#include "location.hh" + class ResourceCompiler; class Expression; @@ -33,16 +35,22 @@ class TypeError class Expression { public: + yy::location location; + + Expression(yy::location loc) : location(loc) {} + virtual int evaluateInt(ResourceCompiler *ctx); virtual std::string evaluateString(ResourceCompiler *ctx); virtual ~Expression(); + + void error(ResourceCompiler *ctx, std::string err); }; class StringExpr : public Expression { std::string str; public: - StringExpr(const std::string& str) : str(str) {} + StringExpr(const std::string& str, yy::location loc) : Expression(loc), str(str) {} ~StringExpr(); virtual std::string evaluateString(ResourceCompiler *ctx); }; @@ -51,7 +59,7 @@ class IntExpr : public Expression { int val; public: - IntExpr(int val) : val(val) {} + IntExpr(int val, yy::location loc) : Expression(loc), val(val) {} ~IntExpr(); virtual int evaluateInt(ResourceCompiler *ctx); @@ -61,6 +69,8 @@ class CompoundExpr : public Expression { std::vector items; public: + CompoundExpr(yy::location loc) : Expression(loc) {} + void addItem(ExprPtr item); ExprPtr getItem(int i) const { return items[i]; } int size() const { return items.size(); } @@ -74,7 +84,7 @@ class CaseExpr : public Expression CompoundExprPtr expr; friend class SwitchField; public: - CaseExpr(const std::string& tag, CompoundExprPtr expr); + CaseExpr(const std::string& tag, CompoundExprPtr expr, yy::location loc); }; class BinaryExpr : public Expression @@ -82,8 +92,8 @@ class BinaryExpr : public Expression BinaryOp op; ExprPtr a, b; public: - BinaryExpr(BinaryOp op, ExprPtr a, ExprPtr b) - : op(op), a(a), b(b) {} + BinaryExpr(BinaryOp op, ExprPtr a, ExprPtr b, yy::location loc) + : Expression(loc), op(op), a(a), b(b) {} ~BinaryExpr(); virtual int evaluateInt(ResourceCompiler *ctx); @@ -95,8 +105,8 @@ class UnaryExpr : public Expression UnaryOp op; ExprPtr a; public: - UnaryExpr(UnaryOp op, ExprPtr a) - : op(op), a(a) {} + UnaryExpr(UnaryOp op, ExprPtr a, yy::location loc) + : Expression(loc), op(op), a(a) {} ~UnaryExpr(); virtual int evaluateInt(ResourceCompiler *ctx); @@ -107,7 +117,7 @@ class IdentifierExpr : public Expression public: std::string id; std::vector arguments; - IdentifierExpr(std::string id); + IdentifierExpr(std::string id, yy::location loc); void addArgument(ExprPtr e); ExprPtr lookup(ResourceCompiler *ctx); @@ -119,7 +129,7 @@ class CountOfExpr : public Expression { IdentifierExprPtr arg; public: - CountOfExpr(IdentifierExprPtr arg) : arg(arg) {} + CountOfExpr(IdentifierExprPtr arg, yy::location loc) : Expression(loc), arg(arg) {} virtual int evaluateInt(ResourceCompiler *ctx); }; @@ -127,7 +137,7 @@ class ArrayIndexExpr : public Expression { IdentifierExprPtr arg; public: - ArrayIndexExpr(IdentifierExprPtr arg) : arg(arg) {} + ArrayIndexExpr(IdentifierExprPtr arg, yy::location loc) : Expression(loc), arg(arg) {} virtual int evaluateInt(ResourceCompiler *ctx); }; @@ -135,7 +145,7 @@ class ReadExpr : public Expression { ExprPtr arg; public: - ReadExpr(ExprPtr arg) : arg(arg) {} + ReadExpr(ExprPtr arg, yy::location loc) : Expression(loc), arg(arg) {} virtual std::string evaluateString(ResourceCompiler *ctx); }; @@ -143,7 +153,7 @@ class UnimplementedExpr : public Expression { std::string msg; public: - UnimplementedExpr(std::string msg) : msg(msg) {} + UnimplementedExpr(std::string msg, yy::location loc) : Expression(loc), msg(msg) {} virtual int evaluateInt(ResourceCompiler *ctx); virtual std::string evaluateString(ResourceCompiler *ctx); }; @@ -154,8 +164,8 @@ class PeekExpr : public Expression ExprPtr offset; ExprPtr size; public: - PeekExpr(ExprPtr addr, ExprPtr offset, ExprPtr size); - PeekExpr(ExprPtr addr, int size); + PeekExpr(ExprPtr addr, ExprPtr offset, ExprPtr size, yy::location loc); + PeekExpr(ExprPtr addr, int size, yy::location loc); virtual int evaluateInt(ResourceCompiler *ctx); }; diff --git a/Rez/ResourceCompiler.cc b/Rez/ResourceCompiler.cc index f332d91d4e..0d77436dd5 100644 --- a/Rez/ResourceCompiler.cc +++ b/Rez/ResourceCompiler.cc @@ -1,10 +1,13 @@ #include "ResourceCompiler.h" #include #include "ResourceDefinitions.h" +#include "RezWorld.h" +#include "Diagnostic.h" ResourceCompiler::ResourceCompiler( - TypeDefinitionPtr type, CompoundExprPtr body, bool verboseFlag) - : typeDefinition(type), + RezWorld& world, TypeDefinitionPtr type, CompoundExprPtr body, bool verboseFlag) + : world(world), + typeDefinition(type), body(body), currentField(nullptr) { @@ -99,14 +102,14 @@ ExprPtr ResourceCompiler::lookupIdentifier(std::string name, const Subscripts &s if(p != labelValues.end()) return p->second; - std::cerr << "ID lookup failed: " << name << std::endl; + //std::cerr << "ID lookup failed: " << name << std::endl; return nullptr; } void ResourceCompiler::defineLabel(const std::string &name) { - labelValues[std::make_pair(name,currentSubscripts)] = std::make_shared(currentOffset); + labelValues[std::make_pair(name,currentSubscripts)] = std::make_shared(currentOffset, yy::location()); } void ResourceCompiler::compile() @@ -142,6 +145,11 @@ int ResourceCompiler::getArrayIndex(const std::string &arrayName) return curArrayIndices[arrayName]; } +void ResourceCompiler::problem(Diagnostic d) +{ + world.problem(d); +} + void ResourceCompiler::beginArrayScope(std::string &arrayName, int index) { if(arrayName != "") diff --git a/Rez/ResourceCompiler.h b/Rez/ResourceCompiler.h index 6b11777dac..890a564db5 100644 --- a/Rez/ResourceCompiler.h +++ b/Rez/ResourceCompiler.h @@ -5,7 +5,8 @@ #include "ResourceDefinitions.h" class Field; - +class RezWorld; +class Diagnostic; class Subscripts { @@ -45,6 +46,7 @@ public: class ResourceCompiler : public BinaryOutput { + RezWorld& world; TypeDefinitionPtr typeDefinition; CompoundExprPtr body; std::map, ExprPtr> labelValues; @@ -53,13 +55,9 @@ class ResourceCompiler : public BinaryOutput Field* currentField; Subscripts currentSubscripts; - - void beginArrayScope(std::string& arrayName, int index); - 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()); @@ -87,6 +85,8 @@ public: : compiler(compiler) { compiler->beginArrayScope(arrayName, index); } ~ArrayScope() { compiler->currentSubscripts.popSubscript(); } }; + + void problem(Diagnostic d); }; diff --git a/Rez/ResourceDefinitions.cc b/Rez/ResourceDefinitions.cc index 50d663abcb..1ae315456c 100644 --- a/Rez/ResourceDefinitions.cc +++ b/Rez/ResourceDefinitions.cc @@ -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); } -void FieldList::addLabel(std::string name) +void FieldList::addLabel(std::string name, yy::location loc) { - addField(std::make_shared(name)); + addField(std::make_shared(name), loc); } void FieldList::compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass) @@ -52,9 +53,9 @@ void SimpleField::addNamedValue(std::string n) { if(lastNamedValue) addNamedValue(n, std::make_shared( - BinaryOp::PLUS, lastNamedValue, std::make_shared(1))); + BinaryOp::PLUS, lastNamedValue, std::make_shared(1, yy::location()), yy::location())); else - addNamedValue(n, std::make_shared(0)); + addNamedValue(n, std::make_shared(0, yy::location())); } 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(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->size() == count); for(int i = 0; i < count; i++) diff --git a/Rez/ResourceDefinitions.h b/Rez/ResourceDefinitions.h index e2d5bb828f..cf84b26a38 100644 --- a/Rez/ResourceDefinitions.h +++ b/Rez/ResourceDefinitions.h @@ -8,6 +8,7 @@ #include "Expression.h" #include "ResType.h" +#include "location.hh" class TypeSpec { @@ -44,6 +45,8 @@ class ResourceCompiler; class Field { public: + yy::location location; + virtual bool needsValue() { return true; } virtual void compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass) = 0; @@ -129,8 +132,8 @@ protected: std::vector fields; public: virtual ~FieldList(); - void addField(FieldPtr field); - void addLabel(std::string name); + void addField(FieldPtr field, yy::location loc); + void addLabel(std::string name, yy::location loc); virtual void compile(ExprPtr expr, ResourceCompiler *compiler, bool prePass); }; diff --git a/Rez/RezParser.yy b/Rez/RezParser.yy index 0b6e9d49af..67fe8ad5b0 100644 --- a/Rez/RezParser.yy +++ b/Rez/RezParser.yy @@ -198,9 +198,9 @@ type_spec : res_type { $$ = TypeSpec($res_type); } ; 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_definition ";" { world.fieldLists.top()->addField($2); } + | field_definitions field_definition ";" { world.fieldLists.top()->addField($2, @2); } ; %type field_definition; @@ -328,71 +328,71 @@ switch_case : "case" IDENTIFIER ":" value : expression { $$ = $1; } - | "{" resource_body "}" { $$ = $2; } + | "{" resource_body "}" { $$ = $2; $$->location = @0; } | string_expression { $$ = $1; } ; expression : expression1 { $$ = $1; } - | expression "^" expression1 { $$ = std::make_shared(BinaryOp::XOR, $1, $3); } + | expression "^" expression1 { $$ = std::make_shared(BinaryOp::XOR, $1, $3, @0); } ; expression1 : expression2 { $$ = $1; } - | expression1 "&" expression2 { $$ = std::make_shared(BinaryOp::AND, $1, $3); } + | expression1 "&" expression2 { $$ = std::make_shared(BinaryOp::AND, $1, $3, @0); } ; expression2 : expression3 { $$ = $1; } - | expression2 "|" expression3 { $$ = std::make_shared(BinaryOp::OR, $1, $3); } + | expression2 "|" expression3 { $$ = std::make_shared(BinaryOp::OR, $1, $3, @0); } ; expression3 : expression4 { $$ = $1; } - | expression3 "==" expression4 { $$ = std::make_shared(BinaryOp::EQUAL, $1, $3); } - | expression3 "!=" expression4 { $$ = std::make_shared(BinaryOp::NOTEQUAL, $1, $3); } + | expression3 "==" expression4 { $$ = std::make_shared(BinaryOp::EQUAL, $1, $3, @0); } + | expression3 "!=" expression4 { $$ = std::make_shared(BinaryOp::NOTEQUAL, $1, $3, @0); } ; expression4 : expression5 { $$ = $1; } - | expression4 ">>" expression5 { $$ = std::make_shared(BinaryOp::SHIFTRIGHT, $1, $3); } - | expression4 "<<" expression5 { $$ = std::make_shared(BinaryOp::SHIFTLEFT, $1, $3); } + | expression4 ">>" expression5 { $$ = std::make_shared(BinaryOp::SHIFTRIGHT, $1, $3, @0); } + | expression4 "<<" expression5 { $$ = std::make_shared(BinaryOp::SHIFTLEFT, $1, $3, @0); } ; expression5 : expression6 { $$ = $1; } - | expression5 "+" expression6 { $$ = std::make_shared(BinaryOp::PLUS, $1, $3); } - | expression5 "-" expression6 { $$ = std::make_shared(BinaryOp::MINUS, $1, $3); } + | expression5 "+" expression6 { $$ = std::make_shared(BinaryOp::PLUS, $1, $3, @0); } + | expression5 "-" expression6 { $$ = std::make_shared(BinaryOp::MINUS, $1, $3, @0); } ; expression6 : expression7 { $$ = $1; } - | expression6 "*" expression7 { $$ = std::make_shared(BinaryOp::MULTIPLY, $1, $3); } - | expression6 "/" expression7 { $$ = std::make_shared(BinaryOp::DIVIDE, $1, $3); } + | expression6 "*" expression7 { $$ = std::make_shared(BinaryOp::MULTIPLY, $1, $3, @0); } + | expression6 "/" expression7 { $$ = std::make_shared(BinaryOp::DIVIDE, $1, $3, @0); } ; expression7 : expression8 { $$ = $1; } - | "-" expression7 { $$ = std::make_shared(UnaryOp::MINUS, $2); } + | "-" expression7 { $$ = std::make_shared(UnaryOp::MINUS, $2, @0); } | "+" expression7 { $$ = $2; } - | "~" expression7 { $$ = std::make_shared(UnaryOp::COMPLEMENT, $2); } + | "~" expression7 { $$ = std::make_shared(UnaryOp::COMPLEMENT, $2, @0); } ; -expression8 : INTLIT { $$ = std::make_shared($1); } - | CHARLIT { $$ = std::make_shared($1); } +expression8 : INTLIT { $$ = std::make_shared($1, @1); } + | CHARLIT { $$ = std::make_shared($1, @1); } | identifier_expression { $$ = $1; } | "(" expression ")" { $$ = $2; } | "$$countof" "(" identifier_expression ")" - { $$ = std::make_shared($identifier_expression); } + { $$ = std::make_shared($identifier_expression, @0); } | "$$arrayindex" "(" identifier_expression ")" - { $$ = std::make_shared($identifier_expression); } + { $$ = std::make_shared($identifier_expression, @0); } | "$$bitfield" "(" expression "," expression "," expression ")" - { $$ = std::make_shared($3, $5, $7); } + { $$ = std::make_shared($3, $5, $7, @0); } | "$$word" "(" expression ")" - { $$ = std::make_shared($3, 16); } + { $$ = std::make_shared($3, 16, @0); } | "$$byte" "(" expression ")" - { $$ = std::make_shared($3, 8); } + { $$ = std::make_shared($3, 8, @0); } | "$$long" "(" expression ")" - { $$ = std::make_shared($3, 32); } + { $$ = std::make_shared($3, 32, @0); } ; %type identifier_expression; -identifier_expression : IDENTIFIER { $$ = std::make_shared($1); } +identifier_expression : IDENTIFIER { $$ = std::make_shared($1, @1); } | IDENTIFIER - { world.functionCalls.push(std::make_shared($1)); } + { world.functionCalls.push(std::make_shared($1, @1)); } "[" function_argument_list1 "]" { $$ = world.functionCalls.top(); world.functionCalls.pop(); } ; @@ -407,7 +407,7 @@ function_argument_list1 : expression %type string_expression string_expression1; string_expression : string_expression1 { $$ = $1; } | string_expression string_expression1 - { $$ = std::make_shared(BinaryOp::CONCAT, $1, $2); } + { $$ = std::make_shared(BinaryOp::CONCAT, $1, $2, @0); } ; %type stringlit; @@ -415,14 +415,14 @@ stringlit : STRINGLIT { $$ = $1; } | DOLLAR STRINGLIT { $$ = fromHex($2); } ; -string_expression1 : stringlit { $$ = std::make_shared($1); } +string_expression1 : stringlit { $$ = std::make_shared($1, @1); } | "$$read" "(" string_expression ")" - { $$ = std::make_shared($string_expression); } + { $$ = std::make_shared($string_expression, @0); } ; 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 resource_body resource_body1; -resource_body : %empty { $$ = std::make_shared(); } - | resource_body1 { $$ = $1; } +resource_body : %empty { $$ = std::make_shared(@0); } + | resource_body1 { $$ = $1; $$->location = @1; } ; -resource_body1 : resource_item { $$ = std::make_shared(); $$->addItem($1); } +resource_body1 : resource_item { $$ = std::make_shared(@1); $$->addItem($1); } | resource_body1 "," resource_item { $$ = $1; $$->addItem($3); } | resource_body1 ";" resource_item { $$ = $1; $$->addItem($3); } | resource_body1 ";" { $$ = $1; } ; resource_item : value { $$ = $1; } - | IDENTIFIER "{" resource_body "}" { $$ = std::make_shared($IDENTIFIER, $resource_body); } + | IDENTIFIER "{" resource_body "}" { $$ = std::make_shared($IDENTIFIER, $resource_body, @0); } ; data : "data" res_spec "{" string_expression "}" { - world.addData($res_spec, $string_expression->evaluateString(nullptr)); + world.addData($res_spec, $string_expression->evaluateString(nullptr), @0); } ; diff --git a/Rez/RezWorld.cc b/Rez/RezWorld.cc index 273eecb527..ae21be0d91 100644 --- a/Rez/RezWorld.cc +++ b/Rez/RezWorld.cc @@ -4,6 +4,8 @@ #include +#include "Diagnostic.h" + RezWorld::RezWorld() : verboseFlag(false) { @@ -14,7 +16,7 @@ void RezWorld::addTypeDefinition(TypeSpec spec, TypeDefinitionPtr 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)); if(p != types.end()) @@ -22,24 +24,31 @@ TypeDefinitionPtr RezWorld::getTypeDefinition(ResType type, int id) p = types.find(TypeSpec(type)); if(p != types.end()) return p->second; + problem(Diagnostic(Diagnostic::Severity::error, "Can't find type definition for '" + std::string(type) + "'", loc)); return nullptr; } -void RezWorld::addResource(ResSpec spec, CompoundExprPtr body) +void RezWorld::addResource(ResSpec spec, CompoundExprPtr body, yy::location loc) { if(verboseFlag) std::cout << "RESOURCE " << spec.type() << "(" << spec.id() << ", " << "\"" << spec.name() << "\"" << spec.attr() << ")" << std::endl; - TypeDefinitionPtr def = getTypeDefinition(spec.type(), spec.id()); - ResourceCompiler compiler(def, body, verboseFlag); + TypeDefinitionPtr def = getTypeDefinition(spec.type(), spec.id(), loc); + + ResourceCompiler compiler(*this, def, body, verboseFlag); compiler.compile(); 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) 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())); } + +void RezWorld::problem(Diagnostic d) +{ + std::cerr << d << std::endl; +} diff --git a/Rez/RezWorld.h b/Rez/RezWorld.h index ee8044f5e1..0c32b687f4 100644 --- a/Rez/RezWorld.h +++ b/Rez/RezWorld.h @@ -9,6 +9,8 @@ #include "ResourceFork.h" #include "ResSpec.h" +class Diagnostic; + class RezWorld { friend class RezParser; @@ -19,18 +21,21 @@ class RezWorld std::stack switches; Resources resources; + public: RezWorld(); 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 addData(ResSpec spec, const std::string& data); + void addResource(ResSpec spec, CompoundExprPtr body, yy::location loc); + void addData(ResSpec spec, const std::string& data, yy::location loc); Resources& getResources() { return resources; } bool verboseFlag; + + void problem(Diagnostic d); };