Harbor (linguagem de programação) - Harbour (programming language)

Projeto Porto
Paradigma multiparadigma : imperativo , funcional , orientado a objetos , reflexivo
Projetado por Antonio Linares
Desenvolvedor Viktor Szakáts e comunidade
Apareceu pela primeira vez 1999 ; 22 anos atras ( 1999 )
Versão estável
3.0.0 / 17 de julho de 2011 ; 10 anos atrás ( 17/07/2011 )
Versão de visualização
Disciplina de digitação Opcionalmente , abaixe , dinâmico , seguro , parcialmente forte
SO Plataforma cruzada
Licença Compatível com GPL de código aberto
Extensões de nome de arquivo .prg, .ch, .hb, .hbp
Local na rede Internet harbour .github .io
Dialetos
Clipper, Xbase ++, FlagShip, FoxPro, xHarbour
Influenciado por
dBase, Clipper
Influenciado
xHarbour

Harbor é uma linguagem de programação de computador , usada principalmente para criar programas de banco de dados / negócios. É uma versão modernizada, de código-fonte aberto e de plataforma cruzada do antigo sistema Clipper , que por sua vez se desenvolveu a partir do mercado de banco de dados dBase das décadas de 1980 e 1990.

O código Harbor usando os mesmos bancos de dados pode ser compilado em uma ampla variedade de plataformas, incluindo Microsoft Windows , Linux , variantes do Unix , vários descendentes de BSD , Mac OS X , MINIX 3 , Windows CE , Pocket PC , Symbian , iOS , Android , QNX , VxWorks , OS / 2 (incluindo eComStation e ArcaOS ), BeOS / Haiku , AIX e MS-DOS .

História

A ideia de um compilador Clipper de software livre já estava flutuando por um longo tempo e o assunto freqüentemente surgiu em discussões no comp.lang.clipper. Antonio Linares fundou o projeto Harbor e a implantação foi iniciada em março de 1999. O nome “Harbor” foi proposto por Linares, é uma brincadeira de Clipper como uma espécie de navio. Harbor é sinônimo de porto (onde os navios atracam), e Harbor é um porto da linguagem Clipper.

Em 2009, o porto foi substancialmente redesenhado, principalmente por Viktor Szakáts e Przemyslaw Czerpak.

Suporte de banco de dados

Harbor estende a abordagem Clipper Replaceable Database Drivers (RDD). Ele oferece vários RDDs, como DBF , DBFNTX, DBFCDX, DBFDBT e DBFFPT. No Harbor, vários RDDs podem ser usados ​​em um único aplicativo e novos RDDs lógicos podem ser definidos combinando outros RDDs. A arquitetura RDD permite a herança, de modo que um determinado RDD pode estender a funcionalidade de outro (s) RDD (s) existente (s). RDDs de terceiros, como RDDSQL, RDDSIX, RMDBFCDX, Advantage Database Server e Mediator exemplificam alguns dos recursos da arquitetura RDD. A implementação de DBFNTX tem quase a mesma funcionalidade de DBFCDX e RDDSIX. NETIO e LetoDB fornecem acesso remoto por protocolo TCP .

O Harbor também oferece suporte ODBC por meio de uma sintaxe OOP e suporte ADO por meio de OLE . MySQL , PostgreSQL , SQLite , Firebird , Oracle são exemplos de bancos de dados que o Harbor pode conectar.

As tecnologias xBase costumam ser confundidas com um software RDBMS . Embora isso seja verdade, o xBase é mais do que um sistema de banco de dados simples, pois ao mesmo tempo as linguagens xBase que usam puramente DBF não podem fornecer o conceito completo de um RDBMS real.

Filosofia de programação

Ao contrário do Java, que deve ser escrito uma vez, executado em qualquer lugar, o Harbor pretende ser escrito uma vez, compilado em qualquer lugar . Como o mesmo compilador está disponível para todos os sistemas operacionais acima, não há necessidade de recodificação para produzir produtos idênticos para plataformas diferentes, exceto quando recursos dependentes do sistema operacional são usados. Compilação cruzada é compatível com MinGW . No Microsoft Windows, o Harbor é mais estável, mas menos documentado do que o Clipper, mas tem capacidade multiplataforma e é mais transparente, personalizável e pode ser executado a partir de uma unidade flash USB.

No Linux e no Windows Mobile, o código-fonte do Clipper pode ser compilado com o Harbor com muito pouca adaptação. A maioria dos softwares originalmente escritos para rodar em Xbase ++, FlagShip, FoxPro, xHarbour e outros dialetos podem ser compilados com Harbor com alguma adaptação. Em 2010, muitos esforços foram feitos para tornar a transição de outros dialetos xBase mais fácil.

Harbor pode usar os seguintes compiladores C, entre outros: GCC , MinGW , Clang , ICC , Microsoft Visual C ++ (6.0+), Borland C ++ , Watcom C , Pelles C e Sun Studio .

O Harbor pode fazer uso de várias emulações de Terminal Gráfico , incluindo drivers de console e Console / GUIs híbridos, como GTWvt e GTWvg.

Harbor suporta GUIs externas, gratuitas (por exemplo, HBQt, HWGui, MiniGUI (versão mais recente baseada em Qt e QtContribs ) e comercial (por exemplo, FiveWin, Xailer). HBQt é uma biblioteca que fornece ligações para Qt. O aplicativo HBIDE é uma amostra do potencial de HBQt.

Harbor é 100% compatível com Clipper e suporta muitas extensões de sintaxe de linguagem, incluindo bibliotecas de tempo de execução muito estendidas, como OLE , Blat , OpenSSL , FreeImage , GD , hbtip, hbtpathy, PCRE , hbmzip ( zlib ), hbbz2 ( bzip2 ), cURL , Cairo , sua própria implementação do CA-Tools, atualizou as bibliotecas NanFor e muitos outros. Harbor tem uma comunidade de desenvolvimento ativa e amplo suporte de terceiros.

Qualquer linguagem xBase oferece uma maneira muito produtiva de criar aplicativos de negócios e de uso intensivo de dados. Harbor não é uma exceção.

Operador de macro (compilador de tempo de execução)

Um dos recursos mais poderosos das linguagens xBase é o Macro Operator '&'. A implementação do Harbour do Macro Operator permite a compilação em tempo de execução de qualquer expressão Harbour válida. Essa expressão compilada pode ser usada como um VALOR, ou seja, o lado direito de uma atribuição (rvalue), mas tal expressão compilada pode ser usada para resolver o lado esquerdo (lvalue) de uma atribuição, ou seja, variáveis ​​privadas ou públicas, ou um campo de banco de dados.

Além disso, o Operador de macro pode compilar e executar chamadas de função, completar atribuições ou mesmo uma lista de argumentos, e o resultado da macro pode ser usado para resolver qualquer um dos contextos acima no aplicativo compilado. Em outras palavras, qualquer aplicativo Harbor pode ser estendido e modificado em tempo de execução para compilar e executar código adicional sob demanda.

O compilador Macro mais recente pode compilar qualquer código Harbor válido, incluindo código para pré-processar antes da compilação.

Sintaxe:

 &( ... )

O valor do texto da expressão '...' será compilado, e o valor resultante da execução do código compilado é o resultado.

 &SomeId

é a forma abreviada de & (SomeId).

 &SomeId.postfix

é a forma abreviada de & (SomeId + "postfix").

Programação orientada a objetos

Programar em um estilo OOP é uma questão mais ampla do que uma biblioteca específica ou uma interface específica, mas a programação OOP é algo que muitos programadores de Clipper esperam. O CA-Clipper 5.2 e especialmente o 5.3 adicionaram várias classes básicas e uma sintaxe OOP correspondente. Bibliotecas como Class (y) , Fivewin, Clip4Win e TopClass fornecem funcionalidade OOP adicional.

O Harbor tem extensões OOP com suporte total para classes, incluindo herança, com base na sintaxe Class (y). A sintaxe OOP no Harbor é muito semelhante à das bibliotecas de classes Clipper anteriores, portanto, deve ser possível manter o código do Clipper legado com alterações mínimas.

Sintaxe e semântica

Código do porto em HBIDE

O Harbor, como toda linguagem xBase, não faz distinção entre maiúsculas e minúsculas e pode, opcionalmente, aceitar palavras-chave escritas apenas por seus primeiros quatro caracteres.

Tipos de dados integrados

Harbor tem seis tipos escalares: Nil , String , Date , Logical , Numeric , Pointer e quatro tipos complexos: Array , Object , CodeBlock e Hash . Um escalar contém um único valor, como uma string, numérico ou referência a qualquer outro tipo. Matrizes são listas ordenadas de escalares ou tipos complexos, indexadas por número, começando em 1. Hashes, ou matrizes associativas , são coleções não ordenadas de valores de qualquer tipo indexados por sua chave associada, que pode ser de qualquer tipo escalar ou complexo.

Representação literal (estática) de tipos escalares:

  • Nada: NIL
  • Fragmento: "hello", 'hello', [hello]
  • Encontro: 0d20100405
  • Lógico: .T., .F.
  • Numérico: 1, 1.1, −1, 0xFF

Tipos complexos também podem ser representados como valores literais:

  • Variedade: { "String", 1, { "Nested Array" }, .T., FunctionCall(), @FunctionPointer() }
  • CodeBlock :{ |Arg1, ArgN| Arg1 := ArgN + OuterVar + FunctionCall() }
  • Cerquilha: { "Name" => "John", 1 => "Numeric key", "Name2" => { "Nested" => "Hash" } }

Hashes podem usar qualquer tipo, incluindo outros Hashes como a chave para qualquer elemento. Hashes e matrizes podem conter qualquer tipo como valor de qualquer membro, incluindo matrizes de aninhamento e hashes.

Codeblocks podem ter referências a Variáveis ​​do Procedimento / Função> método no qual foi definido. Tais Codeblocks podem ser retornados como um valor, ou por meio de um argumento passado POR REFERÊNCIA , neste caso o Codeblock "sobreviverá" à rotina na qual foi definido, e quaisquer variáveis ​​que fizer referência, serão uma variável DESTACADA .

Variáveis ​​desanexadas manterão seus valores enquanto um Codeblock referenciando-as ainda existir. Esses valores serão compartilhados com qualquer outro Codeblock que possa ter acesso a essas mesmas variáveis. Se o Codeblock não sobreviveu à rotina que o contém e será avaliado durante o tempo de vida da rotina na qual está definido, as alterações em suas Variáveis ​​Desanexadas por meio de sua avaliação serão refletidas de volta em sua rotina pai.

Os codeblocks podem ser avaliados qualquer número de vezes, por meio da função Eval ( BlockExp ) .

Variáveis

Todos os tipos podem ser atribuídos a variáveis ​​nomeadas. Os identificadores de variáveis ​​nomeadas têm de 1 a 63 caracteres ASCII, começam com [A-Z|_]e consistem nos caracteres [A-Z|0–9|_]até um máximo de 63 caracteres. Variáveis ​​nomeadas não diferenciam maiúsculas de minúsculas.

As variáveis ​​têm um dos seguintes escopos:

  • LOCAL : Visível apenas dentro da rotina que o declarou. O valor é perdido ao sair da rotina.
  • ESTÁTICA : Visível apenas dentro da rotina que o declarou. O valor é preservado para invocações subsequentes da rotina. Se uma variável STATIC for declarada antes de qualquer Procedimento / Função / Método ser definido, ela tem um escopo MODULE e é visível em qualquer rotina definida no mesmo arquivo de origem, ela manterá sua vida durante o tempo de vida do aplicativo.
  • PRIVADO : Visível dentro da rotina que o declarou e todas as rotinas chamadas por essa rotina.
  • PÚBLICO : Visível por todas as rotinas do mesmo aplicativo.

LOCAL e STATIC são resolvidos em tempo de compilação e, portanto, são muito mais rápidos do que as variáveis PRIVATE e PUBLIC , que são entidades dinâmicas acessadas por meio de uma tabela de símbolos em tempo de execução . Por este mesmo motivo, as variáveis LOCAL e STATIC não são expostas ao compilador Macro, e qualquer código de macro que tente referenciá-las irá gerar um erro de tempo de execução.

Devido à natureza dinâmica das variáveis PRIVATE e PUBLIC , elas podem ser criadas e destruídas em tempo de execução, podem ser acessadas e modificadas por meio de macros de tempo de execução e podem ser acessadas e modificadas por Codeblocks criados em tempo real.

Estruturas de controle

As estruturas de controle básicas incluem todas as estruturas de controle dBase e Clipper padrão , bem como outras inspiradas nas linguagens de programação C ou Java :

rotações

[DO] WHILE ConditionExp
   ...
   [LOOP]
   [EXIT]
END[DO]
FOR Var := InitExp TO EndExp [STEP StepExp]
   ...
   [LOOP]
   [EXIT]
NEXT
FOR EACH Var IN CollectionExp
   ...
   [Var:__enumIndex()]
   [LOOP]
   [EXIT]
NEXT
  • O ... é uma sequência de uma ou mais instruções Harbor e os colchetes []denotam sintaxe opcional.
  • O Var : __ enumIndex () pode ser usado opcionalmente para recuperar o índice de iteração atual (baseado em 1).
  • A instrução LOOP reinicia a iteração atual da estrutura de loop envolvente e, se o loop envolvente for um loop FOR ou FOR EACH , ela aumenta o iterador, passando para a próxima iteração do loop.
  • A instrução EXIT termina imediatamente a execução da estrutura de loop envolvente.
  • A instrução NEXT fecha a estrutura de controle e avança para a próxima iteração da estrutura de loop.

Na instrução FOR , a expressão de atribuição é avaliada antes da primeira iteração do loop. A expressão TO é avaliada e comparada com o valor da variável de controle, antes de cada iteração, e o loop é encerrado se for avaliado para um valor numérico maior que o valor numérico da variável de controle. A expressão opcional STEP é avaliada após cada iteração, antes de decidir se deve realizar a próxima iteração.

Em FOR EACH , a variável Var terá o valor (escalar ou complexo) do respectivo elemento no valor da coleção. A expressão de coleção pode ser uma matriz (de qualquer tipo ou combinações de tipos), uma tabela de hash ou um tipo de objeto.

Declarações IF

IF CondExp
   ...
[ELSEIF] CondExp
   ...
[ELSE]
   ...
END[IF]

... representa 0 ou mais declarações .

A (s) expressão (ões) de condição deve (m) ser avaliada (s) para um valor LÓGICO .

Declarações SWITCH

Harbor suporta uma construção SWITCH inspirada na implementação C de switch ().

SWITCH SwitchExp
CASE LiteralExp
   ...
   [EXIT]
[CASE LiteralExp]
   ...
   [EXIT]
[OTHERWISE]
   ...
END[SWITCH]
  • O LiteralExp deve ser uma expressão numérica resolvível em tempo de compilação e pode envolver operadores, desde que tais operadores envolvam valor estático em tempo de compilação.
  • A instrução opcional EXIT é equivalente à quebra da instrução C e, se presente, a execução da estrutura SWITCH terminará quando a instrução EXIT for alcançada, caso contrário, continuará com a primeira instrução abaixo da próxima instrução CASE (fall through).

Declarações BEGIN SEQUENCE

BEGIN SEQUENCE
   ...
   [BREAK]
   [Break( [Exp] )]
RECOVER [USING Var]
   ...
END[SEQUENCE]

ou:

BEGIN SEQUENCE
   ...
   [BREAK]
   [Break()]
END[SEQUENCE]

A estrutura BEGIN SEQUENCE permite um aborto bem comportado de qualquer sequência, mesmo ao cruzar procedimentos / funções aninhados. Isso significa que um procedimento / função chamado pode emitir uma instrução BREAK ou uma expressão Break () para forçar o desdobramento de quaisquer procedimentos / funções aninhados, de volta à primeira estrutura BEGIN SEQUENCE externa, após sua respectiva instrução END ou uma cláusula RECOVER, se houver. A instrução Break pode, opcionalmente, passar qualquer tipo de expressão, que pode ser aceita pela instrução RECOVER para permitir tratamento de recuperação posterior.

Além disso, o Harbor Error Object oferece suporte às propriedades canDefault , canRetry e canSubstitute , que permitem que os manipuladores de erros executem alguns preparativos e, em seguida, solicitem uma operação de repetição , um currículo ou retornem um valor para substituir a expressão que acionou a condição de erro.

Alternativamente, as instruções TRY [CATCH] [FINALLY] estão disponíveis na biblioteca xhb funcionando como a construção SEQUENCE.

Procedimentos / Funções

[STATIC] PROCEDURE SomeProcedureName
[STATIC] PROCEDURE SomeProcedureName()
[STATIC] PROCEDURE SomeProcedureName( Param1 [, ParamsN] )
INIT PROCEDURE SomeProcedureName
EXIT PROCEDURE SomeProcedureName
[STATIC] FUNCTION SomeProcedureName
[STATIC] FUNCTION SomeProcedureName()
[STATIC] FUNCTION SomeProcedureName( Param1 [, ParamsN] )

Os procedimentos / funções no Harbor podem ser especificados com as palavras - chavePROCEDURE ou FUNCTION. As regras de nomenclatura são iguais às das Variáveis (até 63 caracteres sem distinção entre maiúsculas e minúsculas). Ambos os procedimentos e funções podem ser qualificados pelo qualificador de escopo ESTÁTICO para restringir seu uso ao escopo do módulo onde definido.

Os qualificadores opcionais INIT ou EXIT sinalizarão o procedimento a ser invocado automaticamente antes de chamar o procedimento de inicialização do aplicativo ou logo após encerrar o aplicativo, respectivamente. Os parâmetros passados ​​para um procedimento / função aparecem na sub-rotina como variáveis ​​locais, e podem aceitar qualquer tipo, incluindo referências.

As alterações nas variáveis ​​de argumento não são refletidas nas respectivas variáveis ​​passadas pelo procedimento / função / método de chamada, a menos que explicitamente passadas POR REFERÊNCIA usando o prefixo @ .

PROCEDURE não tem valor de retorno e, se usado em um contexto de Expressão, produzirá um valor NIL .

FUNCTION pode retornar qualquer tipo por meio da instrução RETURN, em qualquer parte do corpo de sua definição.

Segue um exemplo de definição de procedimento e uma chamada de função:

 x := Cube( 2 )

 FUNCTION Cube( n )
    RETURN n ** 3

Código de amostra

O programa típico " hello world " seria:

  ? "Hello, world!"

Ou:

  QOut( "Hello, world!" )

Ou:

  Alert( "Hello, world!" )

Ou, incluso em um procedimento explícito:

 PROCEDURE Main()

    ? "Hello, world!"

    RETURN

Exemplos OOP

Procedimento principal:

 #include "hbclass.ch"

 PROCEDURE Main()

    LOCAL oPerson

    CLS

    oPerson := Person():New( "Dave" )
    oPerson:Eyes := "Invalid"
    oPerson:Eyes := "Blue"

    Alert( oPerson:Describe() )

    RETURN

Definição de classe:

 CREATE CLASS Person

    VAR Name INIT ""

    METHOD New( cName )
    METHOD Describe()

    ACCESS Eyes INLINE ::pvtEyes
    ASSIGN Eyes( x ) INLINE iif( HB_ISSTRING( x ) .AND. x $ "Blue,Brown,Green", ::pvtEyes := x, Alert( "Invalid value" ) )

    PROTECTED:

    VAR pvtEyes

 ENDCLASS

 // Sample of normal Method definition
 METHOD New( cName ) CLASS Person

    ::Name := cName

    RETURN Self

 METHOD Describe() CLASS Person

    LOCAL cDescription

    IF Empty( ::Name )
       cDescription := "I have no name yet."
    ELSE
       cDescription := "My name is: " + ::Name + ";"
    ENDIF

    IF ! Empty( ::Eyes )
       cDescription += "my eyes' color is: " + ::Eyes
    ENDIF

    RETURN cDescription

Ferramentas

  • hbmk2 - Ferramenta de construção como make
  • hbrun - Intérprete Shell para Harbor. A compilação de macro permite executar qualquer código Harbor válido à medida que está sendo compilado
  • hbformat - Formata o código-fonte escrito no Harbor ou outro dialeto de acordo com regras definidas
  • hbpp - Pré-processador, uma ferramenta poderosa que evita problemas típicos encontrados no pré-processador da linguagem C
  • hbi18n - Ferramentas para localizar texto em aplicativos
  • hbdoc - Cria documentação para Harbor

Todas as ferramentas são multiplataforma.

Desenvolvimento

HBIDE look.

Hoje, o desenvolvimento do Harbor é liderado por Viktor Szakáts em colaboração com Przemysław Czerpak, que também contribui com muitos componentes da linguagem central e componentes suplementares. HBIDE e alguns outros componentes, especialmente HBQt, são desenvolvidos por Pritpal Bedi. Outros membros da comunidade de desenvolvimento enviam alterações ao repositório de origem do GitHub . A partir de 2015, o desenvolvimento do porto está ativo e vibrante.

comparação x Harbour

xHarbour é uma ramificação do projeto anterior do Harbor. O xHarbour tem uma abordagem mais agressiva para implementar novos recursos na linguagem, enquanto o Harbor é mais conservador em sua abordagem, visando em primeiro lugar uma replicação exata do comportamento do Clipper e, em seguida, implementando novos recursos e extensões como uma consideração secundária. Também deve ser notado que o Harbor é suportado em uma ampla variedade de sistemas operacionais, enquanto o xHarbour realmente suporta apenas MS Windows e Linux de 32 bits.

Os desenvolvedores do Harbor tentaram documentar todo o comportamento oculto na linguagem Clipper e testar o código compilado pelo Harbor junto com o mesmo código compilado com o Clipper para manter a compatibilidade.

Os desenvolvedores do Harbor rejeitam explicitamente as extensões para a linguagem em que essas extensões quebrariam a compatibilidade do Clipper. Essas rejeições foram suavizadas recentemente, uma vez que a nova arquitetura Harbor permite extensões fora do compilador principal.

Uma comparação detalhada entre as extensões implementadas no Harbor e xHarbour pode ser encontrada no repositório de origem do projeto no GitHub.

Bibliotecas e ferramentas GUI

  • hbide - Ambiente de desenvolvimento integrado para ajudar no desenvolvimento do Harbor e vários dialetos xBase
  • PTSource IDE - Integrated Development Environment inclui Harbor.
  • HwGui - Biblioteca de GUI de plataforma cruzada de código aberto para Harbor
  • HMG -Sistema de desenvolvimentoxBase Win32 / GUI gratuito / de código abertopara Harbor
  • MiniGUI - Sistema de desenvolvimento Win32 / GUI xBase de código aberto / gratuito (um Fork (desenvolvimento de software) de ambos HMG e Harbor)
  • ooHG - Object Oriented Harbor GUI - um fork "baseado em classe e programação oop" do HMG
  • Marinas-GUI - Pacote de desenvolvimento de GUI baseado em QT multi-plataforma para Harbor. O Marinas-GUI é baixado como um pacote de instalação completo para a plataforma de destino escolhida (IDE, Controle de versão, Harbor / C Compiler, Bibliotecas etc.) - Basicamente, instale e comece a codificar e compilar.

Veja também

Referências

links externos