diff -r c4b1341297e5 -r ba85a47ee414 src/compiler/ConstantEvaluator.cpp --- a/src/compiler/ConstantEvaluator.cpp Mon Jun 10 00:46:29 2013 +0100 +++ b/src/compiler/ConstantEvaluator.cpp Mon Jun 10 01:04:43 2013 +0100 @@ -1,94 +1,94 @@ -/* vim: set ts=4 sw=4 tw=99 et: - * - * Copyright (C) 2012 David Anderson - * - * This file is part of SourcePawn. - * - * SourcePawn is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) - * any later version. - * - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * SourcePawn. If not, see http://www.gnu.org/licenses/. - */ -#include "AST.h" -#include "ConstantEvaluator.h" -#include "../Heap-inl.h" -#include "../Handles-inl.h" - -using namespace ke; - -static inline bool -EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right, - BoxedPrimitive *out) -{ - switch (kind) { - case TOK_PLUS: - *out = BoxedPrimitive::Int(left.toInt() + right.toInt()); - return true; - - case TOK_SHL: - *out = BoxedPrimitive::Int(left.toInt() << right.toInt()); - return true; - - default: - return false; - } -} - -static inline bool -EvaluateUnaryOperation(TokenKind kind, const BoxedPrimitive &inner, BoxedPrimitive *out) -{ - switch (kind) { - case TOK_MINUS: - *out = BoxedPrimitive::Int(-inner.toInt()); - return true; - - default: - return false; - } -} - -bool -ke::EvaluateForConstant(Expression *expr, BoxedPrimitive *out) -{ - switch (expr->kind()) { - case AstNode::kBinaryExpression: - { - BoxedPrimitive left; - BoxedPrimitive right; - BinaryExpression *b = expr->toBinaryExpression(); - if (!EvaluateForConstant(b->left(), &left) || - !EvaluateForConstant(b->right(), &right)) - { - return false; - } - return EvaluateBinaryOperation(b->token(), left, right, out); - } - - case AstNode::kUnaryExpression: - { - BoxedPrimitive inner; - UnaryExpression *u = expr->toUnaryExpression(); - if (!EvaluateForConstant(u->expression(), &inner)) - return false; - return EvaluateUnaryOperation(u->token(), inner, out); - } - - case AstNode::kBooleanLiteral: - *out = BoxedPrimitive::Int(expr->toBooleanLiteral()->token() == TOK_TRUE ? 1 : 0); - return true; - - case AstNode::kIntegerLiteral: - *out = BoxedPrimitive::Int(expr->toIntegerLiteral()->value()); - return true; - - default: - return false; - } -} +/* vim: set ts=4 sw=4 tw=99 et: + * + * Copyright (C) 2012 David Anderson + * + * This file is part of SourcePawn. + * + * SourcePawn is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * SourcePawn. If not, see http://www.gnu.org/licenses/. + */ +#include "AST.h" +#include "ConstantEvaluator.h" +#include "../Heap-inl.h" +#include "../Handles-inl.h" + +using namespace ke; + +static inline bool +EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right, + BoxedPrimitive *out) +{ + switch (kind) { + case TOK_PLUS: + *out = BoxedPrimitive::Int(left.toInt() + right.toInt()); + return true; + + case TOK_SHL: + *out = BoxedPrimitive::Int(left.toInt() << right.toInt()); + return true; + + default: + return false; + } +} + +static inline bool +EvaluateUnaryOperation(TokenKind kind, const BoxedPrimitive &inner, BoxedPrimitive *out) +{ + switch (kind) { + case TOK_MINUS: + *out = BoxedPrimitive::Int(-inner.toInt()); + return true; + + default: + return false; + } +} + +bool +ke::EvaluateForConstant(Expression *expr, BoxedPrimitive *out) +{ + switch (expr->kind()) { + case AstNode::kBinaryExpression: + { + BoxedPrimitive left; + BoxedPrimitive right; + BinaryExpression *b = expr->toBinaryExpression(); + if (!EvaluateForConstant(b->left(), &left) || + !EvaluateForConstant(b->right(), &right)) + { + return false; + } + return EvaluateBinaryOperation(b->token(), left, right, out); + } + + case AstNode::kUnaryExpression: + { + BoxedPrimitive inner; + UnaryExpression *u = expr->toUnaryExpression(); + if (!EvaluateForConstant(u->expression(), &inner)) + return false; + return EvaluateUnaryOperation(u->token(), inner, out); + } + + case AstNode::kBooleanLiteral: + *out = BoxedPrimitive::Int(expr->toBooleanLiteral()->token() == TOK_TRUE ? 1 : 0); + return true; + + case AstNode::kIntegerLiteral: + *out = BoxedPrimitive::Int(expr->toIntegerLiteral()->value()); + return true; + + default: + return false; + } +}