PreviousUpNext

15.4.406  src/lib/compiler/back/low/tools/arch/adl-symboltable.pkg

## adl-symboltable.pkg -- derived from  ~/src/sml/nj/smlnj-110.58/new/new/src/MLRISC/Tools/ADL/mdl-env.sml
#
# architecture description symboltable.

# Compiled by:
#     src/lib/compiler/back/low/tools/arch/make-sourcecode-for-backend-packages.lib



###        "Use the word cybernetics, Norbert,
###         because nobody knows what it means.
###         This will always put you at
###         an advantage in arguments."
###
###                         -- Claude Shannon 



stipulate
    package err =  adl_error;                                                                           # adl_error                     is from   src/lib/compiler/back/low/tools/line-number-db/adl-error.pkg
    package lnd =  line_number_database;                                                                # line_number_database          is from   src/lib/compiler/back/low/tools/line-number-db/line-number-database.pkg
    package spp =  simple_prettyprinter;                                                                # simple_prettyprinter          is from   src/lib/prettyprint/simple/simple-prettyprinter.pkg
    package mms =  adl_mapstack;                                                                        # adl_mapstack                  is from   src/lib/compiler/back/low/tools/arch/adl-mapstack.pkg
    package mtj =  adl_type_junk;                                                                       # adl_type_junk                 is from   src/lib/compiler/back/low/tools/arch/adl-type-junk.pkg
    package raw =  adl_raw_syntax_form;                                                                 # adl_raw_syntax_form           is from   src/lib/compiler/back/low/tools/adl-syntax/adl-raw-syntax-form.pkg
    package rsu =  adl_raw_syntax_unparser;                                                             # adl_raw_syntax_unparser       is from   src/lib/compiler/back/low/tools/adl-syntax/adl-raw-syntax-unparser.pkg
herein

    # This package is used in:
    #
    #     src/lib/compiler/back/low/tools/arch/adl-typing.pkg
    #     src/lib/compiler/back/low/tools/arch/adl-gen-rewrite.pkg
    #     src/lib/compiler/back/low/tools/arch/sourcecode-making-junk.pkg
    #     src/lib/compiler/back/low/tools/arch/adl-gen-ssaprops.pkg
    #     src/lib/compiler/back/low/tools/arch/adl-gen-delay.pkg
    #     src/lib/compiler/back/low/tools/arch/architecture-description.pkg
    #     src/lib/compiler/back/low/tools/arch/make-sourcecode-for-translate-machcode-to-asmcode-xxx-g-package.pkg
    #     src/lib/compiler/back/low/tools/arch/adl-gen-rtlprops.pkg
    #     src/lib/compiler/back/low/tools/arch/make-sourcecode-for-translate-machcode-to-execode-xxx-g-package.pkg
    #     src/lib/compiler/back/low/tools/arch/adl-rtl-comp-g.pkg
    #
    package   adl_symboltable
    : (weak)  Adl_Symboltable                                                                           # Adl_Symboltable               is from   src/lib/compiler/back/low/tools/arch/adl-symboltable.api
    {
        Symboltable
            = 
            SYMBOLTABLE
              { te:  mms::Mapstack( raw::Type ),                                                        # Type symboltable.
                ve:  mms::Mapstack( (raw::Expression, raw::Type) ),                                     # Value symboltable.
                ee:  mms::Mapstack( (List(raw::Declaration), Symboltable)       ),                      # Package symboltable.
                de:  List( raw::Declaration ),                                                          # Declarations symboltable.
                se:  List( raw::Declaration )                                                           # Api symboltable.
              };


        infix my ++ ;
        infix my @@ ;
        infix my ===> ;

        @@   = mms::union;
        ===> = mms::bind;


        e = mms::empty;

        empty = SYMBOLTABLE { te => e,
                              ve => e,
                              ee => e,
                              de => [],
                              se => []
                            };


        # '++' combines two symboltables:
        #
        fun (SYMBOLTABLE { te=>te1, ve=>ve1, ee=>ee1, de=>de1, se=>se1 } )
         ++ (SYMBOLTABLE { te=>te2, ve=>ve2, ee=>ee2, de=>de2, se=>se2 } )
            =
            SYMBOLTABLE  { te =>  te1 @@ te2,
                           ve =>  ve1 @@ ve2,
                           ee =>  ee1 @@ ee2,
                           de =>  de1 @  de2,
                           se =>  se1 @  se2
                         };

        fun make_decl d   =   SYMBOLTABLE { te=>e, ve=>e,   ee=>e, de=> [d], se=> []  };
        fun make_api  d   =   SYMBOLTABLE { te=>e, ve=>e,   ee=>e, de=> [],  se=> [d] };
        fun make_vals vbs =   SYMBOLTABLE { te=>e, ve=>vbs, ee=>e, de=> [],  se=> []  };

        fun named_variable (id, e, t)
            =
            make_vals (id ===> (e, t));

        fun type_bind (id, t)
            =
            SYMBOLTABLE { te => id ===> t,
                          ve => e,
                          ee => e,
                          de => [],
                          se => []
                        };

        fun named_package (id, args, e')
            =
            SYMBOLTABLE { te => e,
                          ve => e,
                          ee => id ===> (args, e'),
                          de => [],
                          se => []
                        };

        #  Create a new free variable; instantiation and generalization:
        #
        fun make_variable (SYMBOLTABLE _)   =  mtj::make_variable 0;            # XXX 
        fun instantiate   (SYMBOLTABLE _) t =  mtj::instantiate  0 t;           # XXX 
        fun generalize    (SYMBOLTABLE _) t =  mtj::generalize   0 t;           # XXX 
        fun lambda        (SYMBOLTABLE _) t =  mtj::lambda       0 t;           # XXX 

        # Extract components:
        #
        fun de (SYMBOLTABLE { de, ... } ) =  de;
        fun se (SYMBOLTABLE { se, ... } ) =  se;

        fun sumtype_definitions (SYMBOLTABLE { de, ... } )
            =  
            list::fold_backward collect [] de
            where
                fun collect (raw::SUMTYPE_DECL (dbs, _),                      dbs') =>   dbs @ dbs';
                    collect (raw::SOURCE_CODE_REGION_FOR_DECLARATION (_,   d), dbs') =>   collect (d, dbs');
                    collect (_,                                                dbs') =>   dbs';
                end;
            end;


        # Look up components in the symboltable:
        #
        fun find_type (e as SYMBOLTABLE { te, ee, ... } ) (raw::IDENT([], id))
                =>
                mms::get te id
                except
                    _ = {   err::error("undefined type '" + id + "'");
                            make_variable e;
                        };

            find_type (SYMBOLTABLE { ee, ... } ) (raw::IDENT (s ! ss, id))
                =>
                find_type (find_package' ee (raw::IDENT (ss, s))) (raw::IDENT([], id));
        end

        also
        fun find_value' err (e as SYMBOLTABLE { ve, ee, ... } ) (raw::IDENT([], id))
                =>
                instantiate e (mms::get ve id)
                        except
                            _ = {   err id;
                                    (raw::LITERAL_IN_EXPRESSION (raw::INT_LIT 0), make_variable e);
                                };

            find_value' err (SYMBOLTABLE { ee, ... } ) (raw::IDENT (s ! ss, id))
                =>
                find_value' err (find_package' ee (raw::IDENT (ss, s))) (raw::IDENT([], id));
        end

        also
        fun find_value e x
            =
            find_value' (\\ x =  err::error("undefined value '" + x + "'")) e x

        also
        fun find_package (SYMBOLTABLE { ee, ... } ) id
            =
            find_package' ee id

        also
        fun find_package' ee (raw::IDENT([], id))
                =>
                #2 (mms::get ee id)
                except
                    _ = {   err::error("undefined package '" + id + "'");
                            empty;
                        };

            find_package' ee (raw::IDENT (s ! ss, id))
                =>
                find_package (find_package' ee (raw::IDENT (ss, s))) (raw::IDENT([], id));
        end;

        # Interators:
        #
        fun fold_val f x (SYMBOLTABLE { ve, ... } )
            = 
            mms::fold
                (\\ (id, (e, type), l) =  f (id, e, type, l))
                x
                ve;


        # Elaborate a declaration in an symboltable.
        # We return a delta symboltable containing only
        # info from the given declaration -- use ++ to
        # combine new symboltable with pre-existing one:
        #
        fun digest_declaration symboltable d
            = 
            ddd  symboltable  lnd::dummy_loc  d
            where
                # Elaborate a declaration:
                # 
                make_decl =   \\ (l, d) =  make_decl (raw::SOURCE_CODE_REGION_FOR_DECLARATION (l, d));
                make_api  =   \\ (l, d) =  make_api  (raw::SOURCE_CODE_REGION_FOR_DECLARATION (l, d));

                fun ddd symboltable l (d as raw::SUMTYPE_DECL (dbs, tys)) =>  make_decl (l, d) ++ make_api (l, d);
                    ddd symboltable l (d as raw::BASE_OP_DECL cbs)         =>  make_decl (l, d);
                    ddd symboltable l (d as raw::FUN_DECL _)               =>  make_decl (l, d);
                    #
                    ddd symboltable l (d as raw::RTL_DECL _)               =>  make_decl (l, d);
                    ddd symboltable l (d as raw::RTL_SIG_DECL _)           =>  make_decl (l, d);
                    ddd symboltable l (d as raw::VAL_DECL _)               =>  make_decl (l, d);
                    #
                    ddd symboltable l (d as raw::TYPE_API_DECL _)          =>  make_api  (l, d);
                    ddd symboltable l (d as raw::VALUE_API_DECL _)         =>  make_api  (l, d);
                    ddd symboltable l (d as raw::LOCAL_DECL (d1, d2))      =>  make_decl (l, d);                #  let symboltable' = Ds symboltable l d1 in Ds (symboltable ++ symboltable') l d2 end 
                    #
                    ddd symboltable l (d as raw::SEQ_DECL ds')             =>  ds symboltable l ds';
                    ddd symboltable l (d as raw::OPEN_DECL ids)            =>  make_decl (l, d) ++ open_strs symboltable ids;
                    #
                    ddd symboltable l (d as raw::PACKAGE_DECL (id, args, _, raw::DECLSEXP ds'))
                        =>
                        {   symboltable' =  ds symboltable l ds';
                            #
                            named_package (id, args, symboltable')   ++   make_decl (l, d);
                        };

                    ddd symboltable l (raw::PACKAGE_API_DECL _)          =>  empty;
                    ddd symboltable l (d as raw::INFIX_DECL _)           =>  make_decl (l, d);
                    ddd symboltable l (d as raw::INFIXR_DECL _)          =>  make_decl (l, d);
                    ddd symboltable l (d as raw::NONFIX_DECL _)          =>  make_decl (l, d);

                    ddd symboltable _ (raw::SOURCE_CODE_REGION_FOR_DECLARATION (l, d))
                        =>
                        {   err::set_loc l;
                            #
                            ddd symboltable l d;
                        };

                    ddd symboltable l d
                        =>
                        err::fail("illegal declaration: " + (spp::prettyprint_expression_to_string (rsu::decl d)));
                end

                also
                fun ds symboltable l []             =>  empty;
                    ds symboltable l (d ! more_ds)  =>  {   symboltable' =  ddd symboltable l d;
                                                            #
                                                            symboltable' ++ ds (symboltable ++ symboltable') l more_ds;
                                                        };
                end

                also    #  open up a list of packages
                fun open_strs symboltable ids
                    = 
                    list::fold_backward
                        (\\ (id, symboltable') =   find_package symboltable id  ++  symboltable')
                        empty
                        ids;
            end;


        # Return a symboltable containing the
        # original symboltable augmented by
        # the given declaration:
        #
        fun note_declaration  symboltable  declaration
            =
            symboltable   ++   digest_declaration symboltable declaration;

        # Treat a type expression as a pattern
        # and compute its set of namings.
        # Duplicated names are assigned unique suffixes.
        #
        fun namings_in_type  type
            = 
            (*names, get_name)
            where
                names =  mms::envir  "names";

                fun count id
                    =
                    {   my (n, total) = mms::lookup names id;
                        total := *total + 1;
                    }
                    except
                        _ = mms::set  names  (id, (REF 0, REF 1));


                fun get_name id
                    =
                    {   my (n, total) =  mms::lookup names id;
                        #
                        if (*total == 1)
                            #
                            id;
                        else
                            n := *n + 1;
                            id + int::to_string *n;
                        fi;
                    };

                fun f (raw::IDTY (raw::IDENT(_, id))) =>  count id;
                    f (raw::REGISTER_TYPE id)         =>  count id;                             # This (with id=="bar") came from a   foo: $bar   declaration -- the '$' distinguishes these from regular type declarations.
                    #
                    f (raw::APPTY(_,[type]))          =>  f type;
                    #
                    f (raw::TUPLETY tys)              =>  apply f tys;
                    f (raw::RECORDTY ltys)            =>  apply  (\\ (id, _) = count id)  ltys;
                    #
                    f _                               =>  ();
                end;

                f type;
            end;

        # Look up from nested symboltable:
        #
        fun decl_of (SYMBOLTABLE { ee, ... } ) id
            =
            {   (mms::get ee id) ->   (_, SYMBOLTABLE { de, ... } );
                #
                raw::SEQ_DECL de;
            }
            except _ =  raw::VERBATIM_CODE [];


        fun generic_arg_of (SYMBOLTABLE { ee, ... } ) id
            = 
            {   (mms::get ee id) ->   (args, _);
                #
                raw::SEQ_DECL args;
            }
            except _ =   raw::VERBATIM_CODE [];


        fun type_of (SYMBOLTABLE { ee, ... } ) id
            = 
            {   (mms::get ee id) ->   (_, SYMBOLTABLE { se, ... } );
                raw::SEQ_DECL se;
            }
            except _ =   raw::VERBATIM_CODE [];
    };
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext