Δευτέρα 26 Φεβρουαρίου 2018

Εκτέλεση Παραστάσεων και Κλήση συνάρτησης.

Ακολουθεί ένα παράδειγμα που σχετίζεται με την εκτέλεση παραστάσεων, με το σωρό τιμών στο πρώτο μέρος, και στο δεύτερο καθαρά σε σχέση με τις προτεραιότητες τελεστών. Η εντολή Διακόπτες λειτουργεί στη κονσόλα, αλλά μπορούμε να την καλέσουμε με την Θέσε Διακόπτες και σε τμήμα (πρόγραμμα της Μ2000). Εδώ την χρησιμοποιούμε για να αλλάξουμε το εξ ορισμού τρόπο χρήσης των Διά και Υπόλ ή Υπόλοιπο (και των Δια# και Υπόλ# ή Υπόλοιπο#, για ευκλείδια διαίρεση και υπόλοιπο). Ο εξ ορισμού διακόπτης είναι ο -DIV. O +DIV κάνει την Μ2000 να λειτουργε όπως η Python και το Excel.
Η χρήση προσήμου είναι ίδια όπως στο Excel, δηλαδή το -3^2 δίνει 9 (ενώ η VB6 δίνει -9)


\\ Μέρος Πρώτο
\\ Κατανόηση του σωρού τιμών κατά την κλήση
\\ Σκοπός είναι να αντιληφθεί ο αναγνώστης ότι αυτός που καλεί διαβάζει τον τρέχον σωρό

\\ Η συνάρτηση που καλείται έχει δικό της τρέχον σωρό.
\\ Θέλουμε να εκτελέσουμε αυτό Κύβος(1+Κύβος(2)+Κύβος(3))
\\ αλλά τα 1,2,3 θα τα πάρουμε από το σωρό τιμών, απευθείας με την Αριθμός
\\ η Αριθμός σηκώνει την κορυφή του σωρού, αν είναι αριθμός αλλιώς βγάζει λάθος.
\\ "σηκώνει" σημαίνει εδώ ότι επιστρέφει την τιμή ενώ αυτή δεν υπάρχει πια στο σωρό
\\ ο σωρός θα δείχνει την επόμενη, ως νέα κορυφή, αν υπάρχει αλλιώς θα είναι κενός.
Άδειασε
Συνάρτηση Κύβος(κ) {
      Σειρά 1,2,3
      =κ**Μέγεθος.Σωρού
      \\ τα επιπλέον νούμερα θα χαθούν με την επιστροφή από τη συνάρτηση
}
Σειρά 1,2,3
\\ η αριθμός διαβάζει από τη κορυφή του σωρού
\\ η κορυφή εδώ είναι το 1
Σωρός  ' μας δείχνει το σωρό
\\ Ο διερμηνευτής πάντα εκτελεί από αριστερά προς τα δεξιά,
\\ ενώ κρατάει τις προτεραιότητες όπως πρέπει
\\ εδώ θα καλέσει την Κύβος αλλά δεν θα την εκτελέσει αν δε δώσει το αποτέλεσμα της έκφρασης
\\ η έκφραση διαβάζει πρώτα την κορυφή του σωρού (της εντολής όχι της Κύβος())
\\ μετά εκτελεί την πρόσθεση στέλνοντας την υπόλοιπη έκφραση για εκτέλεση
\\ έτσι ξεκινάει η εκτέλεση του Κύβος(Αριθμός)+Κύβος(Αριθμός), με το τρέχον σωρό
\\ βρίσκει πάλι την Κύβος() και ξεκινάει να εκτελέσει την έκφραση που βρίσκει,
\\ και εδώ είναι μόνο η αριθμός, άρα διαβάζει το 2 και εκτελεί την Κύβος()
\\ μετά βλέπει το + και ξεκινάει να εκτελεί την υπόλοιπη έκφραση Κύβος(Αριθμός)
\\ Πάλι εδώ βρίσκει την Κύβος() και εκτελεί την έκφραση εντός των παρενθέσεων,
\\ δηλαδή την Αριθμός και τραβάει το 3 από το σωρό.
\\ Τώρα το αποτέλεσμα της Κύβος(3) θα επιστραφεί και θα προστεθεί στο
\\ αποτέλεσμα της Κύβος(2) και αυτό θα επιστραφεί και θα προστεθεί στο 1
\\ το αποτέλεσμα αυτό θα γινει ο αριθμο που θα μπει στη Κύβος(),
\\ και θα μας δώσει το αποτέλεσμα 46656
Τύπωσε Κύβος(Αριθμός+Κύβος(Αριθμός)+Κύβος(Αριθμός)) ' 46656
Τύπωσε Κύβος(1+Κύβος(2)+Κύβος(3))
Τύπωσε (1+2**3+3**3)**3
Τύπωσε (1+2^3+3^3)^3 ' η δύναμη γράφεται και με ^
Σειρά 1,2,3
Τύπωσε (Αριθμός+Αριθμός^3+Αριθμός^3)^3
\\ πρώτα εκτελείται η παρένθεση και μετά η ύψωση σε δύναμη
\\ και η συνάρτηση το ίδιο κάνει αλλά την "γνωρίζει" ο διερμηνευτής,
\\ πριν εκτελέσει τα περιεχόμενα στις παρενθέσεις, και την εκτελεί αφού μαζέψει τις τιμές
\\ και τις βάλει σε ένα σωρό μόνο γι' αυτήν.
\\ Εδώ με χρήση της Βάλε, οπότε η κάθε τιμή πάει στη κορυφή
\\ άρα πάνε "ανάποδα", το 3 στη κορυφή, αμέσως μετά το 2 και τελευταίο το 1
\\ δηλαδή το πρώτο που θα μπει θα βγει τελευταίο.
Βάλε 1, 2, 3
\\ η κορυφή εδώ είναι το 3
Σωρός
Τύπωσε Κύβος(Αριθμος+Κύβος(Αριθμός)+Κύβος(Αριθμός)) ' 1728
Τύπωσε Κύβος(3+Κύβος(2)+Κύβος(1)) ' 1728

\\ Εσκεμμένο λογικό λάθος
\\ εξ ορισμού δεν γίνεται έλεγχος για τον αριθμό και τον τύπο των τιμών που δίνουμε στις κλήσεις
\\ στην συνάρτηση όμως αν η Διάβασε περιμένει αριθμό και διαβάσει αλφαριθμητικό θα βγάλει λάθος
\\ όμως αν δώσουμε και άλλες παραμέτρους και δεν τις διαβάσει ο κώδικας ...
\\ θα μείνουν εκεί μέχρι να καταργηθεί ο σωρός (καταργείται στην επιστροφή από τη συνάρτηση),
\\ η αν σβηστούν πιο πριν με μια άδειασε
Τύπωσε Κύβος(3,0)
\\ Δίνει 81 γιατί εξαρτιέται η δύναμη από το μήκος του σωρού.
\\ Εδώ βάλαμε μια παράμετρο παραπάνω, άρα έχουμε τέσσερις όταν διαβάζουμε το μέγεθος του σωρού
\\ και ισοδυναμεί με αυτό
Τύπωσε 3*3*3*3=81 ' δίνει -1 δηλαδή αληθές
\\ Μέρος Δεύτερο
\\ Σκοπός είναι να αντιληφθεί ο αναγνώστης ότι το διάβασμα του κώδικα, γίνεται από αριστερά προς τα δεξιά, ενώ η εκτέλεση των παραστάσεων γίνεται μετά το διάβασμα την ώρα που πρέπει!
\\ Ο διερμηνευτής:
\\ 1. Κάνει πρώτα ένα γρήγορο πέρασμα από αριστερά προς τα δεξιά, χωρίς να εκτελέσει κώδικα,
\\ ούτε να δει αν τα αναγνωριστικά είναι σωστά, απλά για να διαπιστώσει τι παράσταση υπάρχει: αριθμητική ή αλφαριθμητική,
\\ και που τελειώνει.
\\ 2. Περνάει την παράσταση για εκτέλεση στον εκτελεστή παραστάσεων ανάλογα, για αριθμούς ή για αλφαριθμητικά.
\\ Αυτοί εκτελούν με ένα πέρασμα, και ενδέχεται να καλέσουν και άλλες φορές τον ένα ή τον άλλο
\\ Γίνεται χρήση της Reentrant ή Επανεισόδου, που σημαίνει ότι πριν τελειώσει η συνάρτηση εκτέλεσης παραστάσεων μπορεί να κληθεί ξανά,
\\ και θα λειτουργήσει με άλλες τοπικές μεταβλητές. Μεταβλητές τοπικές δηλαδή που κρατάει λογαριασμό για τις μέχρι εκείνη τη στιγμή εκτελέσεις πράξεων.
\\ Ο διερμηνευτής εκτελεί σωστά τις εκφράσεις, βάσει προτεραιοτήτων, τις οποίες δεν τις υπολογίζει προκαταβολικά, αλλά είναι ο κώδικας έτσι γραμμένος που βγαίνουν!
\\ Πάντα διαβάζει το κώδικα από αριστερά προς τα δεξιά, παρόλο που στην επιστροφή κάνει τα απαραίτητα
\\ για να διατηρεί τις προτεραιότητες, αποθηκεύοντας τιμές σε τοπικές μεταβλητές μια συνάρτησης εκτέλεσης.
\\ εδώ θέλουμε το 2^2 να εκτελεστεί ως 4 και μετά το 10*4 να δώσει 40,
\\ επειδή η δύναμη έχει μεγαλύτερη προτεραιότητα από το γινόμενο
\\ Πάλι ο διερμηνευτής εκτελεί από αριστερά προς δεξιά, δείτε πώς:
\\ Πρώτα βρίσκει το 10 και το βάζει στην άκρη. Μετά βρίσκει το "*" που δηλώνει γινόμενο και το βάζει και αυτό στην άκρη
\\ μετά βρίσκει το 2 και το βάζει και αυτό στην άκρη. Αν δεν έχει τίποτα άλλο θα δώσει το 10*2
\\ βλέπει όμως ότι έχει την ύψωση σε δύναμη. Θα δει αν μετά το σύμβολο έχει παρένθεση,
\\ αν ναι τότε θα εκτελέσει την έκφραση στη παρένθεση και το αποτέλεσμα θα είναι η δύναμη που θα υψώσει το 2,
\\ θα βρει το αποτέλεσμα και θα εκτελέσει το γινόμενο με το 10, και τώρα πάει για το επόμενο,
\\ θα βρει το + και θα εκτελέσει την έκφραση (4*4). Θα βρει την παρένθεση, και θα εκτελέσει την έκφραση 4*4
\\ θα βρει το 4 και θα το βάλει στην άκρη, θα βρει το * και θα το βάλει στην άκρη, θα βρει το 4 και θα εκτελέσει τον πολλαπλασιασμό,
\\ με αποτέλεσμα 16, θα πετάξει το κλείσιμο παρένθεσης ")", και το νούμερο θα επιστραφεί,
\\ έτσι θα προστεθεί στο προηγούμενο 40 και θα δώσει 56.
Τύπωσε 10*2^2+4*4 ' 56
Τύπωσε 10*(2^2)+(4*4) '56
Τύπωσε (10*2)^2, 10*2^2, 10*(2^2) ' 400 40 40
\\ Οι συγκρίσεις έχουν μεγαλύτερη προτεραιότητα από τις πράξεις
\\ και εδώ η εκτέλεση θα γίνει από αριστερά προς τα δεξιά
\\ και πάλι όμως θα κρατηθούν μερικά αποτελέσματα για να βγουν οι προτεραιότητες
Τύπωσε 2*-3*2+100=2*(-(3*2))+100
Τύπωσε 2*+3*2+100=2*(+(3*2))+100
Τύπωσε 2*--3*2+100=2*(--(3*2))+100
Τύπωσε 2*--3*2+100=2*(-(-(3*2)))+100
Τύπωσε 2+3*2+100=2+(3*2)+100
Τύπωσε 2+3*-2+100=2+(3*(-2))+100
\\ Οι λογικοί τελεστές έχουν μεγαλύτερη προτεραιότητα από τις πράξεις και από τις συγκρίσεις
Τύπωσε 2+3*-2+100=2+(3*(-2))+100 Και Ψευδές ' δίνει 0
\\ Ο διερμηνευτής της Μ2000 δεν χρειάζεται πολλές παρενθέσεις
\\ Επειδή πάντα εκτελεί με τον ίδιο τρόπο, από αριστερά προς τα δεξιά, δεν υπάρχει μπέρδεμα.
Τύπωσε 2+3*-2+100=2+3*-2+100 Και 1000-900-50=1000-900-50 ' δίνει -1
Τύπωσε 2+3*-2+100=2+(3*(-2))+100 Και 10*5=1000-900-50 ' δίνει -1
Τύπωσε (2+3*-2+100=2+(3*(-2))+100) Και ((10*5)=(1000+(-900)+(-50))) ' δίνει -1
Τύπωσε "Α"<"α" ' Δίνει αληθές  -1
Τύπωσε "Α"<"α" Ή 5>100 ' Δίνει αληθές -1 γιατί το πρώτο είναι αληθές
\\ Αφού εκτελεστεί η πρώτη παράσταση, η Τύπωσε βρίσκει το κόμμα και κοιτάει αν υπάρχει άλλη
\\ το κόμμα στην Τύπωσε δεν λέει υποχρεωτικά πάρε άλλη τιμή, απλά μεταθέτει σε νέα στήλη...
\\ το δρομέα της οθόνης ή της σελίδας του εκτυπωτή, ή σε ένα επίπεδο που το χρησιμοποιούμε για εξαγωγή.
\\ Κάθε παράθυρο χρήστη έχει ένα επίπεδο και η Κονσόλα έχει 32 ακόμα, συν το περιθώριο και τη σελίδα του εκτυπωτή 34.
Τύπωσε "Α"<"α" Ή 5>100, "Α">"α" Ή 5<100 ' δίνει και τα δύο αληθές
\\ Εξ ορισμού ο διακόπτης DIV είναι στο -DIV
\\ Αν τον αλλάξουμε σε +DIV τότε το Υπολ και το Δια έχουν την ίδια προτεραιότητα με το / και το *
\\ Οπότε θα πάρουμε διαφορετικά αποτελέσματα!
Θέσε Διακόπτες "-DIV"
\\ Το Υπόλοιπο διαίρεσης έχει μεγαλύτερη προτεραιότητα από το / και το *
\\ Το Υπολοιπο επιστρέφει τιμές όπως στην Visual Basic 6 αν δουλεύει με ακέραιες τιμές
\\ (στη Μ2000 δουλεύει και με πραγματικούς)
Τύπωσε 103 Υπολ 8/2 = 103 Υπόλοιπο 4 ' δίνει -1, Υπολ και Υπόλοιπο και Υπολοιπο είναι το ίδιο
Τύπωσε 103 Υπολ 8=103 Υπόλοιπο (10-2) ' δίνει -1

Τύπωσε 103 Υπολ 8=103 Υπόλοιπο 10-2 ' δίνει 0
\\ Η δύναμη συνεχίζει να έχει μεγαλύτερη προτεραιότητα
Τύπωσε 103 Υπολ 2**2=103 Υπόλ 16/2**2 ' δίνει -1
Τύπωσε (103 Υπολ (2**2))=(103 Υπόλ (16/(2**2))) ' δίνει -1
Τύπωσε 103 Υπολ 2**3=103 Υπόλ 16/2 ' δίνει -1
Τύπωσε 103 Υπολ 16/2=7 ' -1
Τύπωσε 3 Υπολ 2, -3 Υπολ 2, 3 Υπολ -2, -3 Υπολ -2
Τύπωσε 3 Υπολ# 2, -3 Υπολ# 2, 3 Υπολ# -2, -3 Υπολ# -2 ' Ευκλείδιο υπόλοιπο, είναι πάντα θετικό
Θέσε Διακόπτες "+DIV"
\\ Δουλεύει όπως στην Python, το * και / έχουν ίδια προτεραιότητα με το Υπόλοιπο
\\ Το Υπόλοιπο ή Υπολ δουλεύει όπως του Excel η συνάρτηση Mod()  (με +DIV στην Μ2000)
Τύπωσε 103 Υπολ 16/2=3.5 ' -1
Τύπωσε 3 Υπολ 2, -3 Υπολ 2, 3 Υπολ -2, -3 Υπολ -2
Τύπωσε 3 Υπολ# 2, -3 Υπολ# 2, 3 Υπολ# -2, -3 Υπολ# -2 ' Ευκλείδιο υπόλοιπο, είναι πάντα θετικό

Θέσε Διακόπτες "-DIV"  ' το επαναφέρουμε
\\ Περί προσήμων η Μ2000 ακολουθεί το σύστημα του Excel και όχι της VB6
Τύπωσε -3^2 ' δίνει 9 και όχι -9 γιατί το - είναι το πρόσημο του 3
Τύπωσε 0-3^2 ' δίνει -9 και όχι 9 γιατί το - είναι η αφαίρεση
Τύπωσε 0-++++-3^2=0-++++(-3^2) ' -1 αληθές
Τύπωσε 0-++++-3^2=0-+--+(-3^2) ' -1 αληθές
Τύπωσε ---2, --2, -2 ' -2 2 -2
Τύπωσε 0---2, 0--2, 0-2 ' -2 2 -2
Τύπωσε 0-3^2, 0-(--3^2), 0-(---3^2) ' -9 -9 -9
Τύπωσε 0-3^2, 0---3^2, 0----3^2 ' -9 -9 -9
Τύπωσε 0+3^2, 0+--3^2, 0+---3^2 ' 9 9 9  ' ο πρώτος τελεστής είναι η πράξη, οι άλλοι δίνουν το πρόσημο
Τύπωσε 0+3^3, 0+--3^3, 0+---3^3 ' 27 27 -27  ' ο πρώτος τελεστής είναι η πράξη, οι άλλοι δίνουν το πρόσημο
Τύπωσε 10-3^2 ' δίνει 1  το - είναι η αφαίρεση
Τύπωσε 10+-3^2 ' δίνει 19  το - είναι το πρόσημο του 3
Τύπωσε --(25)=-5*-5 ' -1




Πέμπτη 22 Φεβρουαρίου 2018

Χρήση Διάρθρωσης για κείμενο 8bit και μετατροπές κωδικοσελίδας

Το παρακάτω πρόγραμμα το γράφουμε σε ένα τμήμα έστω Α (με Σ Α + enter και μετά επικόλληση και πατάμε Esc) και μετά το τρέχουμε.
Τι κάνει;
Φτιάχνει μια διάρθρωση μνήμης με bytes (ψηφία) και βάζει από το 32(33ή θέση) έως το 255 όλα τα νούμερα από 32 έως 255. Υποθέτουμε ότι αυτοί είναι χαρακτήρες σε Ρώσικα 8 Bit  σε κωδικοσελίδα 1049. Πραγματικά δεν ξέρουμε τι είναι αν δε μας πουν τι είναι!
Υπάρχει τρόπος να διαβάσουμε το αλφαριθμητικό από την διάρθρωση δίνοντας τη θέση του πρώτου ψηφίου και τον αριθμό των ψηφίων που θα διαβαστεί, στην συνάρτηση Εκφρ$(). Αυτή η συνάρτηση παίρνει ότι του δίνουμε και τα γράφει σε ένα αλφαριθμητικό χωρίς καμία μετατροπή. Το αλφαριθμητικό όμως αν διαβαστεί έτσι θα βγει λάθος γιατί κανονικά διαβάζεται ως UTF16LE ενώ εμείς του έχουμε βάλει ASCII (ή πιο σωστά ANSI το οποίο όμως δεν το έχουμε μετατρέψει). Πράγματι αν διαβάσουμε το μήκος του Α$ θα μας δώσει 112 ενώ οι χαρακτήρες που έχουμε βάλει στην Διάρθρωση είναι 225 (τα 32 πρώτα δεν τα χρησιμοποιούμε)
Παραβλέπουμε για την ώρα μια επιπλέον μετατροπή αν η Ansi κωδικοσελίδα στο σύστημα δεν είναι η ελληνική (το βρίσκουμε βλέποντας αν το Γ είναι το 195).
Η  Χαρ$(αλφαριθμητική παράσταση) κάνει μετατροπή και ανοίγει τους χαρακτήρες από εκεί που ήταν δυο σε μια θέση τους κάνει ένα σε κάθε θέση των δυο ψηφίων (bytes). Γράφουμε το Β$ και τώρα το μήκος του είναι 224, όπως πρέπει δηλαδή.
Δείχνουμε ότι μπορούμε να βλέπουμε το Β$  με διαφορετική κωδικοσελίδα, με λατινικά και με ρώσικα. Επιλέγουμε τα ρώσικα και το Α$ έχει τώρα ρώσικα. Δηλαδή τελικά από την Διάρθρωση διαβάσαμε ρώσικα των 8bit ANSI σε αλφαριθμητικό που τώρα είναι σε UTF16LE.
Τώρα θα κάνουμε το ανάποδο, θα πάρουμε αυτούς τους 224 χαρακτήρες των δύο ψηφίων ο καθένας και θα τους κάνουμε 224 του ενός ψηφίου το καθένα. Και θα βάλουμε αυτούς τους χαρακτήρες στην διάρθρωση και θα κάνουμε έλεχγο αν τα νούμερα είναι όπως πρέπει πχ στη θέση 100 θα είναι το 100, στη θέση 150 το 150. Ήδη έχουμε μηδενίσει την μνήμη με εγγραφή σε όλες τις θέσεις του 0.
Πάλι αφήνουμε την μετατροπή που χρειάζεται αν το σύστημα δεν είναι Ελληνικό (για μη unicode συστήματα).
Μας ενδιαφέρει να γυρίσουν τα νούμερα στα κανονικά (αλλά σε Utf16le) και όταν θα τα προβάλει η Τύπωσε θα βγουν Ελληνικά.
Βάζουμε το αλφαριθμητικό στη διάρθρωση και αυτό γίνεται με αντιγραφή των ψηφίων (bytes), χωρίς μετατροπή.
Τώρα ελέγχουμε σαρώνοντας την διάρθρωση, και αν υπάρχει λάθος θα βγεί λάθος και θα σταματήσει το πρόγραμμα.

Για τους υπολογιστές με λειτουργικό που δεν είναι στα ελληνικά έχουμε κάνει ήδη στο κώδικα τα απαιτούμενα:
1. Να βάλουμε το Τοπικό 0 που σημαίνει ότι σίγουρα θα διαβάζει τη στάνταρ κωδικοσελίδα (που δεν ξέρουμε ποια είναι, αλλά σίγουρα δεν είναι η ελληνική γιατί το Κωδ("Γ") δεν βγαίνει 195 όπως το βρίσκουμε παρακάτω). Δουλεύει και με Τοπικό 1032.
2. Αν δούμε ότι όντως δεν έχουμε ελληνική στανταρ σελίδα κάνουμε μια μετατροπή στη στανταρ με το 0. Αυτό συμβαίνει γιατί το άνοιγμα από ένα σε δυο ψηφία έγινε στα ελληνικά(έτσι έχει επιλεχθεί στη γλώσσα για να υπάρχει κάτι στανταρ).
3. Πάλι χρειάζεται στην ανάποδη μετατροπή μια διαφοροποίηση στη μέθοδο.

Το πρόγραμμα έχει ελεχθεί σε Window XP και 7 σε 32bit, και σε Windows 8 και 10 σε 64bit (με επιλεγμένη γλώσσα για μη Unicode τα αγγλικά), καθώς και σε Wine 1.8 (Ubuntu) (με υποστήριξη ελληνικών στα μη Unicode - εδώ δεν ξέρω και πώς αλλάζει αυτό, αλλά προφανώς το πήρε επειδή η γλώσσα του Ubuntu ειναι τα ελληνικά).



Τοπικό 0
Διάρθρωση Ascii ως ψηφίο*256
Για Ι=32 έως 255
      Επιστροφή Ascii, Ι:=Ι
Επόμενο Ι
Α$=Εκφρ$(Ascii, 32, 224)
Για Ι=32 έως 255
      Επιστροφή Ascii, Ι:=0
Επόμενο Ι
Τύπωσε Μήκος(Α$) ' 112  ' κάθε χαρακτήρας έχει δυο χαρακτήρες
Β$=Χαρ$(Α$) ' τώρα διπλασιάσαμε το μήκος και κάθε χαρακτήρας έχει έναν χαρακτήρα
' εδώ θα γίνει πάντα στα ελληνικά (επειδή έτσι κάνει ο διερμηνευτής και αυτό δεν αλλάζει)
Τύπωσε Μήκος(Β$) ' 224
Τύπωσε Β$ ' εμφανίζεται με την στανταρ κωδικοσελίδα
\\ ελέγχουμε αν είναι όντως ελληνικό το σύστημα για μη unicode
\\ αν δεν είναι δεν βγαίνει το Γ ως 195, και τότε κάνουμε μια μετατροπή ακόμα
Αν Κωδ("Γ")<>195 Τότε Β$=Γραφή$(Β$,0)
\\ μετατρέπουμε τους κωδικούς Ascii σε Unicode βάσει κωδικοσελίδας
Τύπωσε Χαρ$(Β$, 1033) ' εμφανίζεται με την 1033 (λατινικά με τόνους)
Τύπωσε Χαρ$(Β$, 1049) ' εμφανίζεται με ρώσικα.
\\ καθαρίζουμε την μνήμη
Α$=Χαρ$(Β$, 1049) ' τώρα το Α$ έχει 224 χαρακτήρες unicode ρώσικους!
Β$=Γραφή$(Α$, 1049) ' μετατρέπουμε από την 1049 στην 1033
\\ πάλι ελέγχουμε το Γ και αν δεν είναι 195 κάνουμε μετατροπή στα ελληνικά
Αν Κωδ("Γ")<>195 Τότε {
      Β$=Χαρ$(Β$, 1032)
} Αλλιώς Β$=Χαρ$(Β$, 0) ' τώρα γυρνάει στο κανονικό (θέλουμε ελληνικά)
\\ όπως και να έχει θα πάρουμε ελληνική κωδικοσελίδα εδώ
\\ τώρα μπορούμε να τα βάλουμε στη διάθρωση.
Τύπωσε Β$
Τύπωσε Μήκος(Β$) ' 224
Β$=Γραφη$(Β$)
Τύπωσε Μήκος(Β$) ' 112 τώρα βάλαμε δυο χαρακτήρες σε κάθε έναν
Επιστροφή Ascii, 32:=Β$ ' Βάζουμε πίσω στη μνήμη τα ψηφία
Για ι=32 έως 255
      Αν Εκφρ(Ascii, ι)<>ι τότε Λάθος "έκανες λάθος"
Επόμενο ι
Τύπωσε
Τύπωσε Α$



Ανανεωμένο Παράδειγμα Παραθύρων

Κατά την αναθεώρηση του Μικρού Εγχειριδίου (θα βγει κάποια στιγμή με ημερομηνία >= 22-2-2018), έκανα ανανέωση στο παρακάτω πρόγραμμα.

Αν την Τίτλος "Παράδειγμα", 0 την έχουμε σε εκτελέσιμη γραμμή (τώρα είναι στην Σημείωση), θα αφαιρέσει την κοσνόλα και θα ξεκινήσουμε με τρία παράθυρα.

Αν η ΘέασηΓεγονότων γίνει αληθής τότε τα μηνύματα από τα γεγονότα θα έρχονται πρώτα σε μια συνάρτηση Φορμα100() θα μας τα εμφανίζει στην κονσόλα και θα τα καλεί μετά. (Εξαιρούνται μηνύματα που επιστρέφουν τιμές, όπως το unload)

Σε κάθε φόρμα μπορούμε να ζωγραφίσουμε κύκλους με αριστερό κλικ στο ποντίκι. Με δεξί κλικ εξαφανίζουμε τον τίτλο της φόρμας (έτσι δεν μπορούμε να την μετακινήσουμε).

Στις φόρμες έχουμε δυο πλήκτρα. Σε μια φόρμα έχουμε ένα νήμα που ζωγραφίζει γραμμές. Μπορούμε να ζωγραφίζουμε σε όποια φόρμα θέλουμε και το νήμα θα ζωγραφίζει "μόνο του".

Παράλληλα εμφανίζουμε την ώρα στην κονσόλα κάθε δευτερόλεπτο (Κάθε 1000 σημαίνει κάθε 1000 χιλιοστά του δευτερολέπτου).

Στη φόρμα με την "ζωγραφική γραμμών" τα δυο πλήκτρα ελέγχουν το νήμα για την ώρα. Το ένα το σταματάει και το άλλο το εκκινεί.

Σε μια άλλη φόρμα έχουμε και τα δυο πλήκτρα να κάνουν έξοδο, δηλαδή να κλείνουν τις φόρμες και να βγάζουν τον διερμηνευτή στη γραμμή εντολών της Μ2000 (στη κονσόλα).

Σε μια άλλη φόρμα έχουμε ένα πλήκτρο που απλά εμφανίζει το όνομά του όταν το επιλέγουμε και ένα άλλο που ανήγει την φόρμα Έλεγχος. Εκεί κάνουμε κλικ στο Αργή Ροή και βλέπουμε το κώδικα όπως εκτελείται στα νήματα. Μπορούμε να χειριστούμε τις φόρμες και σε κάθε περίπτωση η φόρμα ελέγχου θα μας δείχνει τις εντολές της Μ2000 που εκτελούνται.

Η πρώτη εντολή Οθόνη,0 καθαρίζει τη οθόνη της κονσόλας και θέτει στην πρώτη γραμμή την "χωριστή οθόνη" ή "split screen". Η κοσνόλα έχει ένα σταθερό μέρος και ένα που ολισθαίνει στο κάτω μέρος. Αυτό καθορίζεται από μια γραμμή και έτσι με το 0 λέμε όλη η οθόνη να ολισθαίνει. Αυτό ισχύει και σε κάθε φόρμα, γιατί κάθε φόρμα έχει μια "οθόνη". Η διαφορά της οθόνης στη φόρμα είναι ότι δεν δέχεται εντολές εισαγωγής, πρέπει να χρησιμοποιήσουμε τα στοιχεία ελέγχου.

Όπως γίνεται φανερό στη Μ2000 μπορούμε να έχουμε ταυτόχρονα Κονσόλα και Παράθυρα. Αυτό συμβαίνει γιατί η κονσόλα είναι και αυτή ένα παράθυρο αλλά έχει διαφορετικό χειρισμό (δεν έχει γεγονότα)

Τα νήματα είναι μέρη του τμήματος που φτιάχτηκαν και εκτελούνται με χρονοδρομολογητή (ενσωματωμένο στο περιβάλλον της Μ2000). Κάθε νήμα έχει ένα νούμερο το οποίο μπορούμε να το κρατάμε σε μεταβλητή. Αυτή η μεταβλητή λέγεται Χειριστής του νήματος (Handler). Μέσα από ένα νήμα μπορούμε να χρησιμοποιήσουμε το Αυτό ως χειριστή αντί για νούμερο. Υπάρχει εδώ μια εντολή Εκτέλεση για νήμα. Αυτή η εντολή εκτελείται άμεσα στο νήμα, και εδώ λέμε να σβήσει. Αυτή η εντολή εκτελείται μέσα από συνάρτηση που εκκινεί από γεγονός.

Η εντολή Επίπεδο στέλνει εντολές οθόνης στο επιλεγμένο επίπεδο (οθόνη στην ουσία). Κάθε φόρμα έχει δικό της επίπεδο και εκεί δίνουμε τις εντολές για γραφικά. Όταν φτιάχνουμε ένα νήμα τότε το νήμα κρατάει το επίπεδο στο οποίο φτιάχτηκε και έτσι όλες οι εντολές προς την οθόνη πάνε σε αυτό το επίπεδο. Αν θέλουμε να αλλάξουμε πρόσκαιρα επίπεδο μπορούμε να βάλουμε την εντολή Επίπεδο. Αν σε αυτήν δεν δώσουμε το επίπεδο που θέλουμε τότε εννοείται ότι είναι η κονσόλα. Η εντολή ανανέωση χρειάζεται για να ανανεώνει τις αλλαγές της οθόνης όταν η συγκεκριμένη οθόνη (ή επίπεδο) δεν βρίσκεται στο προσκήνιο (είναι μια πίσω φόρμα μη επιλεγμένη). Ουσιαστικά το σύστημα των παραθύρων έχει διπλή μνήμη, μια που εμφανίζεται άμεσα και μια που παίρνει τις αλλαγές μέχρι να γίνει αυτόματα ή μη η ανανέωση. Οι ανανεώσεις είναι "χρονοβόρες" και ο έλεγχός τους είναι καλός για να ετοιμάζουμε κάτι γρήγορα και μετά να το δείχνουμε. Μπορούμε πρόσκαιρα να αλλάξουμε τον χρόνο επόμενης ανανέωσης με μια Ανανέωση 5000 (βάζουμε την επόμενη σε 5 δευτερόλεπτα) και αφού κάνουμε ότι θέλουμε (χωρίς να φανεί) σε ένα επίπεδο καλούμε την Ανανέωση 100 για να εμφανίσει τα γραφικά, μέχρι την επόμενη φορά που θα χειριστούμε πάλι την ανανέωση. Εδώ δεν χρειάζεται κάτι τέτοιο και απλά η Ανανέωση καλείται χωρίς αριθμό.






Οθόνη,0
\\ αν δεν θέλουμε να βλέπουμε τη κονσόλα, μπορούμε να την κρύψουμε!
\\ αν ξεκινήσουμε το πρόγραμμα από gsb αρχείο, τότε η κονσόλα δεν ανοίγει
\\ χωρίς της εντολή Άναψε
\\ Μετά το Σημ 1 : πατήστε Enter για να μπει η Τίτλος σε εκτελέσιμη γραμμή!
Σημ 1 : Τίτλος "Παράδειγμα", 0
Ν=3
ΘέασηΓεγονότων= Ψευδές \\Αληθές
\\ Με την ΘέασηΓεγονότων=Αληθές το σύστημα στέλνει μηνύματα στο γεγονός Βασικό
\\ το οποίο δημιουργεί στον ορισμό της φόρμας.
\\ Σε αυτό συνδέουμε μια συνάρτηση (στην ουσία ένα μέρος του τμήματος)
\\ που καλείται κάθε φορά που συμβαίνει ένα γεγονός.
\\ Γεγονότα που ζητούν επιστροφή τιμής (όπως το unload) δεν στέλνονται σε αυτό.

Αν ΘέασηΓεγονότων Τότε {
      Όρισε Φόρμα1(Ν) Φόρμα Γεγονός Βασικό
} Αλλιώς Όρισε Φόρμα1(Ν) Φόρμα
Κλάση Πλήκτρα {
      Πίνακας Πληκτρο()
}
Πίνακας Στοιχεία(Ν)=Πλήκτρα()

Για ι=0 Έως Ν-1 {
      Για Στοιχεία(ι) {
            Όρισε Πλήκτρο1(2) Πλήκτρο Φόρμα Φόρμα1(ι)
            Για j=0 Έως 1 {
                  Μέθοδος Πλήκτρο1(j), "move", 1000+4000*j, 2000,3000,1000
            }
            .Πληκτρο()=Πλήκτρο1()
      }
     Επίπεδο Φόρμα1(ι) {
            Φόντο 1,4
            Δρομέας 0,2
            Αναφορά 2, "Γεια χαρά"
            Κίνηση.Π 2000+ι*3000, 2000+ι*3000
     }
      Μέθοδος Φόρμα1(ι), "Show"
}

Φόρμα1_1=Αληθές
Για Στοιχεία(0) {
      Με .Πληκτρο(0), "Caption","Έξοδος"
      Με .Πληκτρο(1), "Caption","Έξοδος"
}
Για Στοιχεία(1) {
      Με .Πληκτρο(0), "Caption","Σταμάτησε Εμφάνιση"
      Με .Πληκτρο(1), "Caption","Εμφάνιση Ώρας"
}
Για Στοιχεία(2) {
      Με .Πληκτρο(0), "Caption","Δείξει το πλήκτρο"
      Με .Πληκτρο(1), "Caption","Άνοίγμα Ελέγχου"
}
Με Φόρμα1(0), "visible" Ως θεατό

ΚλείσεΑυτήΤηΦόρμα=0
Συνάρτηση ΚλείσεΜετά {
      Αν Ρώτα("Να κλείσω τη Φόρμα?")=1 Τότε {
      Αν ΚλείσεΑυτήΤηΦόρμα=1 Τότε Φόρμα1_1=Ψευδές
      Μέθοδος Φόρμα1(ΚλείσεΑυτήΤηΦόρμα), "CloseNow"
      }
}

\\ το γεγονός Unload έχει κάτι ιδιαίτερο
\\ παίρνει πίσω την τιμή του άκυρο
\\ αυτό δεν έρχεται από το Γεγονός Βασικό (αν ορίσαμε να υπάρχει)
\\ αλλά απευθείας καλείται από τη φόρμα, για να πάρει "απόκριση"
Συνάρτηση Φόρμα1.Unload {
      Διάβασε Νέο ποιο, &άκυρο
      άκυρο=Αληθές \\ ακυρώνουμε το Unload
      ΚλείσεΑυτήΤηΦόρμα=ποιο
      \\ και καλούμε μετά 50 χιλιοστά του δευτερολέπτου
      \\ άλλη ρουτίνα ασύγχρονα - γιατί θα έχει πια τερματίσει το γεγονός
      \\ Η Μετά φτιάχνει ένα αυτόματο νήμα που εκτελείται μια φορά και σβήνει
      Μετά 50 { Κάλεσε Τοπικά ΚλείσεΜετά() }
}
Συνάρτηση Πλήκτρο1.Click {
      Διάβασε Κ, Λ
      Τύπωσε "Φόρμα:";Λ,"Πλήκτρο:";Κ
      Αν Ενημέρωση=0 τότε εξοδος
      Για Στοιχεία(Λ) {
           Με .Πληκτρο(Κ), "Caption"  Ως ονομα$
           Τύπωσε ονομα$
           Αν Κ=1 και Λ=2 Τότε {
                 Δοκιμή "Δες Κώδικα" \\ ανοίγει η φόρμα δοκιμής
                 Ανανέωση \\ αυτό για την κοσνόλα
          } Αλλιώς.αν Λ=1 τότε {
              Αν Κ=0 τότε {
                νήμα Ενημέρωση κράτα
                Τύπωσε "Η εμφάνιση ώρας σταμάτησε"
                Ανανέωση
                } Αλλιώς {
                Τύπωσε "Ξεκινώ την εμφάνιση ώρας"
                νήμα Ενημέρωση ξεκίνα
                  }
         } Αλλιώς.αν Λ=0 τότε {
               Δες {
                   \\ εκτελούμε την εντολή μέσα στο νήμα
                   \\ αν δεν υπάρχει βγάζει λάθος
                   \\ Δεν παίζει το Νήμα Ενημέρωση Σβήσε
                   \\ γιατί το νήμα  βρίσκεται σε άλλο αντικείμενο εκτέλεσης
                   \\ και όχι σε αυτό του γεγονότος
                   \\ το νήμα αυτό σβήσε ..καλεί άμεσα το νήμα και το σβήνει!
                   \\ μέσω του Task Manager της Μ2000
                   νήμα Ενημέρωση Εκτέλεση νήμα αυτό σβήσε
                   \\ όταν σβήσει το νήμα τότε το Κύριο Έργο θα τερματίσει υποχρεωτικά!
                  }
         }
     }
}
Συνάρτηση Φόρμα1.MouseMove {
      Διάβασε Κ, Πλήκτρο, πλ_shift, Χ, Υ
      Αν Πλήκτρο=1 Τότε {
           Επίπεδο Φόρμα1(Κ) {
                  Θέση Χ, Υ
                  Κύκλος 500, 1, 14-Κ
            }
      }
}
Συνάρτηση Φόρμα1.MouseDown {
      Διάβασε Κ, Πλήκτρο, Shift, Χ, Υ
      \\ εδώ θα μπούμε στα εσωτερικά της φόρμας
      \\ για να αφαιρέσουμε τον τίτλο
      \\ το πρώτο στοιχείο (0) είναι μια κουκίδα για την αλλαγή μεγέθους
      \\ το δεύτερο (1) είναι ο τίτλος και από εκεί συνεχίζουν όλα τα άλλα
      \\ και όλα είναι ίδια (εκτός της κουκίδας), το βασικό "εσωτερικό στοιχείο"
      \\ το πλήκτρο 2 είναι το δεξί πλήκτρο του ποντικιού
      Αν Πλήκτρο=2 Τότε {
                  Μέθοδος Φόρμα1(Κ), "Control", 1 Ως ΕσωτερικόΣτοιχείο
                  Με ΕσωτερικόΣτοιχείο, "visible" Ως εΘεατό
                  \\ δεν μπορούμε να χρησιμοποιήσουμε το εΘεατό~
                  \\ το εΘεατό δεν είναι μεταβλητή αλλά αντικείμενο proReference
                  \\ το βλέπουμε με το τυπος$(εΘεατό)
                  εΘεατό=όχι εΘεατό
      }
}
Συνάρτηση Φόρμα100 {
     Διάβασε ΚλήσηΓεγονότος$
    Τύπωσε ΚλήσηΓεγονότος$
     Δες { Κάλεσε Τοπικά ΚλήσηΓεγονότος$ }
}

\\\ εδώ ορίζουμε το γεγονός Βασικό να στέλνει την έξοδο σε μια συνάρτηση
\\ την βάζουμε με Οκν$() για να τρέχει σαν να είναι κώδικας του τμήματος
\\ ώστε να βρίσκει άλλες συναρτήσεις.
Αν ΘέασηΓεγονότων Τότε Γεγονός Βασικό Νέο Οκν$(&Φόρμα100())
Νήμα {
      Τύπωσε Γραφή$(Τώρα,"hh:mm:ss")
      Ανανέωση
} Ως Ενημέρωση Κάθε 1000

\\ εδώ είναι η κεντρική επανάληψη, η οποία είναι νήμα!
\\ ουσιαστικά δεν τρέχει κάτι εκτός νήματος
\\ εκτός το Φόρμα100 (που έχει το όνομα τμήματος - και όχι το ψεύτικο όνομα Φόρμα100)
\\ το οποίο εκτελεί τις παραγγελίες των γεγονότων (που δεν έχουν επιστροφή όπως το unload)
\\ Για να δουλέψει το Κύριο.Έργο χρειάζεται ένα τουλάχιστον νήμα εκτός από αυτό
\\ και έτσι έχουμε φτιάξει το Ενημέρωση (αυτή είναι μεταβλητή που κρατάει το νούμερο του νήματος)

Κύριο.Έργο 100 {

      Σημ 2 : Τύπωσε Τύπος$(θεατό), Τύπος$(Φόρμα1_1)
      Αν Όχι θεατό Τότε Έξοδος
  
      Αν Φόρμα1_1 Τότε {
             Επίπεδο Φόρμα1(1) {
                        Χάραξε Έως τυχαίος(χ.σημεία), τυχαίος(υ.σημεία)
            }
      }
}
\\ στην έξοδο το κύριο έργο σταματάει τα νήματα (αλλά όχι νήματα που ξεκίνησαν από νήματα)
\\ Μπορούμε να τα σβήσουμε όλα μαζί με την παρακάτω εντολή:
Νήματα Σβήσε
\\ το κύριο έργο βγαίνει εκτός αν σταματήσει το νήμα
\\  Καθαρισμός (ακόμα και αν τον ξεχάσουμε θα γίνει αυτόματα στην έξοδο από το τμήμα)
Για ι=0 Έως Ν-1 {
      Για Στοιχεία(ι) {
            Πίνακας .Πληκτρο()
      }
}
Όρισε Φόρμα1() Τίποτα
Τίτλος "Τέλος Παραδείγματος"
Άναψε  \\ επιστρέφει την Εστίαση στη κονσόλα




Εξαγωγή του αρχείου βοήθειας σε αρχείο Word

Εδώ είναι η εξαγωγή από το αρχείο βοήθειας της τελευταίας έκδοσης.

Μπήκαν και δυο σύνδεσμοι, ένα για το αγγλικό αρχείο και ένα για το ελληνικό στους συνδέσμους στη στήλη δεξιά.

Τα περιεχόμενα αυτών των αρχείων βρίσκονται στο αρχείο βοήθειας που μπορούμε να χρησιμοποιήσουμε με τις εντολές Βοήθεια και Help άμεσα από τον διερμηνευτή, και έμμεσα από τον ενσωματωμένο διορθωτή όταν επιλέγουμε μια λέξη και δώσουμε το Ctrl+F1 (ή σε Linux ανοίγουμε το μενού επιλογών και κατεβαίνουμε στην επιλογή Βοήθεια - δεν φαίνεται από την αρχή αλλά το μενού κυλάει για να δείξει και άλλες επιλογές).


Τα αρχεία αυτά θα ανανεώνονται, και οι σύνδεσμοι θα δείχνουν πάντα την τελευταία έκδοση.

Το Αγγλικό εδώ



Μπορούμε να ανανεώσουμε το αρχείο βοήθειας, φρεσκάροντας τις εντολές ανά κατηγορία με το παρακάτω πρόγραμμα. Τώρα δίνουμε το Βοήθεια Όλα και πάμε στη κεντρική σελίδα της βοήθειας. Εκεί έχουμε όλες τις κατηγορίες με όλες τις εντολές. Δουλεύει και σε Wine (Linux), αν έχουμε κάνει σωστά εγκατάσταση (αν η βοήθεια διαβάζεται τότε έχουμε κάνει σωστά).
Το παρακάτω το γράφουμε ως εξής: Edit "db_test.gsb" και αντιγράφουμε το κώδικα. Μετά γράφουμε Load db_test και το φορτώνουμε. Τέλος γράφουμε το CreateGeneralGroup και παράγεται το αποτέλεσμα.


MODULE GLOBAL CREATEGENERALGROUP {
      \* For each group we get a field in General Group
      \* Use module mg to create grouporder
      flush
      Dat \\ this is a module with group priorities
                  Read myGroups
                  Dim No(myGroups+1), Name$(myGroups+1)
                  for i=1 to myGroups {
                        Read No(i), name$(i)
                  }
      Document GreekInfo$, EnglishInfo$, GroupInfo$, AllGreek$, AllEnglish$
      Dir AppDir$
      Execute "HELP2000", "DELETE FROM COMMANDS WHERE GROUPNUM =22;"
      \\ Retrieve "HELP2000","GROUP", 1,"",""
            For i=1 To myGroups {
                EnglishInfo$= RightPart$(name$(i),", ")
                 GreekInfo$= LeftPart$(name$(i),", ")
                 GreekInfo$={
}
                 EnglishInfo$={
}
                  Retrieve "HELP2000", "SELECT * FROM COMMANDS WHERE GROUPNUM ="+Str$(No(i)),1,"",""
                  Read mywords
                  If no(i)<>22 Then {
                  For j=1 To mywords {
                        Retrieve "HELP2000", "SELECT * FROM COMMANDS WHERE GROUPNUM ="+Str$(No(i))+" ORDER BY [ENGLISH]",j,"","" 
                        Read mywords
                        Read GreekName$, HelpText$, EnglishName$, groupnumFrom
                        If mywords=j Then {EnglishInfo$= EnglishName$ } Else EnglishInfo$= EnglishName$+", "
                        Retrieve "HELP2000", "SELECT * FROM COMMANDS WHERE GROUPNUM ="+Str$(No(i))+" ORDER BY [DESCRIPTION]",j,"",""        
                        Read mywords
                        Read GreekName$, HelpText$, EnglishName$, groupnumFrom
                        If mywords=j Then {GreekInfo$= GreekName$} Else GreekInfo$= GreekName$+", "                
                  }
               AllGreek$=GreekInfo$+{

}
               AllEnglish$=EnglishInfo$+{

}
               GroupInfo$=GreekInfo$+{
               __<ENG>__
               }+EnglishInfo$+{

               }
               \\  print LeftPart$(name$(i),", ")    \\ Greek name of group
               print RightPart$(name$(i),", ")
               Append "HELP2000",  "COMMANDS", LeftPart$(name$(i),", "), GroupInfo$, RightPart$(name$(i),", "), 22
               Clear GroupInfo$
               }
               Clear GreekInfo$
               Clear EnglishInfo$
            }  
            AllGreek$={
            __<ENG>__
            
} + AllEnglish$
               Append "HELP2000",  "COMMANDS",  "ΟΛΑ", AllGreek$,"ALL", 22
      Print "DONE"
      clear
      Flush
      Dir User
}
MODULE GLOBAL DAT {
      Data 24
      Data 22,"ΓΕΝΙΚΑ, GENERAL"
      Data 14,"ΔΙΕΡΜΗΝΕΥΤΗΣ, INTERPRETER"
      Data 15,"ΧΕΙΡΙΣΜΟΣ ΤΜΗΜΑΤΩΝ, MODULE'S COMMANDS"
      Data 3,"ΡΟΗ ΠΡΟΓΡΑΜΜΑΤΟΣ, FLOW CONTROL"
      Data 9,"ΣΩΡΟΣ, STACK"
      Data 7,"ΟΡΙΣΜΟΙ, DEFINITIONS"
      Data 25,"ΕΓΓΡΑΦΑ, DOCUMENTS"
      Data 11,"ΧΕΙΡΙΣΜΟΣ ΑΡΧΕΙΩΝ, FILE OPERATIONS"
      Data 8,"ΦΟΡΜΑ ΟΘΟΝΗΣ, SCREEN FORM"
      Data 16,"ΟΘΟΝΗ & ΑΡΧΕΙΑ, SCREEN & FILES"
      Data 24,"ΧΕΙΡΙΣΤΕΣ ΤΗΣ ΤΥΠΩΣΕ, OPERATORS IN PRINT"
      Data 13,"ΣΤΟΧΟΙ & ΕΠΙΛΟΓΗ, TARGET & MENU"
      Data 1,"ΓΡΑΦΙΚΑ 2Δ, DRAWING 2D"
      Data 4,"ΕΙΚΟΝΕΣ, BITMAPS"
      Data 2,"ΒΑΣΕΙΣ ΔΕΔΟΜΕΝΩΝ, DATABASES"
      Data 5,"ΗΧΟΙ & ΤΑΙΝΙΕΣ, SOUNDS And MOVIES"
      Data 6,"ΔΕΙΚΤΗΣ, MOUSE"
      Data 10,"ΙΣΤΟΣ, BROWSER"
      Data 12,"ΚΟΙΝΕΣ ΦΟΡΜΕΣ, COMMON DIALOGS"
      Data 19,"ΑΡΙΘΜΗΤΙΚΑ, ARITHMETIC FUNCTIONS"
      Data 20,"ΑΛΦΑΡΙΘΜΗΤΙΚΑ, STRING FUNCTIONS"
      Data 21,"ΜΕΤΑΒΛΗΤΕΣ ΣΥΣΤΗΜΑΤΟΣ, VARS READ ONLY"
      Data 23,"ΣΤΑΘΕΡΕΣ, CONSTANTS"
      Data 17,"ΕΚΤΥΠΩΣΕΙΣ, PRINTINGS"
}