Exemplo n.º 1
0
Arquivo: calc.cpp Projeto: b0nk/mbot
/*
  call parse_expsimple() repeatedly until the entire symbol stack is reduced
  to a single numeric symbol.
*/
double
ModCalc::parse_explist (void)
{
  while (error[0] == 0)
    if (parse_expsimple ())
      {
        symbol_type *symbol = pop_symbol ();
        if (symbol == NULL || symbol->type != S_NUM)
          {
            snprintf (error, MSG_SIZE, "FUNCTION PARAMETER ERROR!");
            break;
          }
        return symbol->value;
      }
  return 0;
}
Exemplo n.º 2
0
Arquivo: calc.cpp Projeto: b0nk/mbot
/*
  parse a simple expression (<num><operation><num>) from the symbol stack
  and push the result. expands <num> to identifiers (constants, variables or
  functions), and to another expression inside braces.
  return 1 if S_EOF is found, 0 otherwise.
*/
bool
ModCalc::parse_expsimple (void)
{
  double d = 0;
  bool lvalue = 0;
  symbol_type *symbol, *op = NULL, *var = NULL;

  while (1)
    {
      symbol = pop_symbol ();
      if (symbol == NULL)
        {
          snprintf (error, MSG_SIZE, "STACK ERROR!");
          error_pos = 0;
          return 0;
        }
      error_pos = symbol->pos;

      if (symbol->type == S_EOF)
        {
          if (!lvalue || op != NULL || braces != 0)
            {
              snprintf (error, MSG_SIZE, "unexpected end of expression");
              break;
            }
          push_symbol (new symbol_type (symbol->pos, d));
          delete symbol;
          return 1;
        }

      else if (symbol->type == S_OP)
        {
          if (symbol->op == OP_ASSIGN)
            {
              if (var == NULL)
                {
                  snprintf (error, MSG_SIZE, "non-variable lvalue in assignment");
                  break;
                }
            }
          else 
            {
              if (op != NULL ||
                  (!lvalue && symbol->op != OP_PLUS && symbol->op != OP_MINUS))
                {
                  if (op != NULL)
                    snprintf (error, MSG_SIZE, "missing rvalue for operator");
                  else
                    snprintf (error, MSG_SIZE, "missing lvalue for operator");
                  break;
                }
              if (!lvalue && (symbol->op == OP_PLUS || symbol->op == OP_MINUS))
                {
                  d = 0;
                  lvalue = 1;
                }
            }
          op = symbol;
        }

      else if (symbol->type == S_NUM)
        {
          if (op == NULL)
            {
              if (lvalue)
                {
                  snprintf (error, MSG_SIZE, "two consecutive values");
                  break;
                }
              d = symbol->value;
              lvalue = 1;
              delete symbol;
              continue;
            }
          if (top != NULL && top->type == S_OP && top->priority > op->priority)
            {
              push_symbol (new symbol_type (symbol->pos, symbol->value));
              parse_expsimple ();
              if (error[0] != 0)
                break;
              delete symbol;
              continue;
            }
          switch (op->op)
            {
              case OP_ASSIGN:
                d = symbol->value;
                var_type *v;
                vars.rewind ();
                while ((v = (var_type *)vars.next ()) != NULL)
                  if (var->id == v->name)
                    break;
                if (v != NULL)
                  {
                    v->value = d;
                    v->time = get_time ();
                  }
                else
                  {
                    vars.add ((void *)new var_type (var->id, d));
                    if (vars.count () == VARS_MAX)
                      {
                        time_t t_old = -1;
                        var_type *v_old = NULL;
                        vars.rewind ();
                        while ((v = (var_type *)vars.next ()) != NULL)
                          if (v->time < t_old)
                            {
                              t_old = v->time;
                              v_old = v;
                            }
                        vars.del ((void *)v_old);
                      }
                  }
                delete var;
                var = NULL;
                break;
              case OP_PLUS:
                d += symbol->value;
                break;
              case OP_MINUS:
                d -= symbol->value;
                break;
              case OP_TIMES:
                d *= symbol->value;
                break;
              case OP_DIV:
                d /= symbol->value;
                break;
              case OP_MOD:
                d = fmod (d, symbol->value);
                break;
              case OP_POW:
                d = pow (d, symbol->value);
                break;
              case OP_SHIFT_L:
                d = ((unsigned long int)d) << ((unsigned long int)symbol->value);
                break;
              case OP_SHIFT_R:
                d = ((unsigned long int)d) >> ((unsigned long int)symbol->value);
                break;
              case OP_AND:
                d = ((unsigned long int)d) & ((unsigned long int)symbol->value);
                break;
              case OP_OR:
                d = ((unsigned long int)d) | ((unsigned long int)symbol->value);
                break;
            }
          push_symbol (new symbol_type (symbol->pos, d));
          delete op;
          delete symbol;
          return 0;
        }
      
      else if (symbol->type == S_BRACE_L)
        {
          int old_braces = braces;
          braces++;
          while (braces != old_braces)
            {
              parse_expsimple ();
              if (error[0] != 0)
                break;
            }
          delete symbol;
        }

      else if (symbol->type == S_BRACE_R)
        {
          if (!lvalue)
            snprintf (error, MSG_SIZE, "missing value in braces");
          else if (op != NULL)
            snprintf (error, MSG_SIZE, "missing rvalue for operator");
          else if (braces == 0)
            snprintf (error, MSG_SIZE, "extra ')' used");
          else
            {
              braces--;
              push_symbol (new symbol_type (symbol->pos, d));
              delete symbol;
              if (op != NULL)
                delete op;
              return 0;
            }
          break;
        }

      else if (symbol->type == S_ID)
        {
          if (parse_exp_id (symbol))
            {
              if (lvalue)
                {
                  snprintf (error, MSG_SIZE, "invalid lvalue in assignment");
                  break;
                }
              var = symbol;
            }
          if (error[0] != 0)
            break;
        }
    }
Exemplo n.º 3
0
void clear_table(void)
{
    _symbol *entry;

    while ((entry = pop_symbol())) clear_entry(entry);
}