]]> ]]>

GNU Pascal

Реализация языка программирования Pascal

GNU Pascal — свободно распространяемый компилятор языка Pascal для 32/64-битных платформ. Является частью GCC (Gnu Compiler Collection).

Преимущества:

  • поддержка стандартного и расширенного набора Pascal в соответствии с ISO, ANSI и IEEE (ISO 7185:1990, ISO/IEC 10206:1991, ANSI/IEEE 770X3.160—1989)
  • поддержка других стандартов Pascal (UCSD Pascal, Borland Pascal, часть Borland Delphi, Mac Pascal и Pascal-SC), учитывая принцип разумности и элегантности
  • генерирует код и работает на любом компьютере, на котором есть GNU C (практически любая 32-х и более битная платформа под практически любой ОС).

GNU Pascal
GNU Pascal

Примеры:

Квадратное уравнение:

Пример для версий Free Pascal 2.2.0, PascalABC.NET 1.8, Turbo Pascal 1.0, Turbo Pascal 2.0, Turbo Pascal 3.0, Turbo Pascal 4.0, Turbo Pascal 5.0, Turbo Pascal 6.0, gpc 20070904

В Pascal есть встроенный комплексный тип данных complex, но команда writeln не работает с ним напрямую (только через функции Re и Im), поэтому существенного удобства от его использования нет. Вычисления проводятся в типе real. Библиотечная функция halt, введенная в Extended Pascal, позволяет выйти из текущего блока (в более поздних версиях заменена на exit).

program Quadratic;

var
   A,B,C,D: integer;

begin
   write('A = ');
   readln(A);
   if (A=0) then
   begin
      writeln('Not a quadratic equation.');
      halt;
   end;
   write('B = ');
   readln(B);
   write('C = ');
   readln(C);
   D := B*B-4*A*C;
   if (D=0) then
   begin
      writeln('x = ',-B/2.0/A);
      halt;
   end;
   if (D>0) then
   begin
      writeln('x1 = ',(-B+Sqrt(D))/2.0/A);
      writeln('x2 = ',(-B-Sqrt(D))/2.0/A);
   end
   else
   begin
      writeln('x1 = (',-B/2.0/A,',',Sqrt(-D)/2.0/A,')');
      writeln('x2 = (',-B/2.0/A,',',-Sqrt(-D)/2.0/A,')');
   end;
end.

CamelCase:

Пример для версий Free Pascal 2.2.0, Free Pascal 2.2.4, Turbo Pascal 4.0, Turbo Pascal 5.0, Turbo Pascal 5.5, Turbo Pascal 6.0, gpc 20070904

Пример использует такую же логику, как и предыдущий, но для проверки того, является ли символ буквой, используются множества символов lower и upper. Это делает код более читабельным.

Отметим, что в Turbo Pascal программа работает, начиная с версии Turbo Pascal 4.0, в которой впервые появляется тип данных char.

program Camelcase;

var
    text, cc: string[100];
    c: char;
    i: integer;
    lastSpace: boolean;
    upper, lower: set of char;

begin
    upper := ['A'..'Z'];
    lower := ['a'..'z'];
    readln(text);
    lastSpace := true;
    cc := '';
    for i := 1 to Length(text) do
    begin
        c := text[i];
        if (c in lower) or (c in upper) then
        begin
            if (lastSpace) then { convert to uppercase }
            begin
                if (c in lower) then
                    c := chr(ord(c) - 32);
            end
            else { convert to lowercase }
                if (c in upper) then
                    c := chr(ord(c) + 32);
            cc := cc + c;
            lastSpace := false;
        end
        else
            lastSpace := true;
    end;
    writeln(cc);
end. 

CamelCase:

Пример для версий Free Pascal 2.2.0, Free Pascal 2.2.4, Turbo Pascal 4.0, Turbo Pascal 5.0, Turbo Pascal 5.5, Turbo Pascal 6.0, gpc 20070904

Программа обрабатывает строку посимвольно. Для определения того, является ли символ буквой, и если является, то в каком он регистре, используются ASCII-коды символов. Функция ord возвращает ASCII-код данного символа, а chr — символ по его коду. Размерность строк не задана и по умолчанию принимается равной 255.

Отметим, что в Turbo Pascal программа работает только начиная с версии 4.0; в более ранних версиях не было типа данных char.

program Camelcase;

