Example #1
0
 void add_defs(unsigned num, expr * const * args, expr * u, expr * identity) {
     if (m_mc) {
         add_def(args[0], u);
         for (unsigned i = 1; i < num; i++)
             add_def(args[i], identity);
     }
 }
Example #2
0
 app * process_extract(func_decl * f, expr * arg) {
     if (!uncnstr(arg))
         return nullptr;
     app * r;
     if (!mk_fresh_uncnstr_var_for(f, arg, r))
         return r;
     if (!m_mc)
         return r;
     unsigned high    = m_bv_util.get_extract_high(f);
     unsigned low     = m_bv_util.get_extract_low(f);
     unsigned bv_size = m_bv_util.get_bv_size(m().get_sort(arg));
     if (bv_size == high - low + 1) {
         add_def(arg, r);
     }
     else {
         ptr_buffer<expr> args;
         if (high < bv_size - 1)
             args.push_back(m_bv_util.mk_numeral(rational(0), bv_size - high - 1));
         args.push_back(r);
         if (low > 0)
             args.push_back(m_bv_util.mk_numeral(rational(0), low));
         add_def(arg, m_bv_util.mk_concat(args.size(), args.c_ptr()));
     }
     return r;
 }
Example #3
0
 app * process_array_app(func_decl * f, unsigned num, expr * const * args) {
     SASSERT(f->get_family_id() == m_ar_util.get_family_id());
     switch (f->get_decl_kind()) {
     case OP_SELECT:
         if (uncnstr(args[0])) {
             app * r;
             if (!mk_fresh_uncnstr_var_for(f, num, args, r))
                 return r;
             sort * s = m().get_sort(args[0]);
             if (m_mc)
                 add_def(args[0], m_ar_util.mk_const_array(s, r));
             return r;
         }
         return nullptr;
     case OP_STORE:
         if (uncnstr(args[0]) && uncnstr(args[num-1])) {
             app * r;
             if (!mk_fresh_uncnstr_var_for(f, num, args, r))
                 return r;
             if (m_mc) {
                 add_def(args[num-1], m().mk_app(m_ar_util.get_family_id(), OP_SELECT, num-1, args));
                 add_def(args[0], r);
             }
             return r;
         }
     default:
         return nullptr;
     }
 }
Example #4
0
 app * process_datatype_app(func_decl * f, unsigned num, expr * const * args) {
     if (m_dt_util.is_recognizer(f)) {
         SASSERT(num == 1);
         if (uncnstr(args[0])) {
             if (!m_mc) {
                 app * r;
                 mk_fresh_uncnstr_var_for(f, num, args, r);
                 return r;
             }
             // TODO: handle model generation
         }
     }
     else if (m_dt_util.is_accessor(f)) {
         SASSERT(num == 1);
         if (uncnstr(args[0])) {
             if (!m_mc) {
                 app * r;
                 mk_fresh_uncnstr_var_for(f, num, args, r);
                 return r;
             }
             func_decl * c = m_dt_util.get_accessor_constructor(f);
             for (unsigned i = 0; i < c->get_arity(); i++) 
                 if (!m().is_fully_interp(c->get_domain(i)))
                     return nullptr;
             app * u;
             if (!mk_fresh_uncnstr_var_for(f, num, args, u))
                 return u;
             ptr_vector<func_decl> const & accs = *m_dt_util.get_constructor_accessors(c);
             ptr_buffer<expr> new_args;
             for (unsigned i = 0; i < accs.size(); i++) {
                 if (accs[i] == f) 
                     new_args.push_back(u);
                 else
                     new_args.push_back(m().get_some_value(c->get_domain(i)));
             }
             add_def(args[0], m().mk_app(c, new_args.size(), new_args.c_ptr()));
             return u;
         }
     }
     else if (m_dt_util.is_constructor(f)) {
         if (uncnstr(num, args)) {
             app * u;
             if (!mk_fresh_uncnstr_var_for(f, num, args, u))
                 return u;
             if (!m_mc)
                 return u;
             ptr_vector<func_decl> const & accs = *m_dt_util.get_constructor_accessors(f);
             for (unsigned i = 0; i < num; i++) {
                 add_def(args[i], m().mk_app(accs[i], u));
             }
             return u;
         }
     }
     return nullptr;
 }
