ALGOL

γλώσσα προγραμματισμού From Wikipedia, the free encyclopedia

ALGOL
Remove ads

Η ALGOL (συντομογραφία των αγγλικών λέξεων ALGOrithmic Language)[1] είναι μια οικογένεια προστακτικών γλωσσών προγραμματισμού που αναπτύχθηκε στα μέσα της δεκαετίας του 1950 και άσκησε σημαντική επιρροή σε πολλές άλλες γλώσσες, ενώ έγινε ο ντε φάκτο τρόπος που περιγράφονταν οι αλγόριθμοι σε βιβλία και ακαδημαϊκά έργα για τα επόμενα 30 χρόνια.[2] Σχεδιάστηκε ώστε να διορθωθούν κάποια από τα προβλήματα της FORTRAN και οδήγησε σε πολλές γλώσσες, μεταξύ αυτών στη BCPL, τη B, την Pascal, τη Simula και τη C. Η ALGOL εισήγαγε τις ενότητες κώδικα (code blocks) και τα ζεύγη begin και end για την οριοθέτησή τους, ενώ ήταν η πρώτη γλώσσα που υλοποίησε εμφωλευμένους ορισμούς συναρτήσεων (nested function definitions) με λεκτική εμβέλεια. Συχνά χρησιμοποιούνται τμήματα σύνταξης που μοιάζουν με ALGOL σαν ψευδοκώδικας (περιγραφή αλγορίθμων που απευθύνεται σε αναγνώστες).

Thumb
Σχέση μεταξύ της ALGOL, της FORTRAN και κάποιων από τις προστακτικές γλώσσες προγραμματισμού που ακολούθησαν.

Υπήρξαν τρεις σημαντικοί ορισμοί:

  • ALGOL 58 - αρχικά προτάθηκε η ονομασία IAL (International Algorithmic Language).
  • ALGOL 60 - αρχικά υλοποιήθηκε σαν X1 ALGOL 60 στα μέσα της δεκαετίας του 1960 - με αναθεώρηση το 1963[3][4]
  • ALGOL 68 - αναθεωρήθηκε το 1973[5] - εισήγαγε νέα στοιχεία όπως οι ευέλικτοι πίνακες (flexible arrays), τα slices, ο παραλληλισμός, η ταυτοποίηση τελεστών (operator identification) και διάφορες άλλες επεκτάσεις.

Ο Niklaus Wirth βάσισε τη δική του ALGOL W στην ALGOL 60 πριν αναπτύξει την Pascal. Η Algol-W επρόκειτο να ήταν η επόμενη γενιά της ALGOL αλλά η επιτροπή της ALGOL 68 αποφάσισε μια σχεδίαση που ήταν πολυπλοκότερη και πιο προχωρημένη από μια καθαρότερη και απλοποιημένη ALGOL 60. Οι επίσημες εκδόσεις της ALGOL ονομάζονται σύμφωνα με το χρόνο που δημοσιεύτηκαν αρχικά.

Η Algol 68 ήταν αρκετά διαφορετική από την Algol 60 αλλά δεν έτυχε καλής υποδοχής, με αποτέλεσμα ο όρος "Algol" γενικά να σημαίνει την Algol 60 και της διαλέκτους της.

Remove ads

Σημαντικές υλοποιήσεις

Η International Algorithmic Language (IAL ή ALGOL 58) υπήρξε επιδραστική και γενικά θεωρείται ο πρόγονος πολλών σύγχρονων γλωσσών προγραμματισμού. Επιπλέον, στην επιστήμη υπολογιστών, ο αντικειμενικός κώδικας της ALGOL (ALGOL object code) ήταν ένας απλός και περιεκτικός τρόπος να περιγραφεί σε αρχιτεκτονική με στοίβες, που χρησιμοποιούνταν στη διδασκαλία κατασκευής μεταγλωττιστών και άλλων γλωσσών υψηλού επιπέδου (με την Algol να θεωρείται γενικά η πρώτη από αυτές).

Remove ads

Ιστορία

