xHarbour - xHarbour

xHarbour to darmowy, wieloplatformowy, rozszerzony kompilator Clipper , oferujący wiele terminali graficznych (GT), w tym sterowniki konsoli, GUI i hybrydowe konsole / GUI. xHarbour jest wstecznie kompatybilny z Clipper i obsługuje wiele rozszerzeń składni językowych, znacznie rozszerzone biblioteki uruchomieniowe i szerokie wsparcie innych firm.

Podobnie jak większość języków dynamicznych, xHarbour jest również dostępny jako język skryptowy (samodzielna aplikacja, biblioteka z możliwością łączenia, silnik MS ActiveScript [Host skryptów Windows, HTML, ASP]) wykorzystujący interpreter napisany w języku xHarbour.

XHarbour Usenet grup dyskusyjnych comp.lang.xharbour to aktywna społeczność do dyskusji xHarbour podobnych pytań.

Wbudowane typy danych

xHarbour ma 6 typów skalarnych: Nil , String , Date , Logical , Number , Pointer i 4 typy złożone: Array , Object , CodeBlock i Hash . Skalar przechowuje pojedynczą wartość, taką jak łańcuch, liczba lub odwołanie do dowolnego innego typu. Tablice to uporządkowane listy skalarów lub typów złożonych, indeksowane według liczby, począwszy od 1. Hashe lub tablice asocjacyjne to nieuporządkowane zbiory wartości dowolnego typu indeksowane przez skojarzony z nimi klucz, który może być dowolnego typu skalarnego lub złożonego.

Dosłowna (statyczna) reprezentacja typów skalarnych:

  • Nil: NIL
  • Ciąg znaków: „witaj”, „witaj”, [witaj] lub E „witaj \ n”
  • Data: ctod („2005-03-17”)
  • Logiczne: .T., .F.
  • Liczba: 1, 1.1, -1, 0xFF

Typy złożone mogą być również reprezentowane jako wartości dosłowne:

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

Hashe mogą używać dowolnego typu, w tym innych skrótów jako klucza dla dowolnego elementu. Hashe i tablice mogą zawierać dowolny typ jako wartość dowolnego elementu członkowskiego, w tym tablice zagnieżdżone i skróty.

Bloki kodu mogą mieć odwołania do zmiennych metody Procedura / Funkcja>, w której zostały zdefiniowane. Takie bloki kodu mogą być zwracane jako wartość lub za pomocą argumentu przekazanego PRZEZ ODNIESIENIE , w takim przypadku Codeblock „przeżyje” procedurę, w której został zdefiniowany, a wszelkie zmienne, do których się odwołuje, będą zmienną ODDZIELONĄ .

Odłączone zmienne zachowają swoją wartość tak długo, jak długo istnieje odwołanie do Codeblock, do którego się odwołują. Takie wartości będą współdzielone z każdym innym Codeblockiem, który może mieć dostęp do tych samych zmiennych. Jeśli Codeblock nie przeżył swojej procedury zawierającej i zostanie oszacowany w czasie trwania procedury, w której jest zdefiniowany, zmiany w jego Odłączonych Zmiennych poprzez jej ocenę zostaną odzwierciedlone z powrotem w jego nadrzędnej procedurze.

Bloki kodu można oceniać dowolną liczbę razy za pomocą funkcji Eval ( BlockExp ).

Zmienne

Do nazwanych zmiennych można przypisać wszystkie typy. Nazwane identyfikatory zmiennych mają długość od 1 do 63 znaków, rozpoczynają się od [AZ | _], a ponadto składają się ze znaków [AZ | 0-9 | _] do maksymalnie 63 znaków. Nazwane zmienne nie uwzględniają wielkości liter.

