anchor.diff:  Left 1100 open.
   
   
  -prefix_op -> add_op : '$1'.
  -prefix_op -> bin_not : '$1'.
  +prefix_op -> add_op   : '$1'.
  +prefix_op -> bin_not  : '$1'.
   prefix_op -> bool_not : '$1'.
   
   program -> exprs    : '$1'.
  
positive.code: 
  % function call
  
  fun_call -> atom fn_parameters           : {call, line('$1'), '$1', '$2'}.
  fun_call -> var fn_parameters            : {call, line('$1'), '$1', '$2'}.
  fun_call -> atom dot atom fn_parameters  :
      {call, line('$2'), {remote, line('$2'), '$1', '$3'}, '$4'}.
  fun_call -> atom dot var fn_parameters  :
      {call, line('$2'), {remote, line('$2'), '$1', '$3'}, '$4'}.
  fun_call -> var dot atom fn_parameters  :
      {call, line('$2'), {remote, line('$2'), '$1', '$3'}, '$4'}.
  fun_call -> var dot var fn_parameters  :
      {call, line('$2'), {remote, line('$2'), '$1', '$3'}, '$4'}.
  fun_call -> fun_call fn_parameters       : {call, line('$1'), '$1', '$2'}.
  
  % function arity
  
  farity -> fn atom split_op integer   :
      {'fun', line('$1'), {function, unwrap('$2'), unwrap('$4')}}.
  
  farity -> fn atom dot atom split_op integer   :
      {'fun', line('$1'), {function, unwrap('$2'), unwrap('$4'), unwrap('$6')}}.
  
  % list comprehension
  
negative.code: astify      -> open_oxford      bool_expr close_oxford  : fn_meta:astify(line('$1'), '$2').
  meta_astify -> open_meta_oxford bool_expr close_list    : fn_meta:astify(line('$1'), fn_meta:eval('$2')).
  
  exprs -> send_expr endl      : ['$1'].
  exprs -> send_expr endl exprs: ['$1'|'$3'].
  
  send_expr -> match_expr send_op send_expr : {op, line('$2'), unwrap('$2'), '$1', '$3'}.
  send_expr -> match_expr                   : '$1'.
  
  match_expr -> def_expr match match_expr : {match, line('$2'), '$1', '$3'}.
  match_expr -> def_expr                  : '$1'.
  
  def_expr -> literal split_def_op bool_expr : {def, line('$2'), '$1', '$3'}.
  def_expr -> bool_expr : '$1'.
  