1f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===- RpnEvaluator.cpp ---------------------------------------------------===//
2f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//
3f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//                     The MCLinker Project
4f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//
5f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// This file is distributed under the University of Illinois Open Source
6f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// License. See LICENSE.TXT for details.
7f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//
8f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/RpnEvaluator.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSymbol.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/ExprToken.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/Operand.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/Operator.h"
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/RpnExpr.h"
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h"
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h"
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines
19f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/Support/Casting.h>
20f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/Support/DataTypes.h>
2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines
22f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <stack>
2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines
24f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <cassert>
25f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
28f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesRpnEvaluator::RpnEvaluator(const Module& pModule,
29f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                           const TargetLDBackend& pBackend)
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : m_Module(pModule), m_Backend(pBackend) {
31f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
32f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
3337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool RpnEvaluator::eval(const RpnExpr& pExpr, uint64_t& pResult) {
34f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  std::stack<Operand*> operandStack;
35f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  for (RpnExpr::const_iterator it = pExpr.begin(), ie = pExpr.end(); it != ie;
3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines       ++it) {
3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    switch ((*it)->kind()) {
3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case ExprToken::OPERATOR: {
3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines        Operator* op = llvm::cast<Operator>(*it);
4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines        switch (op->arity()) {
4137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          case Operator::NULLARY: {
4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines            operandStack.push(op->eval(m_Module, m_Backend));
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines            break;
4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          }
4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          case Operator::UNARY: {
4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines            Operand* opd = operandStack.top();
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines            operandStack.pop();
4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines            op->appendOperand(opd);
4937b74a387bb3993387029859c2d9d051c41c724eStephen Hines            operandStack.push(op->eval(m_Module, m_Backend));
5037b74a387bb3993387029859c2d9d051c41c724eStephen Hines            break;
5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          }
5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          case Operator::BINARY: {
5337b74a387bb3993387029859c2d9d051c41c724eStephen Hines            Operand* opd2 = operandStack.top();
5437b74a387bb3993387029859c2d9d051c41c724eStephen Hines            operandStack.pop();
5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines            Operand* opd1 = operandStack.top();
5637b74a387bb3993387029859c2d9d051c41c724eStephen Hines            operandStack.pop();
5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines            op->appendOperand(opd1);
5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines            op->appendOperand(opd2);
5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines            operandStack.push(op->eval(m_Module, m_Backend));
6037b74a387bb3993387029859c2d9d051c41c724eStephen Hines            break;
6137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          }
6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          case Operator::TERNARY: {
6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines            Operand* opd3 = operandStack.top();
6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines            operandStack.pop();
6537b74a387bb3993387029859c2d9d051c41c724eStephen Hines            Operand* opd2 = operandStack.top();
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines            operandStack.pop();
6737b74a387bb3993387029859c2d9d051c41c724eStephen Hines            Operand* opd1 = operandStack.top();
6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines            operandStack.pop();
6937b74a387bb3993387029859c2d9d051c41c724eStephen Hines            op->appendOperand(opd1);
7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines            op->appendOperand(opd2);
7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines            op->appendOperand(opd3);
7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines            operandStack.push(op->eval(m_Module, m_Backend));
7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines            break;
7437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          }
7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        }  // end of switch operator arity
76f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines        break;
77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      }
78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
7937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case ExprToken::OPERAND: {
8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines        Operand* opd = llvm::cast<Operand>(*it);
8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        switch (opd->type()) {
8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          case Operand::SYMBOL: {
8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines            // It's possible that there are no operators in an expression, so
8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines            // we set up symbol operand here.
8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines            if (!opd->isDot()) {
8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines              SymOperand* sym_opd = llvm::cast<SymOperand>(opd);
8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines              const LDSymbol* symbol =
8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                  m_Module.getNamePool().findSymbol(sym_opd->name());
8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines              if (symbol == NULL) {
9037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                fatal(diag::fail_sym_resolution) << __FILE__ << __LINE__
9137b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                                 << "mclinker@googlegroups.com";
9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines              }
9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines              sym_opd->setValue(symbol->value());
9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines            }
9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines            operandStack.push(opd);
9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines            break;
97f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines          }
9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          default:
9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines            operandStack.push(opd);
10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines            break;
10137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        }  // end of switch operand type
102f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines        break;
103f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      }
10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }  // end of switch
10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }    // end of for
106f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
107f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // stack top is result
108f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  assert(operandStack.top()->type() == Operand::SYMBOL ||
109f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines         operandStack.top()->type() == Operand::INTEGER ||
110f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines         operandStack.top()->type() == Operand::FRAGMENT);
111f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  pResult = operandStack.top()->value();
112f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return true;
113f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
114f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
116