var
    text, cc: string;
    c: char;
    i: integer;
    lastSpace: boolean;

begin
    readln(text);
    lastSpace := true;
    cc := '';
    for i := 1 to Length(text) do
    begin
        c := text[i];
        if ((c >= #65) and (c <= #90)) or ((c >= #97) and (c <= #122)) then
        begin
            if (lastSpace) then
            begin
                if ((c >= #97) and (c <= #122)) then
                    c := chr(ord(c) - 32);
            end
            else
                if ((c >= #65) and (c <= #90)) then
                    c := chr(ord(c) + 32);
            cc := cc + c;
            lastSpace := false;
        end
        else
            lastSpace := true;
    end;
    writeln(cc);
end. 

Факториал:

Пример для версий Free Pascal 2.0.4, Free Pascal 2.2.0, PascalABC.NET 1.8, Turbo Pascal 1.0, Turbo Pascal 2.0, Turbo Pascal 3.0, Turbo Pascal 4.0, Turbo Pascal 5.0, Turbo Pascal 5.5, Turbo Pascal 6.0, Turbo Pascal 7.0, gpc 20070904

Этот пример работает точно так же, как основной рекурсивный пример для Pascal, но использует тип real для хранения значений факториала. Команда writeln(f:-1:0) выводит дробное число f с 0 цифр после десятичной запятой и выравнивает его по левому краю.

program factorial;

function fact(n: integer): real;
begin
    if (n = 0) then
        fact := 1
    else
        fact := n * fact(n - 1);
end;

var
    n: integer;

begin
    for n := 0 to 16 do
        writeln(n, '! = ', fact(n):-1:0);
end.

Hello, World!:

Пример для версий Free Pascal 2.2.0, Free Pascal 2.2.4, PascalABC.NET 1.8, Turbo Pascal 1.0, Turbo Pascal 2.0, Turbo Pascal 3.0, Turbo Pascal 4.0, Turbo Pascal 5.0, Turbo Pascal 5.5, Turbo Pascal 6.0, Turbo Pascal 7.0, gpc 20070904
program helloworld;

begin
    writeln('Hello, World!');
end.

Числа Фибоначчи:

Пример для версий Free Pascal 2.2.0, Free Pascal 2.2.4, PascalABC.NET 1.8, Turbo Pascal 1.0, Turbo Pascal 2.0, Turbo Pascal 3.0, Turbo Pascal 4.0, Turbo Pascal 5.0, Turbo Pascal 5.5, Turbo Pascal 6.0, Turbo Pascal 7.0, gpc 20070904

Этот пример использует рекурсивное определение чисел Фибоначчи.

program fibonacci;

function fib(n:integer): integer;
begin
    if (n <= 2) then
        fib := 1
    else
        fib := fib(n-1) + fib(n-2);
end;

var
    i:integer;

begin
    for i := 1 to 16 do
        write(fib(i), ', ');
    writeln('...');
end.

Факториал:

Пример для версий Free Pascal 1.0.6, Free Pascal 2.0.4, Free Pascal 2.2.0, Free Pascal 2.2.4, PascalABC.NET 1.8, Turbo Pascal 4.0, Turbo Pascal 5.0, Turbo Pascal 5.5, Turbo Pascal 6.0, Turbo Pascal 7.0, gpc 20070904

Используется рекурсивное определение факториала.

Этот пример работает во всех перечисленных компиляторах, но с несколько разным результатом. В Turbo Pascal, Free Pascal и PascalABC.NET возникает арифметическое переполнение при вычислении факториалов 13-16, но Free Pascal сообщает об ошибке:

13! = Runtime error 215 at $004013C7
$004013C7
$00401449
$004063E0

в то время как Turbo Pascal и PascalABC.NET не обнаруживают ошибку и просто выводят неправильные значения:

13! = 1932053504
14! = 1278945280
15! = 2004310016
16! = 2004189184

Следует отметить, что в версиях Turbo Pascal 3.0 и младше этот пример не работает вообще из-за отсутствия типа данных longint.

В GNU Pascal пример работает без переполнения.

program factorial;

function fact(n: integer): longint;
begin
    if (n = 0) then
        fact := 1
    else
        fact := n * fact(n - 1);
end;

var
    n: integer;

begin
    for n := 0 to 16 do
        writeln(n, '! = ', fact(n));
end.

Комментарии

]]>

blog comments powered by Disqus

]]>

Работа программистам