Пара багрепортов от меня:
1) Компилятор не ругается на использование неинициализированных переменных.
Это затрудняет отладку программ.
2) Виртовский вариант цикла Дейкстры реализован как-то неправильно. Вот стандартный пример его использования:
MODULE TestGCD;
IMPORT c := Console;
PROCEDURE GCD(x, y: INTEGER) : INTEGER;
BEGIN
WHILE x > y DO x := x - y
ELSIF x < y DO y := y - x
END;
ASSERT(x = y);
RETURN x
END GCD;
BEGIN
c.Int(GCD(255, 150));
c.Ln;
END TestGCD.Программа падает на ассерте, в логе пишется:
TestGCD.GCD
x INTEGER 105
y INTEGER 45хотя при данных аргументах (255 и 150) обе переменные должны быть равны 15, и сам цикл должен завершаться, когда x = y.
Сишный аналог этой процедуры работает правильно:
#define WHILE for(;;) if (
#define DO ) {
#define ELSIF ; } else if (
#define WEND ; } else break
#define ASSERT(p) if (!(p)) { printf("Oops in %s at line %d", __FILE__, __LINE__); exit(1); }
int gcd(int x, int y)
{
WHILE x > y DO x = x - y
ELSIF x < y DO y = y - x
WEND;
ASSERT(x == y);
return x;
}
3) Вот такой вариант тоже падает на ассерте:
PROCEDURE GCDrec(x, y: INTEGER) : INTEGER;
VAR
result : INTEGER;
BEGIN
IF x > y THEN result := GCDrec(x-y, y )
ELSIF x < y THEN result := GCDrec( x, y-x)
ELSE result := x
END;
ASSERT(x = y);
RETURN result
END GCDrec;Такое впечатление, что что-то не то с операциями сравнения...