Η ALGOL αναπτύχθηκε από μια επιτροπή Ευρωπαίων και Αμερικανών επιστημόνων της επιστήμης των υπολογιστών, σε μια συνάντηση στο ETH Ζυρίχης το 1958 (ALGOL 58). Ορίστηκαν τρεις διαφορετικοί τρόποι σύνταξης: μια σύνταξη αναφοράς (reference syntax), μια σύνταξη δημοσίευσης (publication syntax) και μια σύνταξη υλοποίησης (implementation syntax). Αυτοί οι τρεις διαφορετικοί τρόποι επέτρεπαν τη χρήση διαφορετικών ονομάτων λέξεων-κλειδιών και διαφορετικές συμβάσεις για τα δεκαδικά ψηφία (κόμμα ή περίοδος), για διαφορετικές γλώσσες.

Η ALGOL χρησιμοποιήθηκε κυρίως από ερευνητές της επιστήμης υπολογιστών στις Ηνωμένες Πολιτείες και στην Ευρώπη. Υπήρξαν δυσχέρειες στη χρήση της σε εμπορικές εφαρμογές λόγω έλλειψης ενός πρότυπου συστήματος εισόδου/εξόδου και επίσης έλλειψης ενδιαφέροντος από τις μεγάλες εταιρείες του χώρου. Η ALGOL 60 όμως εδραιώθηκε όσον αφορά τη δημοσίευση αλγορίθμων και είχε πρωτοφανείς επιπτώσεις στην ανάπτυξη μελλοντικών γλωσσών προγραμματισμού.

Ο John Backus ανέπτυξε ειδικά για την ALGOL 58, την κανονική μορφή Μπάκους-Νάουρ (Backus–Naur Form), μια μέθοδο περιγραφής γλωσσών προγραμματισμού. Η μέθοδος αναθεωρήθηκε και επεκτάθηκε από τον Peter Naur για την ALGOL 60 και σύμφωνα με πρόταση του Ντόναλντ Κνουθ, μετονομάστηκε σε κανονική μορφή Μπάκους-Νάουρ.[6]

Σύμφωνα με τον Peter Naur:

"Σαν αρχισυντάκτης του ALGOL Bulletin συμμετείχα στις διεθνείς συνομιλίες σχετικά με τη γλώσσα και επιλέχθηκα σαν μέλος της Ευρωπαϊκής ομάδας σχεδίασης της γλώσσας το Νοέμβριο του 1959. Λόγω αυτού του ρόλου μου, ήμουν αρχισυντάκτης της αναφοράς για την ALGOL 60, η οποία προέκυψε από τη συνάντηση ALGOL 60 στο Παρίσι τον Ιανουάριο του 1960."[7][8]

Τη συνάντηση στο Παρίσι παρακολούθησαν οι εξής άνθρωποι (1-16 Ιανουαρίου):

  • Friedrich L. Bauer, Peter Naur, Heinz Rutishauser, Klaus Samelson, Bernard Vauquois, Adriaan van Wijngaarden και Michael Woodger (από την Ευρώπη)
  • John W. Backus, Julien Green, Charles Katz, Τζον Μακάρθι, Alan J. Perlis και Joseph Henry Wegstein (από τις ΗΠΑ).

Ο Alan Perlis περιέγραψε τη συνάντηση με εύγλωττο τρόπο: "Οι συναντήσεις ήταν εξαντλητικές, ατέρμονες και ευφορικές. Δείχναμε εκνευρισμό όταν καλές μας ιδέες απορρίπτονταν μαζί με κακές ιδέες άλλων. Παρόλα αυτά, υπήρξαμε επιμελείς σε όλη τη διάρκεια των συναντήσεων. Η χημεία των 13 ήταν εξαιρετική."[9]

Ο John Backus και ο Peter Naur υπήρξαν μέλη της επιτροπής που δημιούργησε την ALGOL 60, μαζί με το Wally Feurzeig, ο οποίος αργότερα θα δημιουργούσε τη Logo.

Η ALGOL 60 ενέπνευσε πολλές από τις επόμενες γλώσσες προγραμματισμού. Ο Τόνυ Χόαρ έχει δηλώσει: "Ορίστε μια γλώσσα τόσο μπροστά από την εποχή της που υπήρξε βελτίωση όχι μόνο σε σχέση με τους προκατόχους της αλλά σε σχέση και με σχεδόν όλους τους απογόνους της."[10] Η γλώσσα προγραμματισμού Scheme, η οποία είναι παρακλάδι της Lisp και πήρε τη δομή ενοτήτων (blocks) και τη λεκτική εμβέλεια της ALGOL, υιοθέτησε επίσης και τον τίτλο "Revised Report on the Algorithmic Language Scheme" για τα έγγραφα που περιγράφουν τα πρότυπά της, σαν φόρο τιμής στην ALGOL και στην αναθεωρημένη αναφορά της.[11]

