Pascalは、ニクラウス・ヴィルトによって設計された命令型かつ手続き型のプログラミング言語であり、構造化プログラミングとデータ構造化を用いた優れたプログラミング手法を促進することを目的とした、小さくて効率的な言語です。フランスの数学者、哲学者、物理学者であるブレーズ・パスカルにちなんで名付けられました。[ a ]
PascalはALGOL 60言語をベースに開発されました。WirthはALGOL X開発の一環として言語改良に携わり、 ALGOL Wというバージョンを提案しました。しかし、これは採用されず、ALGOL Xの開発は停滞しました。1968年、WirthはALGOL Xの開発を断念し、ALGOL Wをさらに改良することに決め、1970年にPascalとしてリリースしました。
ALGOLのスカラーと配列に加えて、Pascalでは複雑なデータ型を定義し、リスト、ツリー、グラフなどの動的かつ再帰的なデータ構造を構築できます。Pascalはすべてのオブジェクトに厳密な型付けを備えているため、明示的な変換なしに、ある型のデータを別の型に変換したり、別の型として解釈したりすることはできません。C言語(およびCファミリーの他のほとんどの言語)とは異なり、Pascalでは任意の深さまでネストされたプロシージャ定義が可能で、サブルーチン(プロシージャと関数)内でほとんどの種類の定義と宣言が可能です。したがって、プログラムは構文的には単一のプロシージャまたは関数に似ています。これはALGOL 60のブロック構造に似ていますが、任意のブロック文ではなく、プロシージャと関数のみに制限されています。
Pascalは1970年代に、特に急成長を遂げていたミニコンピュータ市場で大きな成功を収めました。 1970年代後半にマイクロコンピュータ分野が台頭するにつれ、多くのマイクロコンピュータ向けにコンパイラも利用可能になりました。1980年代には大学のプログラミングコースで教材として広く使用され、同時期には商用ソフトウェアの開発にも実用的に用いられました。しかし、1980年代後半から1990年代初頭にかけて、 UNIXベースのシステムが普及し、特にC++がリリースされると、C言語に取って代わられることになりました。
オブジェクト指向プログラミング向けに設計された派生言語であるObject Pascalは、1985年に開発されました。これは1980年代後半にApple Computer ( LisaおよびMacintoshマシン向け)とBorlandによって使用され、後にMicrosoft Windowsプラットフォーム上でDelphiへと発展しました。Pascalの概念を拡張した言語として、 Wirthによって開発されたModula-2とOberonが誕生しました。
1960年代のコンピュータ言語設計の歴史の多くは、ALGOL 60言語に遡ることができる。ALGOLは、アルゴリズムを明確に記述できるようにすることを明確な目標として1950年代に開発された。ALGOLには、今日でも多くの言語で共通して見られる構造化プログラミングのための機能が数多く含まれていた。
1962年の発表直後、ヴィルトはヘルムート・ウェーバーと共に、プログラミング言語「オイラー」に関する博士論文の執筆に取りかかった。オイラーはALGOLの構文と多くの概念に基づいていたが、派生言語ではなかった。その主な目的は、動的なリストと型を追加し、 Lispと同様の役割で使用できるようにすることであった。この言語は1965年に発表された。
この頃までに、ALGOLには標準化された文字列システムがないことなど、いくつかの問題点が明らかになっていた。言語の保守を担当するグループは、改善点を見つけるためにALGOL Xプロセスを開始し、提案を募集した。WirthとTony Hoareは、文字列を追加し、構文を整理するための控えめな修正案を提出した。しかし、これらは新しい標準ALGOLとして使用するには軽微すぎると判断されたため、WirthはALGOL用のコンパイラを作成し、それがALGOL Wと名付けられた。
ALGOL Xの開発では、より複雑な言語であるALGOL 68が採用されることになった。この言語の複雑さゆえに、高性能コンパイラの開発は著しく困難であり、業界で広く普及することはなかった。そのため、より新しい言語が登場する余地が生まれた。
Pascalは、体系的な方法でプログラミングを教え、システムソフトウェアを開発するという明確な目標を持つALGOL Wの取り組みに影響を受けています。 [ 5 ] 1世代の学生は、学部課程の入門言語としてPascalを使用しました。その他の目標には、大規模プログラムを作成するための信頼性が高く効率的なツールを提供すること[ 6 ]、そして当時広く普及していたFortranやCOBOLに代表される科学プログラミングと商用プログラミングの間の溝を汎用言語で埋めることなどがありました。[ 7 ]
この言語の初期の成功例の1つは、カリフォルニア大学サンディエゴ校(UCSD)のUCSD Pascalの導入でした。これは、さまざまなプラットフォームに移植可能なカスタムオペレーティングシステム上で動作するバージョンでした。重要なプラットフォームはApple IIで、 Apple Pascalとして広く使用されました。これにより、PascalはApple Lisa、そして後にMacintoshの開発に使用される主要な高水準言語となりました。オリジナルのMacintoshオペレーティングシステムの一部は、PascalソースコードからMotorola 68000アセンブリ言語に手作業で翻訳されました。[ 8 ]
ドナルド・クヌースによる組版システムTeXは、Digital Equipment Corporation (DEC) PDP-10 Pascalをベースとした、オリジナルのリテラルプログラミングシステムであるWEBで記述された。Adobe Photoshop [ 9 ]のような成功した商用アプリケーションはMacintosh Programmer's Workshop Pascalで記述され、 Total Commander、Skype [ 10 ]、Macromedia CaptivateのようなアプリケーションはDelphi ( Object Pascal )で記述された。Apollo Computerは1980年から、自社のオペレーティングシステムのシステムプログラミング言語としてPascalを使用した。
Pascalの派生言語は、研究プロジェクトからPCゲーム、組み込みシステムまで、あらゆる用途に使用されてきました。より新しいPascalコンパイラも存在し、広く使用されています。[ 11 ]
Wirth氏が言語普及のために考案したコンパイラであるPascal-Pシステムは、自己コンパイル可能な最小限の言語サブセットを使用するように設計されていました。これは、コンパイラをブートストラップし、その後完全なPascal言語へと拡張できるという考えに基づいています。この方式は複数のコンパイラで採用されましたが、注目すべき例外として、Pascal-P2をベースとしたUCSD Pascalがありました。UCSD Pascalは、メモリ容量が限られた当時の新しいマイクロプロセッサでより効率的に動作するという考えに基づき、言語のサブセット状態を維持しました。UCSDはまた、バイト指向のマイクロプロセッサにより適しているという理由から、Pascal-P2インタープリタを「バイトマシン」に変換しました。
UCSD Pascalは、Apple Pascalをはじめとする多くのシステムの基盤となった。Borland PascalはUCSDのコードベースに基づいて開発されたものではないが、UCSDが普及していた時期に登場し、その多くの機能を備えていた。これが、Delphi Pascalと、それに互換性のあるオープンソースコンパイラFPC/ Lazarusへと続く系譜の始まりとなった。
PascalのISO規格であるISO 7185は1983年に発行され、16ビットから32ビットまでのメインフレーム、ミニコンピュータ、IBM PCおよび互換機で広く実装され、使用されました。20世紀末から現在に至るまで最も広く使用されているPascalの2つの方言は、ISO 7185標準バージョンとDelphi/Turbo Pascalバージョンです(このうち、Borlandの2つのバージョンはほぼ互換性があります)。
Pascalの初期の歴史に関する多くの情報は、Pascal User's Groupのニュースレターに掲載されています。
Pascalユーザーグループのニュースレター
Lisaの開発中、ラリー・テスラーは、 Pascalをマルチパラダイムプログラミング言語にするために、オブジェクト指向拡張機能を言語に追加するというアイデアについて、ワースと連絡を取り始めた。これがきっかけとなり、1983年にClascalが発表された。Lisaプログラムが衰退し、Macintoshに取って代わられると、さらに改良されたバージョンであるObject Pascalが開発された。これは1985年にMacAppアプリケーションフレームワークの一部としてMacに導入され、1990年代初頭までAppleの主要開発言語となった。
Object Pascal拡張機能は、1989年にバージョン5.5がリリースされた際にTurbo Pascalに追加されました。 [ 12 ]長年にわたり、Object PascalはMicrosoft Windows用のDelphiシステムの基盤となり、現在もWindowsアプリケーションの開発に使用され、他のシステムへのクロスコンパイルも可能です。Free Pascalは、 Lazarusという独自のグラフィカル統合開発環境(IDE)を備えたオープンソースのクロスプラットフォーム代替システムです。
最初の Pascalコンパイラは、チューリッヒでCDC 6000 シリーズのメインフレーム コンピュータファミリー向けに設計されました。Niklaus Wirth は、1969 年にFORTRAN 66で実装しようとした最初の試みが、FORTRAN 66 が複雑なデータ構造を表現するのに不十分だったため失敗したと報告しています。 2 回目の試みは、C ライクな言語 (Max Engeli による Scallop) で実装され、その後 (R. Schild によって)ブートストラップのために Pascal 自体に手作業で翻訳されました。[ 13 ] 1970 年半ばには動作していました。 それ以降の多くの Pascal コンパイラは同様に自己ホスト型、つまりコンパイラ自体が Pascal で書かれており、言語に新機能が追加されたとき、またはコンパイラが新しい環境に移植されるときに、コンパイラは通常自身を再コンパイルできます。GNU Pascalコンパイラは、C で書かれている注目すべき例外の 1 つです。
CDC Pascalコンパイラを別のメインフレームに移植することに初めて成功したのは、 1972年にベルファストのクイーンズ大学(QUB)のウェルシュとクインによるものでした。対象はインターナショナル・コンピュータ・リミテッド(ICL)の1900シリーズでした。このコンパイラは、情報コンピュータシステムズ(ICS)のMultumミニコンピュータ用のPascalコンパイラの原型となりました。Multumへの移植は、グラスゴー大学計算機科学科のフィンドレー、カプルス、カヴラス、デイビスによって、システムプログラミング言語としてPascalを使用することを目的として開発されました。1973年の夏に完成したMultum Pascalは、最初の16ビット実装であったと考えられています。
1977年、クイーンズ大学ベルファスト校のウェルシュらが全く新しいコンパイラを完成させた。このコンパイラは、グラスゴー大学のフィンドレーとワットが実装したソース言語診断機能(プロファイリング、トレース、型認識フォーマットによる事後ダンプを含む)を提供した。この実装は、1980年にサウサンプトン大学とグラスゴー大学のチームによってICL 2900シリーズに移植された。Standard Pascal Model Implementationもこのコンパイラをベースにしており、1984年にマンチェスター大学のウェルシュとヘイによって、BSI 6192/ISO 7185規格への準拠を厳密にチェックし、移植可能な抽象マシン用のコードを生成するように改良された。
北米で最初に開発されたPascalコンパイラは、イリノイ大学のドナルド・B・ギリーズ氏の指導の下、 PDP -11向けに構築され、ネイティブマシンコードを生成した。マイクロソフトはIBM PC向けにPascalコンパイラを提供していた( Microsoft Pascalを参照)。
言語を迅速に普及させるため、チューリッヒでコンパイラ移植キットが作成されました。このキットには、仮想スタックマシン用のいわゆるpコード(つまり、比較的効率的な解釈に適したコード)を生成するコンパイラと、そのコードのインタプリタであるPascal-Pシステムが含まれていました。Pシステムコンパイラは、Pascal-P1、Pascal-P2、Pascal-P3、およびPascal-P4と名付けられました。Pascal-P1が最初のバージョンで、Pascal-P4がチューリッヒから最後にリリースされたバージョンです。Pascal-P1というバージョン名は、当時存在していたPascal-Pのさまざまなソースに対して後から付けられたものです。コンパイラは移植性を高めるために再設計され、Pascal-P2としてリリースされました。このコードは後に拡張され、Pascal-P2と後方互換性のある中間コードを持つPascal-P3と、後方互換性のないPascal-P4になりました。
Pascal-P4コンパイラ・インタプリタは、オリジナルのPascalと互換性のあるシステム上で実行およびコンパイルできます(Pascal-P2も同様です)。ただし、Pascal言語の一部しか受け付けません。
チューリッヒグループ以外で開発されたPascal-P5は、Pascal言語の全機能をサポートし、ISO 7185との互換性も備えています。
Pascal-P6はPascal-P5の後継バージョンであり、他の機能に加えて、AMD64を含む特定のCPU向けのコンパイラとなることを目指している。
UCSD Pascal は、 Kenneth Bowles が解釈型UCSD p-Systemを作成するために使用したPascal-P2 から派生したものです。これは、初代IBM Personal Computerの発売時に利用可能だった 3 つのオペレーティングシステムの 1 つでした。[ 14 ] UCSD Pascal はバイト値に基づく中間コードを使用していたため、初期のバイトコードコンパイラの 1 つでした。Apple Pascal は、 Apple II およびApple IIIコンピュータ システム向けに 1979 年にリリースされました。これは UCSD Pascal の実装、または大部分が UCSD Pascal に基づいていました。Pascal-P1 から Pascal-P4 はそうではなく、CDC 6600 の60 ビットワード長に基づいていました。
ネイティブバイナリオブジェクトファイルを作成するPascal-P4コンパイラをベースにしたコンパイラが、オーストラリア原子力委員会によってIBM System/370メインフレームコンピュータ向けにリリースされました。これは委員会の名称の略称にちなんでAAEC Pascal 8000 Compilerと名付けられました。 [ 15 ]
Apple Computerは1982年にLisa Workshop向けに独自のLisa Pascalを作成し、1985年にそのコンパイラをApple MacintoshとMPWに移植しました。1985年、ラリー・テスラーはニクラウス・ヴィルトと協議の上、Object Pascalを定義し、これらの拡張機能はLisa PascalとMac Pascalの両方のコンパイラに組み込まれました。
1980年代、アンダース・ヘイルスバーグはNascom -2向けにBlue Label Pascalコンパイラを開発した。このコンパイラをIBM PC向けに再実装したものが、 Borlandに買収されTurbo Pascalと改名される前に、Compas PascalおよびPolyPascalという名称で販売された。
Turbo Pascalは、積極的な価格戦略、初期のフルスクリーンIDEの搭載、そしてコンパイル、リンク、実行までわずか数秒という非常に高速な処理時間のおかげで、絶大な人気を博しました。アセンブリ言語で完全に記述され、高度に最適化されていたため、競合製品の多くよりも小型で高速でした。
1986 年、アンダースは Turbo Pascal を Macintosh に移植し、Apple の Object Pascal 拡張機能を Turbo Pascal に組み込みました。これらの拡張機能は、バージョン 5.5 の Turbo Pascal の PC 版にも追加されました。同時に、Microsoftも Object Pascal コンパイラを実装しました。[ 16 ] [ 17 ] Turbo Pascal 5.5 は、1980 年代後半に主に IBM PC に集中し始めた Pascal コミュニティに大きな影響を与えました。BASIC の構造化された代替品を探していた多くの PC ホビイストがこの製品を使用しました。プロの開発者にも採用され始めました。ほぼ同時期に、 Pascal プログラマがMicrosoft WindowsのC ベースのアプリケーション プログラミング インターフェイス(API)を直接使用できるように、 Cから多くの概念がインポートされました。これらの拡張機能には、ヌル終端文字列、ポインタ演算、関数ポインタ、アドレス演算子、安全でない型キャストが含まれていました。
Turbo Pascalや、ユニット構造またはモジュール構造を持つその他の派生言語は、モジュール型プログラミング言語です。しかし、ネストされたモジュールの概念や、特定のシンボルの修飾インポート/エクスポートは提供していません。
Super Pascalでは、非数値ラベル、return文、および式を型名として使用できる機能が追加されています。
TMT Pascalは、 32ビットMS-DOS互換プロテクトモード、OS/2、およびWin32に対応した、 Borland互換の最初のコンパイラでした。関数と演算子のオーバーロードによって言語を拡張しています。
ウィスコンシン大学マディソン校、チューリッヒ大学、カールスルーエ大学、ヴッパータール大学は、数値計算のプログラミングを目的としたPascal-SC [ 18 ] [ 19 ]およびPascal-XSC [ 20 ] [ 21 ] [ 22 ] (科学計算用拡張機能) コンパイラを開発しました。Pascal-SC の開発は 1978 年に ISO 7185 Pascal レベル 0 のサポートから始まりましたが、レベル 2 のサポートは後の段階で追加されました。[ 23 ] Pascal-SC は当初Z80プロセッサを対象としていましたが、後に DOS ( x86 ) および68000用に書き直されました。Pascal-XSC は、さまざまな時期に Unix ( Linux、SunOS、HP-UX、AIX ) および Microsoft/IBM ( DOS with EMX、OS/2、Windows ) オペレーティングシステムに移植されています。これは、中間 C ソース コードを生成し、それをネイティブ実行可能ファイルにコンパイルすることによって動作します。 Pascal-SC言語拡張機能の一部はGNU Pascalに採用されている。
Pascal Sol は、Sol というUnix ライクなシステムを実装するために、1983 年頃にフランスのチームによって設計されました。これは標準の Pascal レベル 1 (パラメータ化された配列境界付き) でしたが、定義では代替キーワードとフランス語の事前定義済み識別子が許可されており、システム プログラミングを容易にするためのいくつかの拡張機能 (lseek に相当するものなど) が含まれていました。[ 24 ] Sol チームは後にChorusOSプロジェクトに移り、分散オペレーティングシステムを設計しました。[ 25 ]
IP Pascalは、 Micropolis DOSを使用したPascalプログラミング言語の実装ですが、Z80上で動作するCP/M-80へと急速に移行しました。1994年には80386マシンタイプに移行し、現在ではWindows XPおよびLinuxの実装として存在しています。2008年には、このシステムは新たなレベルに引き上げられ、その結果生まれた言語は「Pascaline」(パスカルの電卓にちなんで)と名付けられました。オブジェクト、名前空間制御、動的配列、その他多くの拡張機能を含み、一般的にC#と同じ機能と型保護を備えています。これは、ISO 7185として標準化されているオリジナルのPascal実装とも互換性のある唯一の実装です。
Pascal は、その本来の形では純粋に手続き型の言語であり、単一のステートメントまたはステートメントのブロックに及ぶ、、、、、、などの予約語を含む、ALGOLに似た従来の制御構造を備えています。Pascalには、レコード、バリアント、ポインタ、列挙、セット、プロシージャポインタなど、元のALGOL 60型には含まれていないデータ構造化構成要素もあります。これらの構成要素は、 Simula 67、ALGOL 68、Niklaus Wirth自身のALGOL W 、およびCAR Hoareの提案から部分的に継承または着想を得ています。ifthenelsewhileforcasebeginend
Pascal プログラムは、外部ファイル記述子のリストをパラメータとして指定したprogramキーワード[ 26 ]で始まります(Turbo Pascal などでは不要)。その後、キーワードとキーワードで囲まれたメインブロックが続きます。セミコロンはステートメントを区切り、ピリオド(つまり、ピリオド) はプログラム全体 (またはユニット) を終了します。Pascalソースでは大文字と小文字は区別されません。beginend
以下は、非常にシンプルな「Hello, World!」プログラムで使用されているソースコードの例です。
program HelloWorld ( output ) ; begin WriteLn ( 'Hello, World!' ) {ブロックの最後のステートメントの後には「;」は必要ありません。 追加するとプログラムに「空のステートメント」が追加され、コンパイラによって無視されます。} end .Pascalにおける型宣言は、その型の変数が格納できる値の範囲を定義するために使用されます。また、その型の変数に対して実行可能な一連の操作も定義します。定義済みの型は以下のとおりです。
基本型(ブール型を除く)で許容される値の範囲は、実装依存です。一部のデータ変換には関数が用意されています。realから への変換にはinteger、次の関数が利用可能です。round(0から半分離れた方向に丸めます)およびtrunc(0に向かって丸めます)。
プログラマーは、Pascalの型宣言機能を使用して、定義済みの型に基づいて他の一般的に使用されるデータ型(バイト、文字列など)を自由に定義できます。
type byte = 0 .. 255 ; signed_byte = - 128 .. 127 ; string = packed array [ 1 .. 255 ] of char ;バイト型や文字列型など、よく使われる型は、多くの実装ですでに定義されています。
通常、システムはデータを格納するためにワードを使用します。たとえば、型は8ビットbyte値ではなく、32ビットのマシン整数で格納される場合があります。Pascalには、基本ストレージ型をより細かく定義できる言語要素は含まれていません。この機能は、多くのPascal拡張機能や後継言語に搭載されましたが、Modula-2などの言語では、組み込み型セットを拡張して、16ビット整数などのほとんどのマシンデータ型をカバーしています。
このキーワードは、構造化データ型(セット、配列、レコード)に対して、要素ごとに1ワードpackedを使用するのではなく、最も効率的な格納方法を使用するようにコンパイラに指示します。パッキングは、ワードの一部に容易にアクセスできないマシンでは、アクセス速度を低下させる可能性があります。
任意の順序データ型(実数以外の任意の単純型)のサブレンジも作成できます。
var x : 1 .. 10 ; y : 'a' .. 'z' ;同時代の他のプログラミング言語とは対照的に、Pascalはセット型をサポートしています。[ 27 ]
var Set1 : 1から10までの集合; Set2 : 'a'から' z'までの集合;集合は現代数学における基本的な概念であり、多くのアルゴリズムで使用されます。このような機能は便利であり、集合をサポートしない言語における同等の構造よりも高速になる可能性があります。例えば、多くのPascalコンパイラでは次のようになります。
i が[ 5 .. 10 ]の範囲内であれば...より高速に実行されます:
もし( i > 4 )かつ( i < 11 )ならば...連続していない値の集合は、パフォーマンスと可読性の両面において特に有用である。
i が[ 0 .. 3 , 7 , 9 , 12 .. 15 ]の範囲内であれば...これらの例のように、小さな領域上の集合を扱う場合、コンパイラが集合変数をビットベクトルとして表現することで、通常はパフォーマンスが向上します。これにより、集合演算子をビット単位の機械語演算として効率的に実装できます。
レコードは、フィールドと呼ばれる任意の数のメンバ要素から構成される構造体です。フィールドは、コロンで区切られた識別子とデータ型のペアを指定することで定義されます。ネストされたレコードも可能です。フィールドリストは、キーワードで終了します。レコード変数のフィールドには、レコード名とフィールド識別子の間にendドット()を挿入することで後からアクセスできます。 [ 28 ] Pascalレコード型の例:.
type car = record幅:整数;長さ:整数end ;レコードは、フィールド宣言の括弧付きリストで定義される定数であるバリアントcase ... ofで構成される場合もあります。レコードの末尾には、句を使用して、句内で指定された型のバリアントの数を含む変数部分を宣言します。 [ 29 ]バリアントレコードタイプの例:
type Shape = ( Circle , Square , Triangle ) ; Dimensions = record case Figure : Shape of Circle : ( Diameter : real ) ; Square : ( Width : real ) ; Triangle : ( Side : real ; Angle1 , Angle2 : 0 .. 360 ) end ;バリアントレコードでは、レコード内の複数のフィールドが互いに重なり合うことでメモリを節約できます。
型は、型宣言を使用して他の型から定義できます。
type x = integer ; y = x ; ...さらに、単純な型から複雑な型を構築することもできます。
type a = array [ 1 .. 10 ] of integer ; b = record x : integer ; y : char {extra semicolon not strictly required} end ; c = file of a ;さらに、複合型は他の複合型から再帰的に構築することができる。
const Jack = 11 ; Queen = 12 ; King = 13 ; Ace = 14 ;type valueType = 2 .. Ace ; suitType = club , diamond , heart , spade ;cardType = record suit : suitType ; value : valueType ; end ;deckType = array [ 1 .. 52 ] of cardType ;person = record surname : packed array [ 1 .. 20 ] of char ; age : integer ; end ;テーブル=レコードハンド:配列[ 1 .. 3 ] of deckType ;プレイヤー:配列[ 1 .. 4 ] of person ;終了;type a =整数型のファイル; b =レコードx :整数; y :文字end ; c = b 型のファイル;上記の例に示すように、Pascalファイルはコンポーネントのシーケンスです。すべてのファイルには、f^で表されるバッファ変数があります。get (読み取り用) およびput (書き込み用) の手続きは、バッファ変数を次の要素に移動します。read は、read(f, x)がx := f^; get(f);と同じになるように導入されています。write は、write(f, x) がf^ := x; put(f);と同じになるように導入されています。型は、char 型の file として事前に定義されています。バッファ変数は、使用する次の文字を検査するために使用できます (整数を読み取る前に数字をチェックする) が、これは初期の実装では対話型プログラムで深刻な問題を引き起こしましたが、後に「遅延 I/O」の概念によって解決されました。これは、ファイル操作を実行する前に、ファイルバッファ変数に実際にアクセスされるまで待機します。 text
Pascalはポインタをサポートしています。
type pNode = ^ Node ; Node = record a : integer ; b : char ; c : pNode end ; var NodePtr : pNode ; IntPtr : ^ integer ;ここで変数NodePtrは、レコードであるデータ型Nodeへのポインタです。まだ定義されていない型へのポインタも宣言できます(上記の例では、pNode は Node へのポインタですが、ポインタ型が定義されている時点では Node はまだ定義されていません)。これは前方宣言であり、使用する前に宣言しなければならないという規則の例外です。
新しいレコードを作成し、レコードのフィールドaとbに値10と文字Aを割り当て、ポインタcをヌルポインタ(Pascal では「NIL」)に初期化するには、次のステートメントを使用します。
new ( NodePtr ) ; ... NodePtr ^. a := 10 ; NodePtr ^. b := 'A' ; NodePtr ^. c := nil ; ...withこれは、以下のステートメントを使用しても実行できます。
new ( NodePtr ) ; ... with NodePtr ^ do begin a := 10 ; b := 'A' ; c := nil end ; ...withステートメントの範囲内では、a と b はレコード ポインタNodePtrのサブフィールドを参照し、レコード Node やポインタ型 pNode を参照しません。
レコードにポインタ型フィールド(c)を含めることで、リンクリスト、スタック、キューを作成できます。
ポインタを特徴とする多くの言語とは異なり、Pascal では、ポインタは匿名の動的に作成された変数のみを参照でき、標準の静的変数やローカル変数を参照することはできません。また、ポインタには関連付けられた型が必要であり、ある型のポインタは別の型のポインタと互換性がありません (たとえば、char へのポインタは integer へのポインタと互換性がありません)。これにより、他のポインタ実装、特にPL/IやCで使用される実装に内在する型のセキュリティの問題が解消されます。また、ダングリングポインタによって引き起こされるリスクもいくつか解消されますが、 dispose関数 ( Cにあるfreeライブラリ関数と同じ効果があります)を使用して参照領域を動的に解放できるため、自動ガベージ コレクションを提供する Java や C# などの言語のようにダングリングポインタのリスクは解消されていません[ 30 ]。
これらの制限の一部は、新しい方言では解除される可能性がある。
Pascalは構造化プログラミング言語であり、制御の流れが標準的なステートメントに構造化されており、通常は「goto」コマンドは使用されません。
aとbが一致しない間、 WriteLn ( '待機中' ) ;a > bの場合、 WriteLn ( '条件を満たしました' ) {else の前にセミコロンは使用できません}、そうでない場合はWriteLn ( '条件を満たしていません' ) ;for i := 1 to 10 do {次のステートメントを切り離してしまうため、ここにセミコロンは不要です} WriteLn ( '反復: ' , i ) ;a := a + 1をa = 10になるまで繰り返す。case i of 0 : Write ( 'zero' ) ; 1 : Write ( 'one' ) ; 2 : Write ( 'two' ) ; 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 : Write ( '?' ) end ;Pascalでは、プログラムは手続きと関数に構造化されます。一般的に、手続きはその副作用のために用いられ、関数はその戻り値のために用いられます。
プログラム印刷(出力);var i :整数;procedure PrintAnInteger ( j : integer ) ; begin ... end ;function triple ( x : integer ) : integer ; begin triple := x * 3 end ;begin { メインプログラム } ... PrintAnInteger ( i ) ; PrintAnInteger ( triple ( i )) end .手続きや関数は任意の深さまでネストすることができ、「プログラム」構造は論理的に最も外側のブロックとなる。
デフォルトでは、パラメータは値渡しされます。パラメータ名の前に「var」が付いている場合は、参照渡しされます。
各プロシージャまたは関数は、gotoラベル、定数、型、変数、および他のプロシージャや関数の宣言を独自に持つことができ、それらはすべてこの順序で記述されなければなりません。この順序要件は、もともと効率的なシングルパスコンパイルを可能にするために設けられました。しかし、一部の言語( Delphiなど)では、宣言セクションの厳密な順序要件が緩和されています。
Pascalは、文区切り文字としてセミコロンを使用するなど、ALGOL言語から多くの言語構文の特徴を取り入れています。これは、セミコロンを文末文字として使用するPL/IやCendなどの他の言語とは対照的です。レコード型宣言、ブロック、またはcase文のキーワードの前、untilrepeat文のキーワードの前、およびif文elseのキーワードの前には、セミコロンは必要ありません。
Pascal の初期バージョンでは、余分なセミコロンの存在は許可されていませんでした。しかし、 1973 年改訂レポートでALGOLのような空文が追加され、その後 ISO 7185:1983 で言語が変更されたことにより、現在ではほとんどの場合、セミコロンを省略できます。if 文のキーワードの直前にセミコロンを置くことはまだ許可されていません。これは、 if文が単一の文に続くのであって、文のシーケンスに続くのではないためです。ネストされた if 文では、セミコロンを使用して、ネストされた if 文をセミコロンで終了させることで、ぶら下がり else問題 (内側の if 文には else がなく、外側の if 文には else がある) を回避することはできません。これは、代わりに両方の if 節を終了させてしまいます。代わりに、明示的な...ブロックを使用する必要があります。[ 31 ]elseelsebeginend
一般的に利用可能なPascalコンパイラとインタプリタはいくつかあります。
1983 年、この言語は国際規格 IEC/ISO 7185 [ 38 ]および米国規格 ANSI/IEEE770X3.97-1983 や ISO 7185:1983 を含むいくつかの各国固有の規格で標準化されました。この 2 つの規格の違いは、ISO 規格には適合配列 (実行時まで配列の境界がわからない配列) の「レベル 1」拡張が含まれているのに対し、ANSI では元の (Wirth バージョン) 言語にこの拡張が認められていない点のみです。1989 年に ISO 7185 は、元の文書で見つかったさまざまなエラーや曖昧さを修正するために改訂されました (ISO 7185:1990)。
ISO 7185は、ユーザーマニュアルおよびレポート[Jensen and Wirth]で詳述されているように、Wirthの1974年の言語の明確化であるとされていますが、レベル1として「適合配列パラメータ」を標準に追加したことでも注目に値します。レベル0は、適合配列のないPascalです。この追加は、 CAR Hoareの要請により、Niklaus Wirthの承認を得て行われました。きっかけとなったのは、Hoareが、元々FORTRANで記述されていた(NAG)数値アルゴリズムライブラリのPascal版を作成しようとした際に、可変サイズの配列パラメータを可能にする拡張機能がなければ作成できないことに気づいたことでした。同様の理由から、手続きパラメータと機能パラメータのパラメータ型を指定する機能がISO 7185に盛り込まれました。
ニクラウス・ヴィルト自身は、例えばCDC 6000コンパイラのマシン固有の機能と区別するために、1974年の言語を「標準」と呼んでいました。この言語は、「Pascalユーザーマニュアルおよびレポート」の第2部である「Pascalレポート」 [ 39 ]に文書化されています。
Pascalが生まれた大型マシン(メインフレームやミニコンピュータ)では、一般的に標準規格が遵守されていました。しかし、IBM PCではそうではありませんでした。IBM PCでは、Borlandの標準規格であるTurbo PascalとDelphiが最も多くのユーザーを抱えています。そのため、特定の実装がオリジナルのPascal言語に対応しているのか、それともBorlandの方言に対応しているのかを理解することが、通常は重要になります。
IBM PC版の言語は、UCSD Pascalの登場とともに違いを見せ始めた。UCSD Pascalはインタプリタ方式の実装であり、言語にいくつかの拡張機能が追加された一方で、いくつかの機能が削除され、変更も加えられていた。UCSD言語の多くの機能は、ボーランドの方言を含め、今日でも残っている。
1990年に拡張パスカル標準がISO/IEC 10206として作成されました[ 40 ]。これは技術的な内容[ 41 ]においてIEEE/ANSI 770X3.160-1989 [ 42 ]と同一です。 2019年現在、FreePascal Compilerでの拡張パスカルのサポートが計画されています[ 43 ] 。
Extended Pascal の重要な特徴は、モジュール性と分離コンパイルです。Extended Pascal アプリケーションのソースコードファイルは、1 つの「プログラムファイル」と複数の「モジュールファイル」に分割できます。各モジュールファイルには、独自の型、定数、変数、およびプロシージャ/関数の定義があり、プログラマはこれらの「エンティティ定義」領域の順序を変更できます。また、モジュール固有の定義領域として、ステートメントを含む「初期化」領域to begin do ...とステートメントを含む「終了」領域がありto end do ...、モジュール内のエンティティの初期状態とメモリ割り当てを管理できます。モジュール/プログラムの宣言領域と定義領域の間にステートメントを挿入することでimport ...、モジュールは独自のエンティティを他のモジュール(およびプログラム)と共有できます。
その他の主な機能としては、変数バインディング、類似型のコレクション(スキーマ)、包括的な文字列機能、複素数型のサポート、ステートメントotherwiseにおけるデフォルト分岐フローのキーワードcase、および短絡ブール値評価などがあります。
ニクラウス・ヴィルトによるチューリッヒ版のPascalは、 ETH以外では2つの基本的な形態で公開された。1つはCDC 6000コンパイラのソースコード、もう1つはPascal-Pシステムと呼ばれる移植キットである。Pascal-Pコンパイラは、コンパイラの起動に必要のない、完全版言語のいくつかの機能を省略していた。例えば、パラメータとして使用されるプロシージャや関数、無差別バリアントレコード、パッキング、dispose、プロシージャ間gotoなど、完全版コンパイラの機能は省略されていた。
ケネス・ボウルズ教授の下で開発されたUCSD Pascalは、Pascal-P2キットをベースとしており、そのためPascal-Pの言語制約をいくつか共有していました。UCSD Pascalは後にApple Pascalとして採用され、その後も複数のバージョンを経て開発が続けられました。UCSD Pascalは、Pascal-Pキットに含まれるPascalのサブセットを拡張し、標準的なPascalの構文を再び追加しましたが、それでも完全な標準Pascalのインストールとは言えませんでした。
1990年代初頭、アラン・バーンズとジェフ・デイヴィスは、ニクラウスの著書『アルゴリズム+データ構造=プログラム』に登場するPl/0の拡張版であるPascal-FCを開発しました。Pascal-FCを並行プログラミングの教育ツールとして使用するために、セマフォ、モニタ、チャネル、リモート呼び出し、リソースなどのいくつかの構成要素が追加されました。並行性を実証するために、コンパイラの出力(一種のPコード)を仮想マシン上で実行できるようにしました。この仮想マシンは、通常の公平な環境をシミュレートするだけでなく、極端な条件(不公平モード)もシミュレートすることができました。
アンダース・ヘイルスバーグによって開発されたボーランド社のTurbo Pascalは、 UCSDおよびチューリッヒのコンパイラとは独立したアセンブリ言語で記述されていました。しかしながら、UCSDコンパイラと多くの共通部分および拡張機能を採用していました。これはおそらく、当時利用可能だったリソースが限られたマイクロプロセッサシステム上でアプリケーションを開発するのに適したPascalシステムが、UCSDシステムが最も一般的だったためでしょう。
シュリンクパッケージ化されたTurbo Pascalバージョン3とその後のバージョン(BorlandのObject PascalやDelphi、およびBorland以外の互換に近いものを含む)は、シェアウェアの作者を含むプログラマーの間で人気を博したため、SWAGのPascalコードライブラリには、Delphiなどのバージョンを念頭に置いて書かれたコードが多数含まれている。
このカテゴリに含まれるソフトウェア製品(コンパイラ、IDE/ラピッドアプリケーション開発(RAD)など):
Pascalは、コンピューターコミュニティにおいて、批判的なものから称賛的なものまで、実に多様な反応を引き起こした。
ヴィルトによるこの言語の最初の定義は広く批判された。特に、ニコ・ハーバーマンは著書「プログラミング言語パスカルに関する批判的コメント」(1973年)の中で、その構成要素の多くが定義が不十分であり、特にデータ型、範囲、構造体、およびgotoについてそうであると指摘した。[ 47 ]その後、C言語を普及させたブライアン・カーニハンは、1981年に記事「なぜパスカルは私の好きなプログラミング言語ではないのか」の中でパスカルに対する批判を概説した。[ 48 ]カーニハンが指摘した最も深刻な問題は、配列のサイズと文字列の長さが型の一部であるため、可変長配列や文字列をパラメータとして受け入れる関数を書くことができないことだった。このため、例えばソートライブラリを書くことは不可能だった。カーニハンはまた、ブール式の評価順序が予測不可能であること、ライブラリのサポートが不十分であること、静的変数がないことなどを批判し、その他いくつかの小さな問題も提起した。また、同氏は、この言語には制約や制限を「回避」(意図的に強制的に無視する)するための単純な構造が一切提供されていないと述べた。他の情報源からのより一般的な不満[ 30 ] [ 49 ]では、宣言のスコープが元の言語定義で明確に定義されておらず、ポインタ型を定義するために前方宣言を使用した場合、レコード宣言が相互再帰を引き起こした場合、または列挙リストで識別子が使用されているかどうか不明な場合に、深刻な結果を招くことがあると指摘された。もう1つの難点は、ALGOL 60と同様に、この言語では、パラメーターとして渡されるプロシージャや関数がパラメーターの期待される型を事前に定義することを許可していないことだった。
1975年以降の20年間で、UCSD PascalとTurbo Pascalが利用可能になったことにより、Pascalはますます注目を集め、重要なプラットフォーム(Apple II、Apple III、Apple Lisa、Commodoreシステム、Z-80ベースのマシン、IBM PCなど)向けの主要なプログラミング言語となった。[ 50 ]
当初の批判にもかかわらず、Pascal は進化を続け、Kernighan の指摘のほとんどは、Borland のTurbo Pascalのように商用製品開発に適したように強化された言語のバージョンには当てはまりません。Kernighan が記事で予測したように、これらの問題を解決するための拡張機能のほとんどは、コンパイラ間で互換性がありませんでした。しかし、1990 年代初頭以降、ほとんどのバリエーションは ISO と Borland ライクの 2 つのカテゴリに集約されているようです。Extended Pascal は、これらの初期の批判の多くに対応しています。可変長文字列、変数初期化、分離コンパイル、短絡ブール演算子、および case ステートメントの default ( otherwise) 句をサポートしています。[ 51 ]
Pascalの実装の違いから生じる問題の一部は、モードディレクティブで複数の方言をサポートするFree Pascalの登場によって後に部分的に解決された。[ 52 ]
Object Pascal
を非常に注意深く調査し、バインドされたメソッド参照の動作プロトタイプを作成して、Javaプログラミング言語とそのAPIとの相互作用を理解しました...私たちの結論は、バインドされたメソッド参照は不要であり、言語にとって有害であるというものでした。この決定は、Delphi Object Pascalでバインドされたメソッド参照に関する以前の経験を持つBorland Internationalと協議して行われました。 」
このプロジェクトは「green」という名前で進められ、言語は
UCSD Pascal
の古いモデルに基づいており、解釈型コードの生成が可能だった。