PreviousUpNext

15.4.176  src/lib/c-kit/src/ast/anonymous-structs.pkg

#  Anonymous-structs.pkg 
#  implements package equality for unions, structs, enums, at the level of ParseTree 

# Compiled by:
#     src/lib/c-kit/src/ast/ast.sublib

stipulate
    package f8b =  eight_byte_float;                                    # eight_byte_float      is from   src/lib/std/eight-byte-float.pkg
herein

    package ty_eq {

        stipulate

            include package   parse_tree;

        herein

            fun eq_list eq (x ! xl, y ! yl)
                    =>
                    eq (x, y) and eq_list eq (xl, yl);

                eq_list eq (NIL, NIL)
                    =>
                    TRUE;

                eq_list _ _
                    =>
                    FALSE;
            end;


            fun eq_pair (eq1, eq2) ((x1, x2), (y1, y2))
                =
                eq1 (x1, y1) and eq2 (x2, y2);


            fun eq_string (x: String, y)
                =
                x == y;


            fun eq_declarator (EMPTY_DECR, EMPTY_DECR) => TRUE;
                eq_declarator (ELLIPSES_DECR, ELLIPSES_DECR) =>   TRUE;
                eq_declarator (VAR_DECR s1, VAR_DECR s2)     =>   s1 == s2;

                eq_declarator (ARRAY_DECR (d1, e1), ARRAY_DECR (d2, e2))
                    =>
                    eq_declarator (d1, d2) and eq_expr (e1, e2);

                eq_declarator (POINTER_DECR d1, POINTER_DECR d2)
                    =>
                    eq_declarator (d1, d2);

                eq_declarator (QUAL_DECR (q1, d1), QUAL_DECR (q2, d2))
                    =>
                    q1 == q2 and eq_declarator (d1, d2);

                eq_declarator (FUNC_DECR arg1, FUNC_DECR arg2)
                    =>
                    eq_pair (eq_declarator, eq_list (eq_pair (eq_decltype, eq_declarator)))
                    (arg1, arg2);

                eq_declarator _ => FALSE;   #  fix this 
            end

            also
            fun eq_decltype (x: Decltype, y) =  #  not an equality type.  Why? 
                raise exception DIE "eqDecltype not implemented"

            also
            fun eq_ctype (x: Ctype, y)
                = 
                raise exception DIE "eqCtype not implemented"
                #  (x = y) not an equality type?  Why? 

            also
            fun eq_exp_op (x: Operator, y)
                =
                raise exception DIE "eqExpOp not implemented"
                #  (x = y) not an equality type?  Why? 

            also
            fun eq_expr (EMPTY_EXPR, EMPTY_EXPR) => TRUE;
                eq_expr (INT_CONST i, INT_CONST j) => (i==j);

                eq_expr (REAL_CONST i, REAL_CONST j)
                    =>
                    case (f8b::compare (i, j))
                        #
                        EQUAL => TRUE;
                        _     => FALSE;
                    esac;
                eq_expr (STRING i, STRING j) => (i==j);
                eq_expr (ID i, ID j) => (i == j);

                eq_expr (UNOP (exp_op, expr), UNOP (exp_op', expr'))
                    =>
                    eq_exp_op (exp_op, exp_op') and eq_expr (expr, expr');

                eq_expr (BINOP (exp_op, expr1, expr2), BINOP (exp_op', expr1', expr2'))
                    =>
                    eq_exp_op (exp_op, exp_op') and eq_expr (expr1, expr1') and eq_expr (expr2, expr2');

                eq_expr (QUESTION_COLON (expr1, expr2, expr3),
                         QUESTION_COLON (expr1', expr2', expr3')
                        )
                    =>
                    eq_expr (expr1, expr1') and eq_expr (expr2, expr2')
                    and
                    eq_expr (expr3, expr3');  

                eq_expr (CALL (expr1, exprl), CALL (expr1', exprl'))
                    =>
                    eq_expr (expr1, expr1') and (eq_list eq_expr (exprl, exprl'));

                eq_expr (CAST (ctype, expr), CAST (ctype', expr')) => eq_expr (expr, expr');
                eq_expr (INIT_LIST exprl, INIT_LIST exprl') => eq_list eq_expr (exprl, exprl');
                eq_expr (EXPR_EXT _, EXPR_EXT _) => FALSE;
                eq_expr(_, _) => FALSE;
            end;

            #  Dpo: some small changes to get eqType type correct but is the equality correct? 
            # 
            fun eq_type ( { qualifiers => [], specifiers => [ENUM { tag_opt=>s_opt, enumerators=>sel, ... } ] }
                    ,{ qualifiers => [], specifiers => [ENUM { tag_opt=>s_opt', enumerators=>sel', ... } ] } )
                    =>
                    s_opt == s_opt' and eq_list (eq_pair (eq_string, eq_expr)) (sel, sel');

                eq_type ( { qualifiers => [], specifiers => [STRUCT { is_struct=>b,  tag_opt => s_opt,  members => cdell } ] },
                          { qualifiers => [], specifiers => [STRUCT { is_struct=>b', tag_opt => s_opt', members => cdell' } ] } )
                    =>
                    (b == b') and s_opt == s_opt' and
                    eq_list
                      (eq_pair (eq_ctype, eq_list (eq_pair (eq_declarator, eq_expr))))
                      (cdell, cdell');

                eq_type(_, _)
                    =>
                    FALSE;
            end;

        end;                    # stipulate

    }; #  package ty_eq 
end;

package anonymous_structs {


    # ------------------------------------------------------------
    # Resolving Anonymous Structs (for inter-file analysis)
    # The problem: need to resolve structurally equiv anonymous structs in
    #               different files to same tid.
    #  ------------------------------------------------------------

    anonymous_structs_enums_list = REF (NIL:   List( (parse_tree::Ctype, tid::Uid) ));


    fun reset_anonymous_structs_enums_list ()
        =
        anonymous_structs_enums_list := NIL;


    fun find_anon_struct_enum type
        =
        finder *anonymous_structs_enums_list
        where 

            fun finder ((type', tid) ! l)
                    => 
                    if (ty_eq::eq_type (type, type'))
                         (THE tid);

                            /* debugging code:
                            print ("recovered anon struct with tid " + (Tid::to_string tid)
                                   + "\n");
                            (case type of 
                               ParseTree::Enum _ => print "Enum\n"
                             | ParseTree::Struct(_, _, (_, (dec, e) ! _) ! _) => 
                                 (case dec of
                                    ParseTree::Name name => print("Struct " + name + ".. \n")
                                  | _ => print("Struct ? .. \n"))
                             | _ => print "Something else ..\n"); */

                    else
                       finder l;
                    fi;

                finder NIL => NULL;
            end;
        end;

    fun add_anon_tid (type, tid)
        = 
        {   l = (type, tid) ! *anonymous_structs_enums_list;

            anonymous_structs_enums_list := l;
        };

};                              # package anonymous_structs 


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext