dylan-lang / opendylan

Open Dylan compiler and IDE
http://opendylan.org/
Other
458 stars 69 forks source link

bad warning for `if ... end fi` #1356

Open cgay opened 3 years ago

cgay commented 3 years ago

The following is copied directly from Day 3 of @toshok's https://github.com/toshok/aoc2020/blob/main/diary.md. The only thing I would add is that this is somewhat surprising because we get good warnings for matching end words at the method level.


The error was:

/Users/toshok/src/aoc2020/day3/day3.dylan:12.5-17.32: Serious warning - Invalid syntax for fbody in for macro call.
          --------------------
  12      let line = lines[i];
  13      if(line[x] == '#')
  14        trees := trees + 1;
  15      end fi;
  16      x := x + right;
  17      x := modulo(x, size(line));
      -------------------------------

Which... not the most helpful. Anyway, it's that line 15 there. end fi; should be end if; Found the usual way: comment out everything and introduce bits at a time.

pedro-w commented 3 years ago

I did a little investigating:

define function zero(x)
  if (x = 0)
    format-out("");
  end fi;
end function;

gives

9.7-9: Serious warning - Unexpected token "fi".
            --
        end fi;
            --

6.1-10.15: Serious warning - Skipping constant-definer macro call due to previous syntax error.
      -----------------------
   6  define function zero(x)
   7    if (x = 0)
   8      format-out("");
   9    end fi;
  10    end function;
      --------------

Good! but

  define function one(x)
    if (x)
      if (x = 0)
        format-out("");
      end fi;
    end if;
  end function;

gives

16.9-12: Serious warning - Invalid syntax for false-action in if macro call.
              ---
          end fi;
              ---

13.3-17.9: Serious warning - Skipping if macro call due to previous syntax error.
        ------
  13    if (x)
  14      if (x = 0)
  15        format-out("");
  16      end fi;
  17    end if;
      --------

and

  define function two(x)
    for (i from 0 below 10)
      if (x = 0)
        format-out("");
      end fi;
    end for;
  end function;

gives (as we know)

Serious warning - Invalid syntax for fbody in for macro call.
          ----------
  22      if (x = 0)
  23        format-out("");
  24      end fi;
      -----------

21.3-25.10: Serious warning - Skipping for macro call due to previous syntax error.
        -----------------------
  21    for (i from 0 below 10)
  22      if (x = 0)
  23        format-out("");
  24      end fi;
  25    end for;
      ---------

so is the problem when there's a macro expansion inside a macro expansion? And why are the messages different?

cgay commented 3 years ago

Useful examples. It looks to me like the parser reaches the fi token and, it not being if, the parser decides that end terminates the if statement. Then it is effectively left with fi; ... as where it picks up with parsing, resulting in different errors depending on the surrounding context.