Παρασκευή, 31 Ιουλίου 2015

Χρήση της ΔΙΑΜΕΣΟΥ ή GOSUB στη Μ2000 μέρος Β

Είδαμε στην προηγούμενη ανάρτηση την εντολή Διαμέσου (Gosub) να μεταφέρει την ροή εκτέλεση εντολών "διαμέσου" ρουτινών. Όμως αυτές οι ρουτίνες είναι κάτι παραπάνω από απλά ένα τμήμα εντολών του τμήματος για επαναληπτική εκτέλεση (είδαμε για αναδρομή, για τοπικές μεταβλητές που χάνονται με το πέρας της ρουτίνας).
Η Μ2000 στην 8 έκδοση έβαλε μερικά πράγματα από την παλιά Basic επειδή ο λόγος ύπαρξης της γλώσσας είναι η εκπαίδευση. Έτσι για γνωριμία με την παλιά Basic περιλαμβάνει τις εντολές (εδώ στα αγγλικά):
REM, LET, NEW, PRINT, INPUT, IF THEN, FOR NEXT, CLS, CLEAR, DEF, SUB, GOSUB, GOTO, RETURN, OPEN, CLOSE, WRITE, LINE INPUT, DATA, READ, ON GOTO, ON GOSUB, SAVE, LOAD, LIST
Η Goto είναι η ΠΡΟΣ ενώ η Gosub είναι η ΔΙΑΜΕΣΟΥ
Η εντολή List ή Λίστα δίνει την λίστα μεταβλητών και όχι του προγράμματος. Για να δει κανει το πρόγραμμα πρέπει να γράψει σ ή συγγραφή και το όνομα του τμήματος (μπορεί να φτιάξει κανει το τμήμα RUN και να γράψει RUN και να το τρέξει και φαίνεται ακριβώς όπως στην παλιά Basic).
Επιπλέον η Basic είχε αριθμούς γραμμών. H Μ2000 μπορεί να λειτουργήσει και με αριθμούς γραμμών. Μάλιστα στη συγγραφή αν ξεκινήσουμε με αριθμό μια γραμμή τότε με το Enter έχουμε νέα γραμμή (παράγραφο) με αυτόματη απόδοση επόμενου αριθμού. (έχουμε auto numbering σε εοπεξεργαστή κειμένου...τέλειο).
 Μπορούμε να χρησιμοποιήσουμε το ΔΙΑΜΕΣΟΥ 1000 και ο μεταφραστής ψάχνει από πάνω (αρχή) και όχι από το τέλος όπως στις Ρουτίνες, να βρει τη γραμμή 1000 και συνεχίζει από εκεί μέχρι να βρει το πρώτο Επιστροφή (Return). Η εντολή Επιστροφή έχει δυο πρόσωπα, ένα χωρίς παραμέτρους κάνει επιστροφή από εκτέλεση Διαμέσου, και το άλλο είναι με παραμέτρους και επιστρέφει τιμές σε πεδία σε βάσεις δεδομένων!
Επιπλέον των αριθμών γραμμών υπάρχουν και οι ετικέτες. Οι ετικέτες είναι ονόματα που σηματοδοτούν ένα σημείο του κώδικα. Δεν επιτρέπεται στη γραμμή με ετικέτα να υπάρχει άλλη εντολή εκτός από σημειώσεις (με χρήση \ ή ' ). Μπορούμε  να πάμε προς μια ετικέτα ή να εκτελέσουμε διαμέσου μιας ετικέτας. 

Ενώ στις ρουτίνες δεν βάζαμε πριν την πρώτη κάποια εντολή έξοδος γιατί η ίδια η εντολή Ρουτινα αν βρεθεί, στη ροή, για εκτέλεση κάνει έξοδο από το τμήμα, για τις ρουτίνες με ετικέτα πρέπει να έχουμε κάτι πιο πριν για να κόψουμε την συνεχεια στη ρουτίνα (αν πάμε στο Επιστροφή και δεν υπάρχει κάτι στο σωρό επιστροφής-στον οποίο δεν έχουμε πρόσβαση- τότε θα βγει λάθος!
Σε παλαιότερες εκδόσεις δεν μπορούσε ο μεταφραστής να κάνει άλματα έξω από ένα μπλοκ εντολών. Στην έκδοση 8, κάνουμε παπάδες όπως λέμε...
Η προφανέστερη διαφορά με τις ρουτίνες στο μέρος Α που είδαμε είναι ότι δεν έχουμε παραμέτρους και η δεύτερη είναι ότι κάθε πράγμα που φτιάχνουμε...παραμένει στο τμήμα. Δεν έχουμε τίποτα τοπικό! Μπορούμε να χρησιμοποιήσουμε την εντολή Τοπική αλλά με την επιστροφή δεν θα γυρίσουμε στην προυπάρχουσα..(άρα δεν κερδίζουμε κάτι). Αν θέλουμε να έχουμε όμως κάτι σαν την Ρουτίνα Τέλος ρουτίνας τότε ή χρησιμοποιούμε την Ρουτίνα Τέλος ρουτίνας, ή αν θέλουμε τίποτα άλλο μυστήριο τότε υπάρχει το Για Αυτό { } το οποίο ότι νέο έχουμε στο μπλοκ θα εξαφανιστεί στο πέρας του (είναι το ανάλογο του Σωρός Νέος {} για την προσωρινή χρήση ενός καθαρού σωρού).

Για Ι=1 Εως 100 {
      Διαμεσου ετικετα
      Διαμέσου 1000
}
έξοδος


1000 Τύπωσε Ι**2 : Επιστροφή
ετικετα:
      Τύπωσε Ι
      επιστροφή

Χρήση της ΔΙΑΜΕΣΟΥ ή GOSUB στη Μ2000 μέρος Α

Στην όγδοη έκδοση της Μ2000 μπήκαν και οι ρουτίνες στο συντακτικό της. Στο παράδειγμα παρακάτω το τμήμα Α έχει δυο ρουτίνες την Α(Χ) και την Β(Χ). Προς το παρόν το αναγνωριστικό Ρουτίνα στον ορισμό δεν θέλει τόνο (για να μην κάνει διπλή αναζήτηση ο μεταφραστής, αλλά δέχεται μικρά μεγάλα ανάμεικτα). Το ίδιο πρόγραμμα στο Α εκτελείται και από το τμήμα Α1 αλλά εκεί αντί για ρουτίνες έχουμε τμήματα, τοπικά, τα Α και Β.

Μια εμφανή διαφορά είναι ότι στο Α1 τα τοπικά τμήματα πρέπει να αναφέρονται πριν την χρήση τους, ενώ στο Α οι ρουτίνες απλά πρέπει να υπάρχουν κάπου στο τέλος του τμήματος.
Τα τμήματα εγγράφονται σε ένα ξεχωριστό "ευρετήριο" ενώ οι ρουτίνες υπάρχουν άνευ ευρετηρίου. Κάθε φορά που ζητάμε μια ρουτίνα, αυτή αναζητείται. Επειδή η αναζήτηση γίνεται από το τέλος είναι γρήγορη, όχι όμως όσο η αναζήτηση βάσει ευρετηρίου στα τμήματα. Οπότε το τμήμα Α1 εκτελείται πιο γρήγορα (και επειδή χρησιμοποιεί το γρήγορο Για {} και όχι το Για Επόμενο). Η διαφορά φόρτου (του χρόνου που χρειάζεται δηλαδή να εκτελεστεί) είναι ότι στο τμήμα Α χρειάζεται ένα 10% παραπάνω (περίπου 2% για την Για Επόμενο και το 8% λόγω της αναζήτησης των ρουτινών).

Υπάρχουν όμως δυο διαφορές που δεν γίνονται αμέσως φανερές, επειδή δεν φαίνεται εδώ να μας βοηθάνε σε τίποτα. Η μία είναι ότι οι ρουτίνες είναι εκτός ευρετηρίου που σημαίνει επίσης ότι ανήκουν στον ίδιο χώρο ονομάτων με το τμήμα. Όλες οι μεταβλητές του τμήματος είναι σαν καθολικές μεταβλητές στην ρουτίνα. Επίσης κάθε νέα μεταβλητή θα ανήκει μεν στο τμήμα αλλά στο τμήμα Ρουτινα Τέλος Ρουτίνας κάθε νέα μεταβλητή, τμήμα, συνάρτηση θα χαθεί μετά το πέρας της εκτέλεσης της ρουτίνας. Αν στο τμήμα υπάρχει η κ και θέλουμε να χρησιμοποιήσουμε μια τοπική κ στη ρουτίνα τότε δίνουμε εντολή:
       Τοπική κ
 ή
       Τοπική κ=10, λ=34, Α(10,20)=1 \\ δημιουργούμε και τοπικούς πίνακες!

Εδώ χρειάζεται μια προσοχή γιατί η Μ2000 έχει νήματα (δηλαδή τμήματα παράλληλης εκτέλεσης) στα τμήματα και αυτά μπορούν να καλέσουν τις ρουτίνες (αφού τα νήματα είναι στον ίδιο χώρο με το τμήμα που τα δημιούργησε). Συνήθως όμως στα νήματα χρησιμοποιούμε υπάρχουσες μεταβλητές (ορισμένες στο τμήμα πριν ξεκινήσει το νήμα).
Μια δεύτερη διαφορά είναι ότι οι ρουτίνες θέλουν καθορισμένη λίστα παραμέτρων. Τα τμήματα μπορούν να αλλάξουν τρόπο "συλλογής" παραμέτρων με διαδοχικά Διάβασε ενώ μια ρουτίνα υποχρεωτικά θέλει ότι έχει προδιαγραφεί και από εκεί και πέρα μπορεί να πάρει επιπλέον μέσω της Διάβασε.
Τεχνικά οι Ρουτίνες είναι κομμάτια του τμήματος που θέλουμε να επαναλάβουμε βάσει ονόματος. Μπορούμε να βάλουμε ορισμούς νημάτων, επειδή αυτά δεν έχουν όνομα, διαχειρίζονται με "χειριστές" Handlers, δηλαδή αριθμούς. Με την εντολή ΜΕΤΑ μπορούμε να ορίσουμε ένα νήμα να ξεκινήσει μετά από κάποια χιλιοστά του δευτερολέπτου, ή δευτερόλεπτα, και αυτό θα γίνει αφού θα έχουμε φύγει από την ρουτίνα που περιείχε την εντολή ΜΕΤΑ.
όταν μας ενδιαφέρει η έννοια της στατικής μεταβλητής, δηλαδή να καλούμε μια ρουτίνα και αυτή να γράφει κάποια αποτελέσματα τα οποία σε επόμενη κλήση να τα χρησιμοποιεί, τότε η ρουτίνα της Μ2000 επειδή έχει πρόσβαση στις μεταβλητές του τμήματος που περιλαμβάνεται μπορεί να έχει εκεί τις "στατικές" μεταβλητές. Άλλος τρόπος για χρήση στατικών μεταβλητών είναι να τις έχουμε συμπεριλάβει σε μια Ομάδα, αλλά αυτό είναι προχωρημένο για τώρα (Ομάδες και Κλάσεις είναι το άλλο μεγάλο κεφάλαιο της Μ2000).
Ένα τμήμα έχει ένα σωρό για να βρίσκει ή να αφήνει τιμές. Οι ρουτίνες έχουν κοινό σωρό με το σωρό του τμήματος. Αν θέλουμε νέο σωρό τότε υπάρχει το Σωρός Νέος {    } και ανάμεσα στο μπλοκ η Μ2000 μας παρέχει νέο σωρό (Τα νήματα έχουν πάντα δικό τους σωρό, ενώ τα τμήματα όπως και οι ρουτίνες κληρονομούν τον σωρό του "πατέρα", ή τον πατρικό σωρό). Ο σωρός αυτός ας μην μπερδεύεται με τον σωρό επιστροφής των ρουτινών, αυτός είναι διαφορετικός και απροσπέλαστος από τον προγραμματιστή.
Στο όρισμα της Ρουτίνας μπορούμε να βάλουμε το & για να δηλώσουμε ότι ζητάμε αναφορά. Μπορούμε να περάσουμε πίνακες (αυτούσιους) ή αναφορές σε πίνακες. Μπορούμε να περάσουμε αναφορές σε συναρτήσεις επίσης.
Ακόμα και χωρίς όρισμα χρειάζεται να βάλουμε τις παρενθέσεις για τις ρουτίνες. Επειδή χωρίς παρενθέσεις έχουμε κλήση απλής ρουτίνας που θα δούμε στο μέρος Β.

Επιπλέον οι ρουτίνες αυτές μπορούν να καλούν τον εαυτό τους (έχουν αναδρομή όπως οι συναρτήσεις, αλλά οι συναρτήσεις έχουν νέο σωρό σε κάθε κλήση, ενώ οι ρουτίνες βλέπουν συνέχεια τον πατρικό και τις μεταβλητές/πίνακες/τμήματα/συναρτήσεις του πατρικού).

Πρόσθεσα και τρόπο μέτρησης της διαφοράς στην ταχύτητα.
Στην έκδοση 8.17 αναθεώρηση 17 διαπιστώθηκε bug στην έξοδος για και αποκαταστάθηκε στην αναθερώρηση 18. 
Η έξοδος για μπορεί να γίνει  δίνοντας τον αριθμό γραμμής (αριθμό που δίνουμε εμείς σε μια γραμμή), ή ετικέτα, ή τίποτα (στο τίποτα είχε θέμα, όπως εδώ)


Τμήμα ΟΛΟ {
            Τμήμα Α {
            Για ι=1 Έως 100
                   Διαμεσου Α(ι)
                   Αν ι>59 Τότε έξοδος για
                  Διαμεσου Β(ι)
            Επόμενο ι
            Τύπωσε "Τελικό ι=";ι
          
            Ρουτίνα Α(Χ)
                   Αν Χ>10 Τότε Έξοδος ρουτίνας
                  Τύπωσε Χ
            Τέλος Ρουτίνας
            Ρουτίνα Β(Χ)
                   Αν Χ<50 Τότε Έξοδος ρουτίνας
                  Τύπωσε Χ**2
            Τέλος Ρουτίνας
      }
      Τμήμα Α1 {
            Τμήμα Α {
                   Διάβασε Χ
                  Αν Χ>10 Τότε Έξοδος
                  Τύπωσε Χ
            }       
            Τμήμα Β {
                   Διάβασε Χ
                  Αν Χ<50 Τότε Έξοδος
                  Τύπωσε Χ**2
                  }
            Για ι=1 Έως 100 {
                   Α ι
                  Αν ι>59 Τότε έξοδος
                  Β ι
            }
            Τύπωσε "Τελικό ι=";ι
      }
      Οθόνη
      Αναλυτής
      Α
      αφ=Φόρτος
      Α$=ΚΟΜ$
      Οθόνη
      Αναλυτής
      Α1
      α1φ=Φόρτος
      Τύπωσε αφ, α1φ
}
Κάλεσε ΟΛΟ

Πέμπτη, 23 Ιουλίου 2015

Χειρισμός του Word από την Μ2000

Αισίως είμαστε στην έκδοση 8 αναθεώρηση 11.
Με την συμπλήρωση των εντολών για χειρισμό αντικειμένων όπως το Word.Application η M2000 ολοκληρώθηκε. Κάποιοι έλεγχοι επιβάλλονται ακόμα και έτσι ίσως προκύψει κάποια αναθεώρηση.

Παρακάτω είναι ένα πρόγραμμα γραμμένο σε Μ2000 με ελληνικές εντολές που ανοίγει το Word φτιάχνει ένα νέο έγγραφο ως ιστοσελίδα, γράφει κείμενο και προτρέπει να το σώσουμε. Αν δεν το σώσουμε μας λέει ότι δεν σώθηκε το έγγραφο και το κλείνει. Μετά κλείνει και την εφαρμογή.
Επίσης βλέπουμε πως ορισμένα αντικείμενα όπως ο Επεξεργαστής και τα Κείμενα είναι γενικά δηλαδή φαίνονται μέσα σε τμήματα.

Το πρόγραμμα αυτό μπορούμε να το γράψουμε στη Μ2000 σε ένα τμήμα π.χ. συγγραφή Ασ Α) και μετά τρέχει με το όνομα μόνο  (στο σήμα εισόδου >_ γράφουμε το Α και πατάμε Enter)
Θα δείτε να χρησιμοποιώ το μπλοκ ελέγχου Δες {} για να σταματήσω τυχόν λάθη, πχ μπορεί κάποιος να κλείσει το Word...οπότε οι εντολές πάνε στο πουθενά...

Επίσης δείτε ότι για κάθε αντικείμενο που ορίζω με την Όρισε (η ως αποτέλεσμα στην Μέθοδος) μπορώ να με την Με να αλλάξω ιδιότητες, να ορίσω μεταβλητές σε ιδιότητες ώστε να τις διαβάζω και να τις αλλάζω, και μπορώ με την Μέθοδος να καλέσω κάποια μέθοδο, να περάσω μεταβλητές με σειρά ή με όνομα ή με σειρά και όνομα (αλλά όχι όνομα και μετά σειρά...). Το πέρασμα με όνομα λέγεται named argument pass και στην Μ2000 ισχύει μόνο για τα αντικείμενα.

Δείτε πως ορίζω ένα νέο έγγραφο στο Word, με την
 Μέθοδος  Κείμενα, "add", "", DocumentType:=WdNewWebPage ως έγγραφο1
Το Κείμενα είναι αντικείμενο που ορίσαμε ως Word.Application.Documents  (δες τις δυο πρώτες εντολές, ακολούθησε το σύνδεσμο για να δεις πληροφορίες για το αντικείμενο Documents). Το "add" είναι μέθοδος, η πρώτη παράμετρος είναι το πρότυπο, εδώ δίνουμε το κενό, θα μπορούσαμε να το παραλείψουμε αλλά το έχουμε απλά για να δούμε ότι λειτουργεί, και μετά έχουμε ένα πέρασμα με όνομα, τον τύπο του εγγράφου. Τέλος την εξαγωγή της μεθόδου την γράφουμε στο έγγραφο1 και είναι αντικείμενο τύπου Document. Μπορούμε να δούμε πάντα τον τύπο μιας μεταβλητής με την τύπος$(έγγραφο1).  Το χρώμα στο κώδικα το έβαλα απλά για να διαβάζεται πιο εύκολα...δεν χρειάζεται για κάτι άλλο!

Όρισε γενικό Επεξεργαστής "Word.Application"
Όρισε γενικό Κείμενα με Επεξεργαστής, "Documents"
Γενικό wdDoNotSaveChanges=0
Γενικό WdNewBlankDocument = 0 \\Blank document
Γενικό WdNewEmailMessage = 2 \\E-mail message
Γενικό WdNewFrameset = 3 \\Frameset
Γενικό WdNewWebPage = 1 \\Web page
Γενικό WdNewXMLDocument = 4 \\XML document


\\ θα βάλουμε σε ένα τμήμα τις άλλες εντολές για να δούμε αν
\\ λειτουργούν οι γενικές μεταβλητές (έχουν εμβέλεια παντού)

Τμήμα ΈναΌνομα {
      Με Επεξεργαστής, "visible" ως είναι_φανερό
      Δες ok {
            είναι_φανερό=αληθές
      }
      α$=Κομ$
            Δες {
            Με Επεξεργαστής, "top",100,"left",0
            Δες ok_doc { Μέθοδος Κείμενα, "add", "", DocumentType:=WdNewWebPage ως έγγραφο1 }
            Αν όχι ok_doc Τότε Τύπωσε "Δεν έφτιαξα έγγραφο" : Έξοδος
            Μέθοδος έγγραφο1, "activate"
            Όρισε γενικό επιλογή_κειμένου με Επεξεργαστής, "selection"
            Μέθοδος επιλογή_κειμένου, "TypeText", "Αυτό είναι κείμενο γραμμένο στο Word από την M2000"
            α$=Κομ$
            Δες σώθηκε { Μέθοδος έγγραφο1,"close" }
            Αν δεν σώθηκε Τότε {
                  Τύπωσε "Το έγγραφο δεν σώθηκε, πάτα ένα πλήκτρο"
                  Ανανέωση
                  α$=Κομ$
                  Μέθοδος έγγραφο1,"close", SaveChanges:=wdDoNotSaveChanges \\κλείσιμο χωρίς σώσιμο!
            }
            Άδειασε Λάθος
       }
      \\ Εδώ κρύβουμε το Word
      Αν ok Τότε {Δες { είναι_φανερό=ψευδές }}
      Δες { Όρισε έγγραφο1 τίποτα }
      Δες { Όρισε επιλογή_κειμένου τίποτα }
}
ΈναΌνομα
Αναμονή 10
Δες {
Όρισε Κείμενα τίποτα 


Μέθοδος Επεξεργαστής, "quit"


Όρισε Επεξεργαστής τίποτα
}

Γιώργος Καρράς


Τετάρτη, 15 Ιουλίου 2015

Σε λίγες μέρες...η όγδοη έκδοση της Μ2000

Ευχάριστα νέα για σήμερα.
Επιτέλους η Μ2000 αναβαθμίστηκε με κλάσεις και αντικείμενα (ομάδες λέγονται στη γλώσσα).
Παράδειγμα

Φόρμα 40,25 \\40Χ25
Κλάση Αλφα {
       Χ=10, Υ, Α$="Όνομα"
       Τμήμα Αλφα {
             Αν ταύτιση("NN") Τότε Διάβασε ,
      }
       Τμήμα Νέο.Όνομα {
             Διάβασε .Α$
       }
       Συνάρτηση Νέο.Όνομα$ {
             =.Α$
       }
       Συνάρτηση Ένα { = **2+}
}
Κάπα=Αλφα() \\ κατασκευάζουμε το αντικείμενο χωρίς παραμέτρους
Κάπα.Υ=20
Τύπωσε Κάπα.Ένα()
Βήτα=Αλφα(10,20) \\ εδώ με παραμέτρους
Τύπωσε Βήτα.Ενα()
Για Βήτα {
       Τύπωσε,, .Α$, .Ενα()
}
Λάμδα=Κάπα \\ αντιγραφή αντικειμένου
Για Λάμδα {
       -=5
       .Νέο.Όνομα "Λάμδα"
       Τύπωσε .Νέο.Όνομα$(), .Ένα()
}

Τα αντικείμενα μπορούν να περάσουν με τιμή (ως αντίγραφα) ή με αναφορά σε τμήματα και συναρτήσεις.
Η Άλφα() ή Άλφα(10,20) επιστρέφει ένα αντικείμενο. Οι συναρτήσεις στην νέα έκδοση επιστρέφουν αντικείμενα αλλά και πίνακες. Μπορούμε να αντιγράψουμε ένα πίνακα σε ένα άλλο! Μπορούμε να περάσουμε σε συναρτήσεις και τμήματα πίνακα με τιμή δηλαδή αντίγραφο του πίνακα.
Επιπλέον μπορούμε να περάσουμε με αναφορά συναρτήσεις!

Κάνε α(Χ,Υ)=Χ**2+Υ
Κάνε β(Χ,Υ)=Χ**3+Υ*5+10
Τύπωσε α(10,20), β(10,20)


Τμήμα Μι {
       Διάβασε &κάτι() \\ διαβάζουμε τη συνάρτηση
      Τύπωσε κάτι(100,200)
}
Μι &α() \\ καλούμε με πέρασμα συνάρτησης
Μι &β()

Φτιάχτηκε μέχρι και σύστημα να βλέπει κανείς το πρόγραμμα καθώς εκτελείται:

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

Αυτή την εποχή γράφω την αγγλική έκδοση του M2000 Language Definition και θα δημοσιεύσω τον κώδικα μόλις τελειώσει και το κείμενο και τυχόν διορθώσεις εμπλουτισμοί.
Μια αναθεώρηση του κώδικα της 8ης έκδοσης υπάρχει εδώ

Μισοτελειωμένο το Language Definition (Θα το κάνω στα Ελληνικά με τις Ελληνικές εντολές - η Μ2000 έχει όλες τις εντολές και στις δυο γλώσσες, Αγγλικά και Ελληνικά)

Σε αναμονή λοιπόν της τελικής έκδοσης 8 της Μ2000