1 #include "stdafx.h"
2 #include "ExpressionParser.h"
3 
4 static ExpressionInternal* expression(Tokenizer& tokenizer);
5 
6 static bool allowFunctionCall = true;
7 
allowFunctionCallExpression(bool allow)8 void allowFunctionCallExpression(bool allow)
9 {
10 	allowFunctionCall = allow;
11 }
12 
primaryExpression(Tokenizer & tokenizer)13 static ExpressionInternal* primaryExpression(Tokenizer& tokenizer)
14 {
15 	const Token &tok = tokenizer.peekToken();
16 
17 	switch (tok.type)
18 	{
19 	case TokenType::Float:
20 		tokenizer.eatToken();
21 		return new ExpressionInternal(tok.floatValue);
22 	case TokenType::Identifier:
23 		{
24 			const std::wstring stringValue = tok.getStringValue();
25 			tokenizer.eatToken();
26 			if (stringValue == L".")
27 				return new ExpressionInternal(OperatorType::MemoryPos);
28 			else
29 				return new ExpressionInternal(stringValue,OperatorType::Identifier);
30 		}
31 	case TokenType::String:
32 		tokenizer.eatToken();
33 		return new ExpressionInternal(tok.getStringValue(),OperatorType::String);
34 	case TokenType::Integer:
35 		tokenizer.eatToken();
36 		return new ExpressionInternal(tok.intValue);
37 	case TokenType::LParen:
38 		{
39 			tokenizer.eatToken();
40 			ExpressionInternal* exp = expression(tokenizer);
41 
42 			if (tokenizer.nextToken().type != TokenType::RParen)
43 			{
44 				delete exp;
45 				return nullptr;
46 			}
47 
48 			return exp;
49 		}
50 	case TokenType::Invalid:
51 	default:
52 		break;
53 	}
54 
55 	return nullptr;
56 }
57 
postfixExpression(Tokenizer & tokenizer)58 static ExpressionInternal* postfixExpression(Tokenizer& tokenizer)
59 {
60 	if (allowFunctionCall &&
61 		tokenizer.peekToken(0).type == TokenType::Identifier &&
62 		tokenizer.peekToken(1).type == TokenType::LParen)
63 	{
64 		const std::wstring functionName = tokenizer.nextToken().getStringValue();
65 		tokenizer.eatToken();
66 
67 		std::vector<ExpressionInternal*> parameters;
68 		while (tokenizer.peekToken().type != TokenType::RParen)
69 		{
70 			if (parameters.size() != 0 && tokenizer.nextToken().type != TokenType::Comma)
71 			{
72 				for (ExpressionInternal* exp: parameters)
73 					delete exp;
74 				return nullptr;
75 			}
76 
77 			ExpressionInternal* exp = expression(tokenizer);
78 			if (exp == nullptr)
79 			{
80 				for (ExpressionInternal* exp: parameters)
81 					delete exp;
82 				return nullptr;
83 			}
84 
85 			parameters.push_back(exp);
86 		}
87 
88 		tokenizer.eatToken();
89 
90 		return new ExpressionInternal(functionName,parameters);
91 	}
92 
93 	return primaryExpression(tokenizer);
94 }
95 
unaryExpression(Tokenizer & tokenizer)96 static ExpressionInternal* unaryExpression(Tokenizer& tokenizer)
97 {
98 	ExpressionInternal* exp = postfixExpression(tokenizer);
99 	if (exp != nullptr)
100 		return exp;
101 
102 	const TokenType opType = tokenizer.nextToken().type;
103 	exp = postfixExpression(tokenizer);
104 	if (exp == nullptr)
105 		return nullptr;
106 
107 	switch (opType)
108 	{
109 	case TokenType::Plus:
110 		return exp;
111 	case TokenType::Minus:
112 		return new ExpressionInternal(OperatorType::Neg,exp);
113 	case TokenType::Tilde:
114 		return new ExpressionInternal(OperatorType::BitNot,exp);
115 	case TokenType::Exclamation:
116 		return new ExpressionInternal(OperatorType::LogNot,exp);
117 	case TokenType::Degree:
118 		return new ExpressionInternal(OperatorType::ToString,exp);
119 	default:
120 		delete exp;
121 		return nullptr;
122 	}
123 }
124 
multiplicativeExpression(Tokenizer & tokenizer)125 static ExpressionInternal* multiplicativeExpression(Tokenizer& tokenizer)
126 {
127 	ExpressionInternal* exp = unaryExpression(tokenizer);
128 	if (exp ==  nullptr)
129 		return nullptr;
130 
131 	while (true)
132 	{
133 		OperatorType op = OperatorType::Invalid;
134 		switch (tokenizer.peekToken().type)
135 		{
136 		case TokenType::Mult:
137 			op = OperatorType::Mult;
138 			break;
139 		case TokenType::Div:
140 			op = OperatorType::Div;
141 			break;
142 		case TokenType::Mod:
143 			op = OperatorType::Mod;
144 			break;
145 		default:
146 			break;
147 		}
148 
149 		if (op == OperatorType::Invalid)
150 			break;
151 
152 		tokenizer.eatToken();
153 
154 		ExpressionInternal* exp2 = unaryExpression(tokenizer);
155 		if (exp2 == nullptr)
156 		{
157 			delete exp;
158 			return nullptr;
159 		}
160 
161 		exp = new ExpressionInternal(op,exp,exp2);
162 	}
163 
164 	return exp;
165 }
166 
additiveExpression(Tokenizer & tokenizer)167 static ExpressionInternal* additiveExpression(Tokenizer& tokenizer)
168 {
169 	ExpressionInternal* exp = multiplicativeExpression(tokenizer);
170 	if (exp == nullptr)
171 		return nullptr;
172 
173 	while (true)
174 	{
175 		OperatorType op = OperatorType::Invalid;
176 		switch (tokenizer.peekToken().type)
177 		{
178 		case TokenType::Plus:
179 			op = OperatorType::Add;
180 			break;
181 		case TokenType::Minus:
182 			op = OperatorType::Sub;
183 			break;
184 		default:
185 			break;
186 		}
187 
188 		if (op == OperatorType::Invalid)
189 			break;
190 
191 		tokenizer.eatToken();
192 
193 		ExpressionInternal* exp2 = multiplicativeExpression(tokenizer);
194 		if (exp2 == nullptr)
195 		{
196 			delete exp;
197 			return nullptr;
198 		}
199 
200 		exp = new ExpressionInternal(op,exp,exp2);
201 	}
202 
203 	return exp;
204 }
205 
shiftExpression(Tokenizer & tokenizer)206 static ExpressionInternal* shiftExpression(Tokenizer& tokenizer)
207 {
208 	ExpressionInternal* exp = additiveExpression(tokenizer);
209 	if (exp == nullptr)
210 		return nullptr;
211 
212 	while (true)
213 	{
214 		OperatorType op = OperatorType::Invalid;
215 		switch (tokenizer.peekToken().type)
216 		{
217 		case TokenType::LeftShift:
218 			op = OperatorType::LeftShift;
219 			break;
220 		case TokenType::RightShift:
221 			op = OperatorType::RightShift;
222 			break;
223 		default:
224 			break;
225 		}
226 
227 		if (op == OperatorType::Invalid)
228 			break;
229 
230 		tokenizer.eatToken();
231 
232 		ExpressionInternal* exp2 = additiveExpression(tokenizer);
233 		if (exp2 == nullptr)
234 		{
235 			delete exp;
236 			return nullptr;
237 		}
238 
239 		exp = new ExpressionInternal(op,exp,exp2);
240 	}
241 
242 	return exp;
243 }
244 
relationalExpression(Tokenizer & tokenizer)245 static ExpressionInternal* relationalExpression(Tokenizer& tokenizer)
246 {
247 	ExpressionInternal* exp = shiftExpression(tokenizer);
248 	if (exp == nullptr)
249 		return nullptr;
250 
251 	while (true)
252 	{
253 		OperatorType op = OperatorType::Invalid;
254 		switch (tokenizer.peekToken().type)
255 		{
256 		case TokenType::Less:
257 			op = OperatorType::Less;
258 			break;
259 		case TokenType::LessEqual:
260 			op = OperatorType::LessEqual;
261 			break;
262 		case TokenType::Greater:
263 			op = OperatorType::Greater;
264 			break;
265 		case TokenType::GreaterEqual:
266 			op = OperatorType::GreaterEqual;
267 			break;
268 		default:
269 			break;
270 		}
271 
272 		if (op == OperatorType::Invalid)
273 			break;
274 
275 		tokenizer.eatToken();
276 
277 		ExpressionInternal* exp2 = shiftExpression(tokenizer);
278 		if (exp2 == nullptr)
279 		{
280 			delete exp;
281 			return nullptr;
282 		}
283 
284 		exp = new ExpressionInternal(op,exp,exp2);
285 	}
286 
287 	return exp;
288 }
289 
equalityExpression(Tokenizer & tokenizer)290 static ExpressionInternal* equalityExpression(Tokenizer& tokenizer)
291 {
292 	ExpressionInternal* exp = relationalExpression(tokenizer);
293 	if (exp == nullptr)
294 		return nullptr;
295 
296 	while (true)
297 	{
298 		OperatorType op = OperatorType::Invalid;
299 		switch (tokenizer.peekToken().type)
300 		{
301 		case TokenType::Equal:
302 			op = OperatorType::Equal;
303 			break;
304 		case TokenType::NotEqual:
305 			op = OperatorType::NotEqual;
306 			break;
307 		default:
308 			break;
309 		}
310 
311 		if (op == OperatorType::Invalid)
312 			break;
313 
314 		tokenizer.eatToken();
315 
316 		ExpressionInternal* exp2 = relationalExpression(tokenizer);
317 		if (exp2 == nullptr)
318 		{
319 			delete exp;
320 			return nullptr;
321 		}
322 
323 		exp = new ExpressionInternal(op,exp,exp2);
324 	}
325 
326 	return exp;
327 }
328 
andExpression(Tokenizer & tokenizer)329 static ExpressionInternal* andExpression(Tokenizer& tokenizer)
330 {
331 	ExpressionInternal* exp = equalityExpression(tokenizer);
332 	if (exp == nullptr)
333 		return nullptr;
334 
335 	while (tokenizer.peekToken().type == TokenType::BitAnd)
336 	{
337 		tokenizer.eatToken();
338 
339 		ExpressionInternal* exp2 = equalityExpression(tokenizer);
340 		if (exp2 == nullptr)
341 		{
342 			delete exp;
343 			return nullptr;
344 		}
345 
346 		exp = new ExpressionInternal(OperatorType::BitAnd,exp,exp2);
347 	}
348 
349 	return exp;
350 }
351 
exclusiveOrExpression(Tokenizer & tokenizer)352 static ExpressionInternal* exclusiveOrExpression(Tokenizer& tokenizer)
353 {
354 	ExpressionInternal* exp = andExpression(tokenizer);
355 	if (exp == nullptr)
356 		return nullptr;
357 
358 	while (tokenizer.peekToken().type == TokenType::Caret)
359 	{
360 		tokenizer.eatToken();
361 
362 		ExpressionInternal* exp2 = andExpression(tokenizer);
363 		if (exp2 == nullptr)
364 		{
365 			delete exp;
366 			return nullptr;
367 		}
368 
369 		exp = new ExpressionInternal(OperatorType::Xor,exp,exp2);
370 	}
371 
372 	return exp;
373 }
374 
inclusiveOrExpression(Tokenizer & tokenizer)375 static ExpressionInternal* inclusiveOrExpression(Tokenizer& tokenizer)
376 {
377 	ExpressionInternal* exp = exclusiveOrExpression(tokenizer);
378 	if (exp == nullptr)
379 		return nullptr;
380 
381 	while (tokenizer.peekToken().type == TokenType::BitOr)
382 	{
383 		tokenizer.eatToken();
384 
385 		ExpressionInternal* exp2 = exclusiveOrExpression(tokenizer);
386 		if (exp2 == nullptr)
387 		{
388 			delete exp;
389 			return nullptr;
390 		}
391 
392 		exp = new ExpressionInternal(OperatorType::BitOr,exp,exp2);
393 	}
394 
395 	return exp;
396 }
397 
logicalAndExpression(Tokenizer & tokenizer)398 static ExpressionInternal* logicalAndExpression(Tokenizer& tokenizer)
399 {
400 	ExpressionInternal* exp = inclusiveOrExpression(tokenizer);
401 	if (exp == nullptr)
402 		return nullptr;
403 
404 	while (tokenizer.peekToken().type == TokenType::LogAnd)
405 	{
406 		tokenizer.eatToken();
407 
408 		ExpressionInternal* exp2 = inclusiveOrExpression(tokenizer);
409 		if (exp2 == nullptr)
410 		{
411 			delete exp;
412 			return nullptr;
413 		}
414 
415 		exp = new ExpressionInternal(OperatorType::LogAnd,exp,exp2);
416 	}
417 
418 	return exp;
419 }
420 
logicalOrExpression(Tokenizer & tokenizer)421 static ExpressionInternal* logicalOrExpression(Tokenizer& tokenizer)
422 {
423 	ExpressionInternal* exp = logicalAndExpression(tokenizer);
424 	if (exp == nullptr)
425 		return nullptr;
426 
427 	while (tokenizer.peekToken().type == TokenType::LogOr)
428 	{
429 		tokenizer.eatToken();
430 
431 		ExpressionInternal* exp2 = logicalAndExpression(tokenizer);
432 		if (exp2 == nullptr)
433 		{
434 			delete exp;
435 			return nullptr;
436 		}
437 
438 		exp = new ExpressionInternal(OperatorType::LogOr,exp,exp2);
439 	}
440 
441 	return exp;
442 }
443 
conditionalExpression(Tokenizer & tokenizer)444 static ExpressionInternal* conditionalExpression(Tokenizer& tokenizer)
445 {
446 	ExpressionInternal* exp = logicalOrExpression(tokenizer);
447 	if (exp == nullptr)
448 		return nullptr;
449 
450 	// check a ? b : c
451 	if (tokenizer.peekToken().type != TokenType::Question)
452 		return exp;
453 
454 	tokenizer.eatToken();
455 	ExpressionInternal* second = expression(tokenizer);
456 
457 	if (second != nullptr && tokenizer.nextToken().type == TokenType::Colon)
458 	{
459 		ExpressionInternal* third = expression(tokenizer);
460 		if (third != nullptr)
461 			return new ExpressionInternal(OperatorType::TertiaryIf,exp,second,third);
462 
463 		delete third;
464 	}
465 
466 	delete second;
467 	delete exp;
468 	return nullptr;
469 }
470 
expression(Tokenizer & tokenizer)471 static ExpressionInternal* expression(Tokenizer& tokenizer)
472 {
473 	return conditionalExpression(tokenizer);
474 }
475 
parseExpression(Tokenizer & tokenizer,bool inUnknownOrFalseBlock)476 Expression parseExpression(Tokenizer& tokenizer, bool inUnknownOrFalseBlock)
477 {
478 	TokenizerPosition pos = tokenizer.getPosition();
479 
480 	// parse expression, revert tokenizer to previous position
481 	// if it failed
482 	ExpressionInternal* exp = expression(tokenizer);
483 	if (exp == nullptr)
484 		tokenizer.setPosition(pos);
485 
486 	Expression result;
487 	result.setExpression(exp, inUnknownOrFalseBlock);
488 	return result;
489 }
490