Η Algol και η έρευνα στις γλώσσες προγραμματισμού

Όπως παρατήρησε και ο Peter Landin, η Algol ήταν η πρώτη γλώσσα που συνδύασε επιτυχημένα τα προστακτικά εφέ (imperative effects) με το λ-λογισμό με κλήση κατ' όνομα (call-by-name). Ο John C. Reynolds ίσως έδωσε τον πιο κομψό τυπικό ορισμό της γλώσσας, με τρόπο που επιδεικνύει τη συντακτική και σημασιολογική της καθαρότητα. Η "ιδανική" Algol του Reynolds υπήρξε επίσης επιχείρημα υπέρ της σύγκρισης των τοπικών εφφέ ("local" effects) των γλωσσών με κλήση κατ' όνομα σε σχέση με τα καθολικά εφφέ ("global" effects) που χρησιμοποιούνται από τις γλώσσες με κλήση κατά τιμή (call-by-value), όπως η ML. Η θεωρητική ακεραιότητα της γλώσσας υπήρξε σημαντική για τη χρήση της στην έρευνα της σημασιολογίας, μαζί με την PCF και την ML.[12]

Οι υλοποιήσεις της IAL

Έχουν υπάρξει τουλάχιστον 70 εμπλουτισμένες, εκτεταμένες ή παράγωγες εκδόσεις, καθώς και υπογλώσσες της Algol 60 μέχρι σήμερα.[13]

Περισσότερες πληροφορίες Όνομα, Έτος ...

Οι διάλεκτοι της Burroughs περιλάμβαναν ειδικές διαλέκτους για την εκκίνηση του συστήματος (Bootstrapping), όπως η ESPOL και η NEWP.

Remove ads

Χαρακτηριστικά

Όπως ορίστηκε επίσημα, η ALGOL 60 δεν είχε δυνατότητες εισόδου/εξόδου - κάθε υλοποίηση όριζε το δικό της τρόπο με αποτέλεσμα συνήθως να υπάρχει θέμα συμβατότητας μεταξύ διαφορετικών υλοποιήσεων. Αντίθετα, η ALGOL 68 προσέφερε μια εκτενή βιβλιοθήκη από δυνατότητες transput (όρος της ALGOL 68 για την είσοδο και την έξοδο).

Η ALGOL 60 επέτρεπε δύο ειδών στρατηγικές αποτίμησης για το πέρασμα παραμέτρων: τη συνηθισμένη κλήση κατά τιμή (call-by-value), και την κλήση κατ' όνομα (call-by-name). Η κλήση κατ' όνομα είχε κάποιους περιορισμούς σε σχέση με την κλήση κατ' αναφορά (call-by-reference), με αποτέλεσμα να έχει κάποιες ανεπιθύμητες ιδιότητες όσον αφορά τη σχεδίαση προστακτικών γλωσσών. Για παράδειγμα, είναι αδύνατο στην ALGOL 60 να γραφεί μια διαδικασία που να ανταλλάσσει τις τιμές δύο παραμέτρων, αν αυτές είναι μια παράμετρος τύπου ακεραίου και ένας πίνακας που δεικτοδοτείται από την ίδια μεταβλητή ακεραίου.[16] Έστω ότι περνιέται ένας δείκτης στη swap(i, A[i]) σε μια συνάρτηση. Τότε, κάθε φορά που γίνεται αναφορά στη swap(), αυτή αποτιμάται πάλι. Έστω ότι i := 1 και A[i] := 2, ώστε κάθε φορά που γίνεται αναφορά στη swap(), αυτή θα επιστρέψει τον άλλο συνδυασμό των τιμών ([1,2], [2,1], [1,2], και ομοίως). Άλλη προβληματική περίπτωση είναι το πέρασμα μιας συνάρτησης random() που να επιστρέφει τυχαίες τιμές.

Όμως, η κλήση κατ' όνομα εξακολουθούσε να αποτελεί αγαπημένο θέμα όσων υλοποιούσαν την ALGOL λόγω του ενδιαφέροντος που είχε ο μηχανισμός των "thunks" που χρησιμοποιήθηκε για να την υλοποιήσει. Ο Ντόναλντ Κνουθ εφηύρε το τεστ "άντρας ή αγόρι" ("man or boy test"), για να ξεχωρίσει μεταξύ των μεταγλωττιστών που υλοποιούσαν σωστά την αναδρομή και τις μη-τοπικές αναφορές. Το τεστ αυτό περιλαμβάνει ένα παράδειγμα της κλήσης κατ' όνομα.

Η ALGOL 68 ορίστηκε χρησιμοποιώντας ένα φορμαλισμό γραμματικής δύο επιπέδων που εφευρέθηκε από τον Adriaan van Wijngaarden και από τότε έχει το όνομά του. Οι γραμματικές van Wijngaarden χρησιμοποιούν μια γραμματική χωρίς συμφραζόμενα (context-free grammar) για να παράγουν ένα άπειρο σύνολο από παραγωγές που αναγνωρίζουν ένα συγκεκριμένο πρόγραμμα ALGOL 68 - ειδικότερα, μπορούν να εκφράσουν τις απαιτήσεις αυτές που σε άλλα πρότυπα γλωσσών προγραμματισμού αποκαλούνται "σημασιολογία" και πρέπει να εκφραστούν σε (μη ακριβή) φυσική γλώσσα, σαν κείμενο, και στη συνέχεια να υλοποιηθούν στο μεταγλωττιστή σαν ad hoc κώδικας που συνδέεται με το συντακτικό αναλυτή της γλώσσας.

Remove ads

Παραδείγματα και ζητήματα μεταφερσιμότητας

Συγκρίσεις δειγμάτων κώδικα

ALGOL 60

(Ο τρόπος που γράφεται το κείμενο με έντονα γράμματα, εξαρτάται από την υλοποίηση, για παράδειγμα μπορεί να είναι 'INTEGER' (μαζί με τα εισαγωγικά) ή integer (αυτό ονομάζεται stropping).

procedure Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k);
    value n, m; array a; integer n, m, i, k; real y;
comment Το απόλυτα μεγαλύτερο στοιχείο του πίνακα a, μεγέθους n επί m,
μεταφέρεται στην y και οι δείκτες αυτού του στοιχείου είναι i και k;
begin integer p, q;
    y := 0; i := k := 1;
    for p:=1 step 1 until n do
    for q:=1 step 1 until m do
        if abs(a[p, q]) > y then
            begin y := abs(a[p, q]);
            i := p; k := q
            end
end Absmax

Ακολουθεί ένα παράδειγμα παραγωγής ενός πίνακα στην Elliott 803 ALGOL.[17]

 FLOATING POINT ALGOL TEST'
 BEGIN REAL A,B,C,D'
 READ D'
 FOR A:= 0.0 STEP D UNTIL 6.3 DO
 BEGIN
   PRINT PUNCH(3),££L??'
   B := SIN(A)'
   C := COS(A)'
   PRINT PUNCH(3),SAMELINE,ALIGNED(1,6),A,B,C'
 END'
 END'

η PUNCH(3) στέλνει την έξοδο στον εκτυπωτή (teleprinter) αντί για το διατρητή ταινίας (tape punch).
η SAMELINE αποκρύπτει την αλλαγή γραμμής που τυπώνεται κανονικά ανάμεσα σε δύο παραμέτρους.
η ALIGNED(1,6) θέτει τη μορφή της εξόδου σαν 1 ψηφίο πριν και 6 ψηφία μετά από την υποδιαστολή.

ALGOL 68

Ο ακόλουθος κώδικας είναι ο αντίστοιχος σε ALGOL 68 του πρηγούμενου κώδικα σε ALGOL 60.

Η ALGOL 68 κάνει χρήση του stropping της ALGOL 60. Στην ALGOL 68, οι λέξεις με έντονα γράμματα είναι δεσμευμένες λέξεις, τύποι (modes) ή τελεστές.

proc abs max = ([,]real a, ref real y, ref int i, k)real:
comment Το απόλυτα μεγαλύτερο στοιχείο του πίνακα a, μεγέθους ⌈a επί 2⌈a
μεταφέρεται στην y και οι δείκτες του στοιχείου είναι i και k; comment
begin
   real y := 0; i := ⌊a; k := 2⌊a;
   for p from ⌊a to ⌈a do
     for q from 2⌊a to 2⌈a do
       if abs a[p, q] > y then
           y := abs a[p, q];
           i := p; k := q
       fi
     od
   od;
   y
end # abs max #

Σημείωση: τα κατώτερα (⌊) και ανώτερα (⌈) όρια ενός πίνακα, και οι "φέτες" πίνακα (array slicing), είναι διαθέσιμα στον προγραμματιστή.

δοκιμή με αριθμούς κινητής υποδιαστολής (floating point) σε algol68:
(
  real a,b,c,d;
  printf(($pg$,"Εισάγετε d:"));
  read(d);
  for step from 0 while a:=step*d; a <= 2*pi do
    printf($l$);
    b := sin(a);
    c := cos(a);
    printf(($z-d.6d$,a,b,c))
  od
)

printf - στέλνει την έξοδο στο αρχείο πρότυπη έξοδος (stand out).
printf($p$); - επιλέγει μια νέα σελίδα (new page).
printf($l$); - επιλέγει μια νέα γραμμή (new line).
printf(($z-d.6d$,a,b,c)) - μορφοποιεί την έξοδο με 1 ψηφίο πριν και 6 ψηφία μετά την υποδιαστολή.

Χρονοδιάγραμμα: Hello world

Οι διαφορές και η έλλειψη φορητότητας των προγραμμάτων μεταξύ των υλοποιήσεων φαίνεται από το κλασικό πρόγραμμα που εκτυπώνει τη φράση "hello world".

ALGOL 58 (IAL)

Η ALGOL 58 δεν είχε δυνατότητες εισόδου/εξόδου.

Οικογένεια της ALGOL 60

Η ALGOL 60 δεν είχε δυνατότητες εισόδου/εξόδου, επομένως δεν υπάρχει μεταφέρσιμη έκδοση του προγράμματος στην ALGOL. Το πρόγραμμα που ακολουθεί θα μπορούσε να μεταγλωττιστεί και να εκτελεστεί σε μια υλοποίηση της ALGOL για έναν υπολογιστή Unisys A-Series mainframe, και αποτελεί μια απευθείας απλοποιημένη έκδοση του κώδικα από το The Language Guide του Dearborn Computer and Information Science Department του Πανεπιστημίου του Μίσιγκαν.[18]

BEGIN
  FILE F(KIND=REMOTE);
  EBCDIC ARRAY E[0:11];
  REPLACE E BY "HELLO WORLD!";
  WRITE(F, *, E);
END.

Ένα απλό πρόγραμμα που χρησιμοποιεί απευθείας μορφή:

BEGIN
  FILE F(KIND=REMOTE);
  WRITE(F, <"HELLO WORLD!">);
END.

Ένα ακόμα πιο απλό πρόγραμμα που χρησιμοποιεί την εντολή Display:

BEGIN DISPLAY("HELLO WORLD!") END.

Ακολουθεί ένα εναλλακτικό παράδειγμα, που χρησιμοποιεί την είσοδο/έξοδο της Elliott Algol. Η Elliott Algol χρησιμοποιούσε διαφορετικούς χαρακτήρες για τα δεξιά εισαγωγικά και τα αριστερά εισαγωγικά, τους ‘ και ’.

 program HiFolks;
 begin
    print ‘Hello world’;
 end;

Ακολουθεί μια έκδοση για την Elliott 803 Algol (A104). Το Elliott 803 κλασικά χρησιμοποιούσε χαρτοταινία με 5 τρύπες και είχε μόνο κεφαλαία γράμματα. Ο κώδικας δεν είχε χαρακτήρες εισαγωγικών και χρησιμοποιούνταν το £ (σύμβολο της λίρας του Ηνωμένου Βασιλείου) για το αριστερό εισαγωγικό και το ? (αγγλικό ερωτηματικό) για το δεξιό εισαγωγικό. Οι ειδικές ακολουθίες τοποθετούνταν σε διπλά εισαγωγικά (π.χ. η ££L?? παρήγαγε μια νέα γραμμή στον εκτυπωτή).

  HIFOLKS'
  BEGIN
     PRINT £HELLO WORLD£L??'
  END'

Η ICT 1900 Algol επέτρεπε είσοδο από χαρτοταινία ή διάτρητη κάρτα. Σε κατάσταση χαρτοταινίας, επέτρεπε πεζά γράμματα. Η έξοδος εμφανιζόταν σε έναν εκτυπωτή γραμμής (line printer).

  'BEGIN'
     'WRITE TEXT'("HELLO WORLD");
  'END'

ALGOL 68

Ο κώδικας σε ALGOL 68 εμφανιζόταν με τις δεσμευμένες λέξεις σε πεζά γράμματα αλλά με έντονη γραφή ή υπογράμμιση.

begin
  printf(($gl$,"Hello, world!"))
end

Οι δυνατότητες εισόδου/εξόδου στην αναφορά της γλώσσας ("Algol 68 Report") αποκαλούνταν "Transput".

Χρονοδιάγραμμα των ειδικών χαρακτήρων της ALGOL

Γρήγορες Πληροφορίες

Οι εκδόσεις της ALGOL εμφανίστηκαν σε μια εποχή που τα διάφορα σύνολα χαρακτήρων διέφεραν μεταξύ τους και εξελίσσονταν γρήγορα ενώ η ίδια η γλώσσα οριζόταν έτσι ώστε να χρειάζονται μόνο τα κεφαλαία γράμματα.

1960: IFIP - Η γλώσσα Algol 60 και η αναφορά για αυτήν περιλάμβαναν διάφορα μαθηματικά σύμβολα που είναι διαθέσιμα στους σύγχρονους υπολογιστές και λειτουργικά συστήματα αλλά δεν υποστηρίζονταν στους περισσότερους υπολογιστές της εποχής. Για παράδειγμα: ×, ÷, ≤, ≥, ≠, ¬, ∨, ∧, ⊂, ≡, ␣ και ⏨.

1961, Σεπτέμβριος: ASCII - Το σύνολο χαρακτήρων ASCII, τότε σε αρχικό στάδιο ανάπτυξης, απέκτησε το χαρακτήρα \ (Κάθετος ή Back slash) ώστε να υποστηρίξει τους τελεστές αλήθειας της ALGOL /\ και \/.[19]

1962: ALCOR - Αυτό το σύνολο χαρακτήρων περιλάμβανε τον ασυνήθιστο χαρακτήρα "" (iron/runic cross) και το σύμβολο "⏨" (Decimal Exponent Symbol) για το συμβολισμός κινητής υποδιαστολής. [20]

1964: GOST - Το Ρωσικό πρότυπο GOST 10859 του 1964 επέτρεπε την κωδικοποίηση χαρακτήρων 4-bit, 5-bit, 6-bit και 7-bit characters στην ALGOL.[21]

1968: Η αναφορά ("Algol 68 Report") - έκανε χρήση των ήδη υπαρχόντων χαρακτήρων της ALGOL, και αργότερα υιοθέτησε τους χαρακτήρες →, ↓, ↑, □, ⌊, ⌈, ⎩, ⎧, ○, ⊥ και ¢ του πληκτρολογίου IBM 2741 με τις κεφαλές εκτύπωσης τύπου "golf-ball" (όπως και στην APL), που ήταν διαθέσιμοι στα μέσα της δεκαετίας του 1960, όσο προδιαγραφόταν η ALGOL 68. Η αναφορά μεταφράστηκε στα Ρώσικα, τα Γερμανικά, τα Γαλλικά και τα Βουλγάρικα, και επέτρεπε τον προγραμματισμό σε γλώσσες με μεγαλύτερα σύνολα χαρακτήρων, όπως το Κυριλλικό αλφάβητο του Ρωσικού BESM-4. Όλοι οι χαρακτήρες της ALGOL είναι επίσης μέρος του προτύπου unicode και οι περισσότεροι από αυτούς είναι διαθέσιμοι σε πολλές από τις γνωστές γραμματοσειρές.

2009, Οκτώβριος: Unicode - Το "⏨" (Decimal Exponent Symbol) του συμβολισμού αριθμών κινητής υποδιαστολής προστέθηκε στο Unicode 5.2 για συμβατότητα με ιστορικό λογισμικό σε ALGOL για το διαστημόπλοιο Μπουράν.

Remove ads

Δείτε επίσης

Αναφορές

Περαιτέρω διάβασμα

Εξωτερικοί σύνδεσμοι

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads