PL / I - PL/I

PL / I
Paradigma Processual , imperativo , estruturado
Projetado por IBM e o Comitê de Desenvolvimento de Linguagem SHARE
Desenvolvedor IBM
Apareceu pela primeira vez 1964 ; 57 anos atrás ( 1964 )
Versão estável
IBM Enterprise PL / I para z / OS 5.3 / setembro de 2019
Local na rede Internet www .ibm .com / products / pli-compiler-zos
Dialetos
Veja dialetos
Influenciado por
COBOL , Fortran , ALGOL 60
Influenciado
Linguagem de controle , PL / M , PL / S , PL-6 , PL / 8 , REXX

PL / I ( Programming Language One , pronunciado / p ɛ l w ʌ n / e às vezes escrito PL / 1 ) é uma linguagem de programação de computador procedural e imperativa desenvolvida e publicada pela IBM . Ele é projetado para programação científica, de engenharia, de negócios e de sistemas. Ele tem sido usado por organizações acadêmicas, comerciais e industriais desde que foi introduzido na década de 1960 e ainda é usado.

Os principais domínios do PL / I são processamento de dados , computação numérica , computação científica e programação de sistema . Ele suporta recursão , programação estruturada , estrutura de dados ligados a manipulação, de ponto fixo , de ponto flutuante , complexo , cadeia de caracteres manipulação, e cadeia de bits manuseio. A sintaxe da linguagem é semelhante ao inglês e adequada para descrever formatos de dados complexos com um amplo conjunto de funções disponíveis para verificá-los e manipulá-los.

História antiga

Na década de 1950 e no início da década de 1960, os usuários empresariais e científicos programaram para diferentes hardwares de computador usando diferentes linguagens de programação. Os usuários comerciais estavam mudando de Autocoders via COMTRAN para COBOL , enquanto os usuários científicos programavam em Fortran , ALGOL , GEORGE e outros. O IBM System / 360 (anunciado em 1964 e entregue em 1966) foi projetado como uma arquitetura de máquina comum para ambos os grupos de usuários, substituindo todas as arquiteturas IBM existentes. Da mesma forma, a IBM queria uma única linguagem de programação para todos os usuários. Esperava que o Fortran pudesse ser estendido para incluir os recursos necessários aos programadores comerciais. Em outubro de 1963, um comitê foi formado originalmente por três IBMistas de Nova York e três membros do SHARE , o grupo de usuários científicos da IBM, para propor essas extensões ao Fortran. Dadas as restrições do Fortran, eles foram incapazes de fazer isso e embarcaram no projeto de uma nova linguagem de programação baseada vagamente no ALGOL rotulado como NPL . Esta sigla entrava em conflito com a do National Physical Laboratory do Reino Unido e foi substituída brevemente por MPPL (MultiPurpose Programming Language) e, em 1965, por PL / I (com um algarismo romano "I"). A primeira definição apareceu em abril de 1964.

A IBM pegou o NPL como ponto de partida e completou o design a um nível em que o primeiro compilador poderia ser escrito: a definição do NPL estava incompleta em escopo e detalhes. O controle da linguagem PL / I foi investido inicialmente no New York Programming Center e, posteriormente, no IBM UK Laboratory em Hursley . Os grupos de usuários SHARE e GUIDE estiveram envolvidos na extensão da linguagem e tiveram uma função no processo da IBM para controlar a linguagem por meio de seus Projetos PL / I. A experiência de definir uma linguagem tão ampla mostrou a necessidade de uma definição formal de PL / I. Um projeto foi estabelecido em 1967 no IBM Laboratory Vienna para fazer uma especificação inequívoca e completa. Isso levou, por sua vez, a um dos primeiros Métodos Formais de grande escala para desenvolvimento, o VDM .

Fred Brooks é creditado por garantir que PL / I tinha o tipo de dados CHARACTER.

A linguagem foi especificada em detalhes pela primeira vez no manual "Especificações de linguagem PL / I. C28-6571" escrito em Nova York a partir de 1965 e substituído por "Especificações de linguagem PL / I. GY33-6003" escrito em Hursley de 1967. IBM continuou a desenvolver PL / I no final dos anos sessenta e início dos setenta, publicando-o no manual GY33-6003. Esses manuais foram usados ​​pelo grupo Multics e outros implementadores iniciais.

O primeiro compilador foi entregue em 1966. O padrão para PL / I foi aprovado em 1976.

Metas e princípios

Os objetivos para PL / I evoluíram durante o desenvolvimento inicial da linguagem. A competitividade com o manuseio de registros do COBOL e a redação de relatórios era necessária. O escopo de utilidade da linguagem cresceu para incluir a programação do sistema e a programação orientada a eventos . Metas adicionais para PL / I eram:

  • Desempenho do código compilado competitivo com o do Fortran (mas isso não foi alcançado)
  • Extensibilidade para novo hardware e novas áreas de aplicação
  • Maior produtividade do processo de programação, transferindo esforço do programador para o compilador
  • Independência da máquina para operar efetivamente no hardware do computador principal e sistemas operacionais

Para atingir esses objetivos, o PL / I emprestou ideias de linguagens contemporâneas ao mesmo tempo em que adicionava novos recursos substanciais e os projetava com uma sintaxe distinta, concisa e legível. Muitos princípios e capacidades combinados para dar ao idioma seu caráter e foram importantes para atender aos objetivos do idioma:

  • Estrutura de bloco , com semântica subjacente (incluindo recursão ), semelhante ao Algol 60 . Os argumentos são passados ​​usando chamada por referência , usando variáveis ​​fictícias para valores onde necessário ( chamada por valor ).
  • Uma ampla variedade de tipos de dados computacionais, tipos de dados de controle de programa e formas de estrutura de dados ( tipagem forte ).
  • Extensões dinâmicas para arrays e strings com herança de extensões por parâmetros de procedimento.
  • Sintaxe concisa para expressões, declarações e instruções com abreviações permitidas. Adequado para um conjunto de caracteres de 60 glifos e subconfigurável em 48.
  • Uma extensa estrutura de padrões em instruções, opções e declarações para ocultar algumas complexidades e facilitar a extensão da linguagem enquanto minimiza os pressionamentos de tecla.
  • Processamento iterativo poderoso com bom suporte para programação estruturada .
  • Não deveria haver palavras reservadas (embora os nomes das funções DATEe TIMEprovassem ser impossíveis de cumprir este objetivo). Novos atributos, instruções e opções de instrução podem ser adicionados ao PL / I sem invalidar os programas existentes. Nem mesmo IF, THEN, ELSE, e DOforam reservados.
  • Ortogonalidade : cada capacidade de ser independente de outras capacidades e livremente combinada com outras capacidades sempre que significativo. Cada capacidade deve estar disponível em todos os contextos onde for significativa, para explorá-la o mais amplamente possível e evitar "restrições arbitrárias". A ortogonalidade ajuda a tornar a linguagem "ampla".
  • Recursos de tratamento de exceções para controlar e interceptar condições excepcionais em tempo de execução.
  • Programas divididos em seções compiláveis ​​separadamente, com extensos recursos de tempo de compilação (também conhecidos como macros ), que não fazem parte do padrão, para adaptar e combinar seções de código-fonte em programas completos. Nomes externos para vincular procedimentos compilados separadamente em um único programa.
  • Recursos de depuração integrados à linguagem.

Resumo do idioma

A linguagem foi projetada para ser tudo para todos os programadores. O resumo é extraído do Padrão ANSI PL / I e do Padrão de Subconjunto de Uso Geral ANSI PL / I.

Um programa PL / I consiste em um conjunto de procedimentos, cada um dos quais escrito como uma sequência de instruções. A %INCLUDEconstrução é usada para incluir texto de outras fontes durante a tradução do programa. Todos os tipos de declaração são resumidos aqui em agrupamentos que fornecem uma visão geral da linguagem (o Padrão usa esta organização).

Categoria Demonstração
Estrutural PROCEDURE(ou PROC)
ENTRY
BEGIN
DO
END
Declarativo DECLARE(ou DCL)
DEFAULT(ou DFT)
FORMAT
Fluxo de controle CALL
IF
SELECT
GO TO
RETURN
STOP
Declaração nula
Categoria Demonstração
Manuseio de interrupção ON
SIGNAL
REVERT
Armazenar ALLOCATE(ou ALLOC)
FREE
Declaração de atribuição
Entrada / Saída OPEN
CLOSE
Entrada / saída de fluxo GET
PUT
Entrada / saída de registro READ
WRITE
REWRITE
LOCATE
DELETE

(Recursos como multitarefa e o pré-processador PL / I não estão no padrão, mas são suportados no compilador PL / IF e algumas outras implementações são discutidas na seção de evolução da linguagem.)

Os nomes podem ser declarados para representar dados dos seguintes tipos, como valores únicos ou como agregados na forma de matrizes, com um limite inferior e superior por dimensão ou estruturas (compreendendo estrutura aninhada, matriz e variáveis ​​escalares) :

  • Arithmetic (expandido abaixo)
  • CHARACTER
  • PICTURE for Arithmetic data
  • PICTURE for Character data
  • AREA
  • BIT
  • ENTRY
  • FILE
  • FORMAT
  • LABEL
  • OFFSET
  • POINTER

O arithmetictipo compreende estes atributos:

  • uma base ( BINARYou DECIMAL), e
  • uma escala ( FIXEDou FLOAT), e
  • um modo ( REALou COMPLEX), e
  • a PRECISION( number of digitse para números de pontos fixos, a scale factor)

A base, a escala, a precisão e o fator de escala do Picture-for-arithmetictipo são codificados no picture-specification. O modo é especificado separadamente, com o picture specificationaplicado às partes real e imaginária.

Os valores são calculados por expressões escritas usando um conjunto específico de operações e funções embutidas, a maioria das quais pode ser aplicada a agregados, bem como a valores únicos, juntamente com procedimentos definidos pelo usuário que, da mesma forma, podem operar e retornar agregados, bem como valores únicos. A instrução de atribuição atribui valores a uma ou mais variáveis.

Não há palavras reservadas em PL / I. Uma instrução é encerrada por um ponto e vírgula. O comprimento máximo de uma instrução é definido pela implementação. Um comentário pode aparecer em qualquer lugar em um programa onde um espaço é permitido e é precedido pelos caracteres barra, asterisco e termina com os caracteres asterisco, barra (isto é /* This is a comment. */). As instruções podem ter um prefixo de rótulo introduzindo um nome de entrada ( ENTRYe PROCEDUREinstruções) ou nome de rótulo e um prefixo de condição habilitando ou desabilitando uma condição computacional - por exemplo (NOSIZE)). Os nomes de entrada e rótulo podem ser identificadores únicos ou identificadores seguidos por uma lista de subscritos de constantes (como em L(12,2):A=0;).

Uma sequência de declarações torna-se um grupo quando precedida por uma DOdeclaração e seguida por uma ENDdeclaração. Os grupos podem incluir grupos aninhados e blocos iniciais. A IFinstrução especifica um grupo ou uma única instrução como a THENparte e a ELSEparte (consulte o programa de amostra). O grupo é a unidade de iteração. O bloco inicial ( BEGIN; stmt-list END;) pode conter declarações de nomes e procedimentos internos locais para o bloco. Um procedimento começa com uma PROCEDUREinstrução e é encerrado sintaticamente por uma ENDinstrução. O corpo de um procedimento é uma sequência de blocos, grupos e instruções e contém declarações para nomes e procedimentos locais para o procedimento ou EXTERNALpara o procedimento.

Uma unidade ON é uma única instrução ou bloco de instruções escritas para serem executadas quando uma ou mais dessas condições ocorrerem:

uma condição computacional ,

  • CONVERSION (CONV)
  • FIXEDOVERFLOW (FOFL)
  • OVERFLOW (OFL)
  • SIZE
  • STRINGRANGE (STRG)
  • STRINGSIZE (STRZ)
  • SUBSCRIPTRANGE (SUBRG)
  • UNDERFLOW (UFL)
  • ZERODIVIDE (ZDIV)

ou uma condição de entrada / saída ,

  • ENDFILE(file)
  • ENDPAGE(file)
  • KEY(file)
  • NAME(file)
  • RECORD(file)
  • TRANSMIT(file)
  • UNDEFINEDFILE(file) (UNDF)

ou uma das condições:

  • AREA, CONDITION (identifier), ERROR,FINISH

A declaração de um identificador pode conter um ou mais dos seguintes atributos (mas eles precisam ser mutuamente consistentes):

Atributos de dados Atributos de entrada / saída Outros Atributos
ALIGNED DIRECT AUTOMATIC or AUTO
AREA[(area-size)] ENVIRONMENT(options) or ENV... BASED[(reference)]
BINARY [(precision)] or BIN... INPUT BUILTIN
BIT [(maximum-length)] KEYED CONDITION or COND
CHARACTER[(maximum-length)] or CHAR... OUTPUT CONSTANT
COMPLEX [(precision)] or CPLX... PRINT CONTROLLED or CTL
DECIMAL [(precision)] or DEC... SEQUENTIAL or SEQL DEFINED[(reference)] or DEF...
(dimension-attribute) STREAM EXTERNAL or EXT
ENTRY[(parameter descriptor list] UPDATE GENERIC(criteria list)
FILE RECORD INITIAL(value-list) or INIT...
FIXED [(precision)] INTERNAL or INT
FLOAT [(number of digits)] LIKE unsubscripted reference
FORMAT LOCAL
LABEL OPTIONS(options)
MEMBER PARAMETER or PARM
NONVARYING or NONVAR POSITION [(expression)] or POS...
OFFSET[(reference)] STATIC
PICTURE picture-specification or PIC... VARIABLE
POINTER or PTR
STRUCTURE
UNALIGNED or UNAL
VARYING or VAR

Os compiladores atuais da Micro Focus , e particularmente o da IBM, implementam muitas extensões sobre a versão padronizada da linguagem. As extensões da IBM são resumidas na subseção Implementação do compilador posteriormente. Embora existam algumas extensões comuns a esses compiladores, a falta de um padrão atual significa que a compatibilidade não é garantida.

estandardização

A padronização de idiomas começou em abril de 1966 na Europa com o ECMA TC10. Em 1969, a ANSI estabeleceu um "Comitê de Desenvolvimento de Linguagem Composto", apelidado de "Kludge", mais tarde renomeado como X3J1 PL / I. A padronização tornou-se um esforço conjunto do ECMA TC / 10 e ANSI X3J1. Um subconjunto do documento GY33-6003 foi oferecido ao esforço conjunto da IBM e se tornou o documento base para padronização. Os principais recursos omitidos do documento base foram multitarefa e os atributos para otimização do programa (por exemplo, NORMALe ABNORMAL).

As propostas de alteração do documento base foram votadas por ambas as comissões. No caso de os comitês discordarem, os presidentes, inicialmente Michael Marcotty da General Motors e CAR Hoare representando a ICL tiveram que resolver o desacordo. Além da IBM, Honeywell , CDC , Data General , Digital Equipment Corporation , Prime Computer , Burroughs , RCA e Univac serviram no X3J1 junto com os principais usuários Eastman Kodak , MITER , Union Carbide , Bell Laboratories e vários representantes governamentais e universitários. O desenvolvimento da linguagem ocorreu nos corpos de padrões, com melhorias contínuas na programação estruturada e consistência interna, e com a omissão dos recursos mais obscuros ou contenciosos.

Conforme o desenvolvimento da linguagem se aproximava do fim, o X3J1 / TC10 percebeu que havia uma série de problemas com um documento escrito em inglês. A discussão de um único item pode aparecer em vários lugares que podem ou não concordar. Era difícil determinar se havia omissões, bem como inconsistências. Consequentemente, David Beech (IBM), Robert Freiburghouse (Honeywell), Milton Barber (CDC), M. Donald MacLaren ( Argonne National Laboratory ), Craig Franklin (Data General), Lois Frampton (Digital Equipment Corporation) e editor, DJ Andrews da IBM se comprometeu a reescrever todo o documento, cada um produzindo um ou mais capítulos completos. O padrão é formulado como uma definição formal usando uma "Máquina PL / I" para especificar a semântica. Foi o primeiro e possivelmente o único padrão de linguagem de programação a ser escrito como uma definição semiformal.

Um padrão "PL / I General-Purpose Subset" ("Subset-G") foi publicado pelo ANSI em 1981 e uma revisão publicada em 1987. O subconjunto de propósito geral foi amplamente adotado como o kernel para implementações PL / I.

Implementações

Compiladores IBM PL / IF e D

O PL / I foi implementado pela primeira vez pela IBM, em seus Laboratórios Hursley no Reino Unido, como parte do desenvolvimento do System / 360 . O primeiro compilador PL / I de produção foi o compilador PL / IF para o sistema operacional OS / 360 , desenvolvido pela equipe de John Nash em Hursley no Reino Unido: a equipe da biblioteca em tempo de execução foi gerenciada por IM (Nobby) Clarke. O compilador PL / IF foi escrito inteiramente em linguagem assembly System / 360. A versão 1 foi lançada em 1966. OS / 360 é um ambiente de memória real e o compilador foi projetado para sistemas com apenas 64 kilobytes de armazenamento real - F sendo 64 kB no jargão do S / 360. Para encaixar um grande compilador nos 44 kilobytes de memória disponíveis em uma máquina de 64 kilobytes, o compilador consiste em uma fase de controle e um grande número de fases do compilador (chegando a 100). As fases são trazidas do disco para a memória, uma de cada vez, para lidar com recursos de linguagem específicos e aspectos de compilação. Cada fase faz uma única passagem pelo programa parcialmente compilado, geralmente mantido na memória.

Aspectos da linguagem ainda estavam sendo projetados quando o PL / IF foi implementado, então alguns foram omitidos até versões posteriores. PL / I RECORD I / O foi enviado com PL / IF Release 2. As funções de processamento de lista - Variáveis ​​Baseadas, Ponteiros, Areas e Offsets e LOCATE-mode I / O  - foram enviados pela primeira vez na Release 4. Em uma grande tentativa de acelerar Para cima do código PL / I para competir com o código-objeto Fortran, o PL / IF Release 5 faz uma otimização substancial do programa de loops DO facilitada pela opção REORDER nos procedimentos.

Foi lançada uma versão do PL / IF no sistema operacional TSS / 360 timesharing para o System / 360 Modelo 67 , adaptado no IBM Mohansic Lab. O IBM La Gaude Lab na França desenvolveu "Programas de conversão de linguagem" para converter programas Fortran, Cobol e Algol para o nível PL / IF de PL / I.

O compilador PL / ID, usando 16 kilobytes de memória, foi desenvolvido pela IBM Germany para o sistema operacional DOS / 360 low end. Ele implementa um subconjunto da linguagem PL / I exigindo que todas as strings e arrays tenham extensões fixas, simplificando assim o ambiente de tempo de execução. Refletindo o sistema operacional subjacente, ele carece de alocação dinâmica de armazenamento e da classe de armazenamento controlada . Ele foi enviado dentro de um ano de PL / I F.

Multics PL / I e derivados

Os compiladores foram implementados por vários grupos no início dos anos 1960. O projeto Multics no MIT , um dos primeiros a desenvolver um sistema operacional em uma linguagem de alto nível, usou Early PL / I (EPL), um subconjunto de dialeto de PL / I, como sua linguagem de implementação em 1964. EPL foi desenvolvido em Bell Labs e MIT por Douglas McIlroy , Robert Morris e outros. O influente compilador Multics PL / I foi a fonte da tecnologia de compilador usada por vários fabricantes e grupos de software. EPL era uma linguagem de programação de sistema e um dialeto de PL / I que tinha alguns recursos ausentes na PL / I original (como strings de comprimento variável).

O compilador Honeywell PL / I (para a Série 60) é uma implementação do padrão ANSI X3J1 completo.

Otimizando IBM PL / I e compiladores de checkout

Os compiladores PL / I Optimizer e Checkout produzidos em Hursley suportam um nível comum de linguagem PL / I e visam substituir o compilador PL / IF. O compilador de verificação é uma reescrita de PL / IF em BSL, a linguagem de implementação proprietária semelhante a PL / I da IBM (mais tarde PL / S ). Os objetivos de desempenho definidos para os compiladores são mostrados em uma apresentação da IBM para o BCS. Os compiladores tiveram que produzir resultados idênticos - o Checkout Compiler é usado para depurar programas que seriam enviados ao Optimizer. Dado que os compiladores tinham designs totalmente diferentes e estavam lidando com a linguagem PL / I completa, esse objetivo foi desafiador: ele foi alcançado.

O compilador de otimização PL / I substituiu o compilador PL / IF e foi o compilador robusto da IBM das décadas de 1970 a 1990. Como o PL / IF, é um compilador de passagem múltipla com um ponto de design de 44 kilobytes, mas é um design inteiramente novo. Ao contrário do compilador F, ele deve realizar a avaliação do tempo de compilação de expressões constantes usando a biblioteca de tempo de execução, reduzindo o máximo de memória para uma fase do compilador para 28 kilobytes. Com um design inovador, ele conseguiu eliminar os incômodos do PL / IF, como o diagnóstico em cascata. Ele foi escrito em S / 360 Macro Assembler por uma equipe, liderada por Tony Burbridge, a maioria dos quais havia trabalhado em PL / I F. As macros foram definidas para automatizar serviços de compilador comuns e para proteger os escritores de compiladores da tarefa de gerenciar real. modo de armazenamento, permitindo que o compilador seja movido facilmente para outros modelos de memória. A gama de técnicas de otimização de programa desenvolvidas para o compilador IBM Fortran H contemporâneo foi implantada: o Optimizer igualou as velocidades de execução do Fortran nas mãos de bons programadores. Anunciado com o IBM S / 370 em 1970, ele foi lançado primeiro para o sistema operacional DOS / 360 em agosto de 1971, e logo depois para o OS / 360, e os primeiros sistemas operacionais de memória virtual IBM OS / VS1 , MVS e VM / CMS . (Os desenvolvedores não estavam cientes de que, enquanto encaixavam o código em seções de 28 kb, o IBM Poughkeepsie estava finalmente pronto para fornecer suporte à memória virtual no OS / 360). Suportava os ambientes de programação em lote e, sob TSO e CMS, podia ser executado interativamente. Este compilador passou por muitas versões cobrindo todos os sistemas operacionais de mainframe, incluindo os sistemas operacionais das máquinas compatíveis com plug japoneses (PCMs).

O compilador foi substituído por "IBM PL / I para OS / 2, AIX, Linux, z / OS" abaixo.

O compilador de verificação PL / I (coloquialmente "The Checker") anunciado em agosto de 1970 foi projetado para acelerar e melhorar a depuração de programas PL / I. A equipe era liderada por Brian Marks. O design de três passagens reduziu o tempo de compilação de um programa para 25% do tempo gasto pelo compilador F. Pode ser executado a partir de um terminal interativo, convertendo programas PL / I em um formato interno, "texto H". Este formato é interpretado pelo compilador Checkout em tempo de execução, detectando virtualmente todos os tipos de erros. Os ponteiros são representados em 16 bytes, contendo o endereço de destino e uma descrição do item referenciado, permitindo, assim, diagnosticar o uso de ponteiros "ruins". Em um ambiente de conversação, quando um erro é detectado, o controle é passado para o usuário que pode inspecionar quaisquer variáveis, introduzir instruções de depuração e editar o programa de origem. Com o tempo, a capacidade de depuração de ambientes de programação de mainframe desenvolveu a maioria das funções oferecidas por este compilador e foi retirada (na década de 1990?)

DEC PL / I

Talvez a implementação de maior sucesso comercial, além da IBM, tenha sido o VAX PL / I da Digital Equipment Corporation, mais tarde conhecido como DEC PL / I. A implementação é "um superconjunto estrito do Subconjunto de Propósito Geral ANSI X3.4-1981 PL / I e fornece a maioria dos recursos do novo Subconjunto de Propósito Geral ANSI X3.74-1987 PL / I", e foi lançado pela primeira vez em 1988 Ele originalmente usava um backend de compilador chamado VAX Code Generator (VCG) criado por uma equipe liderada por Dave Cutler . O front end foi projetado por Robert Freiburghouse e foi portado para VAX / VMS da Multics . Ele roda em VMS em VAX e Alpha e em Tru64 . Durante a década de 1990, a Digital vendeu o compilador para UniPrise Systems , que mais tarde o vendeu para uma empresa chamada Kednos. A Kednos comercializou o compilador como Kednos PL / I até outubro de 2016, quando a empresa encerrou as atividades.

Compiladores de subconjunto de ensino

No final dos anos 1960 e no início dos anos 1970, muitas universidades americanas e canadenses estavam estabelecendo serviços de compartilhamento de tempo no campus e precisavam de compiladores / intérpretes de conversação para uso no ensino de ciências, matemática, engenharia e ciência da computação. Dartmouth estava desenvolvendo o BASIC , mas PL / I era uma escolha popular, pois era conciso e fácil de ensinar. Como as ofertas da IBM eram inadequadas, várias escolas criaram seus próprios subconjuntos de PL / I e seu próprio suporte interativo. Exemplos são:

Na década de 1960 e no início dos anos 1970, Allen-Babcock implementou o sistema de compartilhamento de tempo de usuários remotos de hardware compartilhado (RUSH) para um IBM System / 360 Modelo 50 com microcódigo personalizado e posteriormente implementou o CPS da IBM , um sistema de compartilhamento de tempo interativo para OS / 360 voltado para o ensino de noções básicas de ciência da computação, oferecia um subconjunto limitado da linguagem PL / I além do BASIC e uma facilidade de entrada de trabalho remota.

PL / C , um dialeto de ensino, um compilador desenvolvido na Cornell University , tinha a capacidade incomum de nunca deixar de compilar qualquer programa por meio do uso de correção automática extensa de muitos erros de sintaxe e pela conversão de quaisquer erros de sintaxe restantes em declarações de saída. A linguagem era quase toda PL / I implementada pela IBM. PL / C foi um compilador muito rápido.

SL / 1 (Língua do Aluno / 1, Língua do Aluno / Um ou Língua de Subconjunto / 1) era um subconjunto PL / I, inicialmente disponível no final dos anos 1960, que funcionava interpretativamente noIBM 1130; o uso instrucional era seu ponto forte.

O PLAGO , criado no Instituto Politécnico de Brooklyn , usava um subconjunto simplificado da linguagem PL / I e focava em boas mensagens de erro de diagnóstico e tempos de compilação rápidos.

O Computer Systems Research Group da University of Toronto produziu os compiladores SP / k que suportavam uma sequência de subconjuntos de PL / I chamados SP / 1, SP / 2, SP / 3, ..., SP / 8 para o ensino de programação. Os programas executados sem erros nos compiladores SP / k produziram os mesmos resultados em outros compiladores PL / I contemporâneos, como o compilador PL / IF da IBM, o compilador de verificação da IBM ou o compilador PL / C da Cornell University.

Outros exemplos são PL0 de P. Grouse da University of New South Wales, PLUM de Marvin Zelkowitz da University of Maryland e PLUTO da University of Toronto.

IBM PL / I para OS / 2, AIX, Linux, z / OS

Em uma grande reformulação do PL / I, a IBM Santa Teresa na Califórnia lançou um compilador totalmente novo em 1992. A remessa inicial era para OS / 2 e incluía a maioria dos recursos ANSI-G e muitos novos recursos PL / I. As versões subsequentes forneceram plataformas adicionais ( MVS , VM , OS / 390 , AIX e Windows ), mas a partir de 2021, as únicas plataformas suportadas são z / OS e AIX. A IBM continuou a adicionar funções para tornar o PL / I totalmente competitivo com outras linguagens (particularmente C e C ++) em áreas onde havia sido superado. O "IBM Language Environment" correspondente oferece suporte à interoperação de programas PL / I com sistemas de banco de dados e transações e, com programas escritos em C, C ++ e COBOL, o compilador oferece suporte a todos os tipos de dados necessários para a intercomunicação com essas linguagens.

Os princípios de design de PL / I foram mantidos e resistiram a essa grande extensão, compreendendo vários novos tipos de dados, novas instruções e opções de instruções, novas condições de exceção e novas organizações de origem do programa. A linguagem resultante é um superconjunto compatível do Padrão PL / I e dos compiladores IBM anteriores. Os principais tópicos adicionados ao PL / I foram:

  • Novos atributos para melhor suporte de tipos de dados definidos pelo usuário - o DEFINE ALIAS, ORDINALe DEFINE STRUCTUREdeclaração de introduzir tipos definidos pelo usuário, o HANDLEtipo de dados de localização, o TYPEpróprio tipo de dados, o UNIONtipo de dados, e built-in funções para manipular os novos tipos.
  • Tipos de dados adicionais e atributos correspondentes aos tipos de dados comuns de PC (por exemplo UNSIGNED, VARYINGZ).
  • Melhorias na legibilidade de programas - muitas vezes tornando explícitos os usos implícitos (por exemplo, BYVALUEatributo para parâmetros)
  • Construções de programação estruturada adicionais.
  • Interromper adições de manuseio.
  • Pré-processador de tempo de compilação estendido para oferecer quase todos os recursos de manipulação de string PL / I e para fazer interface com o ambiente de desenvolvimento de aplicativos

A série mais recente de compiladores PL / I para z / OS, chamada Enterprise PL / I para z / OS, aproveita a geração de código para os processadores z / Architecture mais recentes (z14, z13, zEC12, zBC12, z196, z114) por meio do uso de O controle de parâmetro ARCHLVL foi aprovado durante a compilação e foi a segunda linguagem de alto nível suportada pelo z / OS Language Environment para fazer isso (XL C / C ++ sendo o primeiro e Enterprise COBOL v5 o último).

Tipos de dados

ORDINALé um novo tipo de dados computacional. Os recursos ordinais são como aqueles em Pascal , por exemplo, DEFINE ORDINAL Colour (red, yellow, green, blue, violet); mas, além disso, o nome e os valores internos são acessíveis por meio de funções integradas. As funções integradas fornecem acesso ao predecessor e sucessor de um valor ordinal.

O DEFINE-statement(veja abaixo) permite que TYPEs adicionais sejam declarados compostos a partir dos atributos embutidos do PL / I.

O HANDLE(data structure)tipo de dados do localizador é semelhante ao POINTERtipo de dados, mas fortemente tipado para vincular apenas a uma estrutura de dados específica. O =>operador é usado para selecionar uma estrutura de dados usando um identificador.

O UNIONatributo (equivalente às CELLespecificações PL / I anteriores) permite que várias variáveis ​​escalares, matrizes ou estruturas compartilhem o mesmo armazenamento em uma unidade que ocupa a quantidade de armazenamento necessária para a alternativa maior.

Competitividade no PC e com C

Esses atributos foram adicionados:

  • Os atributos de cordas VARYINGZ(por terminada em zero cadeias de caracteres), HEXADEC, WIDECHAR, e GRAPHIC.
  • Os atributos aritméticos opcionais UNSIGNEDe SIGNED, BIGENDIANe LITTLEENDIAN. UNSIGNEDexigia a opção UPTHRUe DOWNTHRUem grupos iterativos que permitiam que um loop controlado por contador fosse executado sem exceder o valor limite (também essencial para se ORDINALbom para documentar loops).
  • O DATE(pattern)atributo para controlar representações de data e adições para trazer hora e data para a melhor prática atual. Novas funções para manipulação de datas incluem - DAYSe DAYSTODATEpara conversão entre datas e número de dias, e uma DATETIMEfunção geral para alterar formatos de data.

Novas funções de manipulação de string foram adicionadas - para centralizar o texto, para editar usando um formato de imagem e para aparar espaços em branco ou caracteres selecionados do cabeçalho ou final do texto, VERIFYRpara VERIFYa direita. e SEARCHe TALLYfunções.

Operadores de atribuição compostos a la C, por exemplo +=, &=, -=, ||=foram adicionados. A+=1é equivalente a A=A+1.

Descritores de parâmetro adicionais e atributos foram adicionados para argumentos omitidos e listas de argumentos de comprimento variável.

Legibilidade do programa - tornando as intenções explícitas

O VALUEatributo declara um identificador como uma constante (derivado de um valor literal específico ou expressão restrita).

Os parâmetros podem ter os atributos BYADDR(passagem por endereço) ou BYVALUE(passagem por valor).

Os atributos ASSIGNABLEe NONASSIGNABLEevitam atribuições não intencionais.

DO FOREVER;elimina a necessidade do constructo inventado DO WHILE ( '1'B );.

O DEFINE-statementintroduz nomes especificados pelo usuário (por exemplo INTEGER) para combinações de atributos embutidos (por exemplo FIXED BINARY(31,0)). Assim, DEFINE ALIAS INTEGER FIXED BINARY(31.0)cria o TYPEnome INTEGERcomo um alias para o conjunto de atributos embutidos FIXED BINARY (31.0). DEFINE STRUCTUREaplica-se a estruturas e seus membros; ele fornece um TYPEnome para um conjunto de atributos de estrutura e declarações de membros de subestrutura correspondentes para uso em uma declaração de estrutura (uma generalização do LIKEatributo).

Adições de programação estruturada

Uma LEAVEinstrução para sair de um loop e ITERATEpara continuar com a próxima iteração de um loop.

UPTHRUe DOWNTHRUopções em grupos iterativos.

A construção do pacote consiste em um conjunto de procedimentos e declarações para uso como uma unidade. Variáveis declarada fora dos procedimentos são locais para o pacote, e pode usar STATIC, BASEDou CONTROLLEDarmazenamento. Os nomes de procedimentos usados ​​no pacote também são locais, mas podem ser tornados externos por meio da EXPORTSopção do PACKAGE-statement.

Manuseio de interrupção

O RESIGNAL-statementexecutado em uma unidade LIGADA termina a execução da unidade LIGADA e aumenta a condição novamente no procedimento que chamou a atual (passando assim o controle para a unidade LIGADA correspondente para aquele procedimento).

A INVALIDOPcondição lida com códigos de operação inválidos detectados pelo processador do PC, bem como operações aritméticas ilegais, como subtração de dois valores infinitos.

A ANYCONDITIONcondição é fornecida para interceptar as condições para as quais nenhuma unidade ON específica foi fornecida no procedimento atual.

A STORAGEcondição é gerada quando uma ALLOCATEinstrução não consegue obter armazenamento suficiente.

Outros compiladores de mainframe e minicomputador

Vários fornecedores produziram compiladores para competir com o IBM PL / IF ou o compilador Otimizando em mainframes e minicomputadores na década de 1970. Na década de 1980, o alvo era geralmente o subconjunto ANSI-G emergente.

  • Em 1974, a Burroughs Corporation anunciou PL / I para o B6700 e o B7700.
  • A UNIVAC lançou um UNIVAC PL / I e, na década de 1970, também usou uma variante do PL / I, PL / I PLUS, para a programação do sistema.
  • A partir de 1978, a Data General forneceu PL / I em suas plataformas Eclipse e Eclipse MV executando os sistemas operacionais AOS , AOS / VS e AOS / VS II . Vários programas utilitários de sistema operacional foram escritos nessa linguagem.
  • Paul Abrahams do Courant Institute of Mathematical Sciences da NYU escreveu CIMS PL / I em 1972 em PL / I, bootstrapping via PL / I F. Apoiou "cerca de 70%" de PL / I compilando para o CDC 6600
  • O CDC entregou um compilador PL / I de subconjunto de otimização para as séries Cyber ​​70, 170 e 6000.
  • A Fujitsu entregou um compilador PL / I equivalente ao Otimizador PL / I.
  • Stratus Technologies PL / I é uma implementação ANSI G para o sistema operacional VOS .
  • IBM Series / 1 PL / I é um subconjunto estendido da linguagem de programação ANSI PL / I (ANSI X3.53-1976) para o IBM Series / 1 Realtime Programming System.

Compiladores PL / I para Microsoft .NET

Compiladores PL / I para computadores pessoais e Unix

  • Nas décadas de 1970 e 1980, a Digital Research vendeu um compilador PL / I para CP / M (PL / I-80), CP / M-86 (PL / I-86) e computadores pessoais com DOS . Foi com base no Subconjunto G de PL / I e foi escrito em PL / M .
  • A Micro Focus implementou Open PL / I para sistemas Windows e UNIX / Linux, que adquiriu da Liant.
  • A IBM entregou PL / I para OS / 2 em 1994 e PL / I para AIX em 1995.
  • O Iron Spring PL / I para OS / 2 e posterior Linux foi lançado em 2007.

Dialetos PL / I

  • PL / S , um dialeto de PL / I, inicialmente chamado de BSL, foi desenvolvido no final dos anos 1960 e se tornou a linguagem de programação de sistema para mainframes IBM. Quase todo software de sistema de mainframe IBM nas décadas de 1970 e 1980 foi escrito em PL / S. Ele diferia do PL / I porque não havia conversões de tipo de dados, nenhum ambiente de tempo de execução, as estruturas eram mapeadas de maneira diferente e a atribuição era uma cópia byte a byte. Todas as strings e arrays tinham extensões fixas ou usavam a REFERopção. PL / S foi sucedido por PL / AS e, em seguida, por PL / X, que é a linguagem atualmente usada para trabalho interno nos sistemas operacionais atuais, OS / 390 e agora z / OS . É também utilizado para alguns z / VSE e de z / VM componentes. Db2 para z / OS também é escrito em PL / X.
  • PL / C , é um dialeto instrucional da linguagem de programação de computador PL / I, desenvolvido na Cornell University na década de 1970.
  • Dois dialetos de PL / I denominados PL / MP (Produto de Máquina) e PL / MI (Interface de Máquina) foram usados ​​pela IBM no software de sistema das plataformas System / 38 e AS / 400 . PL / MP foi usado para implementar o chamado Microcódigo Vertical desses sistemas operacionais e direcionou o conjunto de instruções IMPI. Ele foi substituído pelo C ++ quando o OS / 400 foi transferido para a família de processadores IBM RS64 . PL / MI tem como alvo a Interface da Máquina dessas plataformas e é usado no Control Program Facility e nos componentes independentes de hardware do OS / 400 . Ele permanece em uso no IBM i.
  • PL / 8 (ou PL.8), assim chamado porque era cerca de 80% de PL / I, foi originalmente desenvolvido pela IBM Research na década de 1970 para a arquitetura IBM 801 . Posteriormente, ganhou suporte para as arquiteturas Motorola 68000 e System / 370 . Ele continua a ser usado para várias tarefas de desenvolvimento de sistemas internos da IBM (por exemplo, millicode e firmware para sistemas z / Architecture ) e foi reprojetado para usar um back-end baseado em gcc de 64 bits .
  • A Honeywell, Inc. desenvolveu o PL-6 para uso na criação do sistema operacional CP-6 .
  • A Prime Computer usou dois dialetos PL / I diferentes como a linguagem de programação do sistema operacional PRIMOS : PL / P , a partir da versão 18, e então SPL, a partir da versão 19.
  • XPL é um dialeto de PL / I usado para escrever outros compiladores usando as técnicas do compilador XPL. XPL adicionou um tipo de dados de string de heap a seu pequeno subconjunto de PL / I.
  • HAL / S é uma linguagem de programação aeroespacial em tempo real, mais conhecida por seu uso no programa Space Shuttle. Foi projetado pela Intermetrics na década de 1970 para a NASA. HAL / S foi implementado em XPL.
  • A IBM e vários subcontratados também desenvolveram outra variante PL / I no início dos anos 1970 para dar suporte ao processamento de sinais para a Marinha, chamada SPL / I.
  • SabreTalk , um dialeto em tempo real do PL / I usado para programar o sistema de reservas de companhias aéreas Sabre .

Uso

As implementações PL / I foram desenvolvidas para mainframes no final dos anos 1960, minicomputadores nos anos 1970 e computadores pessoais nos anos 1980 e 1990. Embora seu uso principal seja em mainframes , existem versões PL / I para DOS , Microsoft Windows , OS / 2 , AIX , OpenVMS e Unix .

Ele tem sido amplamente utilizado no processamento de dados de negócios e para uso do sistema para escrever sistemas operacionais em certas plataformas. Sistemas muito complexos e poderosos foram construídos com PL / I:

  • O Sistema SAS foi inicialmente escrito em PL / I; a etapa de dados SAS ainda é modelada na sintaxe PL / I.
  • O sistema pioneiro de reservas aéreas online Sabre foi originalmente escrito para o IBM 7090 em assembler. A versão S / 360 foi amplamente escrita usando SabreTalk , um compilador PL / I de subconjunto desenvolvido para um programa de controle dedicado.
  • O sistema operacional Multics foi amplamente escrito em PL / I.
  • PL / I foi usado para escrever uma definição formal executável para interpretar a Arquitetura de Rede de Sistema da IBM .

O PL / I não atendeu às esperanças de seus defensores de que substituiria Fortran e COBOL e se tornaria o principal ator nos mainframes. Continuou a ser uma minoria, mas um jogador significativo. Não pode haver uma explicação definitiva para isso, mas algumas tendências nas décadas de 1970 e 1980 militaram contra seu sucesso ao reduzir progressivamente o território em que PL / I gozava de vantagem competitiva.

Primeiro, a natureza do ambiente de software de mainframe mudou. Os subsistemas de aplicativos para banco de dados e processamento de transações ( CICS e IMS e Oracle no System 370) e geradores de aplicativos tornaram-se o foco do desenvolvimento de aplicativos dos usuários de mainframe. Partes significativas da linguagem tornaram-se irrelevantes devido à necessidade de usar os recursos nativos correspondentes dos subsistemas (como tarefas e grande parte da entrada / saída). O Fortran não foi usado nessas áreas de aplicação, confinando PL / I ao território do COBOL; a maioria dos usuários permaneceu no COBOL. Mas, à medida que o PC se tornou o ambiente dominante para o desenvolvimento de programas, Fortran, COBOL e PL / I se tornaram linguagens minoritárias superadas por C ++ , Java e similares.

Em segundo lugar, PL / I foi ultrapassado no campo de programação de sistema. A comunidade de programação de sistema IBM não estava pronta para usar PL / I; em vez disso, a IBM desenvolveu e adotou um dialeto proprietário de PL / I para programação de sistema. - PL / S . Com o sucesso do PL / S dentro da IBM e de C fora da IBM, os pontos fortes exclusivos do PL / I para programação de sistema se tornaram menos valiosos.

Terceiro, os ambientes de desenvolvimento aumentaram a capacidade de desenvolvimento de software interativo que, novamente, tornou as forças interativas e de depuração exclusivas do PL / I menos valiosas.

Quarto, recursos como programação estruturada, operações de string de caracteres e orientação a objetos foram adicionados ao COBOL e Fortran, o que reduziu ainda mais as vantagens relativas do PL / I.

Em mainframes, também havia questões comerciais substanciais em jogo. Os concorrentes de hardware da IBM tinham pouco a ganhar e muito a perder com o sucesso do PL / I. O desenvolvimento do compilador era caro e os grupos de compiladores IBM tinham uma vantagem competitiva embutida. Muitos usuários da IBM desejavam evitar ficar presos a soluções proprietárias. Sem suporte inicial para PL / I por outros fornecedores, era melhor evitar PL / I.

Evolução da linguagem PL / I

Este artigo usa o padrão PL / I como ponto de referência para recursos de linguagem. Mas uma série de características significativas nas primeiras implementações não estavam no Padrão; e alguns foram oferecidos por compiladores não IBM. E a linguagem de fato continuou a crescer após o padrão, em última análise impulsionada por desenvolvimentos no computador pessoal.

Recursos significativos omitidos do padrão

Multitarefa

A multitarefa foi implementada por PL / IF, o Optimizer e os compiladores AIX e Z / OS mais recentes. Ele compreendia os tipos de dados EVENTe TASKas instruções de E / S TASK-optionno CALL-statement( Fork ), WAIT-statement( Join ) DELAY(delay-time), EVENT-options no registro e a UNLOCKinstrução para desbloquear registros bloqueados em EXCLUSIVEarquivos. Os dados do evento identificam um determinado evento e indicam se ele está completo ('1'B) ou incompleto (' 0'B): os itens de dados da tarefa identificam uma tarefa específica (ou processo ) e indicam sua prioridade em relação a outras tarefas.

Pré-processador

O primeiro pré-processador de tempo de compilação da IBM foi construído pelo IBM Boston Advanced Programming Center localizado em Cambridge, Massachusetts, e enviado com o compilador PL / IF. A %INCLUDEdeclaração estava no padrão, mas o restante dos recursos não. Os compiladores DEC e Kednos PL / I implementaram praticamente o mesmo conjunto de recursos da IBM, com alguns acréscimos próprios. A IBM continuou a adicionar recursos de pré-processador a seus compiladores. O pré-processador trata o programa de origem escrito como uma sequência de tokens, copiando-os para um arquivo de origem de saída ou agindo sobre eles. Quando um token% é encontrado, a seguinte instrução de tempo de compilação é executada: quando um token de identificador é encontrado e o identificador foi DECLAREd, ACTIVATEd e foi atribuído um valor de tempo de compilação, o identificador é substituído por este valor. Os tokens são adicionados ao fluxo de saída se não exigirem ação (por exemplo +), assim como os valores das expressões de tempo de compilação ACTIVATEd. Assim, uma variável de tempo de compilação PIpode ser declarada, ativada e atribuída usando %PI='3.14159265'. As ocorrências subsequentes de PIseriam substituídas por 3.14159265.

Os tipos de dados suportados são FIXED DECIMALinteiros e CHARACTERstrings de comprimento variável, sem comprimento máximo. As declarações de estrutura são:

  • %[label-list:]DO iteration: statements; %[label-list:]END;
  • %procedure-name: PROCEDURE (parameter list) RETURNS (type); statements...;
  • %[label-list:]END;
  • %[label-list:]IF...%THEN...%ELSE..

e as instruções simples, que também podem ter uma [lista de rótulos:]

  • %ACTIVATE(identifier-list) and %DEACTIVATE
  • assignment demonstração
  • %DECLARE identifier-attribute-list
  • %GO TO label
  • %INCLUDE
  • null demonstração

O recurso permitiu aos programadores usar identificadores para constantes - por exemplo, números de peças de produtos ou constantes matemáticas - e foi substituído no padrão por constantes nomeadas para dados computacionais. A compilação condicional e a geração iterativa de código-fonte, possível com recursos de tempo de compilação, não eram suportadas pelo padrão. Vários fabricantes implementaram essas instalações.

Adições de programação estruturada

Adições de programação estruturada foram feitas ao PL / I durante a padronização, mas não foram aceitas no padrão. Esses recursos eram LEAVE-statementpara sair de uma iterativa DO, UNTIL-optione REPEAT-optionadicionado a DO, e uma instrução de caso da forma geral: SELECT (expression) {WHEN (expression) group}... OTHERWISE group
Esses recursos foram todos incluídos nos compiladores PL / I Checkout e Otimização da IBM e no DEC PL / I.

Depurar instalações

PL / IF ofereceu alguns recursos de depuração que não foram apresentados para o padrão, mas foram implementados por outros - notavelmente o prefixo de condição CHECK (lista de variáveis), CHECKon-condition e a SNAPopção. Os compiladores IBM Optimizing e Checkout adicionaram recursos adicionais apropriados ao ambiente de programação de mainframe conversacional (por exemplo, uma ATTENTIONcondição).

Recursos significativos desenvolvidos desde o padrão

Várias tentativas foram feitas para projetar um tipo de membro de estrutura que pudesse ter um dos vários tipos de dados ( CELLno início da IBM). Com o crescimento das classes na teoria da programação, abordagens para isso se tornaram possíveis em uma base PL / I - UNION, TYPEetc., foram adicionadas por vários compiladores.

PL / I foi concebido em um mundo de caracteres de byte único. Com o suporte para os idiomas japonês e chinês se tornando essencial, e os desenvolvimentos nas páginas de código internacionais, o conceito de string de caracteres foi expandido para acomodar strings amplas não ASCII / EBCDIC.

O tratamento de data e hora foi reformulado para lidar com o problema do milênio , com a introdução da função DATETIME, que retornou a data e a hora em um dos cerca de 35 formatos diferentes. Várias outras funções de data lidam com conversões de e para dias e segundos.

Críticas

Problemas de implementação

Embora a linguagem seja fácil de aprender e usar, implementar um compilador PL / I é difícil e demorado. Uma linguagem tão grande quanto PL / I precisava de subconjuntos que a maioria dos fornecedores pudesse produzir e dominar a maioria dos usuários. Isso não foi resolvido até que "ANSI G" foi publicado. Os recursos de tempo de compilação, exclusivos do PL / I, exigiam esforço de implementação e etapas adicionais do compilador. Um compilador PL / I era duas a quatro vezes maior que os compiladores Fortran ou COBOL comparáveis, e também muito mais lento - supostamente compensado por ganhos na produtividade do programador. Isso foi antecipado na IBM antes que os primeiros compiladores fossem escritos.

Alguns argumentam que PL / I é incomumente difícil de analisar. As palavras-chave PL / I não são reservadas para que os programadores possam usá-las como nomes de variáveis ​​ou procedimentos em programas. Como o compilador PL / I (F) original tenta a correção automática ao encontrar uma palavra-chave usada em um contexto incorreto, ele frequentemente assume que é um nome de variável. Isso leva a "diagnósticos em cascata", um problema resolvido por compiladores posteriores.

O esforço necessário para produzir um bom código-objeto talvez tenha sido subestimado durante o design inicial da linguagem. A otimização do programa (necessária para competir com a excelente otimização do programa realizada pelos compiladores Fortran disponíveis) é incomumente complexa devido aos efeitos colaterais e problemas generalizados com o aliasing de variáveis. A modificação imprevisível pode ocorrer de forma assíncrona em manipuladores de exceção , que podem ser fornecidos por "instruções ON" em chamadores (invisíveis). Juntos, eles tornam difícil prever com segurança quando as variáveis ​​de um programa podem ser modificadas em tempo de execução. No uso típico, entretanto, os manipuladores de erros escritos pelo usuário (o ON-unit) geralmente não fazem atribuições a variáveis. Apesar das dificuldades mencionadas, a IBM produziu o compilador de otimização PL / I em 1971.

PL / I contém muitos recursos raramente usados, como suporte multitarefa (uma extensão IBM para a linguagem) que adiciona custo e complexidade ao compilador, e seus recursos de coprocessamento requerem um ambiente de multiprogramação com suporte para vários threads sem bloqueio para processos pelo sistema operacional . Os criadores do compilador eram livres para selecionar se implementariam esses recursos.

Uma variável não declarada é, por padrão, declarada pela primeira ocorrência - portanto, erros ortográficos podem levar a resultados imprevisíveis. Esta "declaração implícita" não é diferente dos programas FORTRAN. Para PL / I (F), entretanto, uma lista de atributos permite ao programador detectar qualquer variável com erro ortográfico ou não declarada.

Problemas do programador

Muitos programadores demoraram a mudar do COBOL ou do Fortran devido à percepção da complexidade da linguagem e da imaturidade do compilador PL / IF. Os programadores foram nitidamente divididos em programadores científicos (que usaram Fortran) e programadores de negócios (que usaram COBOL), com tensão significativa e até antipatia entre os grupos. Sintaxe PL / I emprestada da sintaxe COBOL e Fortran. Portanto, em vez de perceber recursos que tornariam seu trabalho mais fácil, os programadores Fortran da época perceberam a sintaxe COBOL e tinham a opinião de que era uma linguagem de negócios, enquanto os programadores COBOL perceberam a sintaxe Fortran e a consideraram uma linguagem científica.

Tanto os programadores COBOL quanto o Fortran o viam como uma versão "maior" de sua própria linguagem, e ambos ficaram um tanto intimidados com a linguagem e pouco inclinados a adotá-la. Outro fator foram as pseudo- semelhanças com COBOL, Fortran e ALGOL. Esses eram elementos PL / I que se pareciam com uma dessas linguagens, mas funcionavam de maneira diferente em PL / I. Essas frustrações deixaram muitos programadores experientes com uma visão preconceituosa do PL / I e, freqüentemente, uma aversão ativa pela linguagem. Um dos primeiros arquivos da fortuna do UNIX continha a seguinte descrição irônica do idioma:

Falando como alguém que se aprofundou nas complexidades de PL / I, tenho certeza de que apenas Homens de Verdade poderiam ter escrito um monstro tão monopolizador, viciante e envolvente. Alocar uma matriz e liberar o terço do meio? Certo! Por que não? Multiplicar uma string de caracteres por uma string de bits e atribuir o resultado a um decimal flutuante? Vá em frente! Liberar um parâmetro de procedimento de variável controlada e realocá-lo antes de devolvê-lo? Sobrepor três tipos diferentes de variáveis ​​no mesmo local de memória? Tudo o que digas! Escreva uma macro recursiva? Bem, não, mas Homens de Verdade usam rescan. Como uma linguagem tão obviamente projetada e escrita por Homens de Verdade não se destina ao uso do Homem de Verdade?

Do lado positivo, o suporte completo para ponteiros para todos os tipos de dados (incluindo ponteiros para estruturas), recursão , multitarefa , manipulação de strings e funções integradas extensas significava que PL / I era de fato um salto em frente em comparação com as linguagens de programação de seus Tempo. No entanto, isso não foi suficiente para persuadir a maioria dos programadores ou oficinas a mudar para PL / I.

O pré-processador de tempo de compilação do compilador PL / IF era incomum (fora do mundo Lisp ) ao usar a sintaxe e a semântica de sua linguagem alvo ( por exemplo, em comparação com as diretivas "#" do pré-processador C ).

Tópicos especiais em PL / I

Classes de armazenamento

PL / I fornece várias 'classes de armazenamento' para indicar como o tempo de vida do armazenamento de variáveis ​​deve ser gerenciado - STATIC, AUTOMATIC, CONTROLLEDe BASED. O mais simples de implementar é STATIC, que indica que a memória é alocada e inicializada no tempo de carregamento, como é feito no COBOL "armazenamento de trabalho" e no Fortran inicial . Este é o padrão para EXTERNALvariáveis. A classe de armazenamento padrão da PL / I para INTERNALvariáveis ​​é AUTOMATICsemelhante à de outras linguagens estruturadas em bloco influenciadas por ALGOL , como a classe de armazenamento "auto" na linguagem C e a alocação de armazenamento padrão em Pascal e "armazenamento local" em IBM COBOL . O armazenamento de AUTOMATICvariáveis ​​é alocado na entrada no BEGIN-blockprocedimento, ou unidade ON em que são declaradas. O compilador e o sistema de tempo de execução alocam memória para um frame de pilha para contê-los e outras informações de manutenção. Se uma variável for declarada com um INITIAL-attribute, o código para defini-la com um valor inicial é executado neste momento. É necessário cuidado para gerenciar o uso da inicialização de maneira adequada. Grandes quantidades de código podem ser executadas para inicializar variáveis ​​sempre que um escopo é inserido, especialmente se a variável for uma matriz ou estrutura. O armazenamento de AUTOMATICvariáveis ​​é liberado na saída do bloco: STATIC, CONTROLLEDou as BASEDvariáveis ​​são usadas para reter o conteúdo das variáveis ​​entre as invocações de um procedimento ou bloco. CONTROLLEDo armazenamento também é gerenciado usando uma pilha, mas o push e popping de alocações na pilha são gerenciados pelo programador, usando as instruções ALLOCATEe FREE. O armazenamento de BASEDvariáveis ​​é gerenciado usando ALLOCATE/FREE, mas em vez de uma pilha, essas alocações têm tempos de vida independentes e são endereçadas por meio de variáveis OFFSETou POINTER.

O AREAatributo é usado para declarar heaps definidos pelo programador . Os dados podem ser alocados e liberados em uma área específica, e a área pode ser excluída, lida e gravada como uma unidade.

Compartilhamento de tipo de armazenamento

Existem várias maneiras de acessar o armazenamento alocado por meio de diferentes declarações de dados. Alguns deles são bem definidos e seguros, alguns podem ser usados ​​com segurança com uma programação cuidadosa e alguns são inerentemente inseguros e / ou dependentes da máquina.

Passar uma variável como um argumento para um parâmetro por referência permite que o armazenamento alocado do argumento seja referenciado usando o parâmetro. O DEFINEDatributo (por exemplo DCL A(10,10), B(2:9,2:9) DEFINED A) permite que parte ou todo o armazenamento de uma variável seja usado com uma declaração diferente, mas consistente. A definição da linguagem inclui um CELLatributo (posteriormente renomeado UNION) para permitir que diferentes definições de dados compartilhem o mesmo armazenamento. Isso não era suportado por muitos compiladores IBM anteriores. Esses usos são seguros e independentes da máquina.

E / S de registros e processamento de listas produzem situações em que o programador precisa ajustar uma declaração para o armazenamento do próximo registro ou item, antes de saber que tipo de estrutura de dados ele possui. Variáveis ​​baseadas e ponteiros são fundamentais para tais programas. As estruturas de dados devem ser projetadas apropriadamente, normalmente usando campos em uma estrutura de dados para codificar informações sobre seu tipo e tamanho. Os campos podem ser mantidos na estrutura anterior ou, com algumas restrições, na atual. Onde a codificação está na estrutura anterior, o programa precisa alocar uma variável baseada com uma declaração que corresponda ao item atual (usando expressões para extensões quando necessário). Onde as informações de tipo e tamanho devem ser mantidas na estrutura atual ("estruturas de autodefinição"), os campos de definição de tipo devem estar à frente dos itens dependentes de tipo e no mesmo lugar em todas as versões da estrutura de dados. A REFERopção é usada para extensões de autodefinição (por exemplo, comprimentos de string como em DCL 1 A BASED, 2 N BINARY, 2 B CHAR(LENGTH REFER A.N.), etc  - onde LENGTHé usado para alocar instâncias da estrutura de dados. Para estruturas de autodefinição, qualquer digitação e REFERedcampos são colocados antes dos dados "reais". os registros em um conjunto de dados, ou os itens em uma lista de estruturas de dados, são organizados de forma que possam ser tratados com segurança de maneira independente da máquina.

As implementações PL / I não (exceto para o compilador PL / I Checkout) controlam a estrutura de dados usada quando o armazenamento é alocado pela primeira vez. Qualquer BASEDdeclaração pode ser usada com um ponteiro para o armazenamento para acessar o armazenamento - inerentemente inseguro e dependente da máquina. No entanto, esse uso se tornou importante para a "aritmética de ponteiros" (normalmente adicionando uma certa quantia a um endereço conhecido). Este tem sido um assunto controverso na ciência da computação. Além do problema de referências selvagens e saturações de buffer, surgem problemas devido ao alinhamento e comprimento dos tipos de dados usados ​​com máquinas e compiladores específicos. Muitos casos em que a aritmética de ponteiro pode ser necessária envolvem encontrar um ponteiro para um elemento dentro de uma estrutura de dados maior. A ADDRfunção calcula esses ponteiros de forma segura e independente da máquina.

A aritmética de ponteiros pode ser realizada criando um aliasing para uma variável binária com um ponteiro, como em
DCL P POINTER, N FIXED BINARY(31) BASED(ADDR(P)); N=N+255;
Ele se baseia em ponteiros com o mesmo comprimento que FIXED BINARY(31)inteiros e alinhados nos mesmos limites.

Com a prevalência de C e sua atitude fácil e livre para aritmética de ponteiros, os compiladores IBM PL / I recentes permitem que ponteiros sejam usados ​​com os operadores de adição e subtração para fornecer a sintaxe mais simples (mas as opções do compilador podem impedir essas práticas em que segurança e independência da máquina são primordiais).

Unidades ON e tratamento de exceções

Quando o PL / I foi projetado, os programas eram executados apenas em lote, sem possível intervenção do programador em um terminal. Uma condição excepcional, como divisão por zero, abortaria o programa, gerando apenas um dump de memória hexadecimal. O tratamento de exceções PL / I, por meio de unidades ON, permitiu que o programa permanecesse no controle diante das exceções de hardware ou sistema operacional e recuperasse as informações de depuração antes de encerrar com mais facilidade. À medida que um programa era depurado corretamente, a maior parte do tratamento de exceções podia ser removida ou desabilitada: esse nível de controle tornou-se menos importante quando a execução de conversação se tornou comum.

O tratamento de exceções computacionais é habilitado e desabilitado por prefixos de condição em instruções, blocos (incluindo unidades ON) e procedimentos. - por exemplo (SIZE, NOSUBSCRIPTRANGE): A(I)=B(I)*C; . As exceções do sistema operacional para entrada / saída e gerenciamento de armazenamento estão sempre habilitadas.

A unidade ON é uma única instrução ou BEGINbloco introduzido por um ON-statement. Executar a instrução ON ativa a condição especificada, por exemplo ON ZERODIVIDE ON-unit,. Quando a exceção para esta condição ocorre e a condição é habilitada, a unidade ON para a condição é executada. As unidades ON são herdadas ao longo da cadeia de chamadas. Quando um bloco, procedimento ou unidade ON é ativado, as unidades ON estabelecidas pela ativação de chamada são herdadas pela nova ativação. Eles podem ser substituídos por outro ON-statemente podem ser restabelecidos pelo REVERT-statement. A exceção pode ser simulada usando SIGNAL-statement- por exemplo, para ajudar a depurar os tratadores de exceção. O princípio de herança dinâmica para unidades ON permite que uma rotina trate as exceções que ocorrem nas sub-rotinas que usa.

Se nenhuma unidade LIGADA estiver em vigor quando uma condição for levantada, uma ação padrão do sistema é executada (geralmente é para aumentar a ERRORcondição). A ação do sistema pode ser restabelecida usando a SYSTEMopção do ON-statement. Com algumas condições, é possível concluir a execução de uma unidade ON e retornar ao ponto de interrupção (por exemplo, as STRINGRANGE, UNDERFLOW, CONVERSION, OVERFLOW, AREA and FILEcondições) e retomar a execução normal. Com outras condições, como (SUBSCRIPTRANGE), a ERRORcondição é levantada quando isso é tentado. Uma unidade ON pode ser encerrada GO TOevitando o retorno ao ponto de interrupção, mas permitindo que o programa continue a execução em outro lugar, conforme determinado pelo programador.

Uma unidade LIGADA precisa ser projetada para lidar com exceções que ocorrem na própria unidade LIGADA. A ON ERROR SYSTEM;instrução permite uma armadilha de erro aninhada; se ocorrer um erro dentro de uma unidade ON, o controle pode passar para o sistema operacional onde um dump do sistema pode ser produzido ou, para algumas condições computacionais, continuar a execução (conforme mencionado acima).

As RECORDinstruções PL / I / O têm sintaxe relativamente simples, pois não oferecem opções para as muitas situações, desde o fim do arquivo até os erros de transmissão de registro que podem ocorrer quando um registro é lido ou escrito. Em vez disso, essas complexidades são tratadas nas unidades ON para as várias condições de arquivo. A mesma abordagem foi adotada para a AREAsubalocação e a AREAcondição.

A existência de unidades ON de tratamento de exceção pode ter um efeito na otimização, porque as variáveis ​​podem ser inspecionadas ou alteradas em unidades ON. Os valores das variáveis ​​que, de outra forma, poderiam ser mantidos em registros entre as instruções, podem precisar ser devolvidos ao armazenamento entre as instruções. Isso é discutido na seção sobre problemas de implementação acima.

IR PARA com uma meta não fixa

PL / I tem contrapartes para instruções GO TO especializadas de COBOL e FORTRAN.

A sintaxe para COBOL e FORTRAN existe para a codificação de dois tipos especiais de GO TO, cada um deles com um destino que nem sempre é o mesmo.

  • ALTER (COBOL), ATRIBUIR (FORTRAN):
  • ALTER paragraph_name_xxx PARA PROSSEGUIR PARA para_name_zzz.
Existem outras restrições úteis sobre isso, especialmente "em programas ... atributo RECURSIVE, em métodos ou .. opção THREAD."
  • ATRIBUA 1860 PARA IGOTTAGO
    IR PARA IGOTTAGO
Um aprimoramento, que adiciona documentação embutida, é
GO TO IGOTTAGO (1860, 1914, 1939)
(que restringe o valor da variável a "um dos rótulos na lista.")
  • GO TO ... com base no valor semelhante ao subscrito de uma variável.
  • GO TO (1914, 1939, 2140), MYCHOICE
  • IR PARA para_One para_Two para_Three DEPENDENDO DA IDECIDE.

PL / I tem variáveis ​​de rótulo de instrução (com o atributo LABEL), que podem armazenar o valor de um rótulo de instrução e, posteriormente, ser usadas em uma instrução GOTO.

LABL1: ....
.
.
LABL2: ...
.
.
.
MY_DEST = LABL1;
.
GO TO MY_DEST;
GO TO HERE(LUCKY_NUMBER); /* minus 1, zero, or ... */

HERE(-1): PUT LIST ("I O U"); GO TO Lottery;
HERE(0): PUT LIST ("No Cash"); GO TO Lottery;
HERE(1): PUT LIST ("Dollar Bill"); GO TO Lottery;
HERE(2): PUT LIST ("TWO DOLLARS"); GO TO Lottery;

Variáveis ​​de rótulo de instrução podem ser passadas para procedimentos chamados e usadas para retornar a uma instrução diferente na rotina de chamada.

Programas de amostra

Programa Hello World

Hello2: proc options(main);
     put list ('Hello, World!');
end Hello2;

Procure por uma string

/* Read in a line, which contains a string,
/* and then print every subsequent line that contains that string. */

find_strings: procedure options (main);
   declare pattern character (100) varying;
   declare line character (100) varying;
   declare line_no fixed binary;

   on endfile (sysin) stop;

   get edit (pattern) (L);
   line_no = 1;
   do forever;
      get edit (line) (L);
      if index(line, pattern) > 0 then
         put skip list (line_no, line);
      line_no = line_no + 1;
   end;

end find_strings;

Veja também

Notas

Referências

Livros didáticos

  • Neuhold, EJ & Lawson, HW (1971). A máquina PL / I: uma introdução à programação . Addison-wesley. ISBN 978-0-2010-5275-6.
  • Barnes, RA (1979). PL / I para programadores . Holanda do Norte.
  • Hughes, Joan K. (1973). Programação PL / I (1ª ed.). Wiley. ISBN 0-471-42032-8.
  • Hughes, Joan K. (1986). PL / I Structured Programming (3ª ed.). Wiley. ISBN 0-471-83746-6.
  • Groner, GF (1971). Programação PL / I em Aplicações Tecnológicas . Books on Demand, Ann Arbor, MI.
  • Anderson, ME (1973). PL / I para programadores . Prentice-Hall.
  • Stoutemyer, DR (1971). PL / I Programming for Engineering & Science . Prentice-Hall.
  • Ziegler, RR & C. (1986). PL / I: Programação Estruturada e Solução de Problemas (1ª ed.). Oeste. ISBN 978-0-314-93915-9.
  • Sturm, E. (2009). O Novo PL / I ... para PC, Workstation e Mainframe . Vieweg-Teubner, Wiesbaden, Alemanha. ISBN 978-3-8348-0726-7.
  • Vowels, RA (1997). Introdução ao PL / I, Algoritmos e Programação Estruturada (3ª ed.). ISBN 978-0-9596384-9-3.
  • Abrahams, Paul (1979). A linguagem de programação PL / I (PDF) . Courant Mathematics and Computing Laboratory, New York University.

Padrões

  • ANSI ANSI X3.53-1976 (R1998) Sistemas de Informação - Linguagem de Programação - PL / I
  • ANSI ANSI X3.74-1981 (R1998) Sistemas de Informação - Linguagem de Programação - PL / I General-Purpose Subset
  • ANSI ANSI X3.74-1987 (R1998) Sistemas de Informação - Linguagem de Programação - PL / I General-Purpose Subset
  • ECMA 50 Programming Language PL / I , 1ª edição, dezembro de 1976
  • Linguagens de programação ISO 6160: 1979 - PL / I
  • ISO / IEC 6522: 1992 Tecnologia da informação - Linguagens de programação - subconjunto de uso geral PL / I

Manuais de referência

links externos