anchor.diff:    catch {error, {_Line, _Message}} = Error ->
       Error
     end.
  +  
  +%% Ensure a given function body contains only function defs
  +validate_function_body([]) -> ok;
  +validate_function_body([#function{}|Exprs]) ->
  +  validate_function_body(Exprs);
  +validate_function_body([Expr|_]) ->
  +  throw({error, {element(2, Expr), "Arbitrary expressions not allowed in class/module bodies"}}).
     
   %% Interpolate strings, parsing the contents of #{...} tags
   interpolate_string(#string{line=Line, characters=Chars}) ->
  
positive.code:   #module{
      line  = ?line('$1'), 
      name  = element(3, '$2'), 
      exprs = '$4'
    }.
    
  %% Class declarations
  class_decl -> class module_name def_exprs 'end' : 
    #class{
      line  = ?line('$1'), 
      name  = ?identifier_name('$2'), 
      exprs = '$3'
    }.
  class_decl -> class module_name '<' module_name def_exprs 'end' : 
    #class{
      line   = ?line('$1'), 
      name   = ?identifier_name('$2'),
      parent = ?identifier_name('$4'),
      exprs  = '$5'
    }.
  
  %% Expression lists with interspersed defs (eol delimited)
  
negative.code:     block = '$2'#args.block,
      body  = '$4'
    }.
  def_expr -> expr : '$1'.
  
  %% Allowable prefixes for defs
  def_prefix -> def function_identifier : ?identifier_name('$2').
  