Пример #1
0
static double eval_fn(MSymbol* sym)
{
  double args[4];
  unsigned narg = 0;

  if (!follows(MT_KET))
  {
    while (narg < 4)
    {
      MItem* exp = expression();
      if (exp->n >= 0) serror("invalid use of list.");
      args[narg++] = exp->val;

      if (follows(MT_KET)) break;
      if (!follows(MT_COMMA)) serror("',' expected.");
      next_token();
    }
  }
  next_token();

  if (narg < (unsigned long) sym->data) serror("too few arguments to '%s'.", sym->name);
  if (narg > (unsigned long) sym->data) serror("too many arguments to '%s'.", sym->name);

  if (narg == 1)
    return ((double (*)(double)) sym->built_in)(args[0]);
  else if (narg == 2)
    return ((double (*)(double, double)) sym->built_in)(args[0], args[1]);

  error("Internal error.");
}
Пример #2
0
static double term()
{
  double result = power();
  while (follows(MT_STAR) || follows(MT_SLASH))
  {
    if (follows(MT_STAR)) { next_token(); result *= power(); }
                     else { next_token(); result /= power(); }
  }
  return result;
}
Пример #3
0
static double factor()
{
  if (follows(MT_BRA))
  {
    next_token();
    MItem* it = expression();
    if (it->n >= 0)
      serror("invalid use of list.");
    if (!follows(MT_KET))
      serror("')' expected.");
    next_token();
    return it->val;
  }
  else if (follows(MT_NUMBER))
  {
    double val = token->value;
    next_token();
    return val;
  }
  else if (follows(MT_IDENT))
  {
    MSymbol* sym = peek_symbol(token->text);
    if (sym == NULL)
      serror("unknown identifier '%s'.", token->text);
    next_token();

    if (follows(MT_BRA))
    {
      if (sym->built_in == NULL)
        serror("unknown function '%s'.", sym->name);
      next_token();
      return eval_fn(sym);
    }
    else
    {
      if (sym->built_in != NULL)
        serror("invalid use of function.");
      if (sym->data->n >= 0)
        serror("invalid use of list.");
      return sym->data->val;
    }
  }
  else {
    serror("syntax error: '%s'", token->text);
    return 0.0;
  }
}
Пример #4
0
static void assignment(bool debug)
{
  if (!follows(MT_IDENT)) serror("identifier expected.");
  MSymbol* sym = get_symbol(token->text);
  next_token();

  if (!follows(MT_EQUAL)) serror("'=' expected.");
  next_token();

  sym->data = item();

  // semicolon is optional
  if (follows(MT_SEMICOL)) next_token();

  // print numerical temporary variables
  if (debug)
    if (sym->data->n < 0)
      info("%s = %.18g", sym->name, sym->data->val);
}
Пример #5
0
static double power()
{
  double base = factor();
  if (follows(MT_POWER))
  {
    next_token();
    return pow(base, factor());
  }
  return base;
}
Пример #6
0
static void list(MItem* parent)
{
  parent->list = NULL;
  parent->n = 0;
  if (follows(MT_END)) { next_token(); return; }

  parent->list = item();
  parent->n++;
  MItem* it = parent->list;
  while (follows(MT_COMMA))
  {
    next_token();
    it->next = item();
    parent->n++;
    it = it->next;
  };

  if (!follows(MT_END)) serror("'}' expected.");
  next_token();
}
Пример #7
0
static MItem* item()
{
  if (follows(MT_BEGIN))
  {
    next_token();
    MItem* it = new_item();
    list(it);
    return it;
  }
  else
    return expression();
}
Пример #8
0
static void list(MItem* parent)
{
  parent->list = NULL;
  parent->n = 0;
  if (follows(MT_END)) { next_token(); return; }

  parent->list = item();
  parent->n++;
  MItem* it = parent->list;
  while (follows(MT_COMMA))
  {
    next_token();
    it->next = item();
    parent->n++;
    it = it->next;
  };

  if (follows(MT_SEMICOL))
  {
    bool one_word_processed = false;
    while(!follows(MT_END))
    {
      next_token();
      if(follows(MT_END))
        break;
      if(one_word_processed++)
        parent->marker->append(" ");
      it->next = item_string_marker();
      if(token->type == MT_NUMBER) {
	      std::ostringstream sin;
	      sin << token->value;
        parent->marker->append(sin.str());
      }
      else
        parent->marker->append(token->text);

      it = it->next;
    }
  }

  if (!follows(MT_END)) serror("'}' expected.");
  next_token();
}
Пример #9
0
void mesh_parser_run(bool debug)
{
  next_token();
  while (!follows(MT_EOF))
    assignment(debug);
}
Пример #10
0
static MItem* expression()
{
  // special case: expression is a list reference
  if (follows(MT_IDENT))
  {
    MSymbol* list = peek_symbol(token->text);
    if (list != NULL && list->built_in == NULL &&
        list->data != NULL && list->data->n >= 0)
    {
      next_token();
      // only "=", "}", ";" or "," must follow
      if (!follows(MT_EQUAL) && !follows(MT_END) &&
          !follows(MT_COMMA) && !follows(MT_SEMICOL))
        serror("invalid use of list.");
      return list->data;
    }
  }

  // handle unary + and -
  double unary = 1.0;
  if (follows(MT_PLUS) || follows(MT_MINUS))
  {
    if (follows(MT_MINUS)) unary = -1.0;
    next_token();
  }

  double result = unary * term();
  while (follows(MT_PLUS) || follows(MT_MINUS))
  {
    if (follows(MT_PLUS)) { next_token(); result += term(); }
                     else { next_token(); result -= term(); }
  }

  MItem* it = new_item();
  it->n = -1;
  it->val = result;
  return it;
}