@@ -69,6 +69,16 @@ static void fire_error_mix_and_or_no_parenthesis(SrcLocation loc, std::string_vi
6969 " Use parenthesis to emphasize operator precedence." );
7070}
7171
72+ // fire an error "Tolk does not have ++i operator"
73+ GNU_ATTRIBUTE_NORETURN GNU_ATTRIBUTE_COLD
74+ static void fire_error_no_increment_operator (SrcLocation loc, bool is_increment) {
75+ std::string op_name = is_increment ? " increment" : " decrement" ;
76+ std::string op_wrong = is_increment ? " ++" : " --" ;
77+ std::string op_right = is_increment ? " +=" : " -=" ;
78+ throw ParseError (loc, std::string (" Tolk has no " ) + op_name + " operator\n " +
79+ " hint: use `i " + op_right + " 1`, not `i" + op_wrong + " `" );
80+ }
81+
7282// diagnose when bitwise operators are used in a probably wrong way due to tricky precedence
7383// example: "flags & 0xFF != 0" is equivalent to "flags & 1", most likely it's unexpected
7484// the only way to suppress this error for the programmer is to use parenthesis
@@ -847,14 +857,16 @@ static AnyExprV parse_expr100(Lexer& lex) {
847857 }
848858}
849859
850- // parse E(...) and E! having parsed E already (left-to-right)
860+ // parse E(...) / E! / E++ / E-- having parsed E already (left-to-right)
851861static AnyExprV parse_fun_call_postfix (Lexer& lex, AnyExprV lhs) {
852862 while (true ) {
853863 if (lex.tok () == tok_oppar) {
854864 lhs = createV<ast_function_call>(lhs->loc , lhs, parse_argument_list (lex));
855865 } else if (lex.tok () == tok_logical_not) {
856866 lex.next ();
857867 lhs = createV<ast_not_null_operator>(lhs->loc , lhs);
868+ } else if (lex.tok () == tok_double_plus || lex.tok () == tok_double_minus) {
869+ fire_error_no_increment_operator (lex.cur_location (), lex.tok () == tok_double_plus);
858870 } else {
859871 break ;
860872 }
@@ -865,7 +877,7 @@ static AnyExprV parse_fun_call_postfix(Lexer& lex, AnyExprV lhs) {
865877// parse E(...) and E! (left-to-right)
866878static AnyExprV parse_expr90 (Lexer& lex) {
867879 AnyExprV res = parse_expr100 (lex);
868- if (lex.tok () == tok_oppar || lex.tok () == tok_logical_not) {
880+ if (lex.tok () == tok_oppar || lex.tok () == tok_logical_not || lex. tok () == tok_double_plus || lex. tok () == tok_double_minus ) {
869881 res = parse_fun_call_postfix (lex, res);
870882 }
871883 return res;
@@ -892,7 +904,7 @@ static AnyExprV parse_expr80(Lexer& lex) {
892904 lex.unexpected (" method name" );
893905 }
894906 lhs = createV<ast_dot_access>(loc, lhs, v_ident, v_instantiationTs);
895- if (lex.tok () == tok_oppar || lex.tok () == tok_logical_not) {
907+ if (lex.tok () == tok_oppar || lex.tok () == tok_logical_not || lex. tok () == tok_double_plus || lex. tok () == tok_double_minus ) {
896908 lhs = parse_fun_call_postfix (lex, lhs);
897909 }
898910 }
@@ -909,6 +921,12 @@ static AnyExprV parse_expr75(Lexer& lex) {
909921 AnyExprV rhs = parse_expr75 (lex);
910922 return createV<ast_unary_operator>(loc, operator_name, t, rhs);
911923 }
924+ if (t == tok_double_minus || t == tok_double_plus) {
925+ SrcLocation loc = lex.cur_location ();
926+ lex.next ();
927+ parse_expr75 (lex);
928+ fire_error_no_increment_operator (loc, t == tok_double_plus);
929+ }
912930 return parse_expr80 (lex);
913931}
914932
0 commit comments