Esempio n. 1
0
lval *lval_read_double(mpc_ast_t *t) {
    errno = 0;
    double x = strtof(t->contents, NULL);

    if (errno == ERANGE) {
        return lval_err("invalid double");
    } else {
        return lval_double(x);
    }
}
Esempio n. 2
0
lval eval(mpc_ast_t* t) {
  if (strstr(t->tag, "number")) {
    errno = 0;
    if (strstr(t->contents, ".")) {
      double d = strtod(t->contents, NULL);
      return errno != ERANGE ? lval_double(d) : lval_err(LERR_BAD_NUM);
    } else {
      long x = strtol(t->contents, NULL, 10);
      return errno != ERANGE ? lval_num(x) : lval_err(LERR_BAD_NUM);
    }
  }

  char *op = t->children[1]->contents;
  lval x = eval(t->children[2]);

  int i = 3;
  while (strstr(t->children[i]->tag, "expr")) {
    x = eval_op(x, op, eval(t->children[i]));
    i++;
  }

  return x;
}
Esempio n. 3
0
lval eval_op(lval x, char* op, lval y) {
  if (x.type == LVAL_ERR) {
    return x;
  }
  if (y.type == LVAL_ERR) {
    return y;
  }

  if (strcmp(op, "+") == 0) {
    if (x.type == y.type) {
      if (x.type == LVAL_NUM) {
        return lval_num(x.l + y.l);
      } else {
        return lval_double(x.d + y.d);
      }
    } else if (x.type == LVAL_DOUBLE) {
      return lval_double(x.d + y.l);
    } else if (y.type == LVAL_DOUBLE) {
      return lval_double(x.l + y.d);
    }
  }
  if (strcmp(op, "-") == 0) {
    if (x.type == y.type) {
      if (x.type == LVAL_NUM) {
        return lval_num(x.l - y.l);
      } else {
        return lval_double(x.d - y.d);
      }
    } else if (x.type == LVAL_DOUBLE) {
      return lval_double(x.d - y.l);
    } else if (y.type == LVAL_DOUBLE) {
      return lval_double(x.l - y.d);
    }
  }
  if (strcmp(op, "*") == 0) {
    if (x.type == y.type) {
      if (x.type == LVAL_NUM) {
        return lval_num(x.l * y.l);
      } else {
        return lval_double(x.d * y.d);
      }
    } else if (x.type == LVAL_DOUBLE) {
      return lval_double(x.d * y.l);
    } else if (y.type == LVAL_DOUBLE) {
      return lval_double(x.l * y.d);
    }
  }
  if (strcmp(op, "/") == 0) {
    if ((y.type == LVAL_NUM && y.l == 0) || (y.type == LVAL_DOUBLE && y.d == 0)) {
      return lval_err(LERR_DIV_ZERO);
    } else {
      if (x.type == y.type) {
        if (x.type == LVAL_NUM) {
          return lval_num(x.l / y.l);
        } else {
          return lval_double(x.d / y.d);
        }
      } else if (x.type == LVAL_DOUBLE) {
        return lval_double(x.d / y.l);
      } else if (y.type == LVAL_DOUBLE) {
        return lval_double(x.l / y.d);
      }
    }
  }
  if (strcmp(op, "%") == 0) {
    if (! (x.type == LVAL_NUM && y.type == LVAL_NUM)) {
      return lval_err(LERR_BAD_OP);
    } else {
      if (y.l == 0) {
        return lval_err(LERR_DIV_ZERO);
      } else {
        return lval_num(x.l % y.l);
      }
    }
  }

  return lval_err(LERR_BAD_OP);
}