PreviousUpNext

15.3.181  src/lib/compiler/back/low/tools/match-compiler/match-compiler.api

# match-compiler.api
#
# A simple pattern matching compiler.
# This one uses Mikael Pettersson's algorithm.
#
# NOTE: This module is completely detached
# from the rest of the infrastructure, so
# that it can be reused.

# Compiled by:
#     src/lib/compiler/back/low/tools/match-compiler.lib

###             "There are always alternatives."
###
###                     -- Spock, "The Galileo Seven," "Star Trek"



api  Match_Compiler {

    #  These are client defined types 
    package guard:    api {  Guard;
                            to_string:  Guard -> String;
                      };

    package expression: api {  Expression;
                             to_string:  Expression -> String;
                        };

    package action:   api {  Action; };
    package con:      api {  Con;  compare:  (Con, Con) -> Order; };
    package literal:  api {  Literal;
                           compare:  (Literal, Literal) -> Order; 
                      };

    package variable:     api {  Var; };

    #  These are new types 
    Index = INT   Int | LABEL  variable::Var;
    Path  = PATH  List( Index );

    package path
        :
        api {  compare:  (Path, Path) -> Order;
             to_string:  Path -> String;
             to_ident:  Path -> String;
             dot:      (Path, Index) -> Path;

             package map:  Map                  # Map   is from   src/lib/src/map.api
                         where  key::Key == Path;
        };

    Name = VAR  variable::Var | PVAR  Path;

    package subst
        :
        Map             # Map   is from   src/lib/src/map.api
        where
            key::Key == variable::Var;

    Pattern;
    Subst = subst::Map( Name );

    Decon
        = CON    con::Con           #  Match a user constructor.
        | LIT    literal::Literal;  #  Match a user literal.

    exception MATCH_COMPILER  String;

    Compiled_Dfa;               #  Compiled pattern matching dfa 
    Compiled_Rule;
    Rule_Number = Int;
    Compiled_Pat;



    # Compile a user pattern into internal pattern form;
    # This function abstracts out the computation of paths and namings.

    rename
        :
        ( { id_pattern:      variable::Var -> Compiled_Pat,
            as_pattern:      (variable::Var, A_pattern) -> Compiled_Pat,
            wild_pattern:    Void -> Compiled_Pat,
            cons_pattern:    (con::Con, List( A_pattern )) -> Compiled_Pat,
            tuple_pattern:   List( A_pattern ) -> Compiled_Pat,
            record_pattern:  List( (variable::Var, A_pattern) ) -> Compiled_Pat,
            lit_pattern:     literal::Literal -> Compiled_Pat,

            # logical connectives and other extensions to the standard
            or_pattern:      List( A_pattern ) -> Compiled_Pat,
            and_pattern:     List( A_pattern ) -> Compiled_Pat,
            not_pattern:     A_pattern -> Compiled_Pat,
            where_pattern:   (A_pattern, guard::Guard) -> Compiled_Pat,
            nested_pattern:  (A_pattern, ((Int, expression::Expression)), A_pattern) -> Compiled_Pat
          }
          -> A_pattern
          -> Compiled_Pat
        )
        ->
        { number:               Rule_Number,                            #  rule number 
          patterns:             List( A_pattern ),                      #  the pattern 
          guard:                Null_Or( guard::Guard ),                #  optional guard 
          action:               action::Action,                         #  Action 
          match_fail_exception: Null_Or( variable::Var )                # Currently ignored. See comments for MATCH_FAIL_EXCEPTION_IN_EXPRESSION in   src/lib/compiler/back/low/tools/adl-syntax/adl-raw-syntax-form.api
        }
        ->
        Compiled_Rule;


    #  Compile a set of canonical rules into a dfa  
    compile
        :
        { compiled_rules: List( Compiled_Rule ),
          compress: Bool
        }
        ->
        Compiled_Dfa;

    exhaustive:  Compiled_Dfa -> Bool;
    redundant:   Compiled_Dfa -> int_list_set::Set;

    #  For debugging 
    to_string:   Compiled_Dfa -> String;


    # Generate code for a compiled dfa.
    # Assumes an ML-like language:

    code_gen
        :  
        { gen_fail:  Void -> expression::Expression,
          gen_ok:    action::Action -> expression::Expression,
          gen_path:  Path -> expression::Expression,
          gen_bind:  List ((variable::Var, expression::Expression)) -> List( A_decl ),
          gen_case:  (variable::Var,  List ((Decon, List( Null_Or( Path ) ), expression::Expression)), 
                      Null_Or( expression::Expression )) -> expression::Expression,
          gen_if:    (guard::Guard, expression::Expression, expression::Expression) -> expression::Expression,
          gen_goto:  (Int, List( variable::Var )) -> expression::Expression, #  Call a function 
          gen_fun:   (Int, List( variable::Var ), expression::Expression) -> A_decl, #  function def 
          gen_cont:  (variable::Var, Int, List( variable::Var )) -> A_decl,
          gen_let:   (List( A_decl ), expression::Expression) -> expression::Expression,
          gen_variable:   Path -> variable::Var,
          gen_val:   (variable::Var, expression::Expression) -> A_decl,
          gen_proj:  (Path,  List( (Null_Or( Path ), Index))) -> A_decl
        }
        ->
        ((expression::Expression, Compiled_Dfa))
        ->
        expression::Expression;
};


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext