mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-26 06:49:33 +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
|
||||
|
||||
ResSpec.h
|
||||
|
||||
Diagnostic.h Diagnostic.cc
|
||||
)
|
||||
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 <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))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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 != "")
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
@ -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++)
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user