Something went wrong. Try again.
Cider Isn't Darwin Emulation, Really
Something went wrong. Try again.
5.3 kB · 233 lines
C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234#include "Expression.h"#include "ResourceCompiler.h"#include <cassert>#include <iostream>#include <fstream>#include "Diagnostic.h"
int Expression::evaluateInt(ResourceCompiler *ctx){ error(ctx, "Expected an integer or integer expression here."); return 0;}
std::string Expression::evaluateString(ResourceCompiler *ctx){ 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(){}
std::string StringExpr::evaluateString(ResourceCompiler *ctx){ return str;}
IntExpr::~IntExpr(){}
int IntExpr::evaluateInt(ResourceCompiler *ctx){ return val;}
void CompoundExpr::addItem(ExprPtr item){ items.push_back(item);}
CompoundExpr::~CompoundExpr(){}
BinaryExpr::~BinaryExpr(){}
int BinaryExpr::evaluateInt(ResourceCompiler *ctx){ switch(op) { case BinaryOp::XOR: return a->evaluateInt(ctx) ^ b->evaluateInt(ctx); case BinaryOp::OR: return a->evaluateInt(ctx) | b->evaluateInt(ctx); case BinaryOp::AND: return a->evaluateInt(ctx) & b->evaluateInt(ctx); case BinaryOp::SHIFTLEFT: return a->evaluateInt(ctx) << b->evaluateInt(ctx); case BinaryOp::SHIFTRIGHT: return a->evaluateInt(ctx) >> b->evaluateInt(ctx); case BinaryOp::EQUAL: return a->evaluateInt(ctx) == b->evaluateInt(ctx); case BinaryOp::NOTEQUAL: return a->evaluateInt(ctx) != b->evaluateInt(ctx); case BinaryOp::PLUS: return a->evaluateInt(ctx) + b->evaluateInt(ctx); case BinaryOp::MINUS: return a->evaluateInt(ctx) - b->evaluateInt(ctx); case BinaryOp::MULTIPLY: return a->evaluateInt(ctx) * b->evaluateInt(ctx); case BinaryOp::DIVIDE: return a->evaluateInt(ctx) / b->evaluateInt(ctx); default: error(ctx, "Expected an integer or integer expression here."); return 0; }}
std::string BinaryExpr::evaluateString(ResourceCompiler *ctx){ switch(op) { case BinaryOp::CONCAT: return a->evaluateString(ctx) + b->evaluateString(ctx); default: error(ctx, "Expected a string or string expression here."); return ""; }}
UnaryExpr::~UnaryExpr(){}
int UnaryExpr::evaluateInt(ResourceCompiler *ctx){ switch(op) { case UnaryOp::MINUS: return -a->evaluateInt(ctx); case UnaryOp::COMPLEMENT: return ~a->evaluateInt(ctx); default: error(ctx, "Expected an integer or integer expression here."); return 0; }}
IdentifierExpr::IdentifierExpr(std::string id, yy::location loc) : Expression(loc), id(id){}
void IdentifierExpr::addArgument(ExprPtr e){ arguments.push_back(e);}
ExprPtr IdentifierExpr::lookup(ResourceCompiler *ctx){ Subscripts sub; for(auto arg : arguments) sub.addSubscript(arg->evaluateInt(ctx)); ExprPtr val = ctx->lookupIdentifier(id, sub); if(!val) error(ctx, "Identifier \"" + id + "\" is not defined."); return val;}
int IdentifierExpr::evaluateInt(ResourceCompiler *ctx){ if(ctx->isPrePass()) return 0; if(ExprPtr e = lookup(ctx)) return e->evaluateInt(ctx); else return 0;}
std::string IdentifierExpr::evaluateString(ResourceCompiler *ctx){ if(ExprPtr e = lookup(ctx)) return e->evaluateString(ctx); else return "";}
CaseExpr::CaseExpr(const std::string &tag, CompoundExprPtr expr, yy::location loc) : Expression(loc), tag(tag), expr(expr){}
int CountOfExpr::evaluateInt(ResourceCompiler *ctx){ assert(arg->arguments.size() == 0); return ctx->getArrayCount(arg->id);}
int ArrayIndexExpr::evaluateInt(ResourceCompiler *ctx){ assert(arg->arguments.size() == 0); return ctx->getArrayIndex(arg->id);}
std::string ReadExpr::evaluateString(ResourceCompiler *ctx){ std::string filename = arg->evaluateString(ctx); std::ifstream instream(filename); if(!instream) { ctx->problem(Diagnostic(Diagnostic::Severity::error, "could not $$read file " + filename, location)); } return std::string(std::istreambuf_iterator<char>(instream.rdbuf()), std::istreambuf_iterator<char>());}
int UnimplementedExpr::evaluateInt(ResourceCompiler *ctx){ std::cerr << msg << std::endl; return 0;}
std::string UnimplementedExpr::evaluateString(ResourceCompiler *ctx){ std::cerr << msg << std::endl; return "";}
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, yy::location loc) : Expression(loc), addr(addr), offset(std::make_shared<IntExpr>(0,loc)), size(std::make_shared<IntExpr>(size,loc)){}
int PeekExpr::evaluateInt(ResourceCompiler *ctx){ int p = addr->evaluateInt(ctx) + offset->evaluateInt(ctx); int s = size->evaluateInt(ctx);
return ctx->peek(p, s);}