1.1 --- a/src/compiler/ConstantEvaluator.cpp Sat Nov 17 23:13:39 2012 -0800
1.2 +++ b/src/compiler/ConstantEvaluator.cpp Sun Nov 18 14:53:23 2012 -0800
1.3 @@ -0,0 +1,92 @@
1.4 +/* vim: set ts=4 sw=4 tw=99 et:
1.5 + *
1.6 + * Copyright (C) 2012 David Anderson
1.7 + *
1.8 + * This file is part of SourcePawn.
1.9 + *
1.10 + * SourcePawn is free software: you can redistribute it and/or modify it under
1.11 + * the terms of the GNU General Public License as published by the Free
1.12 + * Software Foundation, either version 3 of the License, or (at your option)
1.13 + * any later version.
1.14 + *
1.15 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
1.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License along with
1.20 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
1.21 + */
1.22 +#include "AST.h"
1.23 +#include "ConstantEvaluator.h"
1.24 +
1.25 +using namespace ke;
1.26 +
1.27 +static inline bool
1.28 +EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
1.29 + BoxedPrimitive *out)
1.30 +{
1.31 + switch (kind) {
1.32 + case TOK_PLUS:
1.33 + *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
1.34 + return true;
1.35 +
1.36 + case TOK_SHL:
1.37 + *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
1.38 + return true;
1.39 +
1.40 + default:
1.41 + return false;
1.42 + }
1.43 +}
1.44 +
1.45 +static inline bool
1.46 +EvaluateUnaryOperation(TokenKind kind, const BoxedPrimitive &inner, BoxedPrimitive *out)
1.47 +{
1.48 + switch (kind) {
1.49 + case TOK_MINUS:
1.50 + *out = BoxedPrimitive::Int(-inner.toInt());
1.51 + return true;
1.52 +
1.53 + default:
1.54 + return false;
1.55 + }
1.56 +}
1.57 +
1.58 +bool
1.59 +ke::EvaluateForConstant(Expression *expr, BoxedPrimitive *out)
1.60 +{
1.61 + switch (expr->kind()) {
1.62 + case AstNode::kBinaryExpression:
1.63 + {
1.64 + BoxedPrimitive left;
1.65 + BoxedPrimitive right;
1.66 + BinaryExpression *b = expr->toBinaryExpression();
1.67 + if (!EvaluateForConstant(b->left(), &left) ||
1.68 + !EvaluateForConstant(b->right(), &right))
1.69 + {
1.70 + return false;
1.71 + }
1.72 + return EvaluateBinaryOperation(b->token(), left, right, out);
1.73 + }
1.74 +
1.75 + case AstNode::kUnaryExpression:
1.76 + {
1.77 + BoxedPrimitive inner;
1.78 + UnaryExpression *u = expr->toUnaryExpression();
1.79 + if (!EvaluateForConstant(u->expression(), &inner))
1.80 + return false;
1.81 + return EvaluateUnaryOperation(u->token(), inner, out);
1.82 + }
1.83 +
1.84 + case AstNode::kBooleanLiteral:
1.85 + *out = BoxedPrimitive::Int(expr->toBooleanLiteral()->token() == TOK_TRUE ? 1 : 0);
1.86 + return true;
1.87 +
1.88 + case AstNode::kIntegerLiteral:
1.89 + *out = BoxedPrimitive::Int(expr->toIntegerLiteral()->value());
1.90 + return true;
1.91 +
1.92 + default:
1.93 + return false;
1.94 + }
1.95 +}