Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Refactored the inferrer and related subsystems

  • Loading branch information...
commit 7f39aac0d0be4999b155eaf12f54cdc61adeed82 1 parent 397e0e5
@mwolf76 authored
View
4 src/model/analyzer.cc
@@ -376,7 +376,9 @@ void Analyzer::walk_leaf(const Expr_ptr expr)
if (f_tm.is_boolean(tp)) {
res = EXPR_BOOLEAN;
}
- else if (f_tm.is_integer(tp)) {
+ else if (f_tm.is_int_const(tp) ||
+ f_tm.is_fxd_const(tp) ||
+ f_tm.is_algebraic(tp)) {
res = EXPR_ALGEBRAIC;
}
else assert(0);
View
452 src/model/inferrer.cc
@@ -6,7 +6,9 @@
* type inference engine. The type inference engine is implemented
* using a simple walker pattern: (a) on preorder, return true if the
* node has not yet been visited; (b) always do in-order (for binary
- * nodes); (c) perform proper type checking in post-order hooks.
+ * nodes); (c) perform proper type checking in post-order
+ * hooks. Implicit conversion rules are designed to follow as closely
+ * as possible section 6.3.1 of iso/iec 9899:1999 (aka C99) standard.
*
* Copyright (C) 2012 Marco Pensallorto < marco AT pensallorto DOT gmail DOT com >
*
@@ -41,15 +43,6 @@ Inferrer::Inferrer(ModelMgr& owner)
, f_ctx_stack()
, f_owner(owner)
{
- ExprMgr& em = f_owner.em();
-
- /* build predefined type sets, used in error reporting */
- f_integer_or_boolean.push_back(em.make_integer_type());
- f_integer_or_boolean.push_back(em.make_boolean_type());
-
- f_boolean = em.make_boolean_type();
- f_integer = em.make_integer_type();
-
DEBUG << "Created Inferrer @" << this << endl;
}
@@ -57,10 +50,8 @@ Inferrer::~Inferrer()
{ DEBUG << "Destroying Inferrer @" << this << endl; }
/* this function is not memoized by design, for a memoized wrapper use type() */
-Type_ptr Inferrer::process(Expr_ptr ctx, Expr_ptr body)
+Type_ptr Inferrer::process(Expr_ptr ctx, Expr_ptr body, expected_t expected)
{
- Type_ptr res = NULL;
-
// remove previous results
f_type_stack.clear();
f_ctx_stack.clear();
@@ -69,16 +60,12 @@ Type_ptr Inferrer::process(Expr_ptr ctx, Expr_ptr body)
f_ctx_stack.push_back(ctx);
// invoke walker on the body of the expr to be processed
- // DRIVEL << "Determining type for expression " << ctx << "::" << body << endl;
(*this)(body);
assert(1 == f_type_stack.size());
- res = f_type_stack.back();
-
- // DRIVEL << "Type for " << ctx << "::" << body
- // << " is " << res << endl;
- return res;
+ /* possibly throws an exception */
+ return check_expected_type(expected);
}
void Inferrer::pre_hook()
@@ -101,6 +88,33 @@ void Inferrer::debug_hook()
#endif
}
+Type_ptr Inferrer::check_expected_type(expected_t expected)
+{
+ TypeMgr& tm = f_owner.tm();
+ Type_ptr type = f_type_stack.back(); f_type_stack.pop_back();
+
+ if ((tm.is_boolean(type) && (0 == (expected & TP_BOOLEAN))) ||
+
+ (tm.is_int_const(type) && (0 == (expected & TP_INT_CONST))) ||
+ (tm.is_fxd_const(type) && (0 == (expected & TP_FXD_CONST))) ||
+
+ (tm.is_signed_algebraic(type) && (0 == (expected & TP_SIGNED_INT))) ||
+ (tm.is_unsigned_algebraic(type) && (0 == (expected & TP_UNSIGNED_INT))) ||
+
+ (tm.is_signed_fixed_algebraic(type) && (0 == (expected & TP_SIGNED_FXD))) ||
+ (tm.is_unsigned_fixed_algebraic(type) && (0 == (expected & TP_UNSIGNED_FXD))) ||
+
+ (tm.is_enum(type) && (0 == (expected & TP_ENUM))) ||
+
+ (tm.is_array(type) && (0 == (expected & TP_ARRAY)))) {
+
+ throw BadType(type->repr(), expected);
+ }
+
+ assert (NULL != type);
+ return type;
+}
+
bool Inferrer::walk_F_preorder(const Expr_ptr expr)
{ return cache_miss(expr); }
void Inferrer::walk_F_postorder(const Expr_ptr expr)
@@ -285,14 +299,14 @@ bool Inferrer::walk_lshift_preorder(const Expr_ptr expr)
bool Inferrer::walk_lshift_inorder(const Expr_ptr expr)
{ return true; }
void Inferrer::walk_lshift_postorder(const Expr_ptr expr)
-{ walk_binary_bitwise_postorder(expr); }
+{ walk_binary_shift_postorder(expr); }
bool Inferrer::walk_rshift_preorder(const Expr_ptr expr)
{ return cache_miss(expr); }
bool Inferrer::walk_rshift_inorder(const Expr_ptr expr)
{ return true; }
void Inferrer::walk_rshift_postorder(const Expr_ptr expr)
-{ walk_binary_bitwise_postorder(expr); }
+{ walk_binary_shift_postorder(expr); }
bool Inferrer::walk_eq_preorder(const Expr_ptr expr)
{ return cache_miss(expr); }
@@ -397,17 +411,8 @@ void Inferrer::walk_subscript_postorder(const Expr_ptr expr)
{
TypeMgr& tm = f_owner.tm();
- Type_ptr rhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_integer(rhs) &&
- !tm.is_algebraic(rhs))
- throw BadType(rhs->repr(), f_integer, expr);
-
- Type_ptr lhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_array(lhs))
- throw BadType(lhs->repr(), "array", expr);
-
/* return wrapped type */
- f_type_stack.push_back(tm.as_array(lhs)->of());
+ f_type_stack.push_back(tm.as_array(check_array())->of());
}
void Inferrer::walk_leaf(const Expr_ptr expr)
@@ -418,12 +423,17 @@ void Inferrer::walk_leaf(const Expr_ptr expr)
// cache miss took care of the stack already
if (! cache_miss(expr)) return;
- // a numeric constant is an integer
- if (em.is_numeric(expr)) {
- Type_ptr res = tm.find_integer();
- f_type_stack.push_back(res);
+ // is an integer const ..
+ if (em.is_int_numeric(expr)) {
+ f_type_stack.push_back(tm.find_int_const());
}
+ // .. or a fixed const
+ else if (em.is_fxd_numeric(expr)) {
+ f_type_stack.push_back(tm.find_fxd_const());
+ }
+
+ // .. or a symbol
else if (em.is_identifier(expr)) {
ISymbol_ptr symb = resolve(f_ctx_stack.back(), expr);
assert(symb);
@@ -479,37 +489,15 @@ ISymbol_ptr Inferrer::resolve(const Expr_ptr ctx, const Expr_ptr frag)
// fun: temporal -> temporal
void Inferrer::walk_unary_temporal_postorder(const Expr_ptr expr)
{
- TypeMgr& tm = f_owner.tm();
-
- const Type_ptr top = f_type_stack.back(); f_type_stack.pop_back();
-
- if (!tm.is_boolean(top)) {
- throw BadType(top->repr(), f_boolean, expr);
- }
-
- // f_type_stack.push_back(tm.find_boolean());
- memoize_canonical_result( expr, tm.find_boolean());
+ memoize_canonical_result( expr, check_boolean());
}
// fun: temporal x temporal -> temporal
void Inferrer::walk_binary_temporal_postorder(const Expr_ptr expr)
{
- TypeMgr& tm = f_owner.tm();
-
- { // RHS
- const Type_ptr top = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_boolean(top))
- throw BadType(top->repr(), f_boolean, expr);
- }
-
- { // LHS
- const Type_ptr top = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_boolean(top))
- throw BadType(top->repr(), f_boolean, expr);
- }
-
- // f_type_stack.push_back(tm.find_boolean());
- memoize_canonical_result( expr, tm.find_boolean());
+ check_boolean();
+ memoize_canonical_result( expr,
+ check_boolean());
}
// fun: T -> T
@@ -519,133 +507,38 @@ void Inferrer::walk_unary_fsm_postorder(const Expr_ptr expr)
// fun: arithm -> arithm
void Inferrer::walk_unary_arithmetical_postorder(const Expr_ptr expr)
{
- TypeMgr& tm = f_owner.tm();
-
- const Type_ptr top = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_integer(top) &&
- !tm.is_algebraic(top)) {
- throw BadType(top->repr(), f_integer, expr);
- }
-
- if (tm.is_integer(top)) {
- // f_type_stack.push_back(tm.find_integer());
- memoize_canonical_result( expr, tm.find_integer());
- return;
- }
-
- if (tm.is_algebraic(top)) {
- memoize_canonical_result( expr, top);
- return;
- }
-
- assert( false ); // unreachable
+ memoize_canonical_result( expr, check_arithmetical());
}
// fun: logical -> logical
void Inferrer::walk_unary_logical_postorder(const Expr_ptr expr)
{
- TypeMgr& tm = f_owner.tm();
-
- const Type_ptr top = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_boolean(top)) {
- throw BadType(top->repr(), f_boolean, expr);
- }
-
- memoize_canonical_result( expr, tm.find_boolean());
+ memoize_canonical_result( expr, check_boolean());
}
// fun: arithm, arithm -> arithm
void Inferrer::walk_binary_arithmetical_postorder(const Expr_ptr expr)
{
TypeMgr& tm = f_owner.tm();
-
- const Type_ptr rhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_integer(rhs) && !tm.is_algebraic(rhs)) {
- throw BadType(rhs->repr(), f_integer, expr);
- }
-
- const Type_ptr lhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_integer(lhs) && !tm.is_algebraic(lhs)) {
- throw BadType(lhs->repr(), f_integer, expr);
- }
-
- // both ops integers -> integer
- if (tm.is_integer(lhs) && (tm.is_integer(rhs))) {
- memoize_canonical_result(expr, tm.find_integer());
- return;
- }
-
- // one op algebraic, possibly both.
- unsigned rhs_width = tm.is_algebraic(rhs)
- ? tm.as_algebraic(rhs)->width()
- : 0;
- bool rhs_is_signed = tm.is_algebraic(rhs)
- ? tm.as_algebraic(rhs)->is_signed()
- : false;
-
- unsigned lhs_width = tm.is_algebraic(lhs)
- ? tm.as_algebraic(lhs)->width()
- : 0;
- bool lhs_is_signed = tm.is_algebraic(lhs)
- ? tm.as_algebraic(lhs)->is_signed()
- : false;
-
- /* max */
- unsigned width = rhs_width < lhs_width
- ? lhs_width
- : rhs_width
- ;
- bool is_signed = rhs_is_signed || lhs_is_signed;
-
- // if both are algebraic they have to agree on signedness too.
- if ((0 < rhs_width) && (0 < lhs_width)) {
- assert ( tm.as_algebraic(rhs)->is_signed() ==
- tm.as_algebraic(lhs)->is_signed() );
- }
-
- memoize_canonical_result( expr, (is_signed
- ? tm.find_signed(width)
- : tm.find_unsigned(width)));
+ memoize_canonical_result( expr,
+ tm.arithmetical_result_type( check_arithmetical(),
+ check_arithmetical()));
}
// fun: logical x logical -> logical
void Inferrer::walk_binary_logical_postorder(const Expr_ptr expr)
{
- TypeMgr& tm = f_owner.tm();
-
- const Type_ptr rhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_boolean(rhs)) {
- throw BadType(rhs->repr(), f_boolean, expr);
- }
-
- const Type_ptr lhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_boolean(lhs)) {
- throw BadType(lhs->repr(), f_boolean, expr);
- }
-
- // boolean
- assert(tm.is_boolean(lhs) && tm.is_boolean(rhs));
-
- memoize_canonical_result(expr, tm.find_boolean());
+ check_boolean();
+ memoize_canonical_result(expr,
+ check_boolean());
}
void Inferrer::walk_binary_logical_or_bitwise_postorder(const Expr_ptr expr)
{
TypeMgr& tm = f_owner.tm();
- const Type_ptr rhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_boolean(rhs) &&
- !tm.is_integer(rhs) &&
- !tm.is_algebraic(rhs)) {
- throw BadType(rhs->repr(), f_integer_or_boolean, expr);
- }
-
- const Type_ptr lhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_boolean(lhs) &&
- !tm.is_integer(lhs) &&
- !tm.is_integer(rhs)) {
- throw BadType(lhs->repr(), f_integer_or_boolean, expr);
- }
+ const Type_ptr rhs = check_boolean_or_integer();
+ const Type_ptr lhs = check_boolean_or_integer();
// both ops boolean -> boolean
if (tm.is_boolean(lhs) && tm.is_boolean(rhs)) {
@@ -653,108 +546,17 @@ void Inferrer::walk_binary_logical_or_bitwise_postorder(const Expr_ptr expr)
return;
}
- // both ops integers -> integer
- if (tm.is_integer(lhs) && (tm.is_integer(rhs))) {
- memoize_canonical_result( expr, tm.find_integer());
- return;
- }
-
- // one op algebraic, possibly both.
- unsigned rhs_width = tm.is_algebraic(rhs)
- ? tm.as_algebraic(rhs)->width()
- : 0;
- bool rhs_is_signed = tm.is_algebraic(rhs)
- ? tm.as_algebraic(rhs)->is_signed()
- : false;
-
- unsigned lhs_width = tm.is_algebraic(lhs)
- ? tm.as_algebraic(lhs)->width()
- : 0;
- bool lhs_is_signed = tm.is_algebraic(lhs)
- ? tm.as_algebraic(lhs)->is_signed()
- : false;
-
- /* max */
- unsigned width = rhs_width < lhs_width
- ? lhs_width
- : rhs_width
- ;
- bool is_signed = rhs_is_signed || lhs_is_signed;
-
- // if both are algebraic they have to agree on signedness too.
- if ((0 < rhs_width) && (0 < lhs_width)) {
- assert ( tm.as_algebraic(rhs)->is_signed() ==
- tm.as_algebraic(lhs)->is_signed() );
- }
-
- memoize_canonical_result(expr, (is_signed
- ? tm.find_signed(width)
- : tm.find_unsigned(width)));
+ memoize_canonical_result( expr,
+ tm.bitwise_result_type( rhs, lhs ));
}
-// fun: (A/L) x (A/L) -> A/L
-void Inferrer::walk_binary_bitwise_postorder(const Expr_ptr expr)
+/* specialized for shift ops (use rhs) */
+void Inferrer::walk_binary_shift_postorder(const Expr_ptr expr)
{
- TypeMgr& tm = f_owner.tm();
-
- const Type_ptr rhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_integer(rhs) &&
- !tm.is_algebraic(rhs) &&
- !tm.is_boolean(rhs)) {
- throw BadType(rhs->repr(), f_integer, expr);
- }
-
- const Type_ptr lhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_integer(lhs) &&
- !tm.is_algebraic(lhs) &&
- !tm.is_boolean(lhs)) {
- throw BadType(lhs->repr(), f_integer, expr);
- }
-
- // both ops boolean -> boolean
- if (tm.is_boolean(lhs) && tm.is_boolean(rhs)) {
- memoize_canonical_result( expr, tm.find_boolean());
- return;
- }
-
- // both ops integers -> integer
- if (tm.is_integer(lhs) && (tm.is_integer(rhs))) {
- memoize_canonical_result( expr, tm.find_integer());
- return;
- }
-
- // one op algebraic, possibly both.
- unsigned rhs_width = tm.is_algebraic(rhs)
- ? tm.as_algebraic(rhs)->width()
- : 0;
- bool rhs_is_signed = tm.is_algebraic(rhs)
- ? tm.as_algebraic(rhs)->is_signed()
- : false;
-
- unsigned lhs_width = tm.is_algebraic(lhs)
- ? tm.as_algebraic(lhs)->width()
- : 0;
- bool lhs_is_signed = tm.is_algebraic(lhs)
- ? tm.as_algebraic(lhs)->is_signed()
- : false;
-
- /* max */
- unsigned width = rhs_width < lhs_width
- ? lhs_width
- : rhs_width
- ;
- bool is_signed = rhs_is_signed || lhs_is_signed;
-
- // if both are algebraic they have to agree on signedness too.
- if ((0 < rhs_width) && (0 < lhs_width)) {
- assert ( tm.as_algebraic(rhs)->is_signed() ==
- tm.as_algebraic(lhs)->is_signed() );
- }
-
- memoize_canonical_result( expr, (is_signed
- ? tm.find_signed(width)
- : tm.find_unsigned(width)));
+ Type_ptr rhs = check_arithmetical();
+ check_arithmetical(); // discard lhs
+ memoize_canonical_result( expr, rhs);
}
// fun: arithmetical x arithmetical -> boolean
@@ -762,15 +564,8 @@ void Inferrer::walk_binary_relational_postorder(const Expr_ptr expr)
{
TypeMgr& tm = f_owner.tm();
- const Type_ptr rhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_integer(rhs) && !tm.is_algebraic(rhs)) {
- throw BadType(rhs->repr(), f_integer, expr);
- }
-
- const Type_ptr lhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_integer(lhs) && !tm.is_algebraic(lhs)) {
- throw BadType(lhs->repr(), f_integer, expr);
- }
+ check_arithmetical();
+ check_arithmetical();
memoize_canonical_result( expr, tm.find_boolean());
}
@@ -780,49 +575,30 @@ void Inferrer::walk_binary_boolean_or_relational_postorder(const Expr_ptr expr)
{
TypeMgr& tm = f_owner.tm();
- const Type_ptr rhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_boolean(rhs) &&
- !tm.is_algebraic(rhs) &&
- !tm.is_integer(rhs)) {
- throw BadType(rhs->repr(), f_integer_or_boolean, expr);
- }
+ const Type_ptr rhs = check_boolean_or_integer();
+ const Type_ptr lhs = check_boolean_or_integer();
- const Type_ptr lhs = f_type_stack.back(); f_type_stack.pop_back();
- if (!tm.is_boolean(lhs) &&
- !tm.is_algebraic(lhs) &&
- !tm.is_integer(lhs)) {
- throw BadType(lhs->repr(), f_integer_or_boolean, expr);
- }
-
- // algebraic or integer
- if ((tm.is_integer(lhs) || tm.is_algebraic(lhs)) &&
- (tm.is_integer(rhs) || tm.is_algebraic(rhs))) {
+ // both ops boolean -> boolean
+ if (tm.is_boolean(lhs) && tm.is_boolean(rhs)) {
memoize_canonical_result( expr, tm.find_boolean());
return;
}
- // boolean
- if (tm.is_boolean(lhs) && tm.is_boolean(rhs)) {
+ // both arithmetical -> boolean
+ else if (!tm.is_boolean(lhs) && !tm.is_boolean(rhs)) {
memoize_canonical_result( expr, tm.find_boolean());
return;
}
- throw BadType(rhs->repr(), lhs->repr(), expr);
+ else throw TypeMismatch( lhs->repr(), rhs->repr() );
}
// fun: boolean x T -> T
void Inferrer::walk_ternary_cond_postorder(const Expr_ptr expr)
{
- TypeMgr& tm = f_owner.tm();
-
- const Type_ptr rhs = f_type_stack.back(); f_type_stack.pop_back();
- const Type_ptr lhs = f_type_stack.back(); f_type_stack.pop_back();
-
- // condition is always boolean
- if (!tm.is_boolean(lhs)) {
- throw BadType(lhs->repr(), f_boolean, expr);
- }
+ Type_ptr rhs = f_type_stack.back(); f_type_stack.pop_back();
+ check_boolean(); // condition
memoize_canonical_result(expr, rhs);
}
@@ -830,78 +606,11 @@ void Inferrer::walk_ternary_cond_postorder(const Expr_ptr expr)
// fun: (boolean ? T) x T -> T
void Inferrer::walk_ternary_ite_postorder(const Expr_ptr expr)
{
- TypeMgr& tm = f_owner.tm();
-
const Type_ptr rhs = f_type_stack.back(); f_type_stack.pop_back();
const Type_ptr lhs = f_type_stack.back(); f_type_stack.pop_back();
- unsigned width =0;
- bool is_signed;
-
- // boolean
- if (tm.is_boolean(lhs) && tm.is_boolean(rhs)) {
- memoize_canonical_result( expr, tm.find_boolean());
- return;
- }
-
- // ITEs are forced to be algebraic, even when both children are
- // integers. Actual type is first customarily inferred from
- // children. If no algebraic is found among children, searches
- // backwards in the type stack.
- unsigned rhs_width = tm.is_algebraic(rhs)
- ? tm.as_algebraic(rhs)->width()
- : 0;
- bool rhs_is_signed = tm.is_algebraic(rhs)
- ? tm.as_algebraic(rhs)->is_signed()
- : false;
-
- unsigned lhs_width = tm.is_algebraic(lhs)
- ? tm.as_algebraic(lhs)->width()
- : 0;
- bool lhs_is_signed = tm.is_algebraic(lhs)
- ? tm.as_algebraic(lhs)->is_signed()
- : false;
-
- /* max */
- width = rhs_width < lhs_width
- ? lhs_width
- : rhs_width
- ;
-
- if (0 != width) {
- is_signed = rhs_is_signed || lhs_is_signed;
-
- // if both are algebraic they have to agree on signedness too.
- if ((0 < rhs_width) && (0 < lhs_width)) {
- assert ( tm.as_algebraic(rhs)->is_signed() ==
- tm.as_algebraic(lhs)->is_signed() );
- }
- }
-
- /* fallback case: inspect type stack backwards */
- else {
- /* map canonicity w.r.t. compiler rewrites should help here */
- assert (0 < f_type_stack.size());
-
- TypeStack::reverse_iterator ri = f_type_stack.rbegin();
- do {
- Type_ptr type = (*ri);
- if (tm.is_algebraic(type)) {
-
- width = tm.as_algebraic(type)->width();
- is_signed = tm.as_algebraic(type)->is_signed();
-
- break;
- }
-
- ++ ri;
- } while ( ri != f_type_stack.rend() );
- }
-
- assert (0 < width);
- memoize_canonical_result(expr, is_signed
- ? tm.find_signed(width)
- : tm.find_unsigned(width));
+ if (lhs != rhs) throw TypeMismatch( lhs->repr(), rhs->repr() );
+ memoize_canonical_result(expr, rhs);
}
/* memoize (canonical) and return */
@@ -936,7 +645,8 @@ Expr_ptr Inferrer::find_canonical_expr(Expr_ptr expr)
em.is_ite(expr) ||
em.is_cond(expr) ||
em.is_identifier(expr) ||
- em.is_numeric(expr)) {
+ em.is_int_numeric(expr) ||
+ em.is_fxd_numeric(expr)) {
return expr;
}
View
48 src/model/inferrer.hh
@@ -45,7 +45,7 @@ public:
Type_ptr type(FQExpr& fqexpr);
// walker toplevel
- Type_ptr process(Expr_ptr ctx, Expr_ptr body);
+ Type_ptr process(Expr_ptr ctx, Expr_ptr body, expected_t expected = TP_BOOLEAN);
protected:
void pre_hook();
@@ -197,6 +197,44 @@ private:
ISymbol_ptr resolve(const Expr_ptr ctx, const Expr_ptr id);
+ /* throws a BadType exception if toplevel type does not match any
+ of the expected. Returns type if succesful. */
+ Type_ptr check_expected_type(expected_t expected);
+
+ /* common special cases */
+ inline Type_ptr check_boolean()
+ { return check_expected_type(TP_BOOLEAN); }
+
+ inline Type_ptr check_arithmetical()
+ {
+ return check_expected_type(TP_INT_CONST |
+ TP_FXD_CONST |
+ TP_UNSIGNED_INT |
+ TP_SIGNED_INT |
+ TP_UNSIGNED_FXD |
+ TP_SIGNED_FXD ) ;
+ }
+
+ inline Type_ptr check_arithmetical_integer()
+ {
+ return check_expected_type(TP_INT_CONST |
+ TP_UNSIGNED_INT |
+ TP_SIGNED_INT ) ;
+ }
+
+ inline Type_ptr check_boolean_or_integer()
+ {
+ return check_expected_type(TP_BOOLEAN |
+ TP_INT_CONST |
+ TP_UNSIGNED_INT |
+ TP_SIGNED_INT ) ;
+ }
+
+ inline Type_ptr check_array()
+ {
+ return check_expected_type(TP_ARRAY);
+ }
+
// post-orders only
void walk_unary_temporal_postorder(const Expr_ptr expr);
void walk_unary_fsm_postorder(const Expr_ptr expr);
@@ -207,7 +245,7 @@ private:
void walk_unary_logical_postorder(const Expr_ptr expr);
void walk_binary_logical_postorder(const Expr_ptr expr);
void walk_binary_logical_or_bitwise_postorder(const Expr_ptr expr);
- void walk_binary_bitwise_postorder(const Expr_ptr expr);
+ void walk_binary_shift_postorder(const Expr_ptr expr);
void walk_binary_relational_postorder(const Expr_ptr expr);
void walk_binary_boolean_or_relational_postorder(const Expr_ptr expr);
@@ -217,12 +255,6 @@ private:
// useful for better caching
Expr_ptr find_canonical_expr(Expr_ptr expr);
void memoize_canonical_result(Expr_ptr expr, Type_ptr type);
-
- // useful for errors
- Expr_ptr f_boolean;
- Expr_ptr f_integer;
-
- ExprVector f_integer_or_boolean;
};
#endif
View
32 src/model/model_mgr.cc
@@ -348,10 +348,7 @@ void ModelMgr::analyze()
Expr_ptr body = (*init_eye);
DEBUG << "processing INIT " << ctx << "::" << body << endl;
- Type_ptr tp = f_inferrer.process(ctx, body);
- if (tp != f_tm.find_boolean())
- throw BadType(f_tm.find_boolean()->repr(),
- tp->repr(), body);
+ f_inferrer.process(ctx, body, TP_BOOLEAN);
} // for init
const ExprVector trans = module.trans();
@@ -361,30 +358,11 @@ void ModelMgr::analyze()
Expr_ptr body = (*trans_eye);
DEBUG << "processing TRANS " << ctx << "::" << body << endl;
- Type_ptr tp = f_inferrer.process(ctx, body);
- if (tp != f_tm.find_boolean()) {
- throw BadType(f_tm.find_boolean()->repr(),
- tp->repr(), body);
- }
- } // for trans
-
- // const ExprVector fair = module.fairness();
- // for (ExprVector::const_iterator fair_eye = fair.begin();
- // fair_eye != fair.end(); fair_eye ++) {
-
- // Expr_ptr body = (*fair_eye);
- // DEBUG << "processing FAIRNESS " << ctx << "::" << body << endl;
-
- // Type_ptr tp = f_inferrer.process(ctx, body);
- // if (tp != f_tm.find_boolean()) {
- // throw BadType(f_tm.find_boolean()->get_repr(),
- // tp->get_repr(), body);
- // }
- // } // for fair
-
- } // for modules
+ f_inferrer.process(ctx, body, TP_BOOLEAN);
+ }
+ } // for trans
- }
+ } // for modules
catch (AnalyzerException& ae) {
cerr << ae.what() << endl;
Please sign in to comment.
Something went wrong with that request. Please try again.