/////////////////////////////////////////////////////////////////////////////// // This file is generated automatically using Prop (version 2.3.0), // last updated on Feb 5, 1997. // The original source file is "prog.pC". /////////////////////////////////////////////////////////////////////////////// #define PROP_REWRITING_USED #define PROP_PRINTER_USED #define PROP_QUARK_USED #include ///////////////////////////////////////////////////////////////////////////// // This test implements a rewrite based simplifier for the abstract // syntax of a toy imperative language. ///////////////////////////////////////////////////////////////////////////// #include ///////////////////////////////////////////////////////////////////////////// // The following recursive type equations define the abstract syntax // of our small language. // ( Note: we define our own boolean type because not all C++ compilers // have bool built-in yet. ) ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Forward class definition for List /////////////////////////////////////////////////////////////////////////////// #ifndef datatype_List_defined #define datatype_List_defined # define List(T) a_List * #endif /////////////////////////////////////////////////////////////////////////////// // Class hierarchy for datatype List /////////////////////////////////////////////////////////////////////////////// template class a_List; // base class for datatype List /////////////////////////////////////////////////////////////////////////////// // Definition of datatype 'BOOL' /////////////////////////////////////////////////////////////////////////////// enum BOOL { False = 0, True = 1 }; /////////////////////////////////////////////////////////////////////////////// // Forward class definition for Exp /////////////////////////////////////////////////////////////////////////////// #ifndef datatype_Exp_defined #define datatype_Exp_defined typedef class a_Exp * Exp; #endif /////////////////////////////////////////////////////////////////////////////// // Class hierarchy for datatype Exp /////////////////////////////////////////////////////////////////////////////// class a_Exp; // base class for datatype Exp class Exp_integer; // subclass for 'integer int' class Exp_real; // subclass for 'real double' class Exp_string; // subclass for 'string char *' class Exp_boolean; // subclass for 'boolean BOOL' class Exp_binop; // subclass for 'binop (BinOp, Exp, Exp)' class Exp_unaryop; // subclass for 'unaryop (UnaryOp, Exp)' class Exp_var; // subclass for 'var Id' /////////////////////////////////////////////////////////////////////////////// // Definition of datatype 'BinOp' /////////////////////////////////////////////////////////////////////////////// enum BinOp { add = 0, sub = 1, mul = 2, divide = 3, mod = 4, logical_and = 5, logical_or = 6, eq = 7, ge = 8, le = 9, lt = 10, gt = 11, ne = 12 }; /////////////////////////////////////////////////////////////////////////////// // Definition of datatype 'UnaryOp' /////////////////////////////////////////////////////////////////////////////// enum UnaryOp { uminus = 0, logical_not = 1 }; /////////////////////////////////////////////////////////////////////////////// // Forward class definition for Stmt /////////////////////////////////////////////////////////////////////////////// #ifndef datatype_Stmt_defined #define datatype_Stmt_defined typedef class a_Stmt * Stmt; #endif /////////////////////////////////////////////////////////////////////////////// // Class hierarchy for datatype Stmt /////////////////////////////////////////////////////////////////////////////// class a_Stmt; // base class for datatype Stmt class Stmt_assign_stmt; // subclass for 'assign_stmt (Id, Exp)' class Stmt_while_stmt; // subclass for 'while_stmt (Exp, Stmt)' class Stmt_if_stmt; // subclass for 'if_stmt (Exp, Stmt, Stmt)' class Stmt_print_stmt; // subclass for 'print_stmt Exp' class Stmt_block_stmt; // subclass for 'block_stmt (List , List )' /////////////////////////////////////////////////////////////////////////////// // Forward class definition for Type /////////////////////////////////////////////////////////////////////////////// #ifndef datatype_Type_defined #define datatype_Type_defined typedef class a_Type * Type; #endif /////////////////////////////////////////////////////////////////////////////// // Class hierarchy for datatype Type /////////////////////////////////////////////////////////////////////////////// class a_Type; // base class for datatype Type class Type_primitive_type; // subclass for 'primitive_type Id' class Type_pointer_type; // subclass for 'pointer_type Type' class Type_array_type; // subclass for 'array_type { element : Type, bound : Exp }' class Type_function_type; // subclass for 'function_type { arg : Type, ret : Type }' class Type_tuple_type; // subclass for 'tuple_type List ' class Type_record_type; // subclass for 'record_type List ' /////////////////////////////////////////////////////////////////////////////// // Forward class definition for Decl /////////////////////////////////////////////////////////////////////////////// #ifndef datatype_Decl_defined #define datatype_Decl_defined typedef class a_Decl * Decl; #endif /////////////////////////////////////////////////////////////////////////////// // Class hierarchy for datatype Decl /////////////////////////////////////////////////////////////////////////////// class a_Decl; // base class for datatype Decl /////////////////////////////////////////////////////////////////////////////// // Forward class definition for LabeledType /////////////////////////////////////////////////////////////////////////////// #ifndef datatype_LabeledType_defined #define datatype_LabeledType_defined typedef class a_LabeledType * LabeledType; #endif /////////////////////////////////////////////////////////////////////////////// // Class hierarchy for datatype LabeledType /////////////////////////////////////////////////////////////////////////////// class a_LabeledType; // base class for datatype LabeledType /////////////////////////////////////////////////////////////////////////////// // Definition of type Id /////////////////////////////////////////////////////////////////////////////// typedef char const * Id; /////////////////////////////////////////////////////////////////////////////// // Base class for datatype 'List' /////////////////////////////////////////////////////////////////////////////// template class a_List : public TermObj { public: # define nil_1_ 0 inline friend int boxed(const a_List * x) { return x != 0; } inline friend int untag(const a_List * x) { return x ? 1 : 0; } T _1; a_List * _2; inline a_List (T _x1, a_List * _x2) : _1(_x1), _2(_x2) {} inline friend a_List * list_1_ (T _x1, a_List * _x2) { return new a_List (_x1, _x2); } }; ostream& operator << (ostream&,BOOL); ostream& pretty_print(ostream&,BOOL,int = 0,int = 0); /////////////////////////////////////////////////////////////////////////////// // Base class for datatype 'Exp' /////////////////////////////////////////////////////////////////////////////// class a_Exp : public TermObj { public: enum Tag_Exp { tag_integer = 0, tag_real = 1, tag_string = 2, tag_boolean = 3, tag_binop = 4, tag_unaryop = 5, tag_var = 6 }; protected: const Tag_Exp _tag_; inline a_Exp(Tag_Exp _t_) : _tag_(_t_) {} public: inline int untag() const { return _tag_; } inline friend int boxed(const a_Exp * x) { return 1; } inline friend int untag(const a_Exp * x) { return x->_tag_; } //////////////////////////////////////////////////////////////////////////// // Downcasting functions for Exp //////////////////////////////////////////////////////////////////////////// inline friend Exp_integer * _integer(Exp _x_) { return (Exp_integer *)_x_; } inline friend Exp_real * _real(Exp _x_) { return (Exp_real *)_x_; } inline friend Exp_string * _string(Exp _x_) { return (Exp_string *)_x_; } inline friend Exp_boolean * _boolean(Exp _x_) { return (Exp_boolean *)_x_; } inline friend Exp_binop * _binop(Exp _x_) { return (Exp_binop *)_x_; } inline friend Exp_unaryop * _unaryop(Exp _x_) { return (Exp_unaryop *)_x_; } inline friend Exp_var * _var(Exp _x_) { return (Exp_var *)_x_; } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Exp::integer int' /////////////////////////////////////////////////////////////////////////////// class Exp_integer : public a_Exp { public: int integer; inline Exp_integer (int _xinteger) : a_Exp(a_Exp::tag_integer), integer(_xinteger) {} inline friend a_Exp * integer (int _xinteger) { return new Exp_integer (_xinteger); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Exp::real double' /////////////////////////////////////////////////////////////////////////////// class Exp_real : public a_Exp { public: double real; inline Exp_real (double _xreal) : a_Exp(a_Exp::tag_real), real(_xreal) {} inline friend a_Exp * real (double _xreal) { return new Exp_real (_xreal); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Exp::string char *' /////////////////////////////////////////////////////////////////////////////// class Exp_string : public a_Exp { public: char * string; inline Exp_string (char * _xstring) : a_Exp(a_Exp::tag_string), string(_xstring) {} inline friend a_Exp * string (char * _xstring) { return new Exp_string (_xstring); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Exp::boolean BOOL' /////////////////////////////////////////////////////////////////////////////// class Exp_boolean : public a_Exp { public: BOOL boolean; inline Exp_boolean (BOOL _xboolean) : a_Exp(a_Exp::tag_boolean), boolean(_xboolean) {} inline friend a_Exp * boolean (BOOL _xboolean) { return new Exp_boolean (_xboolean); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Exp::binop (BinOp, Exp, Exp)' /////////////////////////////////////////////////////////////////////////////// class Exp_binop : public a_Exp { public: BinOp _1; Exp _2; Exp _3; inline Exp_binop (BinOp _x1, Exp _x2, Exp _x3) : a_Exp(a_Exp::tag_binop), _1(_x1), _2(_x2), _3(_x3) {} inline friend a_Exp * binop (BinOp _x1, Exp _x2, Exp _x3) { return new Exp_binop (_x1, _x2, _x3); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Exp::unaryop (UnaryOp, Exp)' /////////////////////////////////////////////////////////////////////////////// class Exp_unaryop : public a_Exp { public: UnaryOp _1; Exp _2; inline Exp_unaryop (UnaryOp _x1, Exp _x2) : a_Exp(a_Exp::tag_unaryop), _1(_x1), _2(_x2) {} inline friend a_Exp * unaryop (UnaryOp _x1, Exp _x2) { return new Exp_unaryop (_x1, _x2); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Exp::var Id' /////////////////////////////////////////////////////////////////////////////// class Exp_var : public a_Exp { public: Id var; inline Exp_var (Id _xvar) : a_Exp(a_Exp::tag_var), var(_xvar) {} inline friend a_Exp * var (Id _xvar) { return new Exp_var (_xvar); } }; ostream& operator << (ostream&,Exp); ostream& pretty_print(ostream&,Exp,int = 0,int = 0); ostream& operator << (ostream&,BinOp); ostream& pretty_print(ostream&,BinOp,int = 0,int = 0); ostream& operator << (ostream&,UnaryOp); ostream& pretty_print(ostream&,UnaryOp,int = 0,int = 0); /////////////////////////////////////////////////////////////////////////////// // Base class for datatype 'Stmt' /////////////////////////////////////////////////////////////////////////////// class a_Stmt : public TermObj { public: enum Tag_Stmt { tag_assign_stmt = 0, tag_while_stmt = 1, tag_if_stmt = 2, tag_print_stmt = 3, tag_block_stmt = 4 }; protected: const Tag_Stmt _tag_; inline a_Stmt(Tag_Stmt _t_) : _tag_(_t_) {} public: inline int untag() const { return _tag_; } inline friend int boxed(const a_Stmt * x) { return 1; } inline friend int untag(const a_Stmt * x) { return x->_tag_; } //////////////////////////////////////////////////////////////////////////// // Downcasting functions for Stmt //////////////////////////////////////////////////////////////////////////// inline friend Stmt_assign_stmt * _assign_stmt(Stmt _x_) { return (Stmt_assign_stmt *)_x_; } inline friend Stmt_while_stmt * _while_stmt(Stmt _x_) { return (Stmt_while_stmt *)_x_; } inline friend Stmt_if_stmt * _if_stmt(Stmt _x_) { return (Stmt_if_stmt *)_x_; } inline friend Stmt_print_stmt * _print_stmt(Stmt _x_) { return (Stmt_print_stmt *)_x_; } inline friend Stmt_block_stmt * _block_stmt(Stmt _x_) { return (Stmt_block_stmt *)_x_; } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Stmt::assign_stmt (Id, Exp)' /////////////////////////////////////////////////////////////////////////////// class Stmt_assign_stmt : public a_Stmt { public: Id _1; Exp _2; inline Stmt_assign_stmt (Id _x1, Exp _x2) : a_Stmt(a_Stmt::tag_assign_stmt), _1(_x1), _2(_x2) {} inline friend a_Stmt * assign_stmt (Id _x1, Exp _x2) { return new Stmt_assign_stmt (_x1, _x2); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Stmt::while_stmt (Exp, Stmt)' /////////////////////////////////////////////////////////////////////////////// class Stmt_while_stmt : public a_Stmt { public: Exp _1; Stmt _2; inline Stmt_while_stmt (Exp _x1, Stmt _x2) : a_Stmt(a_Stmt::tag_while_stmt), _1(_x1), _2(_x2) {} inline friend a_Stmt * while_stmt (Exp _x1, Stmt _x2) { return new Stmt_while_stmt (_x1, _x2); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Stmt::if_stmt (Exp, Stmt, Stmt)' /////////////////////////////////////////////////////////////////////////////// class Stmt_if_stmt : public a_Stmt { public: Exp _1; Stmt _2; Stmt _3; inline Stmt_if_stmt (Exp _x1, Stmt _x2, Stmt _x3) : a_Stmt(a_Stmt::tag_if_stmt), _1(_x1), _2(_x2), _3(_x3) {} inline friend a_Stmt * if_stmt (Exp _x1, Stmt _x2, Stmt _x3) { return new Stmt_if_stmt (_x1, _x2, _x3); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Stmt::print_stmt Exp' /////////////////////////////////////////////////////////////////////////////// class Stmt_print_stmt : public a_Stmt { public: Exp print_stmt; inline Stmt_print_stmt (Exp _xprint_stmt) : a_Stmt(a_Stmt::tag_print_stmt), print_stmt(_xprint_stmt) {} inline friend a_Stmt * print_stmt (Exp _xprint_stmt) { return new Stmt_print_stmt (_xprint_stmt); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Stmt::block_stmt (List , List )' /////////////////////////////////////////////////////////////////////////////// class Stmt_block_stmt : public a_Stmt { public: a_List * _1; a_List * _2; inline Stmt_block_stmt (a_List * _x1, a_List * _x2) : a_Stmt(a_Stmt::tag_block_stmt), _1(_x1), _2(_x2) {} inline friend a_Stmt * block_stmt (a_List * _x1, a_List * _x2) { return new Stmt_block_stmt (_x1, _x2); } }; ostream& operator << (ostream&,Stmt); ostream& pretty_print(ostream&,Stmt,int = 0,int = 0); /////////////////////////////////////////////////////////////////////////////// // Base class for datatype 'Type' /////////////////////////////////////////////////////////////////////////////// class a_Type : public TermObj { public: enum Tag_Type { tag_primitive_type = 0, tag_pointer_type = 1, tag_array_type = 2, tag_function_type = 3, tag_tuple_type = 4, tag_record_type = 5 }; protected: const Tag_Type _tag_; inline a_Type(Tag_Type _t_) : _tag_(_t_) {} public: inline int untag() const { return _tag_; } inline friend int boxed(const a_Type * x) { return 1; } inline friend int untag(const a_Type * x) { return x->_tag_; } //////////////////////////////////////////////////////////////////////////// // Downcasting functions for Type //////////////////////////////////////////////////////////////////////////// inline friend Type_primitive_type * _primitive_type(Type _x_) { return (Type_primitive_type *)_x_; } inline friend Type_pointer_type * _pointer_type(Type _x_) { return (Type_pointer_type *)_x_; } inline friend Type_array_type * _array_type(Type _x_) { return (Type_array_type *)_x_; } inline friend Type_function_type * _function_type(Type _x_) { return (Type_function_type *)_x_; } inline friend Type_tuple_type * _tuple_type(Type _x_) { return (Type_tuple_type *)_x_; } inline friend Type_record_type * _record_type(Type _x_) { return (Type_record_type *)_x_; } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Type::primitive_type Id' /////////////////////////////////////////////////////////////////////////////// class Type_primitive_type : public a_Type { public: Id primitive_type; inline Type_primitive_type (Id _xprimitive_type) : a_Type(a_Type::tag_primitive_type), primitive_type(_xprimitive_type) {} inline friend a_Type * primitive_type (Id _xprimitive_type) { return new Type_primitive_type (_xprimitive_type); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Type::pointer_type Type' /////////////////////////////////////////////////////////////////////////////// class Type_pointer_type : public a_Type { public: Type pointer_type; inline Type_pointer_type (Type _xpointer_type) : a_Type(a_Type::tag_pointer_type), pointer_type(_xpointer_type) {} inline friend a_Type * pointer_type (Type _xpointer_type) { return new Type_pointer_type (_xpointer_type); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Type::array_type { element : Type, bound : Exp }' /////////////////////////////////////////////////////////////////////////////// class Type_array_type : public a_Type { public: Type element; Exp bound; inline Type_array_type (Type _xelement, Exp _xbound) : a_Type(a_Type::tag_array_type), element(_xelement), bound(_xbound) {} inline friend a_Type * array_type (Type _xelement, Exp _xbound) { return new Type_array_type (_xelement, _xbound); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Type::function_type { arg : Type, ret : Type }' /////////////////////////////////////////////////////////////////////////////// class Type_function_type : public a_Type { public: Type arg; Type ret; inline Type_function_type (Type _xarg, Type _xret) : a_Type(a_Type::tag_function_type), arg(_xarg), ret(_xret) {} inline friend a_Type * function_type (Type _xarg, Type _xret) { return new Type_function_type (_xarg, _xret); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Type::tuple_type List ' /////////////////////////////////////////////////////////////////////////////// class Type_tuple_type : public a_Type { public: a_List * tuple_type; inline Type_tuple_type (a_List * _xtuple_type) : a_Type(a_Type::tag_tuple_type), tuple_type(_xtuple_type) {} inline friend a_Type * tuple_type (a_List * _xtuple_type) { return new Type_tuple_type (_xtuple_type); } }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'Type::record_type List ' /////////////////////////////////////////////////////////////////////////////// class Type_record_type : public a_Type { public: a_List * record_type; inline Type_record_type (a_List * _xrecord_type) : a_Type(a_Type::tag_record_type), record_type(_xrecord_type) {} inline friend a_Type * record_type (a_List * _xrecord_type) { return new Type_record_type (_xrecord_type); } }; ostream& operator << (ostream&,Type); ostream& pretty_print(ostream&,Type,int = 0,int = 0); /////////////////////////////////////////////////////////////////////////////// // Base class for datatype 'Decl' /////////////////////////////////////////////////////////////////////////////// class a_Decl : public TermObj { public: inline friend int boxed(const a_Decl * x) { return 1; } inline friend int untag(const a_Decl * x) { return 0; } Id name; Type typ; inline a_Decl (Id _xname, Type _xtyp) : name(_xname), typ(_xtyp) {} inline friend a_Decl * decl (Id _xname, Type _xtyp) { return new a_Decl (_xname, _xtyp); } }; ostream& operator << (ostream&,Decl); ostream& pretty_print(ostream&,Decl,int = 0,int = 0); /////////////////////////////////////////////////////////////////////////////// // Base class for datatype 'LabeledType' /////////////////////////////////////////////////////////////////////////////// class a_LabeledType : public TermObj { public: inline friend int boxed(const a_LabeledType * x) { return 1; } inline friend int untag(const a_LabeledType * x) { return 0; } Id _1; Type _2; inline a_LabeledType (Id _x1, Type _x2) : _1(_x1), _2(_x2) {} inline friend a_LabeledType * labeled_type (Id _x1, Type _x2) { return new a_LabeledType (_x1, _x2); } }; ostream& operator << (ostream&,LabeledType); ostream& pretty_print(ostream&,LabeledType,int = 0,int = 0); ///////////////////////////////////////////////////////////////////////////// // Refine the implementation of the datatypes. // The qualifiers may be also declared in the datatype definition. // We qualify the datatypes here so that they won't clutter up // the equations above. // // All types are declared to be printable by // the printer method and rewritable. ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // Generate the interfaces to instantiated polymorphic datatypes. // These are not strictly necessary since the instantiation is in the // same file below. However, in general the 'instantiate extern' declaration // must be placed in the .h files for each instance of a polymorphic // datatype. ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type List /////////////////////////////////////////////////////////////////////////////// ostream& operator << (ostream&, List(Type) ); ostream& pretty_print(ostream&, List(Type) , int = 0, int = 0); /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type List /////////////////////////////////////////////////////////////////////////////// ostream& operator << (ostream&, List(Stmt) ); ostream& pretty_print(ostream&, List(Stmt) , int = 0, int = 0); /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type List /////////////////////////////////////////////////////////////////////////////// ostream& operator << (ostream&, List(LabeledType) ); ostream& pretty_print(ostream&, List(LabeledType) , int = 0, int = 0); /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type List /////////////////////////////////////////////////////////////////////////////// ostream& operator << (ostream&, List(Decl) ); ostream& pretty_print(ostream&, List(Decl) , int = 0, int = 0); ///////////////////////////////////////////////////////////////////////////// // Now instantiate all the datatypes. ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type Exp /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, Exp _x_, int _tab_, int _prec_) { switch (untag(_x_)) { case a_Exp::tag_integer: _f_ << _integer(_x_)->integer; break; case a_Exp::tag_real: _f_ << _real(_x_)->real; break; case a_Exp::tag_string: _f_ << "\""; _f_ << _string(_x_)->string; _f_ << "\""; break; case a_Exp::tag_boolean: pretty_print(_f_, _boolean(_x_)->boolean, _tab_, _prec_); break; case a_Exp::tag_binop: _f_ << "("; pretty_print(_f_, _binop(_x_)->_2, _tab_, _prec_); pretty_print(_f_, _binop(_x_)->_1, _tab_, _prec_); pretty_print(_f_, _binop(_x_)->_3, _tab_, _prec_); _f_ << ")"; break; case a_Exp::tag_unaryop: _f_ << "("; pretty_print(_f_, _unaryop(_x_)->_1, _tab_, _prec_); pretty_print(_f_, _unaryop(_x_)->_2, _tab_, _prec_); _f_ << ")"; break; case a_Exp::tag_var: _f_ << _var(_x_)->var; break; } return _f_; } ostream& operator << (ostream& _f_, Exp _x_) { return pretty_print(_f_,_x_); } /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type BOOL /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, BOOL _x_, int _tab_, int _prec_) { switch ((_x_)) { case False: _f_ << "false"; break; case True: _f_ << "true"; break; } return _f_; } ostream& operator << (ostream& _f_, BOOL _x_) { return pretty_print(_f_,_x_); } /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type BinOp /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, BinOp _x_, int _tab_, int _prec_) { switch ((_x_)) { case add: _f_ << " + "; break; case sub: _f_ << " - "; break; case mul: _f_ << " * "; break; case divide: _f_ << " / "; break; case mod: _f_ << " mod "; break; case logical_and: _f_ << " and "; break; case logical_or: _f_ << " or "; break; case eq: _f_ << " = "; break; case ge: _f_ << " >= "; break; case le: _f_ << " <= "; break; case lt: _f_ << " < "; break; case gt: _f_ << " > "; break; case ne: _f_ << " <> "; break; } return _f_; } ostream& operator << (ostream& _f_, BinOp _x_) { return pretty_print(_f_,_x_); } /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type UnaryOp /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, UnaryOp _x_, int _tab_, int _prec_) { switch ((_x_)) { case uminus: _f_ << "- "; break; case logical_not: _f_ << "not "; break; } return _f_; } ostream& operator << (ostream& _f_, UnaryOp _x_) { return pretty_print(_f_,_x_); } /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type Stmt /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, Stmt _x_, int _tab_, int _prec_) { switch (untag(_x_)) { case a_Stmt::tag_assign_stmt: _f_ << _assign_stmt(_x_)->_1; _f_ << " := "; pretty_print(_f_, _assign_stmt(_x_)->_2, _tab_, _prec_); _f_ << ";"; break; case a_Stmt::tag_while_stmt: _f_ << "while "; pretty_print(_f_, _while_stmt(_x_)->_1, _tab_, _prec_); _f_ << " do"; _tab_ += 3; _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); pretty_print(_f_, _while_stmt(_x_)->_2, _tab_, _prec_); _tab_ -= 3; _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); _f_ << "end while;"; break; case a_Stmt::tag_if_stmt: _f_ << "if "; pretty_print(_f_, _if_stmt(_x_)->_1, _tab_, _prec_); _f_ << " then"; _tab_ += 3; _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); pretty_print(_f_, _if_stmt(_x_)->_2, _tab_, _prec_); _tab_ -= 3; _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); _f_ << " else"; _tab_ += 3; _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); pretty_print(_f_, _if_stmt(_x_)->_3, _tab_, _prec_); _tab_ -= 3; _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); _f_ << "endif;"; break; case a_Stmt::tag_print_stmt: _f_ << "print "; pretty_print(_f_, _print_stmt(_x_)->print_stmt, _tab_, _prec_); _f_ << ";"; break; case a_Stmt::tag_block_stmt: _f_ << "begin "; _tab_ += 3; _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); pretty_print(_f_, _block_stmt(_x_)->_1, _tab_, _prec_); _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); pretty_print(_f_, _block_stmt(_x_)->_2, _tab_, _prec_); _tab_ -= 3; _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); _f_ << "end"; break; } return _f_; } ostream& operator << (ostream& _f_, Stmt _x_) { return pretty_print(_f_,_x_); } /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type Type /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, Type _x_, int _tab_, int _prec_) { switch (untag(_x_)) { case a_Type::tag_primitive_type: _f_ << _primitive_type(_x_)->primitive_type; break; case a_Type::tag_pointer_type: pretty_print(_f_, _pointer_type(_x_)->pointer_type, _tab_, _prec_); _f_ << "^"; break; case a_Type::tag_array_type: _f_ << "array "; pretty_print(_f_, _array_type(_x_)->bound, _tab_, _prec_); _f_ << " of "; pretty_print(_f_, _array_type(_x_)->element, _tab_, _prec_); break; case a_Type::tag_function_type: pretty_print(_f_, _function_type(_x_)->arg, _tab_, _prec_); _f_ << " -> "; pretty_print(_f_, _function_type(_x_)->ret, _tab_, _prec_); break; case a_Type::tag_tuple_type: _f_ << "tuple_type"; _f_ << '('; pretty_print(_f_, _tuple_type(_x_)->tuple_type, _tab_, _prec_); _f_ << ')'; break; case a_Type::tag_record_type: _f_ << "record_type"; _f_ << '('; pretty_print(_f_, _record_type(_x_)->record_type, _tab_, _prec_); _f_ << ')'; break; } return _f_; } ostream& operator << (ostream& _f_, Type _x_) { return pretty_print(_f_,_x_); } /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type Decl /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, Decl _x_, int _tab_, int _prec_) { _f_ << "var "; _f_ << _x_->name; _f_ << " : "; pretty_print(_f_, _x_->typ, _tab_, _prec_); _f_ << ";"; return _f_; } ostream& operator << (ostream& _f_, Decl _x_) { return pretty_print(_f_,_x_); } /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type LabeledType /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, LabeledType _x_, int _tab_, int _prec_) { _f_ << _x_->_1; _f_ << " : "; pretty_print(_f_, _x_->_2, _tab_, _prec_); return _f_; } ostream& operator << (ostream& _f_, LabeledType _x_) { return pretty_print(_f_,_x_); } /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type List /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, List(Type) _x_, int _tab_, int _prec_) { switch (untag(_x_)) { case (int)nil_1_: _f_ << ""; break; case 1: pretty_print(_f_, _x_->_1, _tab_, _prec_); _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); pretty_print(_f_, _x_->_2, _tab_, _prec_); break; } return _f_; } ostream& operator << (ostream& _f_, List(Type) _x_) { return pretty_print(_f_,_x_); } /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type List /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, List(Stmt) _x_, int _tab_, int _prec_) { switch (untag(_x_)) { case (int)nil_1_: _f_ << ""; break; case 1: pretty_print(_f_, _x_->_1, _tab_, _prec_); _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); pretty_print(_f_, _x_->_2, _tab_, _prec_); break; } return _f_; } ostream& operator << (ostream& _f_, List(Stmt) _x_) { return pretty_print(_f_,_x_); } /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type List /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, List(LabeledType) _x_, int _tab_, int _prec_) { switch (untag(_x_)) { case (int)nil_1_: _f_ << ""; break; case 1: pretty_print(_f_, _x_->_1, _tab_, _prec_); _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); pretty_print(_f_, _x_->_2, _tab_, _prec_); break; } return _f_; } ostream& operator << (ostream& _f_, List(LabeledType) _x_) { return pretty_print(_f_,_x_); } /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type List /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, List(Decl) _x_, int _tab_, int _prec_) { switch (untag(_x_)) { case (int)nil_1_: _f_ << ""; break; case 1: pretty_print(_f_, _x_->_1, _tab_, _prec_); _f_ << '\n'; PrettyPrinter::print_tabs(_f_,_tab_); pretty_print(_f_, _x_->_2, _tab_, _prec_); break; } return _f_; } ostream& operator << (ostream& _f_, List(Decl) _x_) { return pretty_print(_f_,_x_); } ///////////////////////////////////////////////////////////////////////////// // Defines the interface of a rewrite class Simplify. // All types that are referenced (directly or indirectly) should be // declared in the interface. ///////////////////////////////////////////////////////////////////////////// class Simplify : public BURS { private: Simplify(const Simplify&); // no copy constructor void operator = (const Simplify&); // no assignment public: struct Simplify_StateRec * stack__, * stack_top__; public: void labeler(const char *, int&, int); void labeler(Quark, int&, int); void labeler(Exp & redex, int&, int); inline virtual void operator () (Exp & redex) { int s; labeler(redex,s,0); } void labeler(BOOL & redex, int&, int); inline virtual void operator () (BOOL & redex) { int s; labeler(redex,s,0); } void labeler(BinOp & redex, int&, int); inline virtual void operator () (BinOp & redex) { int s; labeler(redex,s,0); } void labeler(UnaryOp & redex, int&, int); inline virtual void operator () (UnaryOp & redex) { int s; labeler(redex,s,0); } void labeler(Stmt & redex, int&, int); inline virtual void operator () (Stmt & redex) { int s; labeler(redex,s,0); } void labeler(Type & redex, int&, int); inline virtual void operator () (Type & redex) { int s; labeler(redex,s,0); } void labeler(Decl & redex, int&, int); inline virtual void operator () (Decl & redex) { int s; labeler(redex,s,0); } void labeler(LabeledType & redex, int&, int); inline virtual void operator () (LabeledType & redex) { int s; labeler(redex,s,0); } void labeler(a_List * & redex, int&, int); inline virtual void operator () (a_List * & redex) { int s; labeler(redex,s,0); } void labeler(a_List * & redex, int&, int); inline virtual void operator () (a_List * & redex) { int s; labeler(redex,s,0); } void labeler(a_List * & redex, int&, int); inline virtual void operator () (a_List * & redex) { int s; labeler(redex,s,0); } void labeler(a_List * & redex, int&, int); inline virtual void operator () (a_List * & redex) { int s; labeler(redex,s,0); } private: public: Simplify() {} // Method to print an error message void error(const char message[]) { cerr << message << '\n'; } }; ///////////////////////////////////////////////////////////////////////////// // Now defines the rewrite rules. These rules will be compiled into // efficient pattern matching code by the translator. A real life // system will probably have many more rules than presented here. // (A machine code generator usually needs a few hundred rules) // Currently there are about 60 rules in this class. ///////////////////////////////////////////////////////////////////////////// static const TreeTables::Offset Simplify_accept_base [ 99 ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 5, 7, 9, 11, 13, 16, 18, 22, 26, 34, 36, 39, 41, 45, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 73, 76, 79, 85, 92, 94, 97, 100, 102, 106, 110, 112, 115, 118, 125, 128, 130, 134, 136, 138, 140, 142, 144, 148, 151, 153, 157, 160, 162, 165, 167, 169, 170, 172, 174, 178, 182, 185, 187, 191, 195, 198, 200, 204, 207, 209, 213, 216, 218 }; static const TreeTables::Rule Simplify_accept_vector [ 220 ] = { -1, 17, -1, 18, -1, 19, -1, 21, -1, 20, -1, 16, -1, 7, 8, -1, 38, -1, 38, 5, 6, -1, 35, 37, 48, -1, 34, 35, 36, 37, 47, 48, 4, -1, 33, -1, 33, 3, -1, 32, -1, 32, 2, 31, -1, 34, 36, 47, -1, 31, -1, 14, -1, 0, -1, 23, -1, 24, -1, 25, -1, 27, -1, 26, -1, 22, -1, 46, -1, 46, 12, 13, -1, 46, 0, -1, 43, 45, -1, 42, 43, 44, 45, 11, -1, 34, 36, 43, 45, 47, 0, -1, 41, -1, 41, 10, -1, 41, 0, -1, 40, -1, 39, 40, 9, -1, 40, 0, 31, -1, 1, -1, 38, 1, -1, 42, 44, -1, 35, 37, 42, 44, 48, 1, -1, 33, 1, -1, 39, -1, 32, 39, 1, -1, 15, -1, 29, -1, 28, -1, 30, -1, 56, -1, 54, 56, 29, -1, 56, 29, -1, 51, -1, 49, 51, 28, -1, 51, 28, -1, 54, -1, 54, 29, -1, 49, -1, 49, 28, -1, 58, -1, 55, -1, 53, 55, 29, -1, 54, 55, 29, -1, 55, 29, -1, 52, -1, 50, 52, 28, -1, 49, 52, 28, -1, 52, 28, -1, 53, -1, 53, 56, 29, -1, 53, 29, -1, 50, -1, 50, 51, 28, -1, 50, 28, -1, 57, -1, 59, -1 }; static const TreeTables::State Simplify_theta_3[3] = { 20, 21, 22 }; static const TreeTables::State Simplify_theta_4[14][6][6] = { { { 0, 0, 0, 0, 0, 0 }, { 0, 0, 41, 0, 0, 0 }, { 0, 60, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } }, { { 0, 36, 57, 0, 0, 0 }, { 39, 37, 59, 39, 39, 39 }, { 65, 66, 58, 65, 65, 65 }, { 0, 36, 57, 0, 0, 0 }, { 0, 36, 57, 0, 0, 0 }, { 0, 36, 57, 0, 0, 0 } }, { { 0, 34, 54, 0, 0, 0 }, { 0, 35, 56, 0, 0, 0 }, { 0, 64, 55, 0, 0, 0 }, { 0, 34, 54, 0, 0, 0 }, { 0, 34, 54, 0, 0, 0 }, { 0, 34, 54, 0, 0, 0 } }, { { 0, 32, 51, 0, 0, 0 }, { 38, 33, 53, 38, 38, 38 }, { 62, 63, 52, 62, 62, 62 }, { 0, 32, 51, 0, 0, 0 }, { 0, 32, 51, 0, 0, 0 }, { 0, 32, 51, 0, 0, 0 } }, { { 0, 30, 48, 0, 0, 0 }, { 0, 31, 50, 0, 0, 0 }, { 0, 61, 49, 0, 0, 0 }, { 0, 30, 48, 0, 0, 0 }, { 0, 30, 48, 0, 0, 0 }, { 0, 30, 48, 0, 0, 0 } }, { { 0, 0, 0, 0, 0, 0 }, { 0, 29, 41, 0, 0, 0 }, { 0, 60, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } }, { { 0, 0, 0, 0, 74, 87 }, { 0, 0, 41, 0, 74, 87 }, { 0, 60, 0, 0, 74, 87 }, { 0, 0, 0, 69, 76, 90 }, { 79, 79, 79, 80, 75, 89 }, { 94, 94, 94, 96, 95, 88 } }, { { 0, 0, 0, 0, 71, 83 }, { 0, 0, 41, 0, 71, 83 }, { 0, 60, 0, 0, 71, 83 }, { 0, 0, 0, 68, 73, 86 }, { 77, 77, 77, 78, 72, 85 }, { 91, 91, 91, 93, 92, 84 } }, { { 0, 0, 0, 0, 0, 0 }, { 0, 28, 41, 0, 0, 0 }, { 0, 60, 47, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } }, { { 0, 0, 0, 0, 0, 0 }, { 0, 27, 41, 0, 0, 0 }, { 0, 60, 46, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } }, { { 0, 0, 0, 0, 0, 0 }, { 0, 26, 41, 0, 0, 0 }, { 0, 60, 45, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } }, { { 0, 0, 0, 0, 0, 0 }, { 0, 25, 41, 0, 0, 0 }, { 0, 60, 44, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } }, { { 0, 0, 0, 0, 0, 0 }, { 0, 24, 41, 0, 0, 0 }, { 0, 60, 43, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } }, { { 0, 0, 0, 0, 0, 0 }, { 0, 23, 41, 0, 0, 0 }, { 0, 60, 42, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 } } }; static const TreeTables::State Simplify_theta_5[3][4] = { { 0, 0, 0, 0 }, { 0, 40, 67, 0 }, { 0, 0, 0, 70 } }; static const TreeTables::State Simplify_theta_25[2][1] = { { 0 }, { 81 } }; static const TreeTables::State Simplify_theta_26[3][1][1] = { { { 0 } }, { { 82 } }, { { 97 } } }; static const TreeTables::State Simplify_theta_40[2][1] = { { 0 }, { 98 } }; static const DFATables::State Simplify_check [ 113 ] = { 0, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 7, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 11, 11, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static const DFATables::State Simplify_next [ 113 ] = { 0, 1, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 3, 3, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; inline void Simplify::labeler(char const * redex,int& s__,int) { { s__ = 0; } } inline void Simplify::labeler(Quark redex,int& s__,int) { { s__ = 0; } } void Simplify::labeler (UnaryOp & redex, int& s__, int r__) { replacement__: s__ = redex + 16; } void Simplify::labeler (List(Decl) & redex, int& s__, int r__) { replacement__: if (r__ && boxed(redex) && redex->has_rewrite_state()) { s__ = redex->get_rewrite_state(); return; } if ((redex)) { int s0__; int s1__; labeler(redex->_1, s0__, r__); labeler(redex->_2, s1__, r__); s__ = 0; } else {s__ = 0; } if (boxed(redex)) { redex->set_rewrite_state(s__); } } void Simplify::labeler (Exp & redex, int& s__, int r__) { replacement__: if (r__ && boxed(redex) && redex->has_rewrite_state()) { s__ = redex->get_rewrite_state(); return; } switch(redex->untag()) { case a_Exp::tag_integer: { int s0__; s0__ = 0; // int s__ = 18;} break; case a_Exp::tag_real: { int s0__; s0__ = 0; // double s__ = 19;} break; case a_Exp::tag_string: { int s0__; labeler(_string(redex)->string, s0__, r__); s__ = 0;} break; case a_Exp::tag_boolean: { int s0__; labeler(_boolean(redex)->boolean, s0__, r__); s__ = Simplify_theta_3[Simplify_check[0 + s0__] == 3 ? Simplify_next[0 + s0__] : 0]; } break; case a_Exp::tag_binop: { int s0__; int s1__; int s2__; labeler(_binop(redex)->_1, s0__, r__); labeler(_binop(redex)->_2, s1__, r__); labeler(_binop(redex)->_3, s2__, r__); s__ = Simplify_theta_4[Simplify_check[0 + s0__] == 4 ? Simplify_next[0 + s0__] : 0][Simplify_check[0 + s1__] == 5 ? Simplify_next[0 + s1__] : 0][Simplify_check[5 + s2__] == 6 ? Simplify_next[5 + s2__] : 0]; } break; case a_Exp::tag_unaryop: { int s0__; int s1__; labeler(_unaryop(redex)->_1, s0__, r__); labeler(_unaryop(redex)->_2, s1__, r__); s__ = Simplify_theta_5[Simplify_check[0 + s0__] == 7 ? Simplify_next[0 + s0__] : 0][Simplify_check[10 + s1__] == 8 ? Simplify_next[10 + s1__] : 0]; } break; default: { int s0__; labeler(_var(redex)->var, s0__, r__); s__ = 0;} break; } const TreeTables::Rule * o__ = Simplify_accept_vector + Simplify_accept_base[s__]; accept__: switch (*o__) { case 56: { { redex = _binop(redex)->_2; r__ = 1; goto replacement__; }} break; case 55: { { redex = boolean(True); r__ = 1; goto replacement__; }} break; case 54: { { redex = _binop(redex)->_3; r__ = 1; goto replacement__; }} break; case 53: { { redex = boolean(True); r__ = 1; goto replacement__; }} break; case 52: { { redex = _binop(redex)->_2; r__ = 1; goto replacement__; }} break; case 51: { { redex = boolean(False); r__ = 1; goto replacement__; }} break; case 50: { { redex = _binop(redex)->_3; r__ = 1; goto replacement__; }} break; case 49: { { redex = boolean(False); r__ = 1; goto replacement__; }} break; case 48: if ((_integer(_binop(redex)->_3)->integer == 2)) { { redex = binop(add,_binop(redex)->_2,_binop(redex)->_2); r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 47: if ((_integer(_binop(redex)->_2)->integer == 2)) { { redex = binop(add,_binop(redex)->_3,_binop(redex)->_3); r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 46: if ((_real(_binop(redex)->_3)->real == 1.000000)) { { redex = _binop(redex)->_2; r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 45: if ((_real(_binop(redex)->_3)->real == 1.000000)) { { redex = _binop(redex)->_2; r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 44: if ((_real(_binop(redex)->_2)->real == 1.000000)) { { redex = _binop(redex)->_3; r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 43: if ((_real(_binop(redex)->_3)->real == 0.000000)) { { redex = real(0.000000); r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 42: if ((_real(_binop(redex)->_2)->real == 0.000000)) { { redex = real(0.000000); r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 41: if ((_real(_binop(redex)->_3)->real == 0.000000)) { { redex = _binop(redex)->_2; r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 40: if ((_real(_binop(redex)->_3)->real == 0.000000)) { { redex = _binop(redex)->_2; r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 39: if ((_real(_binop(redex)->_2)->real == 0.000000)) { { redex = _binop(redex)->_3; r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 38: if ((_integer(_binop(redex)->_3)->integer == 1)) { { redex = _binop(redex)->_2; r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 37: if ((_integer(_binop(redex)->_3)->integer == 1)) { { redex = _binop(redex)->_2; r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 36: if ((_integer(_binop(redex)->_2)->integer == 1)) { { redex = _binop(redex)->_3; r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 35: if ((_integer(_binop(redex)->_3)->integer == 0)) { { redex = integer(0); r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 34: if ((_integer(_binop(redex)->_2)->integer == 0)) { { redex = integer(0); r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 33: if ((_integer(_binop(redex)->_3)->integer == 0)) { { redex = _binop(redex)->_2; r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 32: if ((_integer(_binop(redex)->_3)->integer == 0)) { { redex = _binop(redex)->_2; r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 31: if ((_integer(_binop(redex)->_2)->integer == 0)) { { redex = _binop(redex)->_3; r__ = 1; goto replacement__; }} else { ++o__; goto accept__; } break; case 30: { { redex = boolean(BOOL((! _boolean(_unaryop(redex)->_2)->boolean))); r__ = 1; goto replacement__; }} break; case 29: { { redex = boolean(BOOL((_boolean(_binop(redex)->_2)->boolean || _boolean(_binop(redex)->_3)->boolean))); r__ = 1; goto replacement__; }} break; case 28: { { redex = boolean(BOOL((_boolean(_binop(redex)->_2)->boolean && _boolean(_binop(redex)->_3)->boolean))); r__ = 1; goto replacement__; }} break; case 27: { { redex = boolean(BOOL((_real(_binop(redex)->_2)->real <= _real(_binop(redex)->_3)->real))); r__ = 1; goto replacement__; }} break; case 26: { { redex = boolean(BOOL((_real(_binop(redex)->_2)->real >= _real(_binop(redex)->_3)->real))); r__ = 1; goto replacement__; }} break; case 25: { { redex = boolean(BOOL((_real(_binop(redex)->_2)->real < _real(_binop(redex)->_3)->real))); r__ = 1; goto replacement__; }} break; case 24: { { redex = boolean(BOOL((_real(_binop(redex)->_2)->real > _real(_binop(redex)->_3)->real))); r__ = 1; goto replacement__; }} break; case 23: { { redex = boolean(BOOL((_real(_binop(redex)->_2)->real != _real(_binop(redex)->_3)->real))); r__ = 1; goto replacement__; }} break; case 22: { { redex = boolean(BOOL((_real(_binop(redex)->_2)->real == _real(_binop(redex)->_3)->real))); r__ = 1; goto replacement__; }} break; case 21: { { redex = boolean(BOOL((_integer(_binop(redex)->_2)->integer <= _integer(_binop(redex)->_3)->integer))); r__ = 1; goto replacement__; }} break; case 20: { { redex = boolean(BOOL((_integer(_binop(redex)->_2)->integer >= _integer(_binop(redex)->_3)->integer))); r__ = 1; goto replacement__; }} break; case 19: { { redex = boolean(BOOL((_integer(_binop(redex)->_2)->integer < _integer(_binop(redex)->_3)->integer))); r__ = 1; goto replacement__; }} break; case 18: { { redex = boolean(BOOL((_integer(_binop(redex)->_2)->integer > _integer(_binop(redex)->_3)->integer))); r__ = 1; goto replacement__; }} break; case 17: { { redex = boolean(BOOL((_integer(_binop(redex)->_2)->integer != _integer(_binop(redex)->_3)->integer))); r__ = 1; goto replacement__; }} break; case 16: { { redex = boolean(BOOL((_integer(_binop(redex)->_2)->integer == _integer(_binop(redex)->_3)->integer))); r__ = 1; goto replacement__; }} break; case 15: { { redex = real((- _real(_unaryop(redex)->_2)->real)); r__ = 1; goto replacement__; }} break; case 14: { { redex = integer((- _integer(_unaryop(redex)->_2)->integer)); r__ = 1; goto replacement__; }} break; case 13: { { redex = real((_real(_binop(redex)->_2)->real / _real(_binop(redex)->_3)->real)); r__ = 1; goto replacement__; }} break; case 12: if ((_real(_binop(redex)->_3)->real == 0.000000)) { error("division by zero"); } else { ++o__; goto accept__; } break; case 11: { { redex = real((_real(_binop(redex)->_2)->real * _real(_binop(redex)->_3)->real)); r__ = 1; goto replacement__; }} break; case 10: { { redex = real((_real(_binop(redex)->_2)->real - _real(_binop(redex)->_3)->real)); r__ = 1; goto replacement__; }} break; case 9: { { redex = real((_real(_binop(redex)->_2)->real + _real(_binop(redex)->_3)->real)); r__ = 1; goto replacement__; }} break; case 8: { { redex = integer((_integer(_binop(redex)->_2)->integer % _integer(_binop(redex)->_3)->integer)); r__ = 1; goto replacement__; }} break; case 7: if ((_integer(_binop(redex)->_3)->integer == 0)) { error("modulo by zero"); } else { ++o__; goto accept__; } break; case 6: { { redex = integer((_integer(_binop(redex)->_2)->integer / _integer(_binop(redex)->_3)->integer)); r__ = 1; goto replacement__; }} break; case 5: if ((_integer(_binop(redex)->_3)->integer == 0)) { error("division by zero"); } else { ++o__; goto accept__; } break; case 4: { { redex = integer((_integer(_binop(redex)->_2)->integer * _integer(_binop(redex)->_3)->integer)); r__ = 1; goto replacement__; }} break; case 3: { { redex = integer((_integer(_binop(redex)->_2)->integer - _integer(_binop(redex)->_3)->integer)); r__ = 1; goto replacement__; }} break; case 2: { { redex = integer((_integer(_binop(redex)->_2)->integer + _integer(_binop(redex)->_3)->integer)); r__ = 1; goto replacement__; }} break; case 1: { { redex = binop(_binop(redex)->_1,real(_real(_binop(redex)->_2)->real),real(_integer(_binop(redex)->_3)->integer)); r__ = 1; goto replacement__; }} break; case 0: { { redex = binop(_binop(redex)->_1,real(_integer(_binop(redex)->_2)->integer),real(_real(_binop(redex)->_3)->real)); r__ = 1; goto replacement__; }} break; } if (boxed(redex)) { redex->set_rewrite_state(s__); } } void Simplify::labeler (BOOL & redex, int& s__, int r__) { replacement__: s__ = redex + 1; } void Simplify::labeler (Stmt & redex, int& s__, int r__) { replacement__: if (r__ && boxed(redex) && redex->has_rewrite_state()) { s__ = redex->get_rewrite_state(); return; } switch(redex->untag()) { case a_Stmt::tag_assign_stmt: { int s0__; int s1__; labeler(_assign_stmt(redex)->_1, s0__, r__); labeler(_assign_stmt(redex)->_2, s1__, r__); s__ = 0;} break; case a_Stmt::tag_while_stmt: { int s0__; int s1__; labeler(_while_stmt(redex)->_1, s0__, r__); labeler(_while_stmt(redex)->_2, s1__, r__); s__ = Simplify_theta_25[Simplify_check[14 + s0__] == 9 ? Simplify_next[14 + s0__] : 0][0]; } break; case a_Stmt::tag_if_stmt: { int s0__; int s1__; int s2__; labeler(_if_stmt(redex)->_1, s0__, r__); labeler(_if_stmt(redex)->_2, s1__, r__); labeler(_if_stmt(redex)->_3, s2__, r__); s__ = Simplify_theta_26[Simplify_check[12 + s0__] == 11 ? Simplify_next[12 + s0__] : 0][0][0]; } break; case a_Stmt::tag_print_stmt: { int s0__; labeler(_print_stmt(redex)->print_stmt, s0__, r__); s__ = 0;} break; default: { int s0__; int s1__; labeler(_block_stmt(redex)->_1, s0__, r__); labeler(_block_stmt(redex)->_2, s1__, r__); s__ = 0;} break; } switch (s__) { case 82: { { redex = _if_stmt(redex)->_3; r__ = 1; goto replacement__; }} break; case 97: { { redex = _if_stmt(redex)->_2; r__ = 1; goto replacement__; }} break; } if (boxed(redex)) { redex->set_rewrite_state(s__); } } void Simplify::labeler (List(Type) & redex, int& s__, int r__) { replacement__: if (r__ && boxed(redex) && redex->has_rewrite_state()) { s__ = redex->get_rewrite_state(); return; } if ((redex)) { int s0__; int s1__; labeler(redex->_1, s0__, r__); labeler(redex->_2, s1__, r__); s__ = 0; } else {s__ = 0; } if (boxed(redex)) { redex->set_rewrite_state(s__); } } void Simplify::labeler (List(LabeledType) & redex, int& s__, int r__) { replacement__: if (r__ && boxed(redex) && redex->has_rewrite_state()) { s__ = redex->get_rewrite_state(); return; } if ((redex)) { int s0__; int s1__; labeler(redex->_1, s0__, r__); labeler(redex->_2, s1__, r__); s__ = 0; } else {s__ = 0; } if (boxed(redex)) { redex->set_rewrite_state(s__); } } void Simplify::labeler (List(Stmt) & redex, int& s__, int r__) { replacement__: if (r__ && boxed(redex) && redex->has_rewrite_state()) { s__ = redex->get_rewrite_state(); return; } if ((redex)) { int s0__; int s1__; labeler(redex->_1, s0__, r__); labeler(redex->_2, s1__, r__); s__ = Simplify_theta_40[Simplify_check[0 + s0__] == 14 ? Simplify_next[0 + s0__] : 0][0]; } else {s__ = 0; } switch (s__) { case 98: { { redex = redex->_2; r__ = 1; goto replacement__; }} break; } if (boxed(redex)) { redex->set_rewrite_state(s__); } } void Simplify::labeler (Decl & redex, int& s__, int r__) { replacement__: if (r__ && boxed(redex) && redex->has_rewrite_state()) { s__ = redex->get_rewrite_state(); return; } int s0__; int s1__; labeler(redex->name,s0__,r__); labeler(redex->typ,s1__,r__); s__ = 0; if (boxed(redex)) { redex->set_rewrite_state(s__); } } void Simplify::labeler (Type & redex, int& s__, int r__) { replacement__: if (r__ && boxed(redex) && redex->has_rewrite_state()) { s__ = redex->get_rewrite_state(); return; } switch(redex->untag()) { case a_Type::tag_primitive_type: { int s0__; labeler(_primitive_type(redex)->primitive_type, s0__, r__); s__ = 0;} break; case a_Type::tag_pointer_type: { int s0__; labeler(_pointer_type(redex)->pointer_type, s0__, r__); s__ = 0;} break; case a_Type::tag_array_type: { int s0__; int s1__; labeler(_array_type(redex)->element,s0__,r__); labeler(_array_type(redex)->bound,s1__,r__); s__ = 0;} break; case a_Type::tag_function_type: { int s0__; int s1__; labeler(_function_type(redex)->arg,s0__,r__); labeler(_function_type(redex)->ret,s1__,r__); s__ = 0;} break; case a_Type::tag_tuple_type: { int s0__; labeler(_tuple_type(redex)->tuple_type, s0__, r__); s__ = 0;} break; default: { int s0__; labeler(_record_type(redex)->record_type, s0__, r__); s__ = 0;} break; } if (boxed(redex)) { redex->set_rewrite_state(s__); } } void Simplify::labeler (LabeledType & redex, int& s__, int r__) { replacement__: if (r__ && boxed(redex) && redex->has_rewrite_state()) { s__ = redex->get_rewrite_state(); return; } int s0__; int s1__; labeler(redex->_1, s0__, r__); labeler(redex->_2, s1__, r__); s__ = 0; if (boxed(redex)) { redex->set_rewrite_state(s__); } } void Simplify::labeler (BinOp & redex, int& s__, int r__) { replacement__: s__ = redex + 3; } ///////////////////////////////////////////////////////////////////////////// // The main program. // We'll test it with a simple program. ///////////////////////////////////////////////////////////////////////////// int main() { // Instantiate a rewriting object. Simplify simplify; // The input is the following block: // // var x : int; // var y : int; // var z : array [10 * 30] of int; // begin // x = 0 + y * 1; // while (1 <> 1) y := y + 1; // print (not false); // end // Stmt prog = block_stmt( list_1_(decl("x",primitive_type("integer")),list_1_(decl("y",primitive_type("integer")),list_1_(decl("z",array_type(primitive_type("integer"),binop(mul,integer(10),integer(30)))),nil_1_))) , list_1_(assign_stmt("x",binop(add,integer(0),binop(mul,var("y"),integer(1)))),list_1_(while_stmt(binop(ne,integer(1),integer(1)),assign_stmt("y",binop(add,var("y"),integer(1)))),list_1_(print_stmt(unaryop(logical_not,boolean(False))),nil_1_))) ); cout << "Before:\n" << prog << "\n\n"; simplify(prog); cout << "After:\n" << prog << "\n"; return 0; } /* ------------------------------- Statistics ------------------------------- Merge matching rules = yes Number of DFA nodes merged = 0 Number of ifs generated = 0 Number of switches generated = 0 Number of labels = 0 Number of gotos = 0 Adaptive matching = disabled Fast string matching = disabled Inline downcasts = disabled -------------------------------------------------------------------------- */