Zmienne mają jeden z następujących zakresów:

  • LOKAL : Widoczne tylko w ramach procedury, która ją zadeklarowała. Po wyjściu z rutyny traci się wartość.
  • STATYCZNY : Widoczny tylko w ramach procedury, która to zadeklarowała. Wartość jest zachowywana dla kolejnych wywołań procedury. Jeśli zmienna STATIC jest zadeklarowana przed zdefiniowaniem jakiejkolwiek procedury / funkcji / metody, ma ona zasięg MODUŁU i jest widoczna w ramach dowolnej procedury zdefiniowanej w tym samym pliku źródłowym, zachowa ona swoją żywotność przez cały okres istnienia aplikacji.
  • GLOBALNY Widoczny w ramach dowolnej procedury zdefiniowanej w tym samym module źródłowym, w którym zadeklarowana jest zmienna GLOBAL, a także w dowolnej procedurze dowolnego innego modułu źródłowego, który wyraźnie ją deklaruje, za pomocą deklaracji GLOBAL EXTERNAL . Deklaracje GLOBAL i GLOBAL EXTERNAL muszą być zadeklarowane przed zdefiniowaniem jakiejkolwiek procedury / funkcji / metody.
  • PRYWATNE : widoczne w procedurze, która ją zadeklarowała, i we wszystkich procedurach wywoływanych przez tę procedurę.
  • PUBLICZNY : Widoczny dla wszystkich procedur w tej samej aplikacji.

LOKALNE , STATYCZNE i GLOBALNE są rozwiązywane w czasie kompilacji, a zatem są znacznie szybsze niż zmienne PRYWATNE i PUBLICZNE , które są dynamicznymi jednostkami dostępnymi za pomocą tabeli symboli środowiska wykonawczego . Z tego samego powodu zmienne LOCAL , STATIC i GLOBAL nie są ujawniane kompilatorowi makr, a każdy kod makra, który spróbuje się do nich odwołać, wygeneruje błąd w czasie wykonywania.

Ze względu na dynamiczny charakter zmiennych PRYWATNYCH i PUBLICZNYCH , można je tworzyć i niszczyć w czasie wykonywania, można uzyskać do nich dostęp i modyfikować je za pomocą makr środowiska uruchomieniowego, a także mogą być dostępne i modyfikowane przez Codeblocks tworzone w locie.

Struktury kontrolne

Podstawowe struktury kontrolne obejmują wszystkie standardowe struktury kontrolne dBase i Clipper , a także dodatkowe inspirowane językami programowania C lub Java :

Pętle

[DO] WHILE ConditionExp
   ...
   [LOOP]
   [EXIT]
END[DO]
FOR Var := InitExp TO EndExp [STEP StepExp]
   ...
   [LOOP]
   [EXIT]
NEXT
FOR EACH Var IN CollectionExp
   ...
   [HB_EnumIndex()]
   [LOOP]
   [EXIT]
NEXT
  • ... jest sekwencją jednego lub więcej sprawozdań xHarbour i bracketes kwadratowych [] oznaczają opcjonalnie składnia.
  • HB_EnumIndex () można ewentualnie stosować w celu pobrania indeks bieżącego iteracji (1 bazującego).
  • Instrukcja LOOP ponownie uruchamia bieżącą iterację otaczającej struktury pętli, a jeśli otaczająca pętla jest pętlą FOR lub FOR EACH , zwiększa iterator, przechodząc do następnej iteracji pętli.
  • Instrukcja EXIT natychmiast przerywa wykonywanie otaczającej struktury pętli.
  • Instrukcja NEXT zamyka strukturę kontrolną i przechodzi do następnej iteracji struktury pętli.

W DLA deklaracji, przypisanie wartości wyrażenia przed pierwszej iteracji. DO ekspresję i porównano z wartością zmiennej sterowania, przed każdym powtórzeniu, a pętla zostanie zakończone, jeśli ocenia się na wartość większą niż numerycznej wartości liczbowej zmiennej sterowania. Opcjonalne wyrażenie STEP jest oceniane po każdej iteracji, przed podjęciem decyzji, czy wykonać następną iterację.

W For Each The Var zmienna będzie miał wartość (skalarną lub kompleks) z odpowiednim elementem wartości poboru. Wyrażenie kolekcji może być tablicą (dowolnego typu lub kombinacji typów), tabelą skrótów lub typem Object.

Instrukcje IF

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

... reprezentuje 0 lub więcej instrukcji .

Wyrażenie (a) warunku musi mieć wartości LOGICZNEJ .

Instrukcje DO CASE

DO CASE
   CASE CondExp
      ...
   [CASE CondExp]
      ...
   [OTHERWISE]
      ...
END[CASE ]

Powyższa konstrukcja jest logicznie równoważna z:

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

Instrukcje SWITCH

xHarbour obsługuje konstrukcję SWITCH inspirowaną implementacją switch () w C.

SWITCH SwitchExp
   CASE LiteralExp
      ...
      [EXIT]
   [CASE LiteralExp]
      ...
      [EXIT]

   [DEFAULT]
      ...
END
  • LiteralExp muszą być zestawiane razem ekspresji rozpoznawana numeryczna, i mogą obejmować operatorów, tak długo jak takie operatorzy obejmować wartości statycznego kompilacji.
  • Wyjście opcjonalnie stwierdzenie jest odpowiednikiem C sprawozdania przerwy , a jeśli jest obecny, wykonanie konstrukcji przełącznik kończy się po osiągnięciu stwierdzenie WYJŚCIE, w przeciwnym przypadku przejść do pierwszej instrukcji poniżej następnej instrukcji przypadku (nie mieści się).

Instrukcje BEGIN SEQUENCE

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

lub:

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

Struktura BEGIN SEQUENCE pozwala na dobrze zachowującą się aborcję dowolnej sekwencji, nawet podczas krzyżowania zagnieżdżonych procedur / funkcji. Oznacza to, że wywołana procedura / funkcja może wydać instrukcję BREAK lub wyrażenie Break (), aby wymusić rozwinięcie dowolnej zagnieżdżonej procedury / funkcji, aż do pierwszej zewnętrznej struktury BEGIN SEQUENCE, albo po jej odpowiedniej instrukcji END lub klauzula RECOVER, jeśli występuje. Instrukcja Break może opcjonalnie przekazać dowolny typ wyrażenia, który może zostać zaakceptowany przez instrukcję RECOVER, aby umożliwić dalsze przekazywanie odzyskiwania.

Dodatkowo xHarbour błąd Przedmiot obsługuje canDefault , canRetry i canSubstitute właściwości, co umożliwia obsługi błędów wykonać kilka preparatów, a następnie żądać Ponawiać Praca , do CV , lub zwraca wartość zastąpić ekspresji wyzwalania stan błędu.

TRY [CATCH] [FINALLY] instrukcji

TRY
   ...
   [BREAK]
   [Break([Exp])]
   [Throw([Exp])]
CATCH [Var]
   ...
END
TRY
   ...
   [BREAK]
   [Break([Exp])]
   [Throw([Exp])]
CATCH [Var]
   ...
FINALLY
   ...
END

lub:

TRY
   ...
   [BREAK]
   [Break([Exp])]
   [Throw([Exp])]
FINALLY
   ...
END

Konstrukcja TRY jest bardzo podobna do konstrukcji BEGIN SEQUENCE, z wyjątkiem tego, że automatycznie integruje obsługę błędów, dzięki czemu każdy błąd zostanie przechwycony i odzyskany za pomocą instrukcji CATCH lub w przeciwnym razie przesłany do zewnętrznej procedury obsługi CATCH. Gwarantuje się, że sekcja FINALLY zostanie wykonana przed kontrolą przepływu przez sekcje TRY lub CATCH za pomocą opcji RETURN, BREAK lub THROW.

Procedury / funkcje

[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] )

Procedury / funkcje w xHarbour można określić za pomocą słów kluczowych PROCEDURE lub FUNCTION. Zasady nazewnictwa są takie same jak dla zmiennych (do 63 znaków bez rozróżniania wielkości liter). Zarówno procedury, jak i funkcje mogą być kwalifikowane przez kwalifikator zakresu STATIC, aby ograniczyć ich użycie do zakresu modułu, jeśli został zdefiniowany.

INIT lub EXIT opcjonalne kwalifikacyjne, wola flagi procedura jest automatycznie wywoływana tuż przed wywołaniem procedury aplikacji startowej, lub tuż po wyjściu z aplikacji, odpowiednio. Parametry przekazywane do procedury / funkcji pojawiają się w podprogramie jako zmienne lokalne i mogą akceptować dowolny typ, w tym odwołania.

Zmiany w zmiennych argumentowych nie są odzwierciedlane w odpowiednich zmiennych przekazywanych przez wywołującą procedurę / funkcję / metodę, chyba że jawnie przekazano BY ODNOŚNIK przy użyciu przedrostka @ .

PROCEDURA nie zwraca żadnej wartości i jeśli zostanie użyta w kontekście wyrażenia, zwróci wartość NIL .

FUNKCJA może zwrócić dowolny typ za pomocą instrukcji RETURN w dowolnym miejscu w treści swojej definicji.

Oto przykładowa definicja procedury i wywołanie funkcji:

 x := Cube( 2 )

 FUNCTION Cube( n )
 RETURN n ** 3

Obsługa baz danych

xHarbour rozszerza podejście Clipper Replaceable Database Drivers (RDD). Oferuje wiele RDD, takich jak DBF, DBFNTX, DBFCDX, DBFDBT i DBFFPT. W xHarbour można używać wielu RDD w jednej aplikacji, a nowe logiczne RDD można zdefiniować z kombinacji innych RDD. Architektura RDD pozwala na dziedziczenie, dzięki czemu dany RDD może rozszerzać funkcjonalność innych istniejących RDD. Zewnętrzne RDD, takie jak RDDSQL, RDDSIX, RMDBFCDX, Advantage Database Server i Mediator to przykłady niektórych cech architektury RDD.

xHarbour oferuje również obsługę ODBC za pomocą składni OOP i obsługę ADO za pomocą OLE.

Operator makra (kompilator środowiska uruchomieniowego)

Jedną z najpotężniejszych funkcji języków xBase jest operator MAKRO „&”. Implementacja Makro Operatora w xHarbour pozwala na kompilację w czasie wykonywania dowolnego prawidłowego wyrażenia xHarbour. Takie skompilowane wyrażenie może być użyte jako WARTOŚĆ, tj. Prawa strona przypisania, ale takie skompilowane wyrażenie może być użyte do rozstrzygnięcia LEWEJ strony przypisania, tj. Zmienne PRYWATNE, PUBLICZNE lub POLE bazy danych.

Dodatkowo operator makra może kompilować i wykonywać wywołania funkcji, kompletne przypisania, a nawet listę argumentów, a wynik makra może zostać użyty do rozwiązania dowolnego z powyższych kontekstów w skompilowanej aplikacji. IOW, każda aplikacja xHarbour może zostać rozszerzona i / lub zmodyfikowana w czasie wykonywania, aby kompilować i wykonywać dodatkowy kod na żądanie.

Implementacja xHarbour tej funkcji jest tak kompletna, że ​​interpreter xHarbour, xbScript, używa go intensywnie do kompilowania skryptów xHarbour.

Składnia:

 &( ... )

Skompilowana zostanie wartość tekstowa wyrażenia „...”, a wynikiem jest wartość wynikająca z wykonania skompilowanego kodu.

 &SomeId

to skrócona forma wyrażenia & (SomeId).

 &SomeId.postfix

to skrócona forma & (SomeId + "postfix").

Przykładowy kod

Witaj świecie!

Typowy program „ hello world ” wyglądałby tak:

 ? "Hello, world!"

Lub:

 QOut( "Hello, world!" )

Lub:

 Alert( "Hello, world!" )

Lub ujęty w wyraźną procedurę:

 PROCEDURE Main()
 
    ? "Hello, world!"

 RETURN

OOP

 #include "hbclass.ch"

 PROCEDURE Main()

    LOCAl oPerson := Person( "Dave" )

    oPerson:Eyes := "Invalid"

    oPerson:Eyes := "Blue"

    Alert( oPerson:Describe() )
 RETURN
 CLASS Person
    DATA Name INIT ""

    METHOD New() CONSTRUCTOR

    ACCESS Eyes INLINE ::pvtEyes
    ASSIGN Eyes( x ) INLINE IIF( ValType( x ) == 'C' .AND. x IN "Blue,Brown,Green", ::pvtEyes := x, Alert( "Invalid value" ) )

    // Sample of IN-LINE Method definition
    INLINE METHOD Describe()
       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
    ENDMETHOD

    PRIVATE:
       DATA pvtEyes
 ENDCLASS

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

   ::Name := cName

 RETURN Self

Skrypty

xHarbour jest również dostępny jako język interpretowany w kilku odmianach silników skryptowych.

  • Samodzielny tłumacz : przenośny, samodzielny tłumacz xBaseScript .
  • ActiveScript : DLL OLE zgodny z Microsoft ActiveScript, który obsługuje skrypty xHarbour w:
    • Host skryptów systemu Windows (WSH).
    • Internet Explorer, skrypty po stronie klienta HTML.
    • IIS i każdy inny serwer zgodny z ASP.

Linki zewnętrzne