this repo has no description
1#include "Expression.h"
2#include "ResourceCompiler.h"
3#include <cassert>
4#include <iostream>
5#include <fstream>
6#include "Diagnostic.h"
7
8int Expression::evaluateInt(ResourceCompiler *ctx)
9{
10 error(ctx, "Expected an integer or integer expression here.");
11 return 0;
12}
13
14std::string Expression::evaluateString(ResourceCompiler *ctx)
15{
16 error(ctx, "Expected a string or string expression here.");
17 return "";
18}
19
20Expression::~Expression()
21{
22}
23
24void Expression::error(ResourceCompiler *ctx, std::string err)
25{
26 ctx->problem(Diagnostic(Diagnostic::Severity::error, err, location));
27}
28
29
30StringExpr::~StringExpr()
31{
32}
33
34std::string StringExpr::evaluateString(ResourceCompiler *ctx)
35{
36 return str;
37}
38
39
40IntExpr::~IntExpr()
41{
42}
43
44int IntExpr::evaluateInt(ResourceCompiler *ctx)
45{
46 return val;
47}
48
49
50void CompoundExpr::addItem(ExprPtr item)
51{
52 items.push_back(item);
53}
54
55CompoundExpr::~CompoundExpr()
56{
57}
58
59
60BinaryExpr::~BinaryExpr()
61{
62}
63
64int BinaryExpr::evaluateInt(ResourceCompiler *ctx)
65{
66 switch(op)
67 {
68 case BinaryOp::XOR:
69 return a->evaluateInt(ctx) ^ b->evaluateInt(ctx);
70 case BinaryOp::OR:
71 return a->evaluateInt(ctx) | b->evaluateInt(ctx);
72 case BinaryOp::AND:
73 return a->evaluateInt(ctx) & b->evaluateInt(ctx);
74 case BinaryOp::SHIFTLEFT:
75 return a->evaluateInt(ctx) << b->evaluateInt(ctx);
76 case BinaryOp::SHIFTRIGHT:
77 return a->evaluateInt(ctx) >> b->evaluateInt(ctx);
78 case BinaryOp::EQUAL:
79 return a->evaluateInt(ctx) == b->evaluateInt(ctx);
80 case BinaryOp::NOTEQUAL:
81 return a->evaluateInt(ctx) != b->evaluateInt(ctx);
82 case BinaryOp::PLUS:
83 return a->evaluateInt(ctx) + b->evaluateInt(ctx);
84 case BinaryOp::MINUS:
85 return a->evaluateInt(ctx) - b->evaluateInt(ctx);
86 case BinaryOp::MULTIPLY:
87 return a->evaluateInt(ctx) * b->evaluateInt(ctx);
88 case BinaryOp::DIVIDE:
89 return a->evaluateInt(ctx) / b->evaluateInt(ctx);
90 default:
91 error(ctx, "Expected an integer or integer expression here.");
92 return 0;
93 }
94}
95
96std::string BinaryExpr::evaluateString(ResourceCompiler *ctx)
97{
98 switch(op)
99 {
100 case BinaryOp::CONCAT:
101 return a->evaluateString(ctx) + b->evaluateString(ctx);
102 default:
103 error(ctx, "Expected a string or string expression here.");
104 return "";
105 }
106}
107
108
109UnaryExpr::~UnaryExpr()
110{
111}
112
113int UnaryExpr::evaluateInt(ResourceCompiler *ctx)
114{
115 switch(op)
116 {
117 case UnaryOp::MINUS:
118 return -a->evaluateInt(ctx);
119 case UnaryOp::COMPLEMENT:
120 return ~a->evaluateInt(ctx);
121 default:
122 error(ctx, "Expected an integer or integer expression here.");
123 return 0;
124 }
125}
126
127
128IdentifierExpr::IdentifierExpr(std::string id, yy::location loc)
129 : Expression(loc), id(id)
130{
131}
132
133void IdentifierExpr::addArgument(ExprPtr e)
134{
135 arguments.push_back(e);
136}
137
138ExprPtr IdentifierExpr::lookup(ResourceCompiler *ctx)
139{
140 Subscripts sub;
141 for(auto arg : arguments)
142 sub.addSubscript(arg->evaluateInt(ctx));
143 ExprPtr val = ctx->lookupIdentifier(id, sub);
144 if(!val)
145 error(ctx, "Identifier \"" + id + "\" is not defined.");
146 return val;
147}
148
149int IdentifierExpr::evaluateInt(ResourceCompiler *ctx)
150{
151 if(ctx->isPrePass())
152 return 0;
153 if(ExprPtr e = lookup(ctx))
154 return e->evaluateInt(ctx);
155 else
156 return 0;
157}
158
159std::string IdentifierExpr::evaluateString(ResourceCompiler *ctx)
160{
161 if(ExprPtr e = lookup(ctx))
162 return e->evaluateString(ctx);
163 else
164 return "";
165}
166
167
168CaseExpr::CaseExpr(const std::string &tag, CompoundExprPtr expr, yy::location loc)
169 : Expression(loc), tag(tag), expr(expr)
170{
171}
172
173
174int CountOfExpr::evaluateInt(ResourceCompiler *ctx)
175{
176 assert(arg->arguments.size() == 0);
177 return ctx->getArrayCount(arg->id);
178}
179
180
181int ArrayIndexExpr::evaluateInt(ResourceCompiler *ctx)
182{
183 assert(arg->arguments.size() == 0);
184 return ctx->getArrayIndex(arg->id);
185}
186
187
188std::string ReadExpr::evaluateString(ResourceCompiler *ctx)
189{
190 std::string filename = arg->evaluateString(ctx);
191 std::ifstream instream(filename);
192 if(!instream)
193 {
194 ctx->problem(Diagnostic(Diagnostic::Severity::error, "could not $$read file " + filename, location));
195 }
196 return std::string(std::istreambuf_iterator<char>(instream.rdbuf()),
197 std::istreambuf_iterator<char>());
198}
199
200
201int UnimplementedExpr::evaluateInt(ResourceCompiler *ctx)
202{
203 std::cerr << msg << std::endl;
204 return 0;
205}
206
207std::string UnimplementedExpr::evaluateString(ResourceCompiler *ctx)
208{
209 std::cerr << msg << std::endl;
210 return "";
211}
212
213
214PeekExpr::PeekExpr(ExprPtr addr, ExprPtr offset, ExprPtr size, yy::location loc)
215 : Expression(loc), addr(addr), offset(offset), size(size)
216{
217}
218
219PeekExpr::PeekExpr(ExprPtr addr, int size, yy::location loc)
220 : Expression(loc),
221 addr(addr),
222 offset(std::make_shared<IntExpr>(0,loc)),
223 size(std::make_shared<IntExpr>(size,loc))
224{
225}
226
227int PeekExpr::evaluateInt(ResourceCompiler *ctx)
228{
229 int p = addr->evaluateInt(ctx) + offset->evaluateInt(ctx);
230 int s = size->evaluateInt(ctx);
231
232 return ctx->peek(p, s);
233}