PreviousUpNext

15.3.165  src/lib/compiler/back/low/tools/adl-syntax/adl-rewrite-raw-syntax-parsetree.api

# adl-rewrite-raw-syntax-parsetree.api
#
# Motivation
# ==========
#
# One of the most useful of the standard-library list
# functions is 'map', which does a pointwise transform
# of a given list via a client-supplied function which
# supplies the per-element transform.
#
# 'map' is useful because it encapsulates the busywork
# of traversing the original list and constructing the
# result list -- work common to all pointwise list
# transformations -- exposing only the per-element transform
# function itself, which is the part which changes from
# on list transform to another.  (This is the opposite
# of the OOP dictum to "encapsulate the part that changes"!)
#
#
# Overview
# ========
#
# Our idea here is to similarly provide support for doing
# pointwise transforms of raw syntax parsetrees, encapsulating
# all the busywork of doing a recursive dagwalk of the original
# parsetree and building up the replacement parsetree, leaving
# the client code only to supply the pointwise per-element
# transformation.
#
# A critical difference is that all the elements
# of a list are of the same type, whereas our raw
# syntax parsetrees have elements of five different
# types:
#
#     Expression
#     Decl
#     Pattern
#     Package_Exp
#     Type
#
# We handle this by having the client supply us with
# five transform functions, one for each element type.
#
# In practice, typically the client is only interested
# in transforming one of the five node types, hence
# provides only one "real" transform function;  we supply
# a "no-op" function for client use in the other four
# cases.
#
# As a final twist, it turns out that sometimes the client
# per-element function needs to be able to do a recursive
# rewrite of a complete subtree rather than just a single
# element, perhaps because a replacement subtree is being
# pulled out of a symboltable or whatever.
#     Strictly speaking this doesn't fit our paradigm, but
# it is pragmatically useful to support this need, so when
# we call client pointwise functions we supply not only the
# element to be transformed, but also the internal transform-a-subtree
# dagwalk function for elements of this type.
#
# Anyhow, in summary, typical protocol for using this library looks like
#
#     package rrs =  adl_rewrite_raw_syntax_parsetree;                                  # adl_rewrite_raw_syntax_parsetree                      is from   src/lib/compiler/back/low/tools/adl-syntax/adl-rewrite-raw-syntax-parsetree.pkg
#     ... 
#         fun rewrite_type_node  recursive_tree_rewrite  typenode                       # 'recursive_tree_rewrite' does a recursive rewrite of a raw syntax parsetree with a typenode as root.
#             =                                                                         # 'recursive_tree_rewrite' is usually ignored (_) but occasionally useful when a fresh recursive parsetree rewrite is needed.
#             ...
#
#         new_typetree 
#             =
#             fns.rewrite_type_parsetree  old_typetree
#             where     
#                 fns =  rrs::make_raw_syntax_parsetree_rewriters [ rrs::REWRITE_TYPE_NODE rewrite_type_node ];
#             end;      
#
# See also:
#     src/lib/compiler/front/parser/raw-syntax/map-raw-syntax.api

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

stipulate
    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
herein

    # This api is implemented in:
    #     src/lib/compiler/back/low/tools/adl-syntax/adl-rewrite-raw-syntax-parsetree.pkg
    #
    api Adl_Rewrite_Raw_Syntax_Parsetree {
        #

        # This is the type of a client-supplied function
        # performing some application-specific transform
        # on raw syntax tree nodes of a given type:
        #
        Node_Rewrite_Fn(X)                                                              # X will be one of raw::Expression, raw::Decl, raw::Package_Exp, raw::Pattern, raw::Type
            =
            (X -> X)                                                                    # Recursive parsetree-rewriter function synthesized by our package. (Usually ignored.)
            -> X                                                                        # The parsetree node to transform. This is (normally) a node-local operation, not a recursive dagwalk.
            -> X;                                                                       # The transformed parsetree node.

        # These are the five types of functions which a client package
        # can supply to customize the operation of the synthesized
        # parsetree recursive-rewrite functions:
        #
        Rewrite_Node_Fn
          = REWRITE_EXPRESSION_NODE     Node_Rewrite_Fn( raw::Expression        )
          | REWRITE_DECLARATION_NODE    Node_Rewrite_Fn( raw::Declaration       )
          | REWRITE_STATEMENT_NODE      Node_Rewrite_Fn( raw::Package_Exp       )
          | REWRITE_PATTERN_NODE        Node_Rewrite_Fn( raw::Pattern           )
          | REWRITE_TYPE_NODE           Node_Rewrite_Fn( raw::Type              )
          ;     

        # These are the five  parsetree recursive-rewrite functions which
        # we synthesize and return to the client:
        # 
        Rewrite_Parsetree_Fns
          =
          { rewrite_expression_parsetree:       raw::Expression  -> raw::Expression,
            rewrite_declaration_parsetree:      raw::Declaration -> raw::Declaration,
            rewrite_statement_parsetree:        raw::Package_Exp -> raw::Package_Exp,
            rewrite_pattern_parsetree:          raw::Pattern     -> raw::Pattern,
            rewrite_type_parsetree:             raw::Type        -> raw::Type
          };


        # This is our actual client-callable entrypoint:
        #
        make_raw_syntax_parsetree_rewriters:  List(Rewrite_Node_Fn) -> Rewrite_Parsetree_Fns;           # Given fns which rewrite individual parsetree nodes, produce fns which recursively rewrite complete parsetrees.
    };
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext