Exemplo n.º 1
0
int ASMParser::cvtNumString2Number(string s)
  // Converts a string to an integer.  Assumes s is something like "-231" and produces -231
{
    if (!isNumberString(s))
    {
	cerr << "Non-numberic string passed to cvtNumString2Number"
		  << endl;
	return 0;
    }
    int k = 1;
    int val = 0;
    for (int i = s.length()-1; i>0; i--)
    {
	char c = s.at(i);
	val = val + k*((int)(c - '0'));
	k = k*10;
    }
    if (isSign(s.at(0)))
    {
	if (s.at(0) == '-') val = -1*val;
    }
    else
    {
	val = val + k*((int)(s.at(0) - '0'));
    }
    return val;
}
Exemplo n.º 2
0
bool ASMParser::getOperands(Instruction &i, Opcode o, 
			    string *operand, int operand_count)
  // Given an Opcode, a string representing the operands, and the number of operands, 
  // breaks operands apart and stores fields into Instruction.
{

  if(operand_count != opcodes.numOperands(o))
    return false;

  int rs, rt, rd, imm;
  imm = 0;
  rs = rt = rd = NumRegisters;

  int rs_p = opcodes.RSposition(o);
  int rt_p = opcodes.RTposition(o);
  int rd_p = opcodes.RDposition(o);
  int imm_p = opcodes.IMMposition(o);

  if(rs_p != -1){
    rs = registers.getNum(operand[rs_p]);
    if(rs == NumRegisters)
      return false;
  }

  if(rt_p != -1){
    rt = registers.getNum(operand[rt_p]);
    if(rt == NumRegisters)
      return false;

  }
  
  if(rd_p != -1){
    rd = registers.getNum(operand[rd_p]);
    if(rd == NumRegisters)
      return false;

  }

  if(imm_p != -1){
    if(isNumberString(operand[imm_p])){  // does it have a numeric immediate field?
      imm = cvtNumString2Number(operand[imm_p]);
      if(((abs(imm) & 0xFFFF0000)<<1))  // too big a number to fit
	return false;
    }
    else{ 
      if(opcodes.isIMMLabel(o)){  // Can the operand be a label?
	// Assign the immediate field an address
	imm = myLabelAddress;
	myLabelAddress += 4;  // increment the label generator
      }
      else  // There is an error
	return false;
    }

  }

  i.setValues(o, rs, rt, rd, imm);

  return true;
}
Exemplo n.º 3
0
bool ExpressionCell::_compute()
{
    if (this->computed)
        return this->error ? false : true;

    if (data[0]!='=')
    {
        this->error = true;
        this->computed = true;
        this->data = "#parce_expr_error";
        return false;
    }
    
    enum {EQUAL='=', PLUS='+', MINUS='-', MULTIPLICATION='*', DIVISION='\\'} signState=EQUAL;
    int leftValue = 0;
    int rightArgBegin = 1;
    for (unsigned int i=1; i<data.size()+1; i++)
    {
        if ( (i == data.size()-1)
            ||  isSign(data[i]) )
        {
            int rightValue = 0;
            string rightArg = data.substr(rightArgBegin, i-1);
            if (isNumberString(rightArg))
                rightValue = atoi(rightArg.c_str());
            else if (isCellString(rightArg))
            {
                pair<int, int> cellCoord = parseCellCoordinate(rightArg);
                Cell *cell = getCell(cellCoord.first, cellCoord.second);
                // if cell not found or cell can't be computed => error
                if (cell == NULL || !cell->compute() || !cell->isNumber())
                {
                    this->error = true;
                    this->computed = true;
                    this->data = "#incorrect_cell_"+rightArg;
                    return false;
                }
                rightValue = cell->getNumber();
            }
            // Compute operation
            switch (signState)
            {
            case EQUAL: leftValue = rightValue; break;
            case PLUS: leftValue += rightValue; break;
            case MINUS: leftValue -= rightValue; break;
            case MULTIPLICATION: leftValue *= rightValue; break;
            case DIVISION:
                if (rightValue == 0)
                {
                    this->error = true;
                    this->computed = true;
                    this->data = "#division_by_zero";
                    return false;
                }
                leftValue /= rightValue;   
                break;
            }
        }   
        if ( i == data.size()-1 )
            break;
        // set next sing       
        if (data[i] == '+')
            signState = PLUS;
        if (data[i] == '-')
            signState = MINUS;
        if (data[i] == '*')
            signState = MULTIPLICATION;
        if (data[i] == '/')
            signState = DIVISION;
    }
    this->error = false;
    this->computed = true;
    this->data = std::to_string(leftValue);
    this->data_int = leftValue;
    return true;   
}