PreviousUpNext

15.3.4  src/app/make7/paths/anchor-dictionary.api

## anchor-dictionary.api -- Operations over abstract names for make7 source files.

# Compiled by:
#     src/app/make7/paths/srcpath-lib.make6

        
# Overview:
#
#     Per unix tradition, .make6 files may refer to files using
#     "absolute" file paths such as   /aa/bb/cc/... or
#     "relative" file paths such as    aa/bb/cc/...
#     where "aa" "bb" "cc" are called path "arcs".
#
#     In addition, make7 supports 
#     "anchored" file paths such as   $dir/aa/bb/cc/...
#     where "$dir" is an "anchor variable".
#          This allows us to move an entire directory of
#     sourcefiles from one spot to another in the filesystem
#     simply by updating one anchor variable setting.
#
#     Furthermore, make7 file syntax allows anchor variables
#     to have both a fixed default value, and also to be
#     temporarily rebound to another value within a given
#     syntactic scope:  We refer to these as the "free"
#     and "bound" values of the anchor variable respectively,
#     by analogy with lambda calculus nomenclature.
#
#     We give the arcs "." and ".." the special meanings
#     of respectively "current" and "parent" directory.
#
#     We also forbid whitespace in paths, to allow simple 
#     parsing of .make6 files.
#
#     Some hosts may allow use of "." ".." as normal
#     arc names, and some host arc names may in fact include
#     whitespace.  We handle these cases by encoding the
#     arc names using octal escape sequences like \045 
#     for each problemantic character.
#
#     Since the user may move around source files from
#     time to time and update anchor variables accordingly,
#     we attempt to evaluate anchor variables, and expressions
#     involving them, as late as possible in the compilation
#     process, by using thunks and lazy-style datastructure
#     techniques as appropriate.
#        This datastructure "laziness" is potentially
#     problematic in the case of paths specified relative to
#     the current working directory ("CWD"), since the CWD
#     may change from time to time, and our "laziness" could
#     thus result in a path being evaluated relative to an
#     unexpected -- and wrong -- CWD value.
#        To avoid this problem, we track the CWD and
#     implement a system of notifications for when the
#     CWD changes, so as to give the effect of evaluating 
#     path expressions as late as possible, but still
#     relative to the expected CWD value.
#
#     Another twist:  The above unix-like path specification
#     is portably supported on all platforms -- we call it
#     "standard" notation -- but sometimes we need access to
#     idiosyncratic functionalities of a particular host's
#     path syntax, in particular to the ability to specify
#     disk volumes on MS-DOS/MS-Windows, so we also support
#     use of the "native" path notation of the host os.
# -->    In .make6 file surface syntax we use a leading "#" on <--
# --> native path expressions to distinguish them from         <--
# --> standard path expressions.                               <--
#
#     Yet another:  We provide facilities to "pickle" and
#     "unpickle" our file reference datastructures, which
#     is to say, to serialize them as bytestrings suitable
#     for storage in diskfiles and then deserialize such
#     bytestrings back into live datastructures.  This
#     lets us propagate state between executions of make7.
#
#     We implement all this as follows:
#
#     o Our "anchors" are simply strings, which
#        we look up in string-keyed maps. 
#
#     o Paths aa/bb/cc/... are represented as lists of strings 
#          ["aa", "bb", "cc", ...]
#       except that mostly we're interested in being able
#       to add and remove arcs from the logical -end- of
#       the path, so we usually use -reversed- path lists
#          [ ..., "cc", "bb", "aa" ]
#
#     o Anchor values are recorded in an "anchor_dictionary"
#       which includes both a
#         a "free"    map recording the current free (default) values of anchors, and a
#         a "bound"   map recording current bound values of anchors.
#
#     o We define type Path_Root to represent the root of a path.
#   

###                                 "The lyf so short, the craft so long to lerne."
###
###                                                       --Geoffrey Chaucer



api Anchor_Dictionary {

    # We define an exception to raise if
    # we encounter an "impossible" byte
    # sequence while unpickling, presumably
    # as a result of diskfile corruption:
    #
    exception FORMAT;

    File;
    Path_Root;                  # Root of a path
    Anchor_Dictionary;
    Anchor = String;
    Basename;

    Renamings        =        List {          anchor: Anchor,          value:  Basename        }; # MUSTDIE

    Key = File;


    compare:  (File, File) -> Order;                    # Compare paths for ordering 

    sync:            Void -> Void;                      # Re-establish stability of ordering. 
    clear:           Void -> Void;                      # Forget all known path names. 
    revalidate_cwd:  Void -> Void;                      # Re-validate current working directory. 

    add_cwd_watcher:  (String -> Void) -> Void;         # Register a "client" module that wishes 
                                                        # to be notified when the CWD changes.   
                                                        # Currently called only once, at bottom of   src/app/make7/simple-concurrency/unix-compile-client.pkg

    # Make sure all such clients get notified
    # about the CWD during next validation:
    #
    schedule_notification:

        Void -> Void;


    # A default dictionary containing
    # just the ROOT definition:
    #
    dictionary: Anchor_Dictionary;


    #  Destructive updates to anchor settings (for configuration) 
    #
    set_anchor:     (Anchor_Dictionary, Anchor,    Null_Or( String )) -> Void;              #  Native syntax! 
    get_anchor:     (Anchor_Dictionary, Anchor) -> Null_Or( String );

    print_anchors:  (Anchor_Dictionary, String) -> Void;

#   my keyvals_list:      Map( X ) ->  List( key::Key * X )             src/lib/src/map.api
#   my listAnchorsi:    Anchor_Dictionary -> List( Anchor * String)     src/lib/src/ord-map.apk


    #  Make abstract paths: 
    
    from_native
        :
        { plaint_sink: String -> Void }      #  Where to send error messages. 
        ->
        { path_root: Path_Root,
          spec: String
        }
        ->
        Basename;

    from_standard
        :
        { plaint_sink: String -> Void,      #  Where to send error messages. 
          anchor_dictionary: Anchor_Dictionary
        }
        ->
        { path_root: Path_Root,
          spec:    String
        }
        ->
        Basename;



    extend              #  Augment a basename (naming a directory) with a list of arcs.
        :
        Basename -> List( String ) -> Basename;



    file                #  Check that there is at least one arc after the path's path_root.
        :
        Basename -> File;



    file_to_basename    #  To be able to pickle a file, turn it into a basename first... 
        :
        File -> Basename;



    # Directory paths (path_roots) 
    #
    cwd:  Void -> Path_Root;
    dir:  File -> Path_Root;

    # Get info out of abstract paths:
    #
    os_string:   File -> String;
    os_string' : File -> String;        #  Use relative path if shorter 

    abbreviate  : String -> String;     # Abbreviate any ROOT prefix

    # Get path relative to the file's path_root;
    # this will produce an absolute path if
    # the original spec was not relative --
    # i.e., if it was anchored or absolute:
    #
    os_string_relative:  File -> String;

    # Same for basename:
    #
    os_string_basename_relative:  Basename -> String;

    # Get name of path root:
    #
    os_string_dir:  Path_Root -> String;

    # Get name of basename:
    #
    os_string_basename:  Basename -> String;

    # Get a human-readable (well, sort of) description:
    #
    describe:  File -> String;

    # Get a time stamp:
    #
    time_stamp:  File -> time_stamp::Time_Stamp;                # time_stamp    is from   src/app/make7/paths/timestamp.pkg

    # Portable encodings that avoid whitespace:
    #
    encode:  File -> String;
    decode:  Anchor_Dictionary -> String -> File;

    # Check whether encoding (result
    # of "encode") is absolute --
    # i.e., not anchored and not relative:
    #
    encoding_is_absolute
        :
        String -> Bool;



    pickle
        :
        { warn: (Bool, String) -> Void }
        ->
        { file:        Basename,
          relative_to: File
        }
        ->
        List( List( String ) );



    unpickle
        :
        Anchor_Dictionary
        ->
        { pickled: List(  List(  String ) ),
          relative_to: File
        }
        ->
        Basename;

};





Comments and suggestions to: bugs@mythryl.org

PreviousUpNext