Rez: add some error reporting

This commit is contained in:
Wolfgang Thaller 2014-10-30 02:56:49 +01:00
parent 2a86126dad
commit 3da8beb96f
12 changed files with 202 additions and 96 deletions

View File

@ -56,6 +56,8 @@ add_library(RezLib
ResourceCompiler.h
ResSpec.h
Diagnostic.h Diagnostic.cc
)
target_link_libraries(RezLib ResourceFiles ${Boost_LIBRARIES})

17
Rez/Diagnostic.cc Normal file
View 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
View 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

View File

@ -3,21 +3,29 @@
#include <cassert>
#include <iostream>
#include <fstream>
#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<IntExpr>(0)),
size(std::make_shared<IntExpr>(size))
PeekExpr::PeekExpr(ExprPtr addr, int size, yy::location loc)
: Expression(loc),
addr(addr),
offset(std::make_shared<IntExpr>(0,loc)),
size(std::make_shared<IntExpr>(size,loc))
{
}

View File

@ -4,6 +4,8 @@
#include <memory>
#include <vector>
#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<ExprPtr> 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<ExprPtr> 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);
};

View File

@ -1,10 +1,13 @@
#include "ResourceCompiler.h"
#include <iostream>
#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<IntExpr>(currentOffset);
labelValues[std::make_pair(name,currentSubscripts)] = std::make_shared<IntExpr>(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 != "")

View File

@ -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<std::pair<std::string, Subscripts>, 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);
};

View File

@ -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<LabelField>(name));
addField(std::make_shared<LabelField>(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<BinaryExpr>(
BinaryOp::PLUS, lastNamedValue, std::make_shared<IntExpr>(1)));
BinaryOp::PLUS, lastNamedValue, std::make_shared<IntExpr>(1, yy::location()), yy::location()));
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)
@ -200,8 +201,12 @@ void SimpleField::compileCompound(ExprPtr expr, ResourceCompiler *compiler, bool
}
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->size() == count);
for(int i = 0; i < count; i++)

View File

@ -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<FieldPtr> 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);
};

View File

@ -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 <FieldPtr> 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<BinaryExpr>(BinaryOp::XOR, $1, $3); }
| expression "^" expression1 { $$ = std::make_shared<BinaryExpr>(BinaryOp::XOR, $1, $3, @0); }
;
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 { $$ = std::make_shared<BinaryExpr>(BinaryOp::OR, $1, $3); }
| expression2 "|" expression3 { $$ = std::make_shared<BinaryExpr>(BinaryOp::OR, $1, $3, @0); }
;
expression3 : expression4 { $$ = $1; }
| expression3 "==" expression4 { $$ = std::make_shared<BinaryExpr>(BinaryOp::EQUAL, $1, $3); }
| expression3 "!=" expression4 { $$ = std::make_shared<BinaryExpr>(BinaryOp::NOTEQUAL, $1, $3); }
| expression3 "==" expression4 { $$ = std::make_shared<BinaryExpr>(BinaryOp::EQUAL, $1, $3, @0); }
| expression3 "!=" expression4 { $$ = std::make_shared<BinaryExpr>(BinaryOp::NOTEQUAL, $1, $3, @0); }
;
expression4 : expression5 { $$ = $1; }
| expression4 ">>" expression5 { $$ = std::make_shared<BinaryExpr>(BinaryOp::SHIFTRIGHT, $1, $3); }
| expression4 "<<" expression5 { $$ = std::make_shared<BinaryExpr>(BinaryOp::SHIFTLEFT, $1, $3); }
| expression4 ">>" expression5 { $$ = std::make_shared<BinaryExpr>(BinaryOp::SHIFTRIGHT, $1, $3, @0); }
| expression4 "<<" expression5 { $$ = std::make_shared<BinaryExpr>(BinaryOp::SHIFTLEFT, $1, $3, @0); }
;
expression5 : expression6 { $$ = $1; }
| expression5 "+" expression6 { $$ = std::make_shared<BinaryExpr>(BinaryOp::PLUS, $1, $3); }
| expression5 "-" expression6 { $$ = std::make_shared<BinaryExpr>(BinaryOp::MINUS, $1, $3); }
| expression5 "+" expression6 { $$ = std::make_shared<BinaryExpr>(BinaryOp::PLUS, $1, $3, @0); }
| expression5 "-" expression6 { $$ = std::make_shared<BinaryExpr>(BinaryOp::MINUS, $1, $3, @0); }
;
expression6 : expression7 { $$ = $1; }
| expression6 "*" expression7 { $$ = std::make_shared<BinaryExpr>(BinaryOp::MULTIPLY, $1, $3); }
| expression6 "/" expression7 { $$ = std::make_shared<BinaryExpr>(BinaryOp::DIVIDE, $1, $3); }
| expression6 "*" expression7 { $$ = std::make_shared<BinaryExpr>(BinaryOp::MULTIPLY, $1, $3, @0); }
| expression6 "/" expression7 { $$ = std::make_shared<BinaryExpr>(BinaryOp::DIVIDE, $1, $3, @0); }
;
expression7 : expression8 { $$ = $1; }
| "-" expression7 { $$ = std::make_shared<UnaryExpr>(UnaryOp::MINUS, $2); }
| "-" expression7 { $$ = std::make_shared<UnaryExpr>(UnaryOp::MINUS, $2, @0); }
| "+" 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); }
| CHARLIT { $$ = std::make_shared<IntExpr>($1); }
expression8 : INTLIT { $$ = std::make_shared<IntExpr>($1, @1); }
| CHARLIT { $$ = std::make_shared<IntExpr>($1, @1); }
| identifier_expression { $$ = $1; }
| "(" expression ")" { $$ = $2; }
| "$$countof" "(" identifier_expression ")"
{ $$ = std::make_shared<CountOfExpr>($identifier_expression); }
{ $$ = std::make_shared<CountOfExpr>($identifier_expression, @0); }
| "$$arrayindex" "(" identifier_expression ")"
{ $$ = std::make_shared<ArrayIndexExpr>($identifier_expression); }
{ $$ = std::make_shared<ArrayIndexExpr>($identifier_expression, @0); }
| "$$bitfield" "(" expression "," expression "," expression ")"
{ $$ = std::make_shared<PeekExpr>($3, $5, $7); }
{ $$ = std::make_shared<PeekExpr>($3, $5, $7, @0); }
| "$$word" "(" expression ")"
{ $$ = std::make_shared<PeekExpr>($3, 16); }
{ $$ = std::make_shared<PeekExpr>($3, 16, @0); }
| "$$byte" "(" expression ")"
{ $$ = std::make_shared<PeekExpr>($3, 8); }
{ $$ = std::make_shared<PeekExpr>($3, 8, @0); }
| "$$long" "(" expression ")"
{ $$ = std::make_shared<PeekExpr>($3, 32); }
{ $$ = std::make_shared<PeekExpr>($3, 32, @0); }
;
%type <IdentifierExprPtr> identifier_expression;
identifier_expression : IDENTIFIER { $$ = std::make_shared<IdentifierExpr>($1); }
identifier_expression : IDENTIFIER { $$ = std::make_shared<IdentifierExpr>($1, @1); }
| IDENTIFIER
{ world.functionCalls.push(std::make_shared<IdentifierExpr>($1)); }
{ world.functionCalls.push(std::make_shared<IdentifierExpr>($1, @1)); }
"[" function_argument_list1 "]"
{ $$ = world.functionCalls.top(); world.functionCalls.pop(); }
;
@ -407,7 +407,7 @@ function_argument_list1 : expression
%type <ExprPtr> string_expression string_expression1;
string_expression : string_expression1 { $$ = $1; }
| 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;
@ -415,14 +415,14 @@ stringlit : STRINGLIT { $$ = $1; }
| DOLLAR STRINGLIT { $$ = fromHex($2); }
;
string_expression1 : stringlit { $$ = std::make_shared<StringExpr>($1); }
string_expression1 : stringlit { $$ = std::make_shared<StringExpr>($1, @1); }
| "$$read" "(" string_expression ")"
{ $$ = std::make_shared<ReadExpr>($string_expression); }
{ $$ = std::make_shared<ReadExpr>($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 <CompoundExprPtr> resource_body resource_body1;
resource_body : %empty { $$ = std::make_shared<CompoundExpr>(); }
| resource_body1 { $$ = $1; }
resource_body : %empty { $$ = std::make_shared<CompoundExpr>(@0); }
| 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 ";" { $$ = $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 "}"
{
world.addData($res_spec, $string_expression->evaluateString(nullptr));
world.addData($res_spec, $string_expression->evaluateString(nullptr), @0);
}
;

View File

@ -4,6 +4,8 @@
#include <iostream>
#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;
}

View File

@ -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<SwitchFieldPtr> 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);
};