コード例 #1
0
ファイル: fractions.c プロジェクト: amintimany/verifast
int tree_fold(struct tree *tree, fold_function *f, int acc)
    //@ requires [?frac]tree(tree, ?depth) &*& is_fold_function(f) == true;
    //@ ensures [frac]tree(tree, depth);
{
    if (tree == 0) {
        return acc;
    } else {
        //@ open [frac]tree(tree, depth);
        acc = tree_fold(tree->left, f, acc);
        acc = tree_fold(tree->right, f, acc);
        acc = f(acc, tree->value);
        return acc;
        //@ close [frac]tree(tree, depth);
    }
}
コード例 #2
0
ファイル: fractions.c プロジェクト: amintimany/verifast
void folder(struct fold_data *data) //@ : thread_run_joinable
    //@ requires thread_run_pre(folder)(data, ?info);
    //@ ensures thread_run_post(folder)(data, info);
{
    //@ open thread_run_pre(folder)(data, info);
    int acc = tree_fold(data->tree, data->f, data->acc);
    data->acc = acc;
    //@ close thread_run_post(folder)(data, info);
}
コード例 #3
0
ファイル: tree_fold.c プロジェクト: NUOG/ejudge
int
tree_fold(tree_t node, c_value_t *pval)
{
  semainfo_t si;
  struct sema_def *def;
  c_value_t v1, v2;
  int opcode;
  size_t size;
  typeinfo_t tt;
  tree_t decl;

  if (!node) goto failure;

  switch (node->kind) {
  case NODE_EXPRTERNARY:
    if (tree_fold(node->node.refs[3], &v1) < 0) goto failure;
    if (c_value_is_true(&v1)) {
      if (tree_fold(node->node.refs[5], pval) < 0) goto failure;
    } else {
      if (tree_fold(node->node.refs[7], pval) < 0) goto failure;
    }
    break;

  case NODE_EXPRBINARY:
    opcode = sema_binop_to_c_operation(node->node.refs[4]->kind);

    switch (opcode) {
    case COP_ASSIGN:
    case COP_MULASSIGN:
    case COP_DIVASSIGN:
    case COP_MODASSIGN:
    case COP_ADDASSIGN:
    case COP_SUBASSIGN:
    case COP_ASLASSIGN:
    case COP_ASRASSIGN:
    case COP_ANDASSIGN:
    case COP_XORASSIGN:
    case COP_ORASSIGN:
      goto failure;

    case COP_COMMA:
      if (tree_fold(node->node.refs[3], &v1) < 0) goto failure;
      if (tree_fold(node->node.refs[5], pval) < 0) goto failure;
      break;

    case COP_LOGAND:
      if (tree_fold(node->node.refs[3], &v1) < 0) goto failure;
      if (c_value_is_false(&v1)) goto set_false_value;
      if (tree_fold(node->node.refs[5], &v2) < 0) goto failure;
      if (c_value_is_false(&v2)) goto set_false_value;
      goto set_true_value;

    case COP_LOGOR:
      if (tree_fold(node->node.refs[3], &v1) < 0) goto failure;
      if (c_value_is_true(&v1)) goto set_true_value;
      if (tree_fold(node->node.refs[5], &v2) < 0) goto failure;
      if (c_value_is_true(&v2)) goto set_true_value;
      goto set_false_value;

    case COP_BITOR:
    case COP_BITXOR:
    case COP_BITAND:
    case COP_EQ:
    case COP_NE:
    case COP_LT:
    case COP_GT:
    case COP_LE:
    case COP_GE:
    case COP_ASR:
    case COP_ASL:
    case COP_ADD:
    case COP_SUB:
    case COP_MUL:
    case COP_DIV:
    case COP_MOD:
      break;

    default:
      SWERR(("tree_fold: unhandled binary opcode: %d", opcode));
    }

    if (tree_fold(node->node.refs[3], &v1) < 0) goto failure;
    if (tree_fold(node->node.refs[5], &v2) < 0) goto failure;
    if (c_value_operation(0, opcode, &v1, &v2, 0, pval) < 0) goto failure;
    break;

  case NODE_EXPRCAST:
    if (tree_fold(node->node.refs[6], &v1) < 0) goto failure;
    tt = sema_get_expr_type(node->node.refs[6]);
    ASSERT(tt);
    if (tt->tag != CPT_ARITH && tt->tag != CPT_ENUM) goto failure;
    tt = sema_get_expr_type(node);
    if (tt->tag != CPT_ARITH) goto failure;
    if (c_value_cast(&v1, sema_typeinfo_to_index(tt), pval) < 0) goto failure;
    break;

  case NODE_EXPRSIZEOF:
    decl = node->node.refs[5];
    if (!decl) goto failure;
    ASSERT(decl->kind == NODE_DECL);
    si = decl->node.sema;
    if (!si) goto failure;
    ASSERT(si->tag == ST_TYPE);
    tt = si->s_type.type;
    size = sema_get_type_size(tt);
    if (size == SEMA_NO_SIZE) goto failure;
    memset(pval, 0, sizeof(*pval));
    pval->tag = C_ULONG;
    pval->v.ct_ulint = size;
    break;

  case NODE_EXPRUNARY:
    opcode = sema_unop_to_c_operation(node->node.refs[3]->kind);

    switch (opcode) {
    case COP_PREINC:
    case COP_PREDEC:
      goto failure;

    case COP_SIZEOF:
      tt = sema_get_expr_type(node->node.refs[4]);
      size = sema_get_type_size(tt);
      if (size == SEMA_NO_SIZE) goto failure;
      memset(pval, 0, sizeof(*pval));
      pval->tag = C_ULONG;
      pval->v.ct_ulint = size;
      break;

    case COP_DEREF:
    case COP_ADDRESS:
      goto failure;

    case COP_PLUS:
    case COP_MINUS:
    case COP_BITNOT:
    case COP_LOGNOT:
      if (tree_fold(node->node.refs[4], &v1) < 0) goto failure;
      if (c_value_operation(0, opcode, &v1, 0, 0, pval) < 0) goto failure;
      break;

    default:
      SWERR(("tree_fold: unhandled unary opcode: %d", opcode));
    }
    break;

  case NODE_EXPRARRAY:
  case NODE_EXPRCALL:
  case NODE_EXPRFIELD:
  case NODE_EXPRPOSTFIX:
    return -1;

  case NODE_EXPRBRACKETS:
    return tree_fold(node->node.refs[4], pval);

  case NODE_EXPRIDENT:
    si = node->node.sema;
    if (!si) goto failure;
    ASSERT(si->tag == ST_IDUSE);
    def = si->s_iduse.def;
    ASSERT(def->type);
    if (def->type->tag != CPT_ENUM) goto failure;
    if (!SSC_IS_ENUMCONST(def->flags)) goto failure;
    memset(pval, 0, sizeof(*pval));
    memcpy(pval, def->value, sizeof(c_value_t));
    break;

  case NODE_EXPRCONST:
    memset(pval, 0, sizeof(*pval));
    memcpy(pval, &node->node.refs[3]->val.val, sizeof(c_value_t));
    break;

  case NODE_EXPRSTRING:
  case NODE_EXPRVASTART:
  case NODE_EXPRVAARG:
  case NODE_EXPRVAEND:
  case NODE_EXPRINIT:
  case NODE_EXPRASM:
    return -1;
  default:
    SWERR(("tree_fold: bad node: kind == %d", node->kind));
  }
  return 0;

 failure:
  memset(pval, 0, sizeof(*pval));
  pval->tag = C_INT;
  return -1;

 set_false_value:
  memset(pval, 0, sizeof(*pval));
  pval->tag = C_INT;
  return 0;

 set_true_value:
  memset(pval, 0, sizeof(*pval));
  pval->tag = C_INT;
  pval->v.ct_int = 1;
  return 0;
}