PreviousUpNext

15.3.23  src/app/makelib/tools/main/core-tools.api

## core-tools.api
#
# The common core of both public and private interface
# to makelib's tools mechanism.
#
#

# Compiled by:
#     src/app/makelib/makelib.sublib

stipulate
    package fil =  file__premicrothread;                                        # file__premicrothread          is from   src/lib/std/src/posix/file--premicrothread.pkg
    package mvi  =  makelib_version_intlist;                                    # makelib_version_intlist       is from   src/app/makelib/stuff/makelib-version-intlist.pkg
herein

    # This api is referenced in no packages;
    # it is included in:
    #
    #     src/app/makelib/tools/main/private-makelib-tools.api
    #
    api Core_Tools {

        Ilk = String;
            #
            # We don't make ilks abstract.
            # It doesn't look like there
            # would be much point to it.

        File_Path;
            #
            # We keep source paths abstract.
            # Tool writers should not mess
            # with their internals.
            #
            # The function that makes a srcpath
            # from a string is passed as part of
            # the input specification (type "spec").
            #
            # Which function is originally be passed
            # depends on which syntax was used for
            # this member in its .lib file.
            #
            # Most tools will want to work on
            # native pathname syntax (function "outdated" -- see below -- depends
            # on native syntax!).
            #
            # In these cases the tool should first convert
            # the name to a srcpath and then get the native
            # string back by applying "native_spec".

        Dir_Path;

        Renamings = List { anchor: String, value: Dir_Path };                   # MUSTDIE

        native_spec:  File_Path -> String;                                      # Get the spec (i.e., relative to the directory context) of a path: 

        native_pre_spec:  Dir_Path -> String;                                   #  Same for Dir_Path... 

        srcpath:  Dir_Path -> File_Path;                                        # Make a File_Path from a Dir_Path, checking that the "at least one arc" rule is satisfied... 

        augment:  Dir_Path -> List( String ) -> Dir_Path;                       # Augment a Dir_Path with extra arcs. The new path has inherits the context (i.e., any anchoring) from the original one.

        exception TOOL_ERROR  { tool: String, msg: String };

        Pathmaker = Void -> Dir_Path;

        Fnspec = {   name:      String,                                         # A filename specification. 
                     make_path: Pathmaker
                 };

        Tool_Option                                                             # Case-by-case parameters that can be passed to tools... 
          #
          = STRING  Fnspec
          #
          | SUBOPTS   { name:           String,
                        tool_options:   Tool_Options
                      }
        withtype
            Tool_Options = List( Tool_Option );

        Tooloptcvt
            =
            Null_Or( Tool_Options ) ->
            Null_Or( Tool_Options );

        Spec
          =
          { name:               String,
            make_path:          Pathmaker,
            #
            ilk:                Null_Or( Ilk ),
            tool_options:       Null_Or( Tool_Options ),
            #   
            derived:            Bool
          };
          #
          # A member specification consists of the actual string, an optional
          # ilk name, (optional) tool options, a function to convert a
          # string to its corresponding srcpath, and information about whether
          # or not this source is an "original" source or a derived source
          # (i.e., output of some tool).


        Inlining
            =
            Null_Or( Null_Or( Int ) );                                          #  see ....controls::inline... 


        Controller
            =
            { save_controller_state: Void -> Void -> Void,                              # Generate a thunk containing current controller state, which when run will restore controller to that state.
              set:          Void -> Void
            };
            #
            # A controller is a generic mechanism for manipulating state.
            #
            # The first stage of save_controller_state is meant to capture the part of
            # the state in question so that the second stage can restore it.
            #
            # Function 'set', on the other hand, serves to establish the
            # new state.
            #
            # All controllers associated with a Mythryl source
            # are invoked for both parsing and compilation.
            #
            # Roughly speaking, given a controller c, each of these two phases
            # is bracketed as follows:
            #
            #   {   restore = c.save_controller_state ();
            #       c.set ();
            #       parse_or_compile ()
            #       then
            #           restore ();
            #   }

        Ml_Parameters
            =
            { share:            sharing_mode::Request,
              pre_compile_code: Null_Or(String),        
              postcompile_code: Null_Or(String),        
              split:            Inlining,
              noguid:           Bool,
              is_local:         Bool,
              controllers:      List( Controller )
            };

        Makelib_Parameters
            =
            { version:   Null_Or( mvi::Makelib_Version_Intlist )
            ,  renamings: Renamings                                     # MUSTDIE
            };

        Expansion
            =
            { source_files:     List( (File_Path, Ml_Parameters)                ),
              makelib_files:    List( (File_Path, Makelib_Parameters)           ),
              sources:          List( (File_Path, { ilk: Ilk, derived: Bool })  )
            };
            #
            # The goal of applying tools to members is to obtain an "expansion",
            # i.e., a list of source-files and a list of .lib-files.
            # We also obtain a list of "sources".  This is used to implement makelib::sources,
            # i.e., to generate dependency information etc.


        Partial_Expansion                                               # A partial expansion is an expansion with a list of things yet to be expanded...
            =
            (Expansion,  List( Spec ));


        Rulefn =  Void -> Partial_Expansion;
            #
            # A rule takes a spec and a rulecontext
            # where the name contained in the spec
            # -- if relative -- is considered relative
            # to the directory of the corresponding
            # description file.
            #
            # In general, when coding a rule one would
            # write a rule function and pass it to
            # the context, which will temporarily change
            # the current working directory to the one that
            # holds the description file ("the context").
            #
            # If this is not necessary for the rule to work
            # correctly, then one can simply ignore the
            # context (this saves system call overhead
            # during dependency analysis).
            # 
            # If the rule yields a genuine partial expansion
            # (where the resulting spec list is not empty),
            # then it must pass the proper "path maker"
            # along with each new name.
            # 
            # For most cases this will be the given
            # "native path maker" because most rules
            # work on native path names.
            # 
            # Some rules, however, might want to use
            # the same convention for derived specs
            # that was used for the original spec.

        Rulecontext
            =
            Rulefn -> Partial_Expansion;

        Rule
            =
            { spec:             Spec,
              native2pathmaker: String -> Pathmaker,
              context:          Rulecontext,
              default_ilk_of:   Fnspec -> Null_Or( Ilk ),

              sysinfo: { get_makelib_preprocessor_symbol_value: String -> Null_Or( Int ),               # If given preprocessor symbol is defined, returns its Int value, otherwise returns NULL.
                         platform:                              String                                  #  "intel32-linux" or such. 
                       }
            }
            ->
            Partial_Expansion;

        note_ilk:  (Ilk, Rule) -> Void;                                                                 #  Install an ilk:

        # Classifiers are used when the ilk
        # is not given explicitly: 
        #
        Filename_Classifier
            #
            = FILENAME_SUFFIX_CLASSIFIER  String -> Null_Or( Ilk )
            #
            | GENERAL_FILENAME_CLASSIFIER  { name: String, make_filename: Void -> String }
                                           ->
                                           Null_Or( Ilk )
            ;

        standard_filename_suffix_classifier                                                             # Make a classifier which looks for a specific file name suffix. 
            :
            { suffix: String, ilk: Ilk } -> Filename_Classifier;



        Extension_Style                                                                                 # Two standard ways of dealing with filename extensions...
          #                                                                                             # (Tool options can be calculated from the options that we have.)
          = EXTEND                    List ((String, Null_Or( Ilk ), Tooloptcvt))
          | REPLACE  (List( String ), List ((String, Null_Or( Ilk ), Tooloptcvt)))
          ;

        #  Perform filename extension 
        #
        extend_filename
          :
          Extension_Style
          ->
          (String,  Null_Or(Tool_Options))
          ->
          List ((String, Null_Or( Ilk ), Null_Or( Tool_Options )) )
          ;

        # Check for outdated files; the pathname
        # strings must be in native syntax!
        #
        outdated:  String -> (List( String ), String) -> Bool;

        # Alternative way of checking for outdated-ness
        # using a "witness" file.  The idea is that if
        # both targetFileName and timestampFileName
        # exist, then targetFileName is considered outdated
        # if timestampFileName is older than sourceFileName.
        #
        # Otherwise, if targetFileName exists but timestampFileName does not,
        # then targetFileName is considered outdated if it is older than
        # sourceFileName.  If targetFileName does not exist, it is
        # always considered outdated. 
        #
        outdated'
            :
            String
            ->
            { source_file_name:     String,
              timestamp_file_name:  String,
              target_file_name:     String
            }
            ->
            Bool;


        open_text_output                                        # Open output file; make all necessary directories for it.
            :
            String -> fil::Output_Stream;


        make_all_directories_on_path                            # Make all directories leading up to a given file;
            :                                                   # the file itself is to be left alone.
            String -> Void;


        note_filename_classifier                                # Install a classifier.
            :
            Filename_Classifier -> Void;


        parse_options                                           # Grab all named options.
          :
          { tool:           String,
            keywords:       List( String ),
            tool_options:   Tool_Options
          }
          ->
          { matches:            String -> Null_Or( Tool_Options ),
            remaining_options:  List( String )
          };
    };
end;


# (C) 2000 Lucent Technologies, Bell Laboratories
# Author: Matthias Blume (blume@kurims.kyoto-u.ac.jp)
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext