anchor.diff:          when ?OR(E,$e,$E) andalso ?OR(L,$l,$L) andalso ?OR(S,$s,$S)
           andalso (?OR(SP,32,${) orelse ?OR(SP,$i,$I)) ->
       st_else(<<SP:8,Rest/binary>>, Pos, Parsed);
  +code(<<E:8,C:8,H:8,O:8,SP:8,Rest/binary>>, Pos, Parsed)
  +        when ?OR(E,$e,$E) andalso ?OR(C,$c,$C) andalso ?OR(H,$h,$H)
  +        andalso ?OR(O,$o,$O) andalso ?OR(SP,32,$() ->
  +    {Rest0, Pos0, Exp} = expression(<<SP:8,Rest/binary>>,
  +                                     print_level(add_pos(Pos,5)), []),
  +    Print = add_line(#print{expression=[Exp]}, Pos),
  +    code(Rest0, Pos0, [Print|Parsed]);
  +code(<<P:8,R:8,I:8,N:8,T:8,SP:8,Rest/binary>>, Pos, Parsed)
  +        when ?OR(P,$p,$P) andalso ?OR(R,$r,$R) andalso ?OR(I,$i,$I)
  +        andalso ?OR(N,$n,$N) andalso ?OR(T,$t,$T) andalso ?OR(SP,32,$() ->
  +    {Rest0, Pos0, Exp} = expression(<<SP:8,Rest/binary>>,
  +                                     print_level(add_pos(Pos,6)), []),
  +    Print = add_line(#print{expression=[Exp]}, Pos),
  +    code(Rest0, Pos0, [Print|Parsed]);
   code(<<"?>",Rest/binary>>, {code_value,_,_}=Pos, Parsed) ->
       {Rest, normal_level(add_pos(Pos,2)), Parsed};
   code(<<"?>",Rest/binary>>, Pos, Parsed) ->
  
positive.code:     shunting_yard(Rest, [Op], Postfix);
  shunting_yard([open|Rest], OpS, Postfix) ->
      shunting_yard(Rest, [open|OpS], Postfix);
  shunting_yard([close|Rest], OpS, Postfix) ->
      {Add, [_Drop|NewOpS]} = lists:splitwith(fun(A) -> A =/= open end, OpS),
      shunting_yard(Rest, NewOpS, Postfix ++ Add);
  shunting_yard([{_,{left,P1}}=Op|Rest], [{_,{_,P2}}]=OpS, Postfix) when P1 < P2 ->
      shunting_yard(Rest, [Op|OpS], Postfix);
  shunting_yard([{_,{right,P1}}=Op|Rest], [{_,{_,P2}}]=OpS, Postfix) when P1 =< P2 ->
      shunting_yard(Rest, [Op|OpS], Postfix);
  shunting_yard([{_,{left,P1}}=Op|Rest], [{_,{_,P2}}]=OpS, Postfix) when P1 >= P2 ->
      shunting_yard(Rest, [Op], Postfix ++ OpS);
  shunting_yard([{_,{right,P1}}=Op|Rest], [{_,{_,P2}}]=OpS, Postfix) when P1 > P2 ->
      shunting_yard(Rest, [Op], Postfix ++ OpS);
  shunting_yard([{_,{_,_}}=Op|Rest], OpS, Postfix) ->
      shunting_yard(Rest, [Op|OpS], Postfix);
  shunting_yard([A|Rest], OpS, Postfix) ->
      shunting_yard(Rest, OpS, Postfix ++ [A]).
  
  add_line(#eval{}=E, {_,Row,Col}) -> E#eval{line={{line,Row},{column,Col}}};
  add_line(#print{}=P, {_,Row,Col}) -> P#print{line={{line,Row},{column,Col}}};
  add_line(#variable{}=V, {_,R,C}) -> V#variable{line={{line,R},{column,C}}};
  add_line(#constant{}=C, {_,R,C}) -> C#constant{line={{line,R},{column,C}}};
  add_line(#int{}=I, {_,R,C}) -> I#int{line={{line,R},{column,C}}};
  add_line(#text_to_process{}=T, {_,R,C}) ->
      T#text_to_process{line={{line,R},{column,C}}};
  
negative.code: operator(<<"or">>,Left,Right) -> operator('or',Left,Right);
  operator(<<"&&">>,Left,Right) -> operator('and',Left,Right);
  operator(<<"||">>,Left,Right) -> operator('or',Left,Right);
  operator(Op,R1,R2) when (is_record(R1, int) orelse is_record(R1, float))
                  andalso (is_record(R2, int) orelse is_record(R2, float)) ->
      N1 = element(2, R1),
      N2 = element(2, R2),
      Res = case Op of
          <<"+">> -> N1+N2;
          <<"-">> -> N1-N2;
          <<"*">> -> N1*N2;
          <<"/">> -> N1/N2;
          <<"%">> -> N1 rem N2;
          <<">">> -> N1 > N2;
          <<"<">> -> N1 < N2;
          <<"==">> -> N1 == N2
          %% TODO add more optimizations for the rest of the operators
      end,
      if
          is_integer(Res) -> #int{int=Res};
          is_float(Res) -> #float{float=Res};
          is_boolean(Res) -> Res;
          true -> throw({error, R1, R2, Res})
      end;
  operator(<<".">>,#text{text=T1},#text{text=T2}) ->
      #text{text = <<T1/binary,T2/binary>>};
  operator(<<".">>,Left,Right) ->
      #concat{texts=[Left,Right]};
  operator(Op,Left,Right) ->
      #operation{type=Op, expression_left=Left, expression_right=Right}.
  
  