Audience: You are expected to have successfully
  downloaded and installed GCC MELT on your machine (probably under
  GNU/Linux running a recent version -4.6
  at least, and preferably 4.7- of GCC). You should also have read the
  tutorial about using GCC MELT. You are invited to test small
  examples of MELT, e.g. with the
  eval or evalfile mode. Familiarity with
  more than one programming language is welcome, in particular with
  some functional
  programming language, and with pattern
  matching. The well known SICP book is a good
  introduction, and it uses the Scheme
  programming language, which largely inspired MELT.
Notice that MELT is a domain specific language designed to work in the GCC compiler. Hence, it is able to work both on MELT values and also GCC stuff (e.g. raw internal GCC represerntations like Gimple-s, Generic tree-s, and control flow representations like edges and basic blocks, and also raw long integers, etc, etc...).
This page does not focus on the various stuff
  handled by the MELT language (even if
  they are one of its main strengths), nor on the various hooks
  between GCC and MELT. It focus more on MELT as a programming language.
  (deliberately ignoring the fact that you won't use
  MELT for general purpose programming
  tasks) 
  This tutorial page is still incomplete! Read also the DSL 2011 paper and the HiPEAC 2012 tutorial slides.
The distinction between MELT
  values and GCC stuff
  is essential. It is a direct consequence of GCC internal architecture. values are first
  class citizens
 and are dynamically typed (like
  in Scheme, Python, Javascript, ...) but stuff is statically
  typed (like in C, or Ocaml, ...) and require explicit code
  annotations.
Values are easier to work with in MELT, but GCC internals work mostly with stuff. However, you usually should prefer dealing with values. Making a value from some stuff is called boxing. Extracting the stuff inside some value is called unboxing, or taking the content of that value. Of course MELT gives you a lot of value which are not boxing some GCC stuff, but which aggregate other values, e.g. tuples, lists, homegenous hash-tables, objects, closures (or functional values), etc. The MELT runtime handle values efficiently. In particular, they are quickly allocated and garbage collected. But most stuff is directly handled by GCC (so allocating and garbage collecting them could be more costly).
MELT is a Lisp-like (or Scheme-like) language. So almost all
  syntactic constructs are in parenthesis. In particular
  (f) -usually the call of function f
  without arguments like f() in C- is never the same as
  f. Exceptions to this every composite
  expression is parenthesised
 rule are avoidable
  syntactic sugar, see below.
Reference material about the MELT
  language is available on the [large] MELT plugin API document, which
  complements this page. Core language operators (like if or let etc....) are called
  macros, because they are all implemented by a macro-like
  mechanism. That MELT plugin API document also lists the
  documented primitives, functions, classes, iterators, matchers
  etc... available to the user.

MELT is a domain specific language to easily extend GCC. Its distinctive strength is to be tightly related to GCC internals, while facilitating powerful programming paradigms. It is translated to C or C++ and you can insert some C/C++ code chunks inside your MELT code. The MELT language has several features to ease your own extensions or customizations of the GCC compiler.
Here are some guiding distinctions between MELT and some other programming languages. Bear in mind the essential values vs stuff difference, which distingish MELT with every other programming language.
defun. The cond, if,
        progn, and, or,
        let, lambda, syntax looks
        familiar. In contrast to Common
        Lisp, MELT has only one
        name space, and no packages. return is used to
        return from a function. Unlike in Lisp or Scheme,
        MELT lists are not exactly
        pairs: a list knows its first and its last pair. Unlike in
        Scheme or Common Lisp, (quote 2)
        [same as '2 as in all Lisp dialects] is
        not the same as 2 : the expression
        (quote 2) evaluates to a boxed value
        containing 2, but the literal 2 evaluates to
        the raw unboxed long stuff 2. Most
        primitives operations are spelled different in MELT than in Lisp
        or Scheme; MELT does not know car,
        cdr, + but provides equivalent
        functionality.
      forever and exit, and iterators).
        Scheme programmers should notice
        that let in MELT is
        like let* in Scheme
        (introducing a sequence of bindings), and that let
        bindings can define a stuff local variable.
        Some syntactic constructs are spelled differently.
      Notice that MELT is lexically
    scoped. A name is bound in a well defined syntactic scope
    (the let expression defining it, or the rest of
    the source file for global defun,
    definstance, defclass ....).
You should try these examples by
    yourself using the eval or evalfile
    mode of MELT for evaluation. Some
    examples below looks familiar if you know Scheme, others are very MELT specific.
1 gets
      a warning (since that integer is a stuff, not a
      value), and give the auto-boxed value
      containing that integer:
        
      cc1: warning: MELT WARNING MSG [#0]::: 
      runtime expressions ending with a non-value expression, auto-boxing it.
      - CTYPE_LONG [enabled by default]
;;; result of eval mode of 1 expression[s] is ...
|DISCR_CONSTANT_INTEGER#1
      (+i 1 2)
      → |DISCR_CONSTANT_INTEGER#3 with
      auto-boxing warning<i, and if gives a
        conditional expression (like ?: in C, or if in Scheme or Lisp or
        Ocaml), so (if (<i 3 0)
        -1 2) → |DISCR_CONSTANT_INTEGER#2 (with auto-boxing)
        because the condition (<i 3 0) is false.
      quote operator, like (quote 42) →
      |DISCR_CONSTANT_INTEGER#42
      without auto-boxing;(quote
      "some string") → "some
      string" (which is how string values are
      displayed).()The quotation operator quote is so important in MELT that there is some syntactic sugar for
    quote: as in Scheme or Common
    Lisp, in MELT (quote
    expression) can always be written as
    'expression so '23 ≡
    (quote 23) and '"hello" ≡
    (quote "hello") and 'x ≡ (quote
    x)
Notice that in MELT,
    contrarily to Lisp or Scheme, (quote 23) which you prefer
    to write as '23 is not the same as
    23, since '23 gives a value
    but 23 denotes a long stuff
The quotation of a symbol gives some MELT object value, instance of class_symbol, so 'if → `IF|CLASS_SYMBOL/7023b80{}
    the 7023b80 hex-digits are the hash-code of
    that object.
The discrim primitive gets
    the discriminant of some value, since each value has
    its discriminant. For object values, their discriminant is
    their class. So (discrim 'x) show with more
    details the class_symbol (since
    'x → `X|CLASS_SYMBOL/33facab6{}), i.e.
`CLASS_SYMBOL|CLASS_CLASS/5e17eaa#20011{ DISC_METHODICT= |DISCR_METHOD_MAP{/3
      **`DBG_OUTPUT|CLASS_SELECTOR/f9d7509{} == .?.; 
      **`DBG_OUTPUTAGAIN|CLASS_SELECTOR/23059a7{} == .?.; 
      **`NORMAL_EXP|CLASS_SELECTOR/2ffb4614{} == .?.; } 
   DISC_SUPER=^^`CLASS_NAMED|CLASS_CLASS/3016a208  CLASS_ANCESTORS= |DISCR_CLASS_SEQUENCE*3[..] 
   CLASS_FIELDS= |DISCR_FIELD_SEQUENCE*3[..] }
The #20011 is the magic number inside
    class_symbol. The above output shows
    the method dictionnary for symbols, the ancestors, and the
    fields. Some information is hidden with .?., etc..
    (because occuring too deeply).
    It is possible to define your own names with
    define operator at top-level, the
    defined symbol can be used in further expressions. So
    (define one '1) (+iv one '12) → |DISCR_CONSTANT_INTEGER#13 because +iv is
    the primitive adding two values and producing a new integer
    value (it is slower that +i because it is
    allocating a boxed integer value). Other defining
    operators exist (they all start with def), notably
    defun to define named functions,
    definstance to define named object instances, and
    defclass to define a named class.
In MELT local variable
    bindings are introduced with the let operator, followed by a sequence of bindings,
    followed by a body, i.e. a non-empty sequence of expressions.
    The binding sequence could be empty (but that is silly), and
    the body can be reduced to a single expression. The bindings
    make sense only inside the whole let expression. So
    (let ( (:long x 1) (y 'big) ) (if (>i x 0) y
    'bang)) → `BIG|CLASS_SYMBOL/2072af88{} since the body
    (if (>i x 0) y 'bang) gets evaluated in an
    environment with two bindings: first the name x is
    bound to the long stuff 1, and
    then the name y is bound to the big value of
    class_symbol. Of course the sequence
    (let ( (one '1) ) (discrim one)) (if one 12
    33) fails with an error unknown name; symbol is not
    bound - ONE because the binding of one is local to
    the let expression (let ( (one '1) ) (discrim
    one)) so is not visible from the second expression
    (if one 12 33)
The boxed FILE* stream can be obtained with
    (get_field :sysdata_stdout initial_system_data)
    and the add2out variadic function is
    defined to add to some output given by its first argument (a
    boxed FILE* stream value, or a string buffer value),
    so we could code in pure MELT the
    following:
;; file hello-world-pure.melt
  (let ( (stdout  (get_field  :sysdata_stdout initial_system_data))
       )
     (add2out stdout "Hello World\n"))
    Notice that we don't have to define a function (like main for C). We just give an expression (the entire three-lines let expression above) to evaluate, and its evaluation has the desired side-effect (of saying Hello World to us).
However, we could also mix C code inside some MELT file, by incorporating a code chunk, with:
;; file hello-world-chunk.melt
    (code_chunk hello_chk
                #{ /* $HELLO_CHK chunk */ printf("Hello World\n");}#)
Grossly speaking, code_chunk is to
MELT what the asm keyword is to
C, a way to incorporate some code in the
translated form (for MELT language, the
translated form is in C or
    C++, for C, the translated form is in assembly
    language).
    The first argument to the code_chunk, here hello_chk, should be a so-called state symbol (which usually is not bound outside of the code_chunk expression). The state symbol is expanded to some unique generated C identifier.
The second argument to the code_chunk, here
      #{ /* $HELLO_CHK chunk */ printf("Hello
    World\n");}#
    is a macro-string. Macro-strings, inspired by the
    bash shell handling of $ inside double-quoted
    strings, start with bang left-brace #{ and are ended
    by the right-brace bang }# two-characters sequence.
    The two-characters sequences #{ and }# have
    been carefully choosen because they cannot appear in
    C code (outside of literal strings
    or comments, so it is always possible to avoid writing them).
    Macro-strings are mixing string literals and MELT symbols (when they are prefixed with a
    $ dollar sign). Most characters in
    macro-strings are taken literally.
The state symbol in a code_chunk is useful because it is uniquely
    expanded. So the first time some expansion occurs,
    hello_chk is translated as HELLO_CHK__1, the
    second time this expansion occurs, it is emitted as
    HELLO_CHK__2 etc. This is useful to obtain unique
    C identifiers in the generated
    C code. For instance, we could have
    counted the number of Hello World messages, repeating
    them randomly, using:
;; file hello-world-counted.melt
    (code_chunk hellocount_chk
                #{ /* $HELLOCOUNT_CHK chunk */ 
                     static int $HELLOCOUNT_CHK#_counter; 
                     $HELLOCOUNT_CHK#_counter++;
                   $HELLOCOUNT_CHK#_lab:
                     printf ("Hello World, counted %d\n", 
                             $HELLOCOUNT_CHK#_counter);
                     if (random() % 4 == 0) goto $HELLOCOUNT_CHK#_lab;
                }#)
    A uniquely expanded state symbol is useful here
    to generate a unique C label.
    Actually, state symbols are much more useful in other
    MELT constructions defining how to
    translate something to C code, e.g.
    in defciterator-s etc.
It is not uncommon to have macro-strings of a few dozen lines, or more. It is advised to emit, thu the macro-string, some distinctive C comment.
Since MELT 0.9.9,
    a code_chunk can contain
    arbitrary MELT [sub-]expressions given
    for their side-effects, provided their ctype
    is :void (you could use a progn ending
    with (void) for that purpose). Such expressions
    appearing in the code chunk macrostring are expanded, at place of
    their occurrence, to a C++ block.
Macro-strings are also used
    by expr_chunk, a syntactic construct
    giving an expression defined by a state symbol and
    a macro-string. For instance, you could get the process-id
    with (expr_chunk getpid_chk :long #{/* $GETPID_CHK*/
    (long)getpid()}#); notice that in contrast
    to code_chunk-s, expr_chunk-s are
    strictly evaluating their sub-expressions, and are internally
    converted to
    their A-normal
    form like all primitive invocations, function calls,
      etc... in MELT.

Every MELT value has an
    immutable discriminant. For a MELT object, its discriminant is its class.
    Discriminants (in particular classes),
    selectors, and fields are themselves objects
    and are used for message dispatching (à la
    Ruby or Smalltalk) using a method dictionnary
    (actually, an hash-table) inside discriminants. Classes
    are organised with single-inheritance, the top-level class is
    class_root, the top-level
    discriminant is discr_any_receiver
    (which is the super of class_root).
    The null value has discr_null_receiver as its discriminant.
MELT values can be:
() in
      MELT; nil is represented
      by the NULL pointer, but its discrimant is
      conventionally discr_null_receiver;
      nil is the only falsevalue; all other values are considered true (when used as tested conditions).
discr_constant_integer the content cannot
          change; for other discriminants, such as discr_integer, the content can be
          changed.discr_gimplediscr_treediscr_string discriminant) know their constant
      length, and the constant string -e.g. a zero-terminated
      sequence of bytesdiscr_strbuf) contain a growing mutable buffer
      of characters, and can be used to incrementally fill a buffer
      of characters (e.g. to later output it, or make a string
      value from it)discr_pair), a head value, and a tail pair (or
      nil);discr_list), the first and last pair valuesdiscr_multiple), the (constant) number of
      components, and the sequence of component values;discr_closure), the routine, the
      sequence of closed values; they are typically created with
      lambda (for anonymous functions) or
      defun (for defined functions).discr_map_strings) associate non-empty
          strings to values, so are some kind of dictionnary.discr_map_objects) associate MELT objects to values.MELT values can move in
    memory, because of the generational copying
    MELT garbage collector, which may be
    called at any allocation.
    (hence it is usually unsafe to retrieve the raw string
    inside a string value, store an interior pointer somewhere,
    etc...)
It is possible to define names as values (but not stuff) notably:
define you can name any
      value given its expression, e.g. (define three (+iv '1
      '2)).definstance to define a named
      instance, of some given class, filling its fields (those not
      given are cleared to the null value), e.g. (define refj
      class_reference :reference_value '"John Doe"); the
      class_reference has only one field,
      reference_value, and is useful to keep a mutable
      reference to some value.defun to define a named
      function (with the name, then the formal parameter
      lists, ending with the body of the function). So the
      familiar factorial recursive function working on boxed
      integers and producing a boxed integer value is coded as:
        
      (defun fact (nv) 
        (if (<=ivi nv 1)
           nv
           (*iv nv (fact (-ivi nv 1)))))
      defprimitive can be used to define
        new primitive operators by giving, thru a macro-string
        (without state symbol), their expansion in C or C++. For
        instance you could define your squarei primitive
        (returning the long stuff which is the square of
        its sole formal long stuff) with:
        
(defprimitive squarei (:long i) :long #{/*squarei*/ ($I) * ($I)}#)
(the first :long is qualifying the 
        i formal argument. The second :long is typing
        the result of the defined primitive)
      defmacro is used to define a macro (often using quasi-quotation, i.e. backquote)defvar (new
	  in MELT 0.9.9) can be used
	  to define a module variable (which is a value kept
	  in some static C/C++ variable managed
	  by MELT
	  and GCC garbage
	  collectors). Module variables can be assigned
	  with setq but cannot be exported.
	When a variable is an argument to a function or primitive application, its value may be fetched before evaluation of other arguments; so don't depend on the order of argument evaluation.
defhook (new
      in MELT 0.9.9) can be used to define
	hooks, which are translated to [nearly] arbitrary
      C/C++ routines (callable by C or C++ code e.g. in
      some code_chunk or otherwise). Notice that if your
      hook is used outside of MELT code,
      you probably should trigger an explicit minor garbage collection
      (by calling minor_garbcoll just before
      returning from the hook).defcmatcher to define C-matchers (constructs for pattern matchings),
      defunmatcher to define matchers in
      MELT, defciterator to define iterative constructs in
      C or C++ with macro-strings for their expansions,
      etc... $Without being exaustive, here are some common idiomatic expressions to dynamically build values:
(make_integerbox discr_constant integer
	ι) or simply (constant_box ι) (to box an integer stuff into a constant immutable value) (make_integerbox discr_integer
	ι)  or simply (box ι) - (to box an integer stuff into a mutable value);box and  constant_box are new in MELT 0.9.8(tuple v1
      v2 v3)variablelength (some long stuff expression or variable) ln use
(make_multiple
      discr_multiple ln) then use
      multiple_put_nth to change components inside.(list a b
      c)lambda,
      so (lambda (v) (f (get_field :named_name v))) is
      the anonymous function which applies some f to the
      field :named_name (defined in the
      standard class_named) of its formal
      argument v; notice that f is
	a closed variable (or already bound variable), provided by the environment,
      e.g. because it is bound by some
      enclosing let expression. Functional
      values are tremendously useful
      in MELT.instance construct, followed by a class name, then the fields initialization; each initialized field is given by a keyword symbol starting with a colon : e.g. (instance class_gcc_gimple_pass
	  :named_name '"foo_pass"
	  :gccpass_exec foo_exec)) is building a new instance of class_gcc_gimple_pass with the named_name field (inherited from the ancestor class class_named) initialized to the "foo_pass" boxed string, and the gccpass_exec field (defined in the parent class class_gcc_pass) initialized to the function foo_exec.make_integerbox to build a boxed integer, like (make_integerbox discr_integer (+i 3 1)) to build a boxed 4 integer;make_tree to build a
	    boxed GCC tree, like (make_tree discr_tree t)make_mapobject to build an hash-map keyed by MELT object values, like (make_mapobject discr_map_objects 120) where 120 is an initial estimate of the hash-table size (which will grow as needed)make_mapgimple to build an hash-map keyed by GCC Gimple stuff, like (make_mapgimple discr_map_gimples 400)make_bucketlong to build a sorted bucket associating arbitrary long stuff to non-nil values, like (make_bucketlong discr_bucket_longs 100); contrarily to hash-maps, buckets don't automatically grow, but the bucketlong_put primitive may return a new bucket bigger than the original one.(make_maptree discr_integer 10)
	this primitive gives nil (here make_maptree wants discr_map_trees, not discr_integer!).
MELT needs to be able to handle
    raw GCC stuff. It does so by
    static c-type annotations (using so called Lisp
    keyword symbols
 starting with a colon
    :), using:
:long to annotate raw long
      integerslong C
      type.):tree to annotate raw GCC tree-s (for Generic Trees),
      e.g. variables and declarations and operands of the
      GCC compiled code;:gimple to annotate raw GCC gimple-s (internal representation
      of simple elementary instructions, like assignment,
      arithmetic [e.g. a = b - c;], calls, conditional
      jumps, etc...);:basic_block to annotate raw GCC basic blocks;:edge,
      :loop, etc....;:value to annotate
      MELT values (which is the
      default c-type):cstring to annotate constant raw
      strings in read-only memory. The only safe
      stuff of that :cstring c-type are
      constant literal strings like "hello"; you
      should not (and cannot) compute a stuff of that c-type (e.g.
      extracting a :cstring from a string value
      will crash MELT).:void annote something which
      does not carry any data. The expression of that c-type
      is (void):auto annotation (new
      in MELT 0.9.8!)
      within let bindings means that
      the let-bound variable takes its type from the
      expression defining it.Lisp-like keyword symbols starting with
    a colon can also play other roles. In particular
    :true denote the prefered boolean true
    value; but unlike in Scheme, and
    inspired by Lisp or C, every non-null value is considered
    true in MELT. the leyword
    :rest is used in variadic formal arguments, and
    :else may appear in conditionals. Very often,
    keyword symbols represent fields inside MELT objects, like in (get_field
    :content_value x), but keyword symbols
    are not reserved in any way (you might want to use them in
    MELT like you would use enumaration
    identifiers in C).
A MELT c-type is reified
    as some predefined MELT object. For
    example, the object ctype_long
    describes the :long c-type, and
    ctype_tree describes
    :tree etc. Use the MELT
    evaluator to display some of these.
C-type annotations appear in
(x :long i j :value v) represents 4 formals,
      x being a value formal, i
      & j being raw long stuff formals, and
      v being a value formal(:long i
      1) binds the raw long stuff 1 to the
      symbol name i; but the binding (one
      '1) which is same as (one (quote 1)) or
      even (:value one (quote 1)) binds the symbol
      name one to the boxed value 1 of
      dicriminant discr_constant_integerStuff usually fits in a machine word, because long
    does, and because other stuff c-types like :tree,
    :gimple etc... are in fact pointers to some
    GCC internal data. So a
    :long stuff is true iff it isn't O, and a
    :tree stuff is true iff it isn't the null tree
    pointer, etc.
Beware that some GCC passes are
	forcibly destroying some stuff (without using Ggc, the
      Gcc garbage collector). So handle stuff with care, only in your
      passes inserted appropriately. For instance, the "expand"
      pass of GCC in its
      file gcc/cfgexpand.c is forcibly destroying
      some edges, so you cannot manipulate
      in MELT these edges (even if they
      have been boxed by your code) after that pass has been executed.
      (this is not specific to  MELT; every GCC plugin would have this issue.)

Functions are a very powerful feature of the MELT language, and are not like functions in
    C, but more like functional values
    in Ocaml, Lisp, Lua,
    Ruby, etc... Functions are first
    class values (called closures). You can define
    top-level named functions with defun, and dynamically build anonymous
    functions with lambda. The last
    expression in the function body usually gives the result of the
    function.
    The defun operator is followed by the
    defined function name, then the list of formal arguments, then
    the body of the function. The lambda
    operator is followed by the list of formal arguments, then the
    body of the anonymous function.
The first argument (if given) of a MELT function should be a value but
    other arguments can be any things, either values or stuff.
    The primary result of a function should be a
    value. Hence you cannot code (defun
    badsucc (:long i) (+i i 1)) for two reasons: its
    first formal argument i is a long stuff, and
    its primary result is also a long stuff (both should
    be values).
A function can possibly return other secondary
    results which may be any things (either a value
    or some stuff).
    The requirement that the first argument, if any, of a
    function is a value, and that the primary result is a value
    facilitates nesting of function calls, and using functions as
    method in the object system and in message passing, then the
    first arrgument is the reciever of the message.
A function can get, from some call, less arguments than what its formal arguments list requires. In that case, missing arguments are cleared. If the type of actual arguments does not match the type of formal parameters, the remaining formals are cleared.
The secondary results of a function (if any) are ignored,
    unless the calling site use the multicall
    syntax to retrieve multiple results from the call. Every function
    return a (primary) result value, which is the value of the last
    expression of the body of the function, unless
    a return expression is evaluated. A
    function can also have secondary results given by an
    explicit return expression (which returns
    both the primary value and the secondary results). For instance
    after a 
   (defun foo (x :long n) (return (tuple x
	(constant_box (+i 3 n)) (*i 2 n)))) 
 which defines foo as a function return a primary result value (some tuple) and a secondary long stuff result, the
    expression (multicall (y :long k) (foo 'a 5) (debug "y=" y
    "k=" k)) would debug-print y= same as the result
      of (tuple 'a '8) and k= the long stuff 10.
When a non-functional value (like a boxed number or an object) gets applied (i.e. called), nothing happens, and the call gives the null value.
Functions are first-class values and can be passed as arguments, put inside aggregate values (like objects or lists), or returned as results.
The following example is a defining a high-order function foobar which, given some (hopefully functional) value f and some other value v returns an anonymous function φ which, when later called with some value a, returns primarily the result of applying f to a tuple containing the v and the a, and secondarily the original v:
(Each call to foobar above will return a different (and unique) function φ -actually a closure, so for instance if we defineddefunfoobar (f v) (lambda(a) (return(f (tuplev a)) v)))
(defun quad (v) (list v v v v)) -so that (quad
    'a) gives the list containing four occurrences of the
    symbol a then ((foobar quad 'b) 'c) -that
    is the application of the function returned by (foobar
    quad 'b) to the symbol value c- would return
    two values, primarily the list containing four identical
    occurrences (in the same single value) of the 2-tuple c
    b, i.e. the same value as the evaluation of
    (let ( (tcb (tuple c b)) ) (list tcb tcb
    tcb tcb)), and the second result of our call
    ((foobar quad 'b) 'c) would be the symbol
    b. We could capture both results and make a reversed
    list of them by coding (multicall
    (r1 r2) ((foobar quad 'b) 'c) (list r2
    r1)) which shows that multicall
    is followed by a formal list of results -which are locally
    bound by that multicall, then the called expression,
    then the body of the multicall. The example above shows that
    each returned anonymous function φ has closed the value
    v at the moment foobar was called. So
    different calls to foobar with different arguments
    would give different anonymous functions.
    Only values can be closed in closures, e.g. those
    obtained as lambda functions. In
    particular
      (let ( (:long one 1) ) (lambda (v)
    (list v (make_integerbox discr_integer one)))) will be
    rejected, since one would be a closed stuff.
Functions are very powerful in MELT. You could code an extension in two passes, the first one would build an hash-table associating some gimple-s of the compiled program to some closures, and the second pass would choose some gimple-s and invoke appropriately the function associted to them in the first pass. This functional style enables very powerful programs.

;; -*- Lisp -*- to make emacs happy
      (multi-line comments starting with #| and
      ending with |# are possible but not
      recommended);a+b is a single symbol of 3 characters,
        and is not the same as a + b (a
        sequence of 3 symbols which does not represent the
        sum of a and b!).class_symbol.
      If is the same as if or
      iF; conventionally lower-cases are preferedkeyword symbolsare symbols starting with a colon sign
: like
      :else or :foo, and are parsed as (shared)
      instances of class_keyword; keyword
      symbols are "self-evaluating" and cannot be explicitly bound
      (e.g. by some let). Notice that
      keyword symbols in MELT are
      not like keyword identifiers (e.g.
      for) in C.class_keyword, a sub-class of class_symbol.and, assert_msg,
      cond, debug,
      defciterator, defclass,
      defcmatcher, define,
      definstance, defprimitive,
      defun, defunmatcher,
      exclaim, exit,
      export_class, export_macro,
      export_values, forever,
      if, instance, lambda,
      let, letrec, match,
      multicall, or, progn,
      question, quote,
      return, setq, when, 
      
       are so important that you don't want to use them outside of
      their pre-established MELT
      meaning, and you should not redefine them.10 or
      +10 or 0xa or +0xa or
      012 is ten, with 0x prefix for
      hexadecimal, and 0 prefix for octal notation. An
      integer literal constant should fit in a long.#\a and they are considered as integer literals,
      so #\a is the same as 97
      (because 97 or 0x61 is the
      ASCII encoding of the a letter).
      Multi-byte UTF-8 encoding is not yet supported. Some control
      characters can be conveniently input, e.g. #\nul
      or #\alarm or #\backspace or
      #\tab or \#linefeed or
      \#vtab or \#page or
      \#return or \#space or
      \#esc. But character constants are integer
      literals (so represent stuff of :long
      c-type)."ab\nd" is a four-character string literal whose
      third is the newline. They represent stuff of
      :cstring c-type.( and terminate
        with a balanced closed parenthesis ). They are read as unique instances of
        class_sexpr which have their
        :loca_location field set, when possible, to
        the source location of the s-expr and their
        :sexp_contents field set to the list of
        components, i.e. the sub-expressions, of that
        s-expr. Syntactic sugar (see below) enables some few s-exprs
        to be read without starting with a left parenthesis.
      There are some other [obscure and deprecated] lexical conventions (see the meltgc_readval and other meltgc_read* functions in melt-runtime.c)
Macro-strings (a mix of symbols and verbatim strings) are
    useful to express generated C
    or C++ templating
 code
    pieces, used in several constructs (describing
    how to emit C or C++ code from MELT
    source).
Inside macro-strings, almost all characters (notably the backslash \, the braces { & }, the semi-colon ;, the new-line control character, etc... who are very useful in C programs) stand for themselves. But some escapes are possible.
hello_chk
      symbol in our example. If the symbol is immediately followed
      by a bang #, that character is skipped.code_chunk,
      sub-expressions should be of :void c-type and are
      useful only for their side-effects.Macro-strings starting with #{
    are parsed as an s-expression, so
      #{ /* $HELLO_CHK chunk */ printf("Hello
    World\n");}#
    is exactly parsed as
      (" /* " hello_chk " chunk */printf(\"Hello
    World\\n\");")
    which is a 3-component s-expression
    starting with the 4-character string " /* ", then
    the hello_chk symbol, then a string containing
    back-slashes, double-quotes, ended by a semi-colon.
Macro-strings starting with the 3-character
    (bang bang left-brace) sequence ##{ which also end with the two-character sequence
    }# are parsed as a sequence of
    s-expressions.
    (We could have written our entire code chunk as
    (##{$code_chunk /* $HELLO_CHK chunk */ printf("Hello
    World\n");}#)
    which is very poor taste)
All macro-strings end with the 2-character
    (right-brace bang) }#
    which is not part of the macro-string.

A practically important feature
  of MELT is the ability to deeply
  mix MELT
  and C/C++
  code. The C/C++ code is represented
  with macro-strings. The MELT
  code is given
  thru s-expressions. 
(since MELT
  0.9.9, macro-strings and s-expressions can be arbitrarily
  nested, so macro-strings can contain s-expressions containing
  themselves macro-strings etc..., and nearly arbitrary routines can
  be coded in MELT
  as hooks)
ftw C function wants a
  callback function and requires some header. We need first to include
  that header and declare that callback function using
  the cheader construction (to give some C
  code to be emitted in the declaration part of
  the C/C++ code emitted
  by MELT):
(cheader #{
  #include <ftw.h>
  static int 
  my_ftw_callback(const char *fpath, const struct stat *sb, int typeflag);
}#)
ftw API don't give any way to pass some
client data to the callback): With defvar we
define two module variables: varfun will hold the user
given MELT function to apply on each file,
and varhook will keep the hook data.
(defvar varfun)
(defvar varhook)
defhook, that
is a C++ routine coded in MELT. That hook
gets the file path and the file size as input arguments, it has no output arguments,  and return a
long flag (zero to continue the file tree traversal).
Our hook needs to call(defhook myftwcb;; name of the hook(:cstring filename :long filesize);;input formals();;no output formals:long;;ctype of result:var varhook;; put the hook data in that module variable
varfun with the boxed file
name string (because the first argument given
to 
     (let ( 
         (boxedfilename (make_stringconst discr_string filename))
         (rescall (varfun boxedfilename filesize))
        )
      (if rescall 
       (return 1) 
       (return 0))))    ;; end of hook myftwcb 
We now need to implement our my_ftw_callback function, passed
     as a function pointer to ftw. It just tests that the
visited path is a file (not a directory) and then calls our hook. As a C++ function, our hook is called melthookproc_MYFTWCB (that name is derived from the MELT symbol myftwcb). 
Our  my_ftw_callback glue function is
     plain C++ code, encapsulated in
     a cimplement MELT
     directive:
(cimplement #{
static int 
my_ftw_callback(const char *fpath, const struct stat *sb, int typeflag) {
  if (typeflag == FTW_F) { // plain file 
    long filsiz = (long) sb->st_size; // the file size
    long res = melthookproc_MYFTWCB (fpath, filsize);
    if (res) 
      return 0; // continue the file tree walk
    else
      return 1; // abort the file tree walk
  } 
  else // not a file, skip it by returning 0
    return 0;
}
}#)
At last, we implement (in MELT mostly) the
user function walk-file-tree which is given a closure and a string value representing
some directory to scan. That function will save, set, and restore
the varfun module variable (to deal with
improbable recursive calls to our walk-file-tree thru
its clos closure argument) containing the closure,
and contains a code chunk to call the ftw C library function:
(defun walk-file-tree (clos dirpath)
  (if (and (is_closure clos) (is_string dirpath))
   (let ( (oldvarfun varfun) ;; backup & save varfun
          (:long err 0) ;; error code returned by ftw
         )
         (setq varfun clos)
         (code_chunk callftw_chk
           #{ /* in walk-file-tree $CALLFTW_CHK */
      // copy the directory path string locally, since ... 
      // ... `dirpath' could be moved by the MELT garbage collector called inside the closure
           char pathbuf[256];
           memset (pathbuf, 0, sizeof(pathbuf));
           strncpy (pathbuf, melt_string_str($DIRPATH), sizeof(pathbuf)-1);
           // call ftw(3) with at most 40 file descriptors.
           $ERR = (long) ftw(pathbuf, my_ftw_callback, 40);
          }#)
        (setq varfun oldvarfun) ;; restore varfun
        (return (if err () :true)))
   ;; else bad arguments to walk-file-tree
  (return ())
  )) ;; end of walk-file-tree
The example above demonstrates that MELT has now (since MELT 0.9.9) the ability to interface to arbitrary C or C++ libraries, including those requiring some function pointers of an arbitrary signature (thanks to hooks). Please publish, if possible, any such small glue code to your favorite C++ library.

We use some EBNF-like
  syntax: lower-case name-like-this is a
  non-terminal, lower-cases names like if (and others) are terminals, parenthesis
  like  and 
  are meta-linguistic, brackets like 
  and  are around optional items, the
  postfix star  denotes optional
  repetition of 0, 1, or more, and the postfix plus  denotes mandatory repetition of 1 or more. The
  vertical bar  is for linguistic
  conjunction. The assigment  sign is
  for definition of the left-handed non-terminal. We don't claim to
  be complete (and advanced MELT users
  could extend the grammar thru their own macros), so this is an
  incomplete grammar
.
Some syntactic sugar is possible for brevity, but
    could always be avoided. The ≡ sign means here is read
    the same as
:
'ε(quote ε) and
      is used for quotations. So (quote 2) is the same as '2 and refers to the quoted integer value
      2.?π(question π)
      and is used for patterns with match. In particular ?_ represents the catch-allwildcard pattern. (in Ocaml the wildcard pattern is written _ in matches.)
!ρ(exclaim ρ)
      is used for dereference, and is understood like
      (get_field :reference_value
      ρ).`ε(backquote ε)
      to build s-expressions by quasi-quotation.,ε(comma ε) is to
      insert something in a backquote-ed
      s-expression.@ε(at ε) is
      reserved for future use.Some of the special characters above are possible in symbols, after letters. The above syntactic sugar is implemented in the MELT reader.
Formal parameters list or formals are
    given in parenthesis and contain formal name symbols
    (e.g. x or perhaps p-1)
    and c-type keyword symbol annotations
    like :long or :tree
    or :gimple or :value which apply to the
    following formals. The last :rest annotation is for
    variadic functions.
| formals | (ctype
	    name:rest
	     | |
| ctype | :long | for long stuff | 
| :cstring | for raw constant c-string stuff | |
| :tree | for GCC tree stuff | |
| :gimple | for GCC gimple stuff | |
| :gimple_seq | for GCC gimple_seq (sequence of gimple-s) stuff | |
| :basic_block | for GCC basic_block stuff | |
| :edge | for GCC edge-s [between basic blocks] stuff | |
| :loop | for GCC loop-s stuff | |
| :value | for MELT first-class values | |
| :void | cannot be used in formals; annotate lack of data like void in C | |
| etc etc.... | 
Conventionally, formal names are short and only made of letters, perhaps followed by digit. We avoid underscore _ and minus sign - in formals.
There are some restrictions on formals: in particular, the
formals of a function should start with a value formal (if any). And
variadic formals (ending with :rest) are only
  permitted for functions (not for primitives). The implicit initial ctype annotation is :value.
The expression operators have often a greedy evaluation of their operands. But some expressions are lazily evaluated (for their arguments), like if etc...
       The MELT translator decides if
	an expression is a function application, a primitive
	invocation, a message sending, a hook call, etc ... according to the
	binding related to the operator name. 
       Expressions with a non-name operator (e.g. a complex sub-expression, like a conditional or an application, etc...) in operator position are always function applications..
 
      
((if somecond +i -i) 2 3) won't work as you want : since the operator is a complex sub-expression (if somecond +i -i), it is assumed to be a function application, but you want that to be a primitive invocation.defhook), it is a hook call.
        defselector), it is a message sending. The first argument (evaluated to a value) is required and is the reciever of the message.defmacro or export-macro etc...), it is a macro invocation. Most MELT syntax is defined by macros : actually, if, lambda, let, defun, quote  etc... -and most operators described here- are all predefined macros. quote operator does not
	evaluate its sole argument, and gives a constant value. 
	  discr_constant_integer,
	so (quote 2), often given as '2
	gives the same as (make_integerbox
	discr_constant_integer 2), except that the boxing
	happens only once (the boxed integer value is constructed at
	      initialization time).class_symbol which is the interned (shared, unique) instance of the symbol.class_sexpr.backquote operator is used for quasi-quotations to dynamically build s-expressions, often with the comma operator. For example (let ( (one 1) (ab (list 'a 'b)) ) (backquote (+ (comma one) (comma ab)))) which can be written (let ( (one 1) (ab (list 'a 'b)) ) `(+ ,one ,ab)) expands to an s-expr like (+ 1 a b) built at runtime (since ab is a sequence, it is expanded to its constituents).debug operator is useful for
	debugging. It accepts any number of arguments of any kind
	(stuff or things), e.g. (debug "here x=" x "and g="
	(gimple_content gv)). When you
	run MELT with
	the -fplugin-arg-melt-debug
	or -fplugin-arg-melt-debugging=all program
	option, some debugging output happens, mentionning the source
	location of that debug
	expression. But MELT modules
	of optimized flavor do not show any debugging
	output.box operator (new
	in MELT 0.9.8!) is taking a
	stuff operator and gives a mutable value boxing
	it. So (box (+i 2 3)) gives the same
	as (make_integerbox discr_integer 5).constant_box
	operator (new in MELT
	0.9.8!) is taking a stuff operator and gives
	a constant value boxing it. So (constant_box
	(+i 2 3)) gives the same as (make_integerbox
	discr_constant_integer 5).unbox operator (new
	    in MELT 0.9.8!) is taking a c-type [of the result of the unboxing] and some value. It safely unboxes that value, returning its content or else a cleared stuff. So (unbox :tree v) is nearly the same as (tree_content v) and delivers the raw tree content of v if it is a boxed tree, or else the null tree.lambda operator is for making
	  anonymous functional values or closures (it is
	  a constructive expression).tuple operator builds tuple
	  values of discr_multiple
	  discriminant (it is a constructive expression). For
	  example, (tuple '2 'x) evaluates to a 2-sized
	  tuple whose first component is a boxed constant integer
	  2.list operator builds list
	values and implicitly the contained pair values (it is
	a constructive expression). For example (list
	(tuple 'a) '2) is a list of two pairs, the first of
	which having a 1-tuple as its head. Notice that -contrarily
	to Scheme
	or Common Lisp-
	in MELT the
	expression (list) does not evaluate to nil (but
	to an empty list without pairs). Remember that lists know
	their first and last pairs.exclaim operator (e.g. (exclaim x) which is the same as !x in MELT) is for dereferencing.instance operator dynamically builds an object, of a given class, with appropriate field initializations. Each field has a globally unique name, and is a keyword symbol so starts with a colon, like :reference_value; for example (instance class_reference :reference_value 'a)get_field operator safely
	retrieves some given field from an object
	value. If the value is not an instance of the class defining
	that field, nil is given. For instance (get_field
	:reference_value r) is the same as !rput_fields operator
	safely mutates an object value with some
	given fields. If the value is not an instance of the
	class defining that fields, no harm is done. For
	instance (put_fields pass :gccpass_exec somefun
	:gccpass_data somedata) won't touch pass
	if it is not an instance
	of class_gcc_pass (or some sub-class
	of it) which defines the :gccpass_exec
	and :gccpass_data fields.code_chunk operator enables
	the embedding of a chunk of C code
	(or in the subset of C++ acceptable
	inside GCC). It is only useful for
	its side-effects. It is quite useful in
	practice. Sub-expressions appearing in the macro-string should
	be of :void c-type and are expanded at place of
	occurrence.expr_chunk operator (new
	    in MELT 0.9.9) permits embedding
	some C/C++ expression
	in MELT.  Sub-expressions appearing
	in the macro-string are always strictly evaluated (like
	arguments to primitives or to function calls) before the
	computation of the expression chunk. Hence,
	an expr_chunk of :void c-type is not
	the same as the equivalent code_chunk.parent_module_environment
	operator produces the parent environment, that is the
	environment which is extended by the current module. Use with
	care, and avoid modifying the parent environment.current_module_environment_reference
	operator gives a reference to the current module
	environment. Use with care, and avoid modifying the referenced
	current module environment yourself.+, -, *, /
	are expanded to left-nested invocations of binary
	primitives +i, -i, *i, /i. Notice
	that no variadic comparator exist, so use the
	binary >i, ==i (on long
	stuff), == (to test identity of values), etc...
	etc...| expr | ||
| (exprop   expr) | function application (operator exprop should be evaluated to a closure; first argument, if any, should be a value) | |
| (nameprimitive   expr) | primitive invocation | |
| (namemacro   expr) | macro invocation | |
| (nameselector   exprreciever  expr) | message sending | |
| (quoteliteral-or-name) | quotation, often with 'syntactic sugar | |
| (backquoteexpr) | quasi-quotation building an s-expr, often with `syntactic sugar | |
| (commaexpr) | insertion inside quasi-quotation, often with ,syntactic sugar | |
| (debugexpr) | debug printing | |
| (boxexpr) | mutable value boxing | |
| (constant_boxexpr) | constant value boxing | |
| (unboxc-type expr) | safe value unboxing, producing some stuff of appropriate c-type | |
| (exclaimexpr) | dereferencing, often with !syntactic sugar | |
| (tupleexpr) | tuple constructor | |
| (listexpr) | list constructor | |
| (lambdaformals  exprbody) | anonymous functional value | |
| (instancenameclass:namefield   expr) | dynamic instance creation. The field names are keyword symbols, so start with a colon :. | |
| (get_field:namefield expr). | safely retrieve a field from an object value. Field keyword names start with a colon :nil is given if expr is not a value of the appropriate class defining the field. | |
| (put_fieldsexprobj:namefield   expr) | safe object mutation. The field names are keyword symbols, so start with a colon :.Nothing happens if exprobj is not a value of the appropriate class defining all the fields. | |
| (code_chunknamestate  macro-string) | Embed some C/C++ code, for side effects. | |
| (expr_chunknamestate  c-type  macro-string) | Embed some C/C++ expression. | |
| (parent_module_environment) | Gives the parent environment extended by the current module. | |
| (current_module_environment_reference) | Gives a reference to the current module environment. | 
The control operators are mostly familiar to Scheme or Common Lisp developers:
if operator is the
	  conditional ternary operator (like if in Ocaml or Scheme, or the ternary ?: operator of C, etc...), if the
	condition exprtest is
	evaluated as true, the second operand,
	i.e. the exprthen is
	evaluated and gives the result of the whole if
	expression. Otherwise, the optional third
	operand exprelse is
	evaluated, and if missing, a cleared value or stuff is
	given.when operator is a syntactic
	sugar, with test expression and body sub-expressions (it is
	transformed to a progn as the thenexression of an if without
elsepart). When the test is true, the sub-expressions are evaluated in sequence, and the last one gives the result of the when expression.
cond operator is the
	multi-conditional expression, with conditional clauses. Each
      conditional clause starts with a test expression followed by
      sub-expressions which gets evaluated in sequence if their
      condition was true, but the last clause may start
      with :else. The result of the entire cond
      expression is the last expression of the first true conditional
	clause.
      and operator is a
	lazy and-thenconditional (similar to && in C). Sub-expressions are evaluated in sequence till a false (nil or 0, ...) result is obtained.
or operator is a
	lazy or-elseconditional (similar to || in C). Sub-expressions are evaluated in sequence till a true result is obtained.
progn construct is
	for sequential evaluation of sub-expressions, only
	the last sub-expression gives the result of the
	entire progn expression and all but the last
	sub-expressions are evaluated only for their
	side-effects. Hence it is similar to
	the begin operator
	of Scheme, to
	the progn construct
	of Lisp, to
	the comma
	operator ,
	of C and to the
	semi-colon ; operator
	of Ocamlreturn construct is returning
	a primary value (or nil if none is given) with secondary
	results, if given. So (return) just returns the
	nil value from the enclosing function, and (return v 1
	!r) returns v as the primary value result,
	and the long stuff 1 with the value inside the
	reference r as the secondary results. Secondary
	results can be captured with
	the multicall binding construct in the
	caller code.forever construct is for
	endless loops. It is followed by the name of the loop. These
	loops can be exited with exit (and
	also with return) expressions. The
	result of the forever expression is the last
	expression in the internal exit sub-expression
	exiting that loop. Notice that the exited forever
	loop should be in the same function as the exit
	expression.exit construct is a local
	jump outside of a forever loop. The exit
	is followed by the name of the loop to be exited, then some
	expressions, the last of which gives the result of the exited
	loop.(foreach_long_upto (2 6) (:long i) (debug "i="
	    i)), where (:long i) is the local
	    formals of the iteration (so i is bound only
	    inside the iteration body).
	    The foreach_long_upto c-iterator is
	    defined with defciterator in
	    the MELT standard librarywhich also defines many other c-iterators, such as foreach_in_multiple to iterate on the components of tuple values, and foreach_argument_of_gimple_call to iterate on the arguments of a Gimple call instruction. A c-iterator is defined by providing macro-strings to be expanded before and after its body. Some c-iterators loop only once, e.g. with_cfun_decl to get the current C function declaration in a pass. As MELT expressions, iterations are of void c-type and don't give any result. They are only used for side-effects (and bindings of the local formals within their body).
match, then a matched expression, then a sequence of matching clauses. Each matching clause starts with a pattern.| expr | ||
| (ifexprtest   exprthen   exprelse) | conditional expression | |
| (whenexprtest   exprbody) | syntactic sugar, same as (if exprtest (progn exprbody))if the test is true, the body sub-expressions are evaluated in sequence, the last giving the result of the when; otherwise false is given. | |
| (condconditional-clause  else-clause) | multiple conditional expression | |
| (andexpr) | sequential lazy and-thenconjonction. evaluated left-to-right till a false result is given. The last evaluated conjunct is the result of the whole and. | |
| (orexpr) | sequential lazy or-elsedisjonction. evaluated left-to-right till a true result is given. The first evaluated true disjunct is the result of the whole or. | |
| (prognexpr) | sequential evaluation last expression gives result, previous for side effects only! | |
| (returnexpr) | return from function. first expression (if present) should give a value, the primary result. Remaining expressions give secondary results. See also multicall. | |
| (forevernameloop  expr) | infinite loop with internal exit | |
| (exitnameloop  expr) | exit enclosing loop; last expression gives result of enclosing forever loop. | |
| (matchexprmatched  matching-clause) | pattern matching; the matched matching-clause gives the result. | |
| (nameiterator(exprinput)formalslocal
      exprbody) | iteration. | |
| conditional-clause | (exprcond exprbody) | if the condition is true, the body sub-expressions are evaluated, the last giving the result of the enclosing cond. | 
| else-clause | (:else exprbody
       | if all previous conditions are false, the body sub-expressions are evaluated, the last giving the result of the enclosing cond. | 
| matching-clause | (pattern exprbody) | If the matched thing is matching the pattern, the
    body sub-expressions are evaluated with pattern-variables locally bound the last body sub-expression giving the result of the enclosing match. | 
Notice that in some conditional expressions, the then
    and else part should be of same c-type; it could be
    useful to force one of them to be void
    with (void); likewise for matching
    clauses.
Binding operators introduce new lexically scoped local bindings, and the locally bound variables are not visible outside of the whole binding expression:
let operator is followed by a
      sequence of bindings and has body sub-expressions. It is similar
    to the let* of Scheme, because
    the bindings are done sequentially, and a previous binding can be
    used in the expression of some following
    binding. Each let-binding starts optionally by a c-type
    annotation or by :auto [which is the
    default], then the newly and locally bound symbol, then the
    expression defining that symbol. If a real c-type annotation is
    given (e.g. :long or :tree), then the
    binding expression should be of that c-type. If no c-type
    annotation is given, or if :auto is given, then the
    binding expression's type is used to determinate the c-type of the
    newly bound variable, e.g. in (let ( (:auto i 1) (:value v 'xx) (t (tuple v (box i))) )
    (debug "t=" t) t)   the c-type of i
    is :long (given by 1) and the c-type
    of t is :value (given by tuple). The
    result of that entire let is a tuple value, and
    the debug sub-expression is for its side-effects
    only.letrec operator is for
    co-recursively defined constructive bindings. Each
    constructive binding has a locally bound variable and a
      constructive expression
    (.e.g. lambda, tuple, instance
    etc....), so binds a value to the defined name. You can
    use letrec to build circular data structures
    e.g. (letrec ( (ipse (instance class_reference
    :reference_value ipse)) ) ipse) which defines a silly
    reference pointing to itself. multicall operator captures the
    primary and the secondary results of a call (or a message
    sending). It is inspired
    by Lisp's call-with-values. It
    is followed by a formals list (to be bound to the results), then
    the function application or message sending expression, then the
    body sub-expressions. The first formal should be a value name,
    since it gets the primary result. The other formals get the
    secondary results.variadic expressions can appear
    only in variadic functions (whose formal parameters end
      with :rest). A variadic-clause gets evaluated if the
    current variadic arguments fit in the formals of the clause.| expr | ||
| (let(binding)expr) | local bindings; the variables are bound in sequence. the body sub-expressions are evaluated with these bindings. The last body sub-expression gives the result of the whole let expression. | |
| (letrec(binding)expr) | recursive constructive bindings; each binding should be with a constructive expression (lambda, tuple, instance etc...). the body sub-expressions are evaluated with these bindings. The last body sub-expression gives the result of the whole letrec expression. | |
| (multicallformals   exprapply-or-send   exprbody) | call with multiple results. The first formal capture the primary result value; the following formals capture the secondary results. The first expression should be a function application or a message sending. The last body sub-expression gives the result of the entire multicall expression. | |
| expriteration | [see iteration as a control operator] | |
| (variadicvariadic-clause else-clause ) | within variadic functions, capture some variadic formals | |
| binding | (ctype:autoname   expr) | Locally bind the given name to expr. If :auto or no c-type is given, it is guessed from the expr. | 
| variadic-clause | (formals expr) | Inside variadic when the actual variadic parameters match the given formals, evaluate the sequence of expr | 
Pattern matching
(thru (match .... )
expressions) is one of the main strengths of
the MELT programming language. It
practically enables very powerful, expressive and concise coding. For
instance, the following code (extracted from
a MELT pass checking the coding style of
the MELT runtime) is matching
a tcurfield variable (some :tree stuff) to find
if it is a field declaration of a field named mcfr_varptr
which is an array whose size should go into tsize pattern
variable.
   (match tcurfield
          ( ?(tree_field_decl
              ?(tree_identifier 
                ?(cstring_same "mcfr_varptr"))
              ?(tree_array_type ?telemtype 
                                ?(tree_integer_type_bounded ?tindextype
                                                            ?(tree_integer_cst 0)
                                                            ?(tree_integer_cst ?lmax) 
                                                            ?tsize)))
             (debug "meltframe_exec telemtype=" telemtype
                    " tindextype=" tindextype 
                    " tsize=" tsize
                    " lmax=" lmax)
             (setq tmeltframvarptr tcurfield)
             (setq nbvarptr lmax)
             )
          (?_ 
           (void)))
Patterns appear only within matching expressions (i.e. match operations) as the first syntactic element of matching clauses. Patterns use the question syntax, often thru its syntactic sugar ?π for (question π). The pattern of a given matching clause may introduce new pattern variables which are local to the matching clause and initially cleared (so set to the null value if it is a value pattern variable, set to 0 if it is a long stuff pattern variable, set to the null tree if it is a tree stuff pattern variable, etc...). Pattern variables may be bound by matching, and they can be used in the body expressions of their matching clause. 
 A pattern can be 
2 matches the long stuff 2. Constant patterns are tested using the identity test == in the generated C/C++ code (so never write "some string literal" as a pattern but code ?(cstring_same "some string literal") which gets translated to a test calling strcmp, because two same string literals are not identical in C code).?_ has its matching always
  successful. (so the underscore _ is
  not a valid pattern variable name)?v?tr); if the pattern variable v is not pattern-bound in the current matching clause, [pattern-]bind it to the matched data and succeed the matching; if it is pattern-bound to some data (by a previous occurrence of the same pattern variable in the current matching clause), test for identity (with == in the generated C or C++ code) of the matching data to the pattern variable's data.defcmatcher by macro-strings describing
  the C/C++ code to test the pattern and to
  fill, for sub-patterns, the extracted data, or
  in fun-matchers defined with defunmatcher  by a MELT
  function -returning a true value on successful match- whose
    secondary results are the extracted data. The standard MELT library provides a big lot of useful matchers.?(tuple ... ) match a tuple value, and whose components match the corresponding sub-pattern.?(list ... ) match a list value, whose elements match the corresponding sub-pattern.?(instance nameclass ... ) match a MELT object value, instance (directly or thru subclasses) of the given class nameclass, whose fields match the corresponding sub-patterns.?(and ...) matches if and only if all the conjunct sub-patterns match; side-effect, notably pattern variable bindings, are transmitted betwen conjunct sub-patterns which are lazily processed in order.?(or ...) matches as soon as one disjunct sub-pattern matches; sub-patterns are lazily processed in order (so further disjunct sub-patterns are not matched when a previous disjunct did match)| pattern | ||
| expr | some "constant" expression, often a literal or a local variable bound in an enclosing let | |
| ?_ | the catch-all wildcard pattern always match | |
|  | pattern variables If not pattern-bound, bind the variable to the matched data; if previously pattern-bound, test for identity == to the pattern-variable's bound data Side effect: pattern-bind that namevarto the matched data. | |
|  | The namematcher of the matcher defines the number and roles of [input] sub-expressions exprin and [output] sub-patterns patternout | |
|  | Match a tuple value of given sub-pattern-s | |
|  | Match a list value of given sub-pattern-s | |
| ?(instance nameclass:namefield 
pattern) | Match an value of given class (or some subclass) and fields | |
| ?(and pattern) | conjunctive pattern, all sub-patterns should match; sub-patterns are lazily matched in order till match failure | |
| ?(or pattern) | disjunction pattern, some sub-pattern should match; sub-patterns are lazily matched in order till match success | 
to be completed