Example #5
0
 app * process_bv_div(func_decl * f, expr * arg1, expr * arg2) {
     if (uncnstr(arg1) && uncnstr(arg2)) {
         sort * s = m().get_sort(arg1);
         app * r;
         if (!mk_fresh_uncnstr_var_for(f, arg1, arg2, r))
             return r;
         if (!m_mc)
             return r;
         add_def(arg1, r);
         add_def(arg2, m_bv_util.mk_numeral(rational(1), s));
         return r;
     }
     return nullptr;
 }
Example #6
0
/* theta_type -- compute type of a theta-exp or theta-select */
PRIVATE type theta_type(tree t, env e, type a, tree cxt)
{
     def d = get_schema((tok) t->x_the_name, t->x_loc);
     schema s;
     env e1 = new_env(e);
     type b;
     int i;

     if (d == NULL)
	  return err_type;

     s = d->d_schema;
     check_rename(s, (tok) t->x_the_decor, t->x_the_rename, t);

     for (i = 0; i < s->z_ncomps; i++) {
	  sym x = s->z_comp[i].z_name;
	  sym xp = get_rename(x, (tok) t->x_the_decor, t->x_the_rename);
	  type tt = (a == NULL
		     ? ref_type(xp, nil, e, t)
		     : comp_type(a, xp, cxt, t->x_loc));
	  add_def(VAR, x, tt, e1);
     }

     b = mk_sproduct(mk_schema(e1));
     if (! aflag && d->d_abbrev && d->d_nparams == 0
	 && type_equal(b, arid, mk_sproduct(s), arid))
	  return mk_abbrev(d, arid);
     else
	  return b;
}
Example #7
0
 app * process_le_ge(func_decl * f, expr * arg1, expr * arg2, bool le) {
     expr * v;
     expr * t;
     if (uncnstr(arg1)) {
         v = arg1;
         t = arg2;
     }
     else if (uncnstr(arg2)) {
         v = arg2;
         t = arg1;
         le = !le;
     }
     else {
         return nullptr;
     }
     app * u;
     if (!mk_fresh_uncnstr_var_for(f, arg1, arg2, u))
         return u;
     if (!m_mc)
         return u;
     // v = ite(u, t, t + 1) if le
     // v = ite(u, t, t - 1) if !le
     add_def(v, m().mk_ite(u, t, m_a_util.mk_add(t, m_a_util.mk_numeral(rational(le ? 1 : -1), m().get_sort(arg1)))));
     return u;
 }
Example #8
0
 app * process_bv_mul(func_decl * f, unsigned num, expr * const * args) {
     if (num == 0)
         return nullptr;
     if (uncnstr(num, args)) {
         sort * s = m().get_sort(args[0]);
         app * r;
         if (!mk_fresh_uncnstr_var_for(f, num, args, r))
             return r;
         if (m_mc)
             add_defs(num, args, r, m_bv_util.mk_numeral(rational(1), s));
         return r;
     }
     // c * v (c is even) case
     unsigned bv_size;
     rational val;
     rational inv;
     if (num == 2 && 
         uncnstr(args[1]) && 
         m_bv_util.is_numeral(args[0], val, bv_size) &&
         m_bv_util.mult_inverse(val, bv_size, inv)) {
         app * r;
         if (!mk_fresh_uncnstr_var_for(f, num, args, r))
             return r;
         sort * s = m().get_sort(args[1]);
         if (m_mc)
             add_def(args[1], m_bv_util.mk_bv_mul(m_bv_util.mk_numeral(inv, s), r));
         return r;
     }
     return nullptr;
 }
Example #9
0
 app * process_arith_mul(func_decl * f, unsigned num, expr * const * args) {
     if (num == 0)
         return nullptr;
     sort * s = m().get_sort(args[0]);
     if (uncnstr(num, args)) {
         app * r;
         if (!mk_fresh_uncnstr_var_for(f, num, args, r))
             return r;
         if (m_mc)
             add_defs(num, args, r, m_a_util.mk_numeral(rational(1), s));
         return r;
     }
     // c * v case for reals
     bool is_int;
     rational val;
     if (num == 2 && uncnstr(args[1]) && m_a_util.is_numeral(args[0], val, is_int) && !is_int) {
         if (val.is_zero())
             return nullptr;
         app * r;
         if (!mk_fresh_uncnstr_var_for(f, num, args, r))
             return r;
         if (m_mc) {
             val = rational(1) / val;
             add_def(args[1], m_a_util.mk_mul(m_a_util.mk_numeral(val, false), r));
         }
         return r;
     }
     return nullptr;
 }
Example #10
0
 app * process_bv_le(func_decl * f, expr * arg1, expr * arg2, bool is_signed) {
     if (m_produce_proofs) {
         // The result of bv_le is not just introducing a new fresh name,
         // we need a side condition.
         // TODO: the correct proof step
         return nullptr;
     }
     if (uncnstr(arg1)) {
         // v <= t
         expr * v = arg1;
         expr * t = arg2;
         // v <= t --->  (u or t == MAX)   u is fresh
         //     add definition v = ite(u or t == MAX, t, t+1)
         unsigned bv_sz = m_bv_util.get_bv_size(arg1);
         rational MAX;
         if (is_signed)
             MAX = rational::power_of_two(bv_sz - 1) - rational(1);
         else
             MAX = rational::power_of_two(bv_sz) - rational(1);
         app * u;
         bool is_new = mk_fresh_uncnstr_var_for(f, arg1, arg2, u);
         app * r = m().mk_or(u, m().mk_eq(t, m_bv_util.mk_numeral(MAX, bv_sz)));
         if (m_mc && is_new)
             add_def(v, m().mk_ite(r, t, m_bv_util.mk_bv_add(t, m_bv_util.mk_numeral(rational(1), bv_sz))));
         return r;
     }
     if (uncnstr(arg2)) {
         // v >= t
         expr * v = arg2;
         expr * t = arg1;
         // v >= t --->  (u ot t == MIN)  u is fresh
         //    add definition v = ite(u or t == MIN, t, t-1)
         unsigned bv_sz = m_bv_util.get_bv_size(arg1);
         rational MIN;
         if (is_signed)
             MIN = -rational::power_of_two(bv_sz - 1);
         else
             MIN = rational(0);
         app * u;
         bool is_new = mk_fresh_uncnstr_var_for(f, arg1, arg2, u);
         app * r = m().mk_or(u, m().mk_eq(t, m_bv_util.mk_numeral(MIN, bv_sz)));
         if (m_mc && is_new)
             add_def(v, m().mk_ite(r, t, m_bv_util.mk_bv_sub(t, m_bv_util.mk_numeral(rational(1), bv_sz))));
         return r;
     }
     return nullptr;
 }
Example #11
0
void visit_form(Process *process, Obj *env, Obj *bytecodeObj, int *position, Obj *form) {
  if(eval_error) {
    return;
  }
  else if(form->tag == 'C') {
    if(form->car->car == NULL) {
      add_literal(bytecodeObj, position, nil);
    }
    else if(HEAD_EQ("quote")) {
      add_literal(bytecodeObj, position, form->car);
    }
    else if(HEAD_EQ("if")) {
      add_if(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("while")) {
      add_while(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("do")) {
      add_do(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("let")) {
      add_let(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("def")) {
      add_def(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("reset!")) {
      add_reset(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("ref")) {
      add_ref(process, env, bytecodeObj, position, form);
    }
    /* else if(HEAD_EQ("or")) { */
    /*   add_or(process, env, bytecodeObj, position, form); */
    /* } */
    else if(HEAD_EQ("not")) {
      add_not(process, env, bytecodeObj, position, form);
    }
    else if(HEAD_EQ("fn")) {
      Obj *lambda = obj_new_lambda(form->cdr->car, form_to_bytecode(process, env, form->cdr->cdr->car), env, form);
      add_literal(bytecodeObj, position, lambda);
    }
    else {
      add_call(process, env, bytecodeObj, position, form);
    }
  }
  else if(form->tag == 'Y') {
    add_lookup(bytecodeObj, position, form);
  }
  else {
    add_literal(bytecodeObj, position, form);
  }
  /* else { */
  /*   printf("Bytecode can't handle form: "); */
  /*   obj_print_cout(form); */
  /*   exit(1); */
  /* } */
}
Example #12
0
 app * process_add(family_id fid, decl_kind add_k, decl_kind sub_k, unsigned num, expr * const * args) {
     if (num == 0)
         return nullptr;
     unsigned i;
     expr * v = nullptr;
     for (i = 0; i < num; i++) {
         expr * arg = args[i];
         if (uncnstr(arg)) {
             v = arg;
             break;
         }
     }
     if (v == nullptr)
         return nullptr;
     app  * u;
     if (!mk_fresh_uncnstr_var_for(m().mk_app(fid, add_k, num, args), u))
         return u;
     if (!m_mc) 
         return u;
     ptr_buffer<expr> new_args;
     for (unsigned j = 0; j < num; j++) {
         if (j == i)
             continue;
         new_args.push_back(args[j]);
     }
     if (new_args.empty()) {
         add_def(v, u);
     }
     else {
         expr * rest;
         if (new_args.size() == 1)
             rest = new_args[0];
         else
             rest = m().mk_app(fid, add_k, new_args.size(), new_args.c_ptr());
         add_def(v, m().mk_app(fid, sub_k, u, rest));
     }
     return u;
 }
Example #13
0
 app * process_bv_app(func_decl * f, unsigned num, expr * const * args) {
     SASSERT(f->get_family_id() == m_bv_util.get_family_id());
     switch (f->get_decl_kind()) {
     case OP_BADD:
         return process_add(f->get_family_id(), OP_BADD, OP_BSUB, num, args);
     case OP_BMUL:
         return process_bv_mul(f, num, args);
     case OP_BSDIV:
     case OP_BUDIV:
     case OP_BSDIV_I:
     case OP_BUDIV_I:
         SASSERT(num == 2);
         return process_bv_div(f, args[0], args[1]);
     case OP_SLEQ:
         SASSERT(num == 2);
         return process_bv_le(f, args[0], args[1], true);
     case OP_ULEQ:
         SASSERT(num == 2);
         return process_bv_le(f, args[0], args[1], false);
     case OP_CONCAT:
         return process_concat(f, num, args);
     case OP_EXTRACT:
         SASSERT(num == 1);
         return process_extract(f, args[0]);
     case OP_BNOT:
         SASSERT(num == 1);
         if (uncnstr(args[0])) {
             app * r;
             if (!mk_fresh_uncnstr_var_for(f, num, args, r))
                 return r;
             if (m_mc)
                 add_def(args[0], m().mk_app(f, r));
             return r;
         }
         return nullptr;
     case OP_BOR:
         if (num > 0 && uncnstr(num, args)) {
             sort * s = m().get_sort(args[0]);
             app * r;
             if (!mk_fresh_uncnstr_var_for(f, num, args, r))
                 return r;
             if (m_mc)
                 add_defs(num, args, r, m_bv_util.mk_numeral(rational(0), s));
             return r;
         }
         return nullptr;
     default:
         return nullptr;
     }
 }
Example #14
0
 app * process_concat(func_decl * f, unsigned num, expr * const * args) {
     if (num == 0)
         return nullptr;
     if (!uncnstr(num, args))
         return nullptr;
     app * r;
     if (!mk_fresh_uncnstr_var_for(f, num, args, r))
         return r;
     if (m_mc) {
         unsigned i = num;
         unsigned low = 0;
         while (i > 0) {
             --i;
             expr * arg  = args[i];
             unsigned sz = m_bv_util.get_bv_size(arg);
             add_def(arg, m_bv_util.mk_extract(low + sz - 1, low, r));
             low += sz;
         }
     }
     return r;
 }
Example #15
0
int
main(int argc, char *argv[])
{
	int ch, i;

	args = NULL;
	cargs = nargs = 0;

	while ((ch = getopt(argc, argv, "cD:EgI:L:o:O:sU:l:")) != -1) {
		if (ch == 'l') {
			/* Gone too far. Back up and get out. */
			if (argv[optind - 1][0] == '-')
				optind -= 1;
			else
				optind -= 2;
			break;
		} else if (ch == '?')
			usage();
	}

	addarg("cc");
	addarg("-std=iso9899:1990");
	addarg("-pedantic");
	addarg("-m32");
	for (i = 1; i < optind; i++) {
	  /* "--" indicates end of options. Radar 3761967.  */
	  if (strcmp (argv[i], "--") == 0)
	    dash_dash_seen = 1;
	  /* White space is OK between -O and 1 or 2. Radar 3762315.  */
	  else if (strcmp (argv[i], "-O") == 0) {
	    if (i+1 < argc) {
	      if (strcmp (argv[i+1], "1") == 0 || strcmp (argv[i+1], "0") == 0) {
		combine_and_addarg(argv[i], argv[i+1]);
		i++;
	      } else
		addarg(argv[i]);
	    }
	  } else if (strcmp (argv[i], "-U") == 0) {
	    /* Record undefined macros.  */
	    record_undef (argv[i+1]);
	    addarg(argv[i]);
	    addarg(argv[i+1]);
	    i++;
	  } else if (strncmp (argv[i], "-U", 2) == 0) {
	    /* Record undefined macros.  */
	    record_undef (argv[i]+2);
	    addarg(argv[i]);
	  } else if (strcmp (argv[i], "-L") == 0 && i+1 < argc) {
	    combine_and_addarg(argv[i], argv[i+1]);
	    i++;
	  } else if (strcmp (argv[i], "-D") == 0) {
	    add_def (argv[i+1]);
	    i++;
	  } else if (strncmp (argv[i], "-D", 2) == 0)
	    add_def (argv[i]+2);
	  else
	    addarg(argv[i]);
	}
	while (i < argc) {
		if (strncmp(argv[i], "-l", 2) == 0) {
			if (argv[i][2] != '\0')
				addlib(argv[i++] + 2);
			else {
				if (argv[++i] == NULL)
					usage();
				addlib(argv[i++]);
			}
		}
		else if (strcmp (argv[i], "-L") == 0 && i+1 < argc) {
		    combine_and_addarg(argv[i], argv[i+1]);
		    i+=2;
		}
		else if (strcmp (argv[i], "--") == 0) {
		  dash_dash_seen = 1;
		} else
		  addarg(argv[i++]);
	}
	execv("/usr/bin/cc", args);
	err(1, "/usr/bin/cc");
}
Example #16
0
PUBLIC type tc_expr(tree t, env e)
#endif
{
     switch (t->x_kind) {
     case REF:
	  return ref_type((sym) t->x_tag, t->x_params, e, t);
	  
     case INGEN:
	  return ref_type((sym) t->x_tag,
			  list2(t->x_param1, t->x_param2), e, t);

     case PREGEN:
	  return ref_type((sym) t->x_tag, list1(t->x_param), e, t);

     case NUMBER:
	  return nat_type;
	  
     case SEXPR: {
	  def d;
	  frame params;

	  if (! open_sref(t->x_ref, e, &d, &params))
	       return err_type;

	  if ((tok) t->x_ref->x_sref_decor != empty) {
	       tc_error(t->x_loc, "Decoration ignored in schema reference");
	       tc_e_etc("Expression: %z", t);
	       tc_e_end();
	  }

	  if (t->x_ref->x_sref_renames != nil) {
	       tc_error(t->x_loc, "Renaming ignored in schema reference");
	       tc_e_etc("Expression: %z", t);
	       tc_e_end();
	  }

	  if (! aflag && d->d_abbrev)
	       return mk_power(mk_abbrev(d, params));
	  else
	       return mk_power(seal(mk_sproduct(d->d_schema), params));
     }

     case POWER: {
	  type tt1, tt2;	  
	  if (! anal_power(tt1 = tc_expr(t->x_arg, e), &tt2, t->x_arg)) {
	       tc_error(t->x_loc, "Argument of \\power must be a set");
	       tc_e_etc("Expression: %z", t);
	       tc_e_etc("Arg type:   %t", tt1);
	       tc_e_end();
	  }
	  return mk_power(mk_power(tt2));
     }
	   
     case TUPLE : {
	  type a[MAX_ARGS];
	  int n = 0;
	  tree u;
	       
	  for (u = t->x_elements; u != nil; u = cdr(u)) {
	       if (n >= MAX_ARGS)
		    panic("tc_expr - tuple too big");
	       a[n++] = tc_expr(car(u), e);
	  }
	  return mk_cproduct(n, a);
     }

     case CROSS: {
	  type a[MAX_ARGS];
	  type tt1, tt2;
	  int n = 0;
	  tree u;

	  for (u = t->x_factors; u != nil; u = cdr(u)) {
	       if (n >= MAX_ARGS)
		    panic("tc_expr - product too big");
	       tt1 = tc_expr(car(u), e);
	       if (! anal_power(tt1, &tt2, car(u))) {
		    tc_error(t->x_loc,
			     "Argument %d of \\cross must be a set", n+1);
		    tc_e_etc("Expression: %z", t);
		    tc_e_etc("Arg %d type: %t", n+1, tt1);
		    tc_e_end();
	       }
	       a[n++] = tt2;
	  }
	  return mk_power(mk_cproduct(n, a));
     }

     case EXT:
     case SEQ:
     case BAG: {
	  type elem_type;
	  type tt;
	  tree u;

	  if (t->x_elements == nil)
	       elem_type = new_typevar(t);
	  else {
	       elem_type = tc_expr(car(t->x_elements), e);
	       for (u = cdr(t->x_elements); u != nil; u = cdr(u)) {
		    if (unify(elem_type, tt = tc_expr(car(u), e)))
			 elem_type = type_union(elem_type, arid, tt, arid);
		    else {
			 tc_error(t->x_loc, "Type mismatch in %s display",
				  (t->x_kind == EXT ? "set" :
				   t->x_kind == SEQ ? "sequence" : "bag"));
			 tc_e_etc("Expression: %z", car(u));
			 tc_e_etc("Has type:   %t", tt);
			 tc_e_etc("Expected:   %t", elem_type);
			 tc_e_end();
		    }
	       }
	  }
	  switch (t->x_kind) {
	  case EXT:
	       return mk_power(elem_type);
	  case SEQ:
	       return (aflag ? rel_type(num_type, elem_type) 
			     : mk_seq(elem_type));
	  case BAG:
	       return (aflag ? rel_type(elem_type, num_type) 
			     : mk_bag(elem_type));
	  }
     }

     case THETA: 
	  return theta_type(t, e, (type) NULL, t);

     case BINDING: {
	  tree u;
	  env e1 = new_env(e);
	  for (u = t->x_elements; u != nil; u = cdr(u))
	       add_def(VAR, (sym) car(u)->x_lhs, 
		       tc_expr(car(u)->x_rhs, e), e1);
	  return mk_sproduct(mk_schema(e1));
     }

     case SELECT: {
	  type a = tc_expr(t->x_arg, e);

	  if (type_kind(a) != SPRODUCT) {
	       tc_error(t->x_loc,
			"Argument of selection must have schema type");
	       tc_e_etc("Expression: %z", t);
	       tc_e_etc("Arg type:   %t", a);
	       tc_e_end();
	       mark_error();
	       return err_type;
	  }

	  switch (t->x_field->x_kind) {
	  case IDENT:
	       return (comp_type(a, (sym) t->x_field, t, t->x_loc));

	  case THETA:
	       return (theta_type(t->x_field, e, a, t));

	  default:
	       bad_tag("tc_expr.SELECT", t->x_field->x_kind);
	       return (type) NULL;
	  }
     }

     case APPLY:
	  return tc_apply(APPLY, t, t->x_arg1, t->x_arg2, e);

     case INOP:
	  return tc_apply(INOP, t, simply(t->x_op, t->x_loc), 
			  pair(t->x_rand1, t->x_rand2), e);

     case POSTOP:
	  return tc_apply(POSTOP, t, simply(t->x_op, t->x_loc), 
			  t->x_rand, e);

     case LAMBDA: {
	  env e1 = tc_schema(t->x_bvar, e);
	  type dom = tc_expr(char_tuple(t->x_bvar), e1);
	  type ran = tc_expr(t->x_body, e1);
	  return (aflag ? rel_type(dom, ran) : mk_pfun(dom, ran));
     }
    
     case COMP:
     case MU: {
	  env e1 = tc_schema(t->x_bvar, e);
	  type a = tc_expr(exists(t->x_body) ? the(t->x_body) :
			   char_tuple(t->x_bvar), e1);
	  return (t->x_kind == COMP ? mk_power(a) : a);
     }

     case LETEXPR:
	  return tc_expr(t->x_body, tc_letdefs(t->x_defs, e));

     case IF: {
	  type a, b;
	  tc_pred(t->x_if, e);
	  a = tc_expr(t->x_then, e);
	  b = tc_expr(t->x_else, e);
	  if (unify(a, b))
	       return type_union(a, arid, b, arid);
	  else {
	       tc_error(t->x_loc,
			"Type mismatch in conditional expression");
	       tc_e_etc("Expression: %z", t);
	       tc_e_etc("Then type:  %t", a);
	       tc_e_etc("Else type:  %t", b);
	       tc_e_end();
	       return err_type;
	  }
     }

     default:
	  bad_tag("tc_expr", t->x_kind);
	  /* dummy */ return (type) NULL;
     }
}
int
main(int argc, char *argv[])
{
	char exec_path[PATH_MAX];
	char link_path[PATH_MAX];
	uint32_t exec_path_size = sizeof(exec_path);
	char *compiler_path = exec_path;
	char *lastslash;
	int link = 1;
	int inputs = 0;
	int verbose = 0;
        int m_32_64_set = 0;

	/* Find the path to this executable. */
	if (_NSGetExecutablePath(exec_path, &exec_path_size))
		memcpy(exec_path, "/usr/bin/c99", sizeof("/usr/bin/c99"));
	if (realpath(exec_path, link_path))
		compiler_path = link_path;

	/* Chop off c99 and replace it with clang. */
	lastslash = strrchr(compiler_path, '/');
	if (!lastslash)
		err(EX_OSERR, "unexpected path name: %s", compiler_path);
	strcpy(lastslash+1, "clang");

	addarg(compiler_path);
	addarg("-std=iso9899:1999");
	addarg("-pedantic");
	addarg("-Wextra-tokens"); /* Radar 4205857 */
	addarg("-Wno-error=return-type"); /* Radar 13535926 */
	addarg("-Wstatic-in-inline"); /* Radar 12866627 */
	addarg("-Wignored-qualifiers"); /* Radar 13535742 */
	addarg("-fmath-errno");  /* Radar 4011622 */
	addarg("-fno-blocks");  /* Radar 13118788 */

	for (;;)
	  {
	    int ch = getopt(argc, argv, "cD:EgI:L:o:O:sU:W:l:");
	    if (optind >= argc && ch == -1)
	      break;
	    switch (ch)
	      {
	      case 'c':
		addarg ("-c");
		link = 0;
		break;
	      case 'D':
		add_def (optarg);
		break;
	      case 'E':
		addarg ("-E");
		link = 0;
		break;
	      case 'g':
		addarg ("-g");
		break;
	      case 'I':
		combine_and_addarg ("-I", optarg);
		break;
	      case 'L':
		combine_and_addarg ("-L", optarg);
		break;
	      case 'o':
		addarg ("-o");
		addarg (optarg);
		break;
	      case 'O':
		combine_and_addarg ("-O", optarg);
		break;
	      case 's':
		addarg ("-s");
		break;
	      case 'U':
		record_undef (optarg);
		combine_and_addarg ("-U", optarg);
		break;
	      case 'W':
		if (strcmp (optarg, "32") == 0) {
		  addarg ("-m32");
                  m_32_64_set = 1;
                } else if (strcmp (optarg, "64") == 0) {
		  addarg ("-m64");
                  m_32_64_set = 1;
		} else if (strcmp (optarg, "verbose") == 0)
		  {
		    addarg ("-v");
		    verbose = 1;
		  }
		else
		  errx(EX_USAGE, "invalid argument `%s' to -W", optarg);
		break;
	      case 'l':
		addlib (optarg);
		break;
	      case -1:
		if (strcmp (argv[optind-1], "--") == 0)
		  {
		    while (optind < argc)
		      {
			if (argv[optind][0] == '-')
			  combine_and_addarg ("./", argv[optind]);
			else
			  addarg (argv[optind]);
			inputs++;
			optind++;
		      }
		  }
		else
		  {
		    addarg (argv[optind++]);
		    inputs++;
		  }
		break;
	      case '?':
		usage ();
		break;
	      }
	  }
        /* If the user didn't set the width, set it from the current
           host architecture. */
#ifdef __LP64__
        if (!m_32_64_set)
          addarg("-m64");
#else
        if (!m_32_64_set)
          addarg("-m32");
#endif

	if (link && inputs > 0) {
	  addarg("-liconv");
	}
	if (verbose)
	  {
	    int i;
	    for (i = 0; args[i]; i++)
	      printf ("\"%s\" ", args[i]);
	    putchar ('\n');
	  }

        /* Exec clang. */
	execv(compiler_path, args);
	err(EX_OSERR, "failed to exec compiler %s", compiler_path);
}
Example #18
0
 app * process_eq(func_decl * f, expr * arg1, expr * arg2) {
     expr * v;
     expr * t;
     if (uncnstr(arg1)) {
         v = arg1;
         t = arg2;
     }
     else if (uncnstr(arg2)) {
         v = arg2;
         t = arg1;
     }
     else {
         return nullptr;
     }
     
     sort * s = m().get_sort(arg1);
     
     // Remark:
     // I currently do not support unconstrained vars that have
     // uninterpreted sorts, for the following reasons:
     // - Soundness
     //     (forall ((x S) (y S)) (= x y))
     //     (not (= c1 c2))
     //
     //   The constants c1 and c2 have only one occurrence in
     //   the formula above, but they are not really unconstrained.
     //   The quantifier forces S to have interpretations of size 1.
     //   If we replace (= c1 c2) with fresh k. The formula will
     //   become satisfiable. 
     //
     // - Even if the formula is quantifier free, I would still
     //   have to build an interpretation for the eliminated 
     //   variables.
     //
     if (!m().is_fully_interp(s))
         return nullptr;
     
     // If the interpreted sort has only one element,
     // then it is unsound to eliminate the unconstrained variable in the equality
     sort_size sz = s->get_num_elements();
     
     if (sz.is_finite() && sz.size() <= 1)
         return nullptr;
     
     if (!m_mc) {
         // easy case, model generation is disabled.
         app * u;
         mk_fresh_uncnstr_var_for(f, arg1, arg2, u);
         return u;
     }
     
     expr_ref d(m());
     if (mk_diff(t, d)) {
         app * u;
         if (!mk_fresh_uncnstr_var_for(f, arg1, arg2, u))
             return u;
         add_def(v, m().mk_ite(u, t, d));
         return u;
     }
     return nullptr;
 }
Example #19
0
 app * process_basic_app(func_decl * f, unsigned num, expr * const * args) {
     SASSERT(f->get_family_id() == m().get_basic_family_id());
     switch (f->get_decl_kind()) {
     case OP_ITE:
         SASSERT(num == 3);
         if (uncnstr(args[1]) && uncnstr(args[2])) {
             app * r;
             if (!mk_fresh_uncnstr_var_for(f, num, args, r))
                 return r;
             add_def(args[1], r);
             add_def(args[2], r);
             return r;
         }
         if (uncnstr(args[0]) && uncnstr(args[1])) {
             app * r;
             if (!mk_fresh_uncnstr_var_for(f, num, args, r))
                 return r;
             add_def(args[0], m().mk_true());
             add_def(args[1], r);
             return r;
         }
         if (uncnstr(args[0]) && uncnstr(args[2])) {
             app * r;
             if (!mk_fresh_uncnstr_var_for(f, num, args, r))
                 return r;
             add_def(args[0], m().mk_false());
             add_def(args[2], r);
             return r;
         }
         return nullptr;
     case OP_NOT:
         SASSERT(num == 1);
         if (uncnstr(args[0])) {
             app * r;
             if (!mk_fresh_uncnstr_var_for(f, num, args, r))
                 return r;
             if (m_mc)
                 add_def(args[0], m().mk_not(r));
             return r;
         }
         return nullptr;
     case OP_AND:
         if (num > 0 && uncnstr(num, args)) {
             app * r;
             if (!mk_fresh_uncnstr_var_for(f, num, args, r))
                 return r;
             if (m_mc)
                 add_defs(num, args, r, m().mk_true());
             return r;
         }
         return nullptr;
     case OP_OR:
         if (num > 0 && uncnstr(num, args)) {
             app * r;
             if (!mk_fresh_uncnstr_var_for(f, num, args, r))
                 return r;
             if (m_mc)
                 add_defs(num, args, r, m().mk_false());
             return r;
         }
         return nullptr;
     case OP_IFF:
     case OP_EQ:
         SASSERT(num == 2);
         return process_eq(f, args[0], args[1]);
     default:
         return nullptr;
     }
 }