Πέμπτη 14 Σεπτεμβρίου 2017

Διαφορές μεταξύ ΓΛΩΣΣΑΣ (ΑΕΠΠ) και Μ2000


Μερικά παραδείγματα σε ΓΛΩΣΣΑ είναι από εδώ: http://alkisg.mysch.gr/ΓΛΩΣΣΑ/
Αναθεώρηση για να συμβαδίζει με την έκδοση 9.8




Τύποι Δεδομένων στη ΓΛΩΣΣΑ:

Στη ΓΛΩΣΣΑ υπάρχουν τέσσερις τύποι Πραγματικός, Ακέραιος, Λογικός, Χαρακτήρες. Οι χαρακτήρες δεν υποστηρίζονται με έτοιμες συναρτήσεις αλφαριθμητικών, και μπορούν να περιέχονται σε πίνακες και να τυπώνονται. Δεν μπορούμε να προσθέσουμε δυο αλφαριθμητικά. Μπορούμε όμως να συγκρίνουμε αλφαριθμητικά και να τα εμφανίζουμε ή να τα εκχωρούμε σε μεταβλητές ή σε πίνακες. 
Η γλώσσα υποστηρίζει και σταθερές, ονόματα δηλαδή με σταθερές τιμές.
Στους περιεχόμενους αριθμούς στο κώδικα η υποδιαστολή δηλώνει ότι ο αριθμός είναι πραγματικός, ενώ ή έλλειψη αυτής ότι είναι ακέραιος.
Για την εκχώρηση τιμών χρησιμοποιούμε το <-, ενώ για το = χρησιμοποιείται μόνο στις συγκρίσεις. Ενώ όλες οι εντολές είναι στα ελληνικά, οι τελεστές mod και div είναι στα αγγλικά.

Στην Μ2000:

Έχουμε αρκετούς τύπους αριθμητικούς, και εξ ορισμού μια τιμή είναι πραγματική. Πχ το 100 είναι πραγματική, αλλά αν πάει σε μεταβλητή έστω Λογιστικό τότε θα γίνει τύπου Λογιστικό (Currency). Ίσως προκύψει υπερχείλιση! Στη Μ2000 η υπερχείλιση δίνει λάθος. Μπορούμε να καθορίσουμε έναν αριθμό το τι θα είναι με σύμβολα. 
Παραδείγματα τιμών:
Διπλός (Πραγματικός διπλής ακρίβειας)
-12.324
121
1.1212ε-15
Αλλαγές από την 9η έκδοση
Δεκαεξαδική αναπαράσταση που δίνουν όμως Λογιστικό (χρήση μόνο 32 bit από 64, πάντα θετικός ή μηδέν), Μακρύς (32 bit, με πρόσημο), Ακέραιο (16 Bit, με πρόσημο)
0XAFBC3F23 χωρίς πρόσημο 32bit (Λογιστικός/Currency)
0XAFBC3F23& με πρόσημο 32bit (Μακρύς/Long)
0XAFBC% με πρόσημο 16bit (Ακέραιος/Integer)

Εδώ έχουμε αλλαγή τύπου:

123232.1233@ Αριθμός (decimal)
1232112321.1231# λογιστικός
12321& ακέραιος 32bit
121% ακέραιος 16bit
12.ε4~ απλός πραγματικός
 

Το = χρησιμοποιείται και για εκχώρηση και για ισότητα.



Σε ορισμένες περιπτώσεις εκχώρηση κάνουν και τα <=, := και ->



Για ισότητα το == χρησιμοποιείται με στρογγύλευση των δυο τιμών



Επίσης υπάρχει και ο τριπλός τελεστής <=> ο οποίος δίνει 1 0 -1 πχ το Τύπωσε 1<=>0 δίνει 1, ενώ το Τύπωσε 0<=>1 δίνει -1. Είναι ο μοναδικός τελεστής σύγκρισης που δεν δίνει λογικό τύπο.Ο τύπος ΛΟΓΙΚΟΣ, από την 9η έκδοση υποστηρίζεται κανονικά. Υπάρχουν τα ΑΛΗΘΗΣ και ΨΕΥΔΗΣ ως τιμές πραγματικές, -1 και 0, αλλά οι συγκρίσεις επιστρέφουν τύπο λογικό, ή boolean, με τιμές οι οποίες μετατρέπονται σε -1 και 0 σε παραστάσεις.




κάνε λογικό α, β, γ
α=100 ' το 100 θα γίνει λογικό -1, κάθε μη μηδενική τιμή γίνεται Αληθές
Τυπωσε α=-1 ' αληθές
Τύπωσε α=αληθές, α=αληθής ' και το αληθής υπάρχει
α~
Τύπωσε α=ψευδές, α=ψευδής, α=0
Συνάρτηση αντίστροφο(α ως λογικός) {
      =όχι α
}
Τύπωσε αντίστροφο(0)=-1, αντίστροφο(100)=0
Τύπωσε αντίστροφο(0)=αληθές, αντίστροφο(100)=ψευδές
χ=τυχαίος(-1,0)
\\ μετατροπή σε λογικό
Τύπωσε Τιμή(χ->λογικός)
κ=τιμή(χ->λογικός)
Τύπωσε τύπος$(κ)="Boolean"



Η Μ2000 έχει αρκετούς τύπους δεδομένων που δεν υποστηρίζει η ΓΛΩΣΣΑ όπως:
Αριθμό (Decimal), Διπλό (Double), Απλό (Single),  Λογιστικό (Currency), Μακρύ (32bit Long), Ακέραιο (16bit Integer), Λογικό (Boolean)



Επίσης έχει αντικείμενα όπως η Κατάσταση (λίστα τιμών με κλειδί), ο Σωρός Τιμών (συνδεδεμένη λίστα) , η συνάρτηση λάμδα, κ.α.



Οι ακέραιες μεταβλητές στη Μ2000 έχουν το % στο τέλος και είναι εσωτερικά πραγματικές, ή οποιοσδήποτε άλλος τύπος. Το Α%=12.5 θα γίνει 13. Με decimal μπορούμε να έχουμε ακέραιους με 28 ψηφία.
Οι μεταβλητές δεν αλλάζουν τύπο , που έλαβαν μετά την πρώτη εκχωρηση, ή όταν δηλώθηκε τύπος κατά τον ορισμό. εκτός από τρεις περιπτώσεις:
1. Αν ορίσουμε ως Μακρύς, τότε η μεταβλητή θα αλλάξει σε Μακρύς (υπάρχει έλεγχος υπερχείλισης και θα δώσει λάθος αν η υπάρχουσα τιμή είναι εκτός ορίων για Μακρύ).
2. Αν βάλουμε σε μεταβλητή ένα αντικείμενο ενώ δεν έχει αντικείμενο τότε ανάλογα το αντικείμενο παίρνει δείκτη σε αυτό ή είναι αυτό (μοναδικός εσωτερικός δείκτης, λέγεται και στατικό αντικείμενο). Τα αντικείμενα σωρός, πίνακας και κατάσταση μπορούν να εναλλάσσονται σε ίδιο δείκτη.
3. Αν είναι γενικές μεταβλητές και η εκχώρηση γίνεται στην γραμμή εντολών της Μ2000, και σε τμήμα ή συνάρτηση με τη Θέσε  (η οποία εκτελεί την γραμμή στον μεταφραστή γραμμής εντολών). Αν χρησιμοποιούμε μεταβλητή με % στο όνομα, τότε μπορούμε να αλλάζουμε και από μακρύς σε κάτι άλλο (ενώ οι αριθμητικές χωρίς το %, χωρίς δηλαδή την στρογγυλοποίηση στο 0.5) αν αλλάξουν σε μακρύς δεν αλλάζουν ξανά.

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



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



Σταθερή Μ=1000
Απαρίθμηση Προσανατολισμός {Βορράς=0, Ανατολή=90, Νότος=180, Δύση=270}
Κ=Βορράς
Τύπωσε Εκφρ$(Κ)="Βορράς", Κ=90
Κ++
Τύπωσε Εκφρ$(Κ)="Ανατολή", Κ=90
Δες {
      Βορράς=10
}
Τύπωσε λάθος$
Δες {
      Μ=500
}
Τύπωσε λάθος$




Περί πινάκων:
1. Αυτόματοι πίνακες
Οι αυτόματοι πίνακες ή tuple όπως λέγονται σε άλλες γλώσσες, είναι δομές πινάκων οι οποίοι καθορίζονται ως μονοδιάστατοι με βάση πάντα το 0.
Α=(1,2,3,4)
Τύπωσε Α#αθρ()
Στη Μ2000 το (1,2,3,4) δίνει αυτόματο πίνακα μονοδιάστατο τεσσάρων στοιχείων, ενώ το ((1,2),(3,4)) δίνει έναν αυτόματο πίνακα δυο στοιχείων όπου κάθε στοιχείο είναι πίνακας δύο στοιχείων. Τα στοιχεία στους πίνακες μπορούν να πάρουν και αλφαριθμητικά, και αντικείμενα. Αντικείμενα είναι οι πίνακες, καταστάσεις ειδών, σωροί τιμών (ειδική στοίβα συνδεδεμένων στοιχείων με εύκολη αλλαγή θέσης), λάμδα συναρτήσεις, ομάδες (αντικείμενα με μέλη οποιοδήποτε τύπο μεταβλητής, τμήματα, συναρτήσεις, τελεστές καθώς και ομάδες και ιδιότητες που είναι επίσης αντικείμενα ομάδες), γεγονότα δηλαδή συλλογές συναρτήσεων που καλούνται με μια κλήση και διαδοχικό πέρασμα τιμών (multicast)
\\ χρήση επάλληλων συναρτήσεων
\\ κάθε #συνάρτηση() παίρνει το αποτέλεσμα της προηγούμενης
Α=(1,2,3,4,5,6,7,8)
\\ #αθρ() δίνει το άθροισμα
Τύπωσε Α#αθρ()=36
\\ συνδυάζονται ορισμένες έτοιμες συναρτήσεις με λάμδα συναρτήσεις
Ζυγοί=Λάμδα ->Αριθμός υπολ 2 = 0
\\ γράφεται και με μεταβλητή
\\ σε πολλές γραμμές
Ζυγοί=Λάμδα ->{
      Διάβασε χ ' το Διάβασε χ μπορεί να γίνει (χ) όπως παρακάτω
      =χ υπολ 2 = 0
}
\\ ή σε μία γραμμή
Ζυγοί=Λάμδα (χ)->χ υπολ 2 = 0
\\ Στην αντιστοίχιση η λάμδα καλείται ως τμήμα
\\ οπότε η εξαγωγή γίνεται στον ίδιο σωρό που γίνεται η εισαγωγή.
Τετράγωνο=Λάμδα -> {
            Βάλε Αριθμός**2
}
\\ #Φιλτρο(λάμδα συνάρτηση [, εναλλακτική πηγή])
\\ αν το φίλτρο δεν δώσει πίνακα τότε δεν βγαίνει λάθος και θα γίνει η σύγκριση
Σημ : Ζυγοί=Λάμδα (χ)->χ>5000 ' θα τυπώσει μονο το "οκ"
Τύπωσε Α#Φίλτρο(Ζυγοί)#Αντ(Τετράγωνο)#Αθρ()=120, "οκ"
\\ μπορούμε να δώσουμε άμεσα τη λάμδα (αν δε έχει πολλές γραμμές)
\\ αλλά αν ακολουθεί παράμετρος τότε πρέπει να την βάλουμε μέσα σε παρενθέσεις.
Τύπωσε Α#Φίλτρο(λάμδα->αριθμός υπολ 2=0)#Αντ(Τετράγωνο)#Αθρ()=120, "οκ"
Τύπωσε Α#Αντ((λάμδα ->{Βάλε Αριθμός**2}))#Αθρ()=204
Τύπωσε Α#Πακ((λάμδα ->{Βάλε Αριθμός+Αριθμός}), 0)=Α#αθρ()
\\ το 1033 λέει να έχουν οι αριθμοί τη τελεία (όπως στα αγγλικά)
\\ δοκίμασε με 1032. Υπάρχει η εντολή Τοπικό που βάζει το νούμερο που θέλουμε για κάθε εμφάνιση
Τύπωσε Α#Πακ$((λάμδα (α,β$) ->{Βάλε β$+" "+Γραφή$(α, 1033)}), "Δεδομένα:")="Δεδομένα: 1 2 3 4 5 6 7 8"
Υπάρχουν και άλλες επάλληλες συναρτήσεις και φυσικά και στα αγγλικά (Filter, Map, Fold, Fold$). Όταν θέλουμε να γυρίσουμε αλφαριθμητικό θα χρησιμοποιήσουμε σαν τελευταία επάλληλη συνάρτηση μια με το $ στο όνομα. Όπως στο παράδειγμα η Πακ$() ή Fold$().
Μήκος αυτόματου πίνακα:
Το Α=(,) κάνει μηδενικού μήκους πίνακα. Η Τύπωσε Μήκος(Α) θα δώσει 0. Το Α=(1,) θα δώσει πίνακα μήκους 1 (ενώ το (1) δεν είναι πίνακας θα δώσει το νούμερο 1). Μπορούμε να δώσουμε ότι θέλουμε σε στοιχεία, αλλά όχι κενά στοιχεία. Πχ το Α=("α",1, "β",2) θα δώσει πίνακα με τέσσερα στοιχεία, ενώ το Α=(("α",1),("β", 2)) θα δώσει πίνακα με δυο στοιχεία, και κάθε στοιχείο θα είναι ένας πίνακας επίσης (θα μπορούσε ο δεύτερος να ήταν μεγαλύτερος
Α=("α",1,"β",2)
Τύπωσε Α#Τιμή$(0)="α", Α#Τιμή(1)=1
Α=(("α",1),("β",2))
Τύπωσε Α#Τιμή(0)#Τιμή$(0)="α", Α#Τιμή(0)#Τιμή(1)=1
Τύπωσε Πίνακας$(Πίνακας(Α,0),0)="α", Πίνακας(Πίνακας(Α,0),1)=1




Πράξεις με αυτόματους πίνακες:
Εδώ έχουμε δυο κατηγορίες. Η πρώτη έχει να κάνει με τους αριθμούς στους αυτόματους πίνακες. Πχ αν Α=(1,2,3) τότε το Α+=10  θα κάνει το πίνακα (10,20, 30). Αν πριν είχαμε κάνει το Β=Α τότε και το Β θα πάρει την αλλαγή, γιατί το Β και το Α είναι δείκτες στον ίδιο πίνακα. Αποφεύγουμε να βάλουμε στοιχείο ενός πίνακα έναν άλλο πίνακα που περιλαμβάνει τον πρώτο στα στοιχεία του (δεν θα διαγραφεί όσο ο διερμηνευτής τρέχει). Οι πίνακες διαγράφονται όταν δεν υπάρχει δείκτης για να τα κρατάει, και όταν τερματίσει ο διερμηνευτής.
Η δεύτερη κατηγορία έχει να κάνει με το πως προσθέτουμε στοιχεία σε πίνακες, πώς βγάζουμε στοιχεία, πως αλλάζουμε στοιχεία. Πχ το Επιστροφή Α, 0:=100 θα κάνει το στοιχείο 0 με τιμή 100. Πχ Επιστροφή Α, 0:="Α", 1:=Β  όπου το Β μπορεί να είναι οτιδήποτε, ακόμα και άλλος πίνακας.



α=(1,2,3,4)
α1=α
β=πρώτο(α) ' car()
γ=επόμενα(α) ' cdr()
Τύπωσε μήκος(β)=1, μήκος(γ)=3
α=ένωση(γ, β) ' cons()
Τύπωσε α ' 2 3 4 1
Τύπωσε α1 ' 1 2 3 4
α1=ενωση(α1, α, α1)
Τύπωσε α1 ' 1 2 3 4 2 3 4 1 1 2 3 4






2. Πίνακες που ορίζονται με όνομα με παρενθέσεις:
Ορίζουμε πίνακες μέχρι δέκα διαστάσεις με την εντολή Πίνακας (και βοηθητικά με τη εντολή Γενική και Τοπική ή Γενικές και Τοπικές)
Οι πίνακες αυτοί έχουν ονόματα με παρενθέσεις, και έχουν αρχική τιμή το "Empty" ή αλλιώς το κενό. Η συνάρτηση Τύπος$() επιστρέφει πάντα το όνομα στα αγγλικά (για να μπορούμε να δουλεύουμε και με τα δυο λεξιλόγια, το ελληνικό και το αγγλικό). Μπορούμε όμως να ορίσουμε μια τιμή για όλα τα στοιχεία όπως εδώ όπου φτιάχνουμε ένα πίνακα δέκα στοιχείων με το 1 σε καθένα από αυτά.
Πίνακας Α(10)=1



Βάση Πινάκων:
Στη ΓΛΩΣΣΑ οι πίνακες έχουν βάση το 1, δηλαδή ένας πίνακας 50 στοιχείων έχει το πρώτο στοιχείο στη θέση 1. 
Στη Μ2000 η βάση μπορεί να ρυθμιστεί ανεξάρτητα για κάθε διάσταση. Εξ ορσιμού όταν δίνουμε ένα αριθμό μεγέθους η βάση είναι 0 εκτός και αν έχουμε ορίσει ειδικά να είναι 1
Πίνακας Βάση 1, Α(10)=1
Ή μπορούμε να ορίσουμε για όλους τους επόμενους πίνακες η βάση να είναι 1
Βάση 1
Μπορούμε να δουλεύουμε με πίνακες διαφορετικών βάσεων. Μπορούμε να ορίσουμε πρώτο και τελευταίο νούμερο, και να έχουμε αρνητικά νούμερα:
Πίνακας Α(5 έως 10), Β(-10 έως10), Γ(2 έως 5, -10 έως 5)



Λίστα
Η εντολή Λίστα (λίστα μεταβλητών/πινάκων) θα μας δώσει:
Α(6), Β(21), Γ(4,16)
Μπορούμε να ορίσουμε ξανά έναν πίνακα, και όσα στοιχεία μπορούν να παραμείνουν στον πίνακα δεν αλλάζουν τιμή (εκτός αν δώσουμε το = και τη τιμή που θέλουμε να έχουν όλα τα στοιχεία). Εκτός από το = υπάρχει και ο τελεστής << που καλεί μια λάμδα συνάρτηση για όλα τα στοιχεία.



φυσικός=λάμδα χ=1 -> {
      =χ : χ++
}
Πίνακας Α(1 έως 100)<<φυσικός()
Τύπωσε Α()



Η Τύπωσε όπως και στους αυτόματους πίνακες τυπώνει όλο το πίνακα αν δεν πάρει δείκτη για κάποιο στοιχείο, χρησιμοποιόντας στήλες. 
Η Γλώσσα δεν έχει νοητές στήλες για αποτελέσματα στην εμφάνιση στοιχείων. Δεν έχει επίσης εντολή για ΜΗ αλλαγή γραμμής και ο Διερμηνευτής της Γλώσσας (εφαρμογή του σχολείου) θεωρεί τη μη αλλαγή από το αν βρίσκεται ο χαρακτήρας διάστημα ως τον τελευταίο χαρακτήρα που θα εμφανίσει στην οθόνη.
Οι πίνακες με παρενθέσεις στην Μ2000 είναι σαν τις μεταβλητές, έτσι το Α()=Β() θα κάνει το Α() αντίγραφο του Β(). Πρέπει το Α() να έχει πρώτα οριστεί ως Πίνακας Α().
Οι συναρτήσεις στην Μ2000 μπορούν να γυρίσουν πολλές τιμές ως πίνακες, ή να γυρίσουν πίνακες:



Συνάρτηση Έντεκα {
      Πίνακας Α(10 εως 20)=1
      =Α()
}
Τύπωσε Έντεκα()#αθρ()=11
Πίνακας Κ()
Κ()=Έντεκα()
Τύπωσε Κ(20)
\\ η βάση 1 αλλάζει στο =1,2,3 τη βάση σε 1
Βάση 1
Συνάρτηση ΤρειςΤιμές {
      =1,2,3
}
Κ()=ΤρειςΤιμές()
Τύπωσε Κ(1)=1
\\ οι αυτόματοι πίνακες έχουν πάντα βάση 0
\\ μπορούμε να ορίζουμε ξανά μια συνάρτηση
\\ ή να την ορίζουμε κατά συνθήκη
Συνάρτηση ΤρειςΤιμές {
      =(1,2,3)
}
Κ()=ΤρειςΤιμές()
Τύπωσε Κ(0)=1




Αλφαριθμητικά:

Στη ΓΛΩΣΣΑ ορίζονται με απλά ή με διπλά εισαγωγικά. 



Στη Μ2000 με διπλά ή με αγκύλες. (με αγκύλες βάζουμε και αλλαγές γραμμών).
Οι μεταβλητές για αλφαριθμητικά έχουν απαραίτητα το $ στο τέλος.
Τα αλφαριθμητικά μπορούν να περιέχουν οτιδήποτε, ακόμα και δυαδικά δεδομένα. Υπάρχει δομή που λέγεται Διάρθρωση μνήμης και ορίζουμε φυσική μνήμη, και είδος, από βασικούς ή από Δομές βασικών ή και άλλων δομών. Αυτές οι δομές είτε αρχικοποιούνται με καθαρισμό, είτε μένουν ως έχουν, είτε φορτώνονται δεδομένα από αρχεία (δυαδικά αρχεία, δηλαδή οτιδήποτε!), είτε με δυαδικά δεδομένα ως Base64 κωδικοποίηση μέσα στο κώδικα.




Ομαδοποίηση δεδομένων:
Μπορούμε να έχουμε δυο ειδών ομαδοποιήσεις:
1. Ομάδα
Εδώ είναι ένα μικρό παράδειγμα. Μια ομάδα μπορεί να έχει άλλες ομάδες εσωτερικά. Οι ομάδες είναι και σαν τις μεταβλητές και μπορούν να εκχωρούνται όπως εδώ σε πίνακα, αλλά μπορούμε να τις δουλέψουμε με δείκτες, έχει προστεθεί ένα μικρό δείγμα στο παράδειγμα. Οι ομάδες μπορούν να λειτουργουν με τιμή επιστροφής, τιμή εισόδου να προσομοιώνουν άλλους τύπους, όπως επίσης μπορούμε να έχουμε τελεστές και γεγονότα. Μπορεί μια ομάδα να επικοινωνεί με γεγονότα με το πρόγραμμα αλλά αυτό είναι προχωρημένο για αυτό το κείμενο.
Εκχώρηση ομάδας σε αριθμητική μεταβλητή κάνει την μεταβλητή ομάδα με αντίγραφό της. Εκχώρηση ομαδας σε ομάδα κάνει ένωση, δηλαδή αλλάζει τιμές σε κοινά μέλη και προσθέτει μέλη που δεν υπάρχουν στη τελική από αυτήν που εκχωρούμε. Με τους δείκτες υπάρχει διαφορά. Οι δείκτες αλλάζουν αυτό που δείχνουν! Αν δώσουμε το 0& (0 σε τύπο μακρύ) τότε απελευθερώνουν το όποιο αντικείμενο, αλλά συνεχίζει ο τύπος να παραμένει ο ίδιος (απλά δεν έχει μέλη).
Οι ομάδες δεν έχουν τύπους, αλλά μπορούμε να κάνουμε έλεγχο αν η Α έχει τουλάχιστον τα μέλη που έχει η Β.
Οι ομάδες χωρίζονται σε επώνυμες και ανώνυμες. Στο παράδειγμα οι ομάδες στο πίνακα Α() είναι ανώνυμες (ή πτητικές επειδή μπορούν να μετακινηθούν, πχ να επιστραφεί ο πίνακας, άρα και οι ομάδες μαζί). Οι δείκτες μπορούν να δείχνουν και σε ανώνυμες και σε επώνυμες (αν δείχνουν σε επώνυμες είναι στην ουσία ισχνές αναφορές, και αν χαθεί το πραγματικό αντικείμενο που δίνει η ισχνή αναφορά, θα είναι μη έγκυροι δείκτες).


Ομάδα ΜιαΟμάδα {
      Ιδιωτικό:
            χ=10
      Δημόσιο:
            Τμήμα Εμφάνιση {
                  Τύπωσε
            }
            Τμήμα Εκχώρηση (α) {
                  αν α>200 τότε λάθος "εισαγωγή εκτός ορίου"
                  <=α
            }
            Συνάρτηση χ {
                  =
            }
}
ΜιαΟμάδα.Εμφάνιση
ΜιαΟμάδα.Εκχώρηση 50
ΜιαΟμάδα.Εμφάνιση
Πίνακας Α(1 έως 10)=ΜιαΟμάδα
Α(1).Εμφάνιση
Α(1).Εκχώρηση 100
Τύπωσε Α(1).χ()=100, Α(2).χ()=50





\\ με χρήση δεικτών (προχωρημένο)
\\ αλλάζουμε τη Ζ και αλλάζει η Α(1)
Ζ->Α(1)
Ζ=>Εκχώρηση 100
Τύπωσε Α(1).χ()=100, Ζ=>χ()=100
Α(1).Εκχώρηση 150
Τύπωσε Α(1).χ()=150, Ζ=>χ()=150
Ζ->Α(2)
Τύπωσε Α(1).χ()=150, Ζ=>χ()=50
Ζ->Α(1)
Τύπωσε Α(1).χ()=150, Ζ=>χ()=150



2. Δομές Μνήμης
Οι δομές ορίζουν το πως θα ορίζεται μια έκταση μνήμης. Εκτάσεις μνήμης παράγουμε με την Διάρθρωση ή Buffer. Τις χρησιμοποιούμε όταν καλούμε εξωτερικές βιβλιοθήκες και θέλουμε να δωσουμε  διευθύνσης μνήμης. Μπορούμε να έχουμε μπλοκ εντός της δομής για να ορίσουμε ενώσεις (unions). Οι απλές δομές ψηφίο (8bit), ακέραιος (16bit), μακρύς (32bit) παίρνουν τιμές χωρίς πρόσημο (πχ στο ψηφίο βάζουμε από 0 έως 255). Αν βάλουμε μεγαλύτερο δεν βγαίνει λάθος θα μπει το υπόλοιπο της ανάλογης διαίρεσης. Μπορούμε σε 4byte να βάλουμε απλό πραγματικό και σε 8byte να βάλουμε διπλό πραγματικό. Τα ονόματα εντός της δομής είναι ιδιωτικά, και τα βλέπουν ειδικές εντολές.
Η διάρθρωση είναι αντικείμενο και μπορεί να επιστραφεί από συναρτήσεις. Αν καμία μεταβλητή δεν κρατάει τη διάρθρωση τότε διαγράφεται. Μπορούμε να αυξήσουμε ή να μειώσουμε τον αριθμό των περιεχόμενων δομών, αλλά δεν μπορούμε να αλλάξουμε τη βασική δομή (μπορούμε όμως να έχουμε ενώσεις στη δομή και έτσι να βλέπουμε με πολλούς τρόπους τα ίδια δεδομένα). Υπάρχει μια ειδική διάρθρωση, η Διάρθρωση Κώδικας η οποία μπορεί να έχει κώδικα σε γλώσσα μηχανής. Όταν καλούμε για εκτέλεση κώδικα από τη διάρθρωση τότε αυτή κλειδώνει για αλλαγές, πρέπει να έχουμε μια άλλη διάρθρωση για να  πάρουμε αποτελέσματα.



Δομή Πελάτης {
      ΌνομαΠελάτη ως ακέραιος*30 ' 2*30
      Τηλεφωνο ως ακέραιος*20 ' 2*20
      Πληροφορίες ως γράμμα ' μεταβλητό (είναι δείκτης σε αλφαριθμητικό)
}
Τύπωσε Μήκος(Πελάτης)=104
Διάρθρωση Κενή Επαφές ως Πελάτης*100
Τύπωσε Μήκος(Επαφές)=10400
Εδώ=0
Επιστροφή Επαφές, Εδώ!ΌνομαΠελάτη:="Πέτρος Πέτρου"
Επιστροφή Επαφές, Εδώ!Τηλέφωνο:="0123012312", 0!Πληροφορίες:="Ο,τι να είναι"
Τύπωσε Εκφρ$(Επαφές,Εδώ!ΌνομαΠελάτη, 60)
Τύπωσε Εκφρ$(Επαφές,Εδώ!Τηλέφωνο, 40)
Τύπωσε Εκφρ$(Επαφές,Εδώ!Πληροφορίες)
Τύπωσε Επαφές(0) ' δίνει τη διεύθυνση στη μνήμη
Τύπωσε Επαφές(1) -Επαφές(0) =104





Μέρη Προγράμματος:



Στη ΓΛΩΣΣΑ αναφέρονται τα μέρη του προγράμματος, ως τμήματα: Η επικεφαλίδα, το τμήμα δήλωσης σταθερών, το τμήμα δήλωσης μεταβλητών, το κυρίως σώμα. τα υποπρογράμματα. Τα τμήματα δηλώσεων δεν είναι υποχρεωτικά.



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



Τα τμήματα της Μ2000 μπορούν να έχουν ρουτίνες (υπορουτίνες όπως στη ΓΛΩΣΣΑ στο τέλος του κώδικά τους). Οι συναρτήσεις στη ΓΛΩΣΣΑ γράφονται στις δηλώσεις υποπρογράμματων, ενώ στη Μ2000 είναι σαν τα τμήματα, γράφονται οπουδήποτε, και μπορούν να έχουν τμήματα., συναρτήσεις, και ρουτίνες.




Υποπρογράμματα:

Στη ΓΛΩΣΣΑ όλα τα υποπρογράμματα είναι γενικά! Δηλαδή από κάθε υποπρόγραμμα μπορούμε να καλέσουμε ένα οποιοδήποτε άλλο. Στη Μ2000 ένα τμήμα μπορεί να καλέσει ένα γενικό τμήμα ή ένα τμήμα που ορίστηκε σε αυτό, αλλά όχι τον εαυτό του, και όχι τμήματα σε άλλα τμήματα. Οι ρουτίνες (υποπρογράμματα σε τμήματα) μπορούν να καλέσουν οποιαδήποτε ρουτίνα υπάρχει στο τμήμα, και τον εαυτό τους. Οι ρουτίνες στη Μ2000 γράφονται στο τέλος. Μπορούμε να καλέσουμε τμήματα και συναρτήσεις που είναι δημόσια σε αντικείμενα τύπου ομάδας.

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



Πέρασμα Τιμών:



Γλώσσα:
  • Πέρασμα με αναφορά εκτός αν δεν γίνεται αλλιώς (πχ μόνο με τιμή σε Συνάρτηση, ή έχουμε έκφραση ως παράμετρο)
  • Ορίζουμε στην αρχή τύπο παραμέτρων για τα υποπρογράμματα (τις λέμε τυπικές παραμέτρους)
  • Όλες οι παράμετροι κατά τη κλήση πρέπει να είναι επακριβώς όπως ορίστηκαν ως τυπικές παράμετροι στο υποπρόγραμμα, αν περνάνε με αναφορά, ή με εκφράσεις που δίνουν τον ίδιο τύπο, και ενημερώνονται οι τυπικές παράμετροι στην αρχή της κλήσης. Αν θέλουμε μια μεταβλητή να περαστεί με τιμή, τότε την βάζουμε σε παρένθεση (την δίνουμε σαν παράσταση)
  • Στις Συναρτήσεις δεν μπορούμε να περάσουμε με αναφορά μεταβλητές (οι συναρτήσεις έχουν μια επιστροφή τιμής).
  • Στις Συναρτήσεις ορίζουμε επακριβώς τον τύπο της τιμής επιστροφής.
  • Οι πίνακες σε πέρασμα με τιμή (σε συναρτήσεις ή διαδικασίες) θα περαστούν με αντιγραφή, Το ίδιο συμβαίνει και στο πέρασμα με αναφορά, και πρέπει να δηλωθεί και στη διαδικασία το μέγεθος του πίνακα. Ο λόγος που γίνεται αυτό είναι για να διατηρηθεί το copy in copy out, που θέλει μια μεταβλητή με αναφορά να αντιγράφει την τιμή της (copy in) κατά την κλήση, και να την αντιγράφει πίσω (copy out) κατά την έξοδο από τη διαδικασία. Υπάρχει μια λογική σε αυτό για πολυεπεξεργασία κάτι όμως που δεν έχει η ΓΛΩΣΣΑ.



Μ2000:



Σίγουρα η Μ2000 έχει περισσότερες δυνατότητες ως προς το πέρασμα τιμών, φαίνεται και από την λίστα παρακάτω, και αυτό ίσως να την βάζει στις δύσκολες γλώσσες. Όμως δεν είναι υποχρεωμένος κανείς να τα χρησιμοποιήσει όλα.
  • Πέρασμα με τιμή εξ ορισμού, και με έμμεσους τρόπους αυτό φαίνεται και ως πέρασμα με αναφορά.
  • Τα περάσματα γίνονται σε ένα σωρό τιμών, που είναι διαχειρίσιμος με εντολές, και ως προς το μέγεθος και ως προς την ανάγνωση τύπου.
  • Η εντολή Διάβασε διαβάζει τα ορίσματα των τυπικών παραμέτρων.
  • Δεν απαιτείται να ορίζουμε στην αρχή παραμέτρους. Ορίζονται με την εντολή Διάβασε οπουδήποτε στο Τμήμα/Συνάρτηση/Ρουτίνα (ο καλούμενος).
  • Λέμε ορίσματα τις τιμές που βάζουμε στο σωρό και αυτές διαβάζονται (και ορίζουν αν δεν υπάρχουν ήδη) τις παραμέτρους από την πλευρά του καλούμενου
  • Δεν γίνεται έλεγχος στο τύπο (εκτός και αν το επιλέξουμε τοπικά, με όνομα στη διαβασε ή με αρχικοποίηση πριν την διάβασε) και στον αριθμό ορισμάτων, όμως το & στην κλήση μπροστά από το όνομα θα δώσει την ισχνή αναφορά του ονόματος ενώ το & στο διάβασμα θα δώσει την ισχνή αναφορά στο όνομα που ακολουθεί (αν δεν ακολουθεί όνομα, ή δεν υπάρχει ισχνή αναφορά τότε βγαίνει λάθος). Ισχνή αναφορά είναι το κλειδί σε μια Λίστα δεδομένων στη Μ2000. (λίστα μεταβλητών, δουλεύει και αυτή με Ο(1) στην αναζήτηση, την προσθήκη και την διαγραφή, και διαγράφονται με την ανάποδη σειρά, και επίσης δέχεται και όμοια ονόματα - και έτσι δουλεύουν και οι σκιάσεις).
  • Αν ζητάμε μια τιμή (δηλαδή αριθμό) και δεν δοθεί θα βγει λάθος.
  • Δεν επιτρέπεται να δώσουμε δεύτερη αναφορά σε ένα όνομα που έχει οριστεί. Αν αυτό είναι απαραίτητο όμως μπορούμε να το κάνουμε σε νέο όνομα που θα σκιάσει το υπάρχον με μια Διάβασε Νέο. Υπάρχει τρόπος να έχουμε ένα μπλοκ κώδικα για προσωρινές μεταβλητές. Αυτό συμβαίνει στις ρουτίνες με παρενθέσεις, στην Για αντικείμενο { }, και στις συναρτήσεις και τμήματα (όμως σε αυτά τα δύο έχουμε αλλαγή χώρου ονόματος, οπότε θα περιοριστεί η θέαση αναγνωριστικών, άρα δεν μετράει το προσωρινό, αφού όλα είναι προσωρινά, δεν έχουμε θέαση σε κάτι που φτιάχτηκε πιο πριν εκτός αν είναι γενικό και δεν το σκιάσουμε, δεν κάνουμε το τοπικό με το ίδιο όνομα). 
  • Μπορούμε να δεχόμαστε προαιρετικές τιμές με την Διάβασε ?. Μπορούμε στην κλήση να δώσουμε το ? ως "αδιάφορο" για να κρατήσει η Διάβασε την τρέχουσα τιμή ή αν δεν υπάρχει την αρχική που προβλέπεται σε μια μεταβλητή. Σε συναρτήσεις μπορούμε απλά να παραλείπουμε τιμές και να παραθέτουμε το κόμμα μέχρι εκεί που θα βάλουμε τιμή). Η δήλωση Κ=10 : Διάβασε ? Κ θα αφήσει την Κ με 10 αν δεν βρει κάτι στο σωρό, ή αν βρει το "αδιάφορο" (το περνάμε με το ?). Όμως αν υπάρχει αλφαριθμητικό θα βγει λάθος! Στη κλήση τμήματος έστω Αλφα αν έχουμε έστω δυο παραμέτρους με προαιρετικό διάβασμα, και δεν θέλουμε να περάσουμε καμία τιμή πρέπει να αποκλείσουμε την περίπτωση να τραβήξει από το σωρό άλλες υπάρχουσες τιμές. Έτσι καλούμε με Άλφα ?, ?
  • Μπορούμε να ορίσουμε αρχική τιμή οπότε αν δεν δώσουμε τιμή θα χρησιμοποιηθεί αυτή. 
Από την 9.5 έκδοση μπορούμε να περνάμε με αναφορά στατικές μεταβλητές (διατηρούν την τελευταία τιμή στη νέα κλήση τμήματος ή συνάρτησης που περιβλαμβάνονται), και στοιχεία πίνακα:


\\ αν αφήσουμε τη Καθαρό, θα σβήσει τις στατικές σε όλα τα περιεχόμενα τμήματα
Σημ : Καθαρό
Συνάρτηση Αύξησε () {
      χ++
}
Τμήμα Δοκίμασέ_με (, &τι()){
      Στατική Κ=10
      χ+=Κ
      Τύπωσε Κ*χ
      \\ Κ++  γίνεται πιο απλά
      Κάλεσε Τι(&Κ)
}
Πίνακας Α(1 έως 10)=1
Για ι=1 έως 10 {
      Δοκίμασέ_με &Α(ι), &Αύξησε()
}
Τύπωσε Α()



Ενώ στη Γλώσσα εκεί που ζητάει αναφορά μπορεί να πάρει έκφραση, στη Μ2000 εκεί που ζητάμε αναφορά θα πρέπει να δώσουμε αναφορά.



Άδειασε  \\ αδειάζει το σωρό



Τμήμα βητα {
       Διάβασε ? X, Y
       Τύπωσε X, Y
       Βάλε 100
}
Συνάρτηση αλφα {
      Διάβασε ? X, Y
      Τύπωσε X, Y
      Βάλε 10
      =0
}



\\ βάζουμε κάτι στο σωρό
Βάλε 1000



\\ ο σωρός θα είναι αυτός του τμήματος
βήτα ?,?



\\ ο σωρός θα είναι νέος
Ν=αλφα(,)



\\ ο σωρός με την κάλεσε θα είναι αυτός του τμήματος
Κάλεσε αλφα(?,?)



\\ μας δείχνει το σωρό
Σωρός



Συνάρτηση Νέα(χ=10, α$="οκ") {
      αν α$="οκ" τότε { =χ**2 } αλλιώς =χ/2
}
Τύπωσε Νέα()=100
Τύπωσε Νέα(5)=25
Τύπωσε Νέα(5, "--")=2.5



  • Στις συναρτήσεις μπορούμε να επιστρέψουμε πολλές τιμές ως πίνακα πχ. το =1,2 θα δώσει πίνακα. Αν θέλουμε να δώσουμε πίνακα ενός στοιχείου θα χρησιμοποιήσουμε το τρόπο δήλωσης αυτόματου πίνακα: (10,)  (δείτε το κόμμα πριν το κλείσιμο), το (,) είναι ο κενός πίνακας ενώ το (1,2) είναι πίνακας δυο στοιχείων.
  • Στις συναρτήσεις το $ στο όνομά τους δηλώνει ότι θα γυρίσουν αλφαριθμητικό, ή αντικείμενο που γυρίζει αλφαριθμητικό. Έτσι στο Α$=Συναρτ$() το Α$ μπορεί να είναι αλφαριθμητικό ή αντικείμενο που γυρνάει αλφαριθμητικό. 
  • Οι πίνακες μπορούν να περαστούν με αντιγραφή, με αναφορά, με δείκτη. Επειδή η αντιγραφή θα γίνει στο διάβασμα, αν στο διάβασμα ζητάμε δείκτη τότε θα πάρουμε δείκτη, θα γίνει από πέρασμα με αντιγραφή σε πέρασμα με δείκτη. Στο πέρασμα με αναφορά δεν μπορούμε να το μετατρέψουμε σε πέρασμα με αντιγραφή, άμεσα, αλλά οποτεδήποτε βγάζουμε αντίγραφο πίνακα.
  •  Οι συναρτήσεις μπορούν να περαστούν με αναφορά. Αντί να γραφτεί κάποια ισχνή αναφορά σε μια συνάρτηση θα γραφτεί απευθείας ο κώδικάς της, και έτσι με την Διάβασε θα σχηματιστεί αμέσως μια νέα συνάρτηση με αυτόν τον κώδικα. Μπορούμε να περάσουμε μια ανώνυμη συνάρτηση ως αλφαριθμητικό έτσι: "{Διάβασε Χ : = Χ*Χ}"


Εκχώρηση τιμής:
Στη ΓΛΩΣΣΑ η εκχώρηση γίνεται με το <-, με δυο χαρακτήρες ή ένας ←(unicode). Στη Μ2000 υπάρχουν τρία σύμβολα εκχώρησης: =. <= και :=. Το = δημιουργεί τοπική μεταβλητή αν δεν υπάρχει (εκτός και αν στην γραμμή εμφανίζεται μια λέξη από τα Γενικό ή Γενική ή Γενικές). Το <= αλλάζει τιμές σε γενικές, και σε μέλη αντικειμένων (εντός τμημάτων τους). Το := χρησιμοποιείται για εκχώρηση πολλαπλών τιμών σε πίνακες (και το = μπορεί να χρησιμοποιηθεί για πολλαπλές τιμές σε πίνακες), καθώς και για τιμές σε εντολές για πολλαπλές εκχωρήσεις σε αντικείμενα.

Στη Μ2000 το Α%=-5.5 θα κάνει το Α% να έχει τιμή -6, δηλαδή θα γίνει αυτόματη μετατροπή σε ακέραιο. Στη ΓΛΩΣΣΑ αυτό δεν επιτρέπεται, ενώ επιτρέπεται να δώσουμε ακέραια τιμή σε πραγματικό (όπως και στη Μ2000).


Τυπική εμφάνιση κώδικα στη ΓΛΩΣΣΑ:
Μια εντολή ανά γραμμή. Στη Μ2000 εκτός από μια περίπτωση που μόνο μια εντολή μπορούμε να βάλουμε σε μια γραμμή (στην δομή Επίλεξε, αν δεν βάλουμε μπλοκ εντολών με αγκύλες), σε κάθε άλλη περίπτωση μπορούμε με διαχωριστική άνω και κάτω τελεία να βάζουμε εντολές (όπως στη BASIC)
Η Γλώσσα πάντα εμφανίζεται μια γραμμή εντολών σε μια γραμμή στον διορθωτή της. Στη Μ2000 μπορούμε να ορίσουμε αναδίπλωση λέξης και να έχουμε μια γραμμή εντολών που να εμφανίζεται σε πολλές γραμμές (με F1 αλλάζουμε από αναδίπλωση σε χωρίς αναδίπλωση). Μπορούμε να έχουμε αλφαριθμητικές σταθερές πολλαπλών παραγράφων, και με την αναδίπλωση μας βοηθάει να τις βλέπουμε και να τις διορθώνουμε).
Στη Μ2000 μπορούμε να βάζουμε αριθμούς γραμμων πριν από εντολές (μεχρι 5 ψηφία και μπορούν να υπάρχουν μηδενικά στην αρχή πχ το 0010 είναι το 10. Οι αριθμοί έχουν την λειτουργία των ετικετών, και μπορούν να μπουν όπως θέλουμε.



προς 10
εξοδος
0010 τύπωσε "10"


Έτοιμες Συναρτήσεις:
Η ΓΛΩΣΣΑ έχει την E() ως eX
Στη Μ2000 πρέπει να την ορίσουμε:


Κάνε εκθ(χ)= 2.71828182845905^χ
Τύπωσε Λφ(εκθ(1.24412))
Τύπωσε Λφ(2.71828182845905)


Στη ΓΛΩΣΣΑ έχουμε το ΛΟΓ() για φυσικό λογάριθμο, ενώ στη Μ2000 αυτή η συνάρτηση είναι ο δεκαδικός λογάριθμος, και ο ΛΦ() ο φυσικός λογάριθμος. Στα ημίτονα/συνημίτονα έχουμε μοίρες και στις δυο γλώσσες. Το ακέραιο μέρος Α_Μ() στη Μ2000 είναι ΑΚ(), η απόλυτη τιμή Α_Τ() είναι ΑΠΟΛ(). Η εφαπτομένη ΕΦ() είναι στη Μ2000 ως ΕΦΑΠ(), ενώ υπάρχει και το ΤΟΞ.ΕΦ() για το τόξο εφαπτομένης. Η τετραγωνική ρίζα Τ_Ρ υπάρχει ως ΡΙΖΑ(). Τέλος η Μ2000 έχει έναν μεγάλο αριθμό συναρτήσεων που σχετίζονται με δεδομένα, με ώρα, με χρόνο, με συγκρίσεις, καθώς επίσης και συναρτήσεις για αλφαριθμητικά που λείπουν από την ΓΛΩΣΣΑ.



Η εντολή ΓΡΑΨΕ στη ΓΛΩΣΣΑ:
Η αντίστοιχη στη Μ2000 είναι η ΤΥΠΩΣΕ (ενώ υπάρχει η ΓΡΑΨΕ για αρχεία). Υπάρχουν πολλές διαφορές γιατί στην ΤΥΠΩΣΕ η Μ2000 λογαριάζει στήλες και τρόπο στοίχισης σε αυτές, και μπορούν να μεταβληθούν. Ο δρομέας χαρακτήρων μπορεί να τοποθετηθεί όπου θέλουμε με συντεταγμένες γραμμή και στήλη. Οι πίνακες και άλλες δομές εμφανίζουν άμεσα τις τιμές τους με την Τύπωσε:



Πίνακας Α(4)
Α(0):=1,2,3,4
Τύπωσε Α()



Η εντολή ΔΙΑΒΑΣΕ στη ΓΛΩΣΣΑ:
Η ΔΙΑΒΑΣΕ εισάγει τιμές σε μεταβλητές που πληκτρολογούμε. Στη Μ2000 αυτό το κάνει η εντολή ΕΙΣΑΓΩΓΗ ενώ η ΔΙΑΒΑΣΕ διαβάζει από το σωρό τιμών. Επίσης η εντολή ΕΙΣΑΓΩΓΗ με αριθμό αρχείου (μεταβλητή με # στην αρχή) διαβάζει τιμές από αρχείο που έχει γραφτεί με την ΓΡΑΨΕ, ενώ η ΕΙΣΑΓΩΓΗ ΓΡΑΜΜΗΣ διαβάζει από αρχείο ολόκληρη γραμμή που έχει τυπωθεί με την ΤΥΠΩΣΕ και με αριθμό αρχείου. Η ΓΛΩΣΣΑ δεν υποστηρίζει αρχεία, αλλά μπορούν έμμεσα να χρησιμοποιηθεί τουλάχιστον ένα αρχείο εισαγωγής τιμών σε περιβάλλον διερμηνευτή.



Ανάπτυξη Δομών Ροής/Προγράμματος:
Στη ΓΛΩΣΣΑ υπάρχουν δυο λέξεις (αναγνωριστικά) τουλάχιστον που ενσωματώνουν κώδικα, μια λέξη αρχής και μια λέξη τέλους. Στην Μ2000 κώδικας ενσωματώνεται σε αγκύλες { } εκτός:
Η ΓΙΑ ή οποία έχει δυο τρόπους, έναν με αγκύλες και έναν χωρίς, και η Αν Τότε ή Αν Αλλιώς όταν δεν χρησιμοποιούμε άλλο μέρος (πχ Αλλιώς.Αν ή Τότε πριν την Αλλιώς). Ειδικά στην Αν μετά την Τότε (αν δεν υπάρχει η Αλλιώς μετά) μπορούμε σε μια γραμμή να βάλουμε εντολές με διαχωριστική άνω και κάτω τελεία μέχρι το τέλος της παραγράφου.


Η εντολή ΑΝ στη ΓΛΩΣΣΑ:
Στις συγκρίσεις η Μ2000 χρησιμοποιεί και το == για αριθμητικές εκφράσεις, με περιορισμό στην ακρίβεια κατά τη σύγκριση.
Η ΑΝ έχει ακόμα τέσσερα αναγνωριστικά, την ΤΟΤΕ, την ΑΛΛΙΩΣ_ΑΝ, την ΑΛΛΙΩΣ και την ΤΕΛΟΣ_ΑΝ
Ομοίως στη Μ2000 η ΑΝ έχει την ΤΟΤΕ, την ΑΛΛΙΩΣ.ΑΝ την ΑΛΛΙΩΣ αλλά δεν έχει κάποια "τέλος αν" γιατί τελειώνει στο τέλος της παραγράφου (ή γραμμής) ή αν ξεκινάει μπλοκ σε αγκύλες στο τέλος του μπλοκ.
Πχ στη Μ2000
Αν Χ>5 Τότε {
εντολες.....
}
Αν Χ=10 Τότε Εντολη1 : Εντολη2:............ ΕντολήΝ
Δείτε εδώ με την Αλλιώς στη θέση της Τότε δηλαδή εκτελείται όταν το Ζ δεν θα είναι ίσο με 100
Αν Ζ=100 Αλλιώς Εντολή1: Εντολη2:......ΕντολήΝ


Και εδώ με όλα τα καλά:
Αν Χ>10 Τότε { εντολές...
} Αλλιώς.Αν Χ<-20 Τότε { εντολές...
} Αλλιώς.Αν Χ<-10 Τότε { εντολές...
} Αλλιώς { εντολές...
}


Η εντολή ΕΠΙΛΕΞΕ στη ΓΛΩΣΣΑ:Εδώ έχουμε τα αναγνωριστικά ΠΕΡΙΠΤΩΣΗ, ΠΕΡΙΠΤΩΣΗ_ΑΛΛΙΩΣ. ΤΕΛΟΣ ΕΠΙΛΟΓΩΝ
η διάρθρωση είναι ως εξής:
ΕΠΙΛΕΞΕ έκφραση
ΠΕΡΙΠΤΩΣΗ τύπος_εκφρασης [, τ τύπος_εκφρασης]
εντολή
ΠΕΡΙΠΤΩΣΗ_ΑΛΛΙΩΣ.
εντολή
ΤΕΛΟΣ_ΕΠΙΛΟΓΩΝ



Στη Μ2000 είναι περίπου ίδιο:
ΕΠΙΛΕΞΕ ΜΕ έκφραση
ΜΕ τύπος_εκφρασης [, τ τύπος_εκφρασης]
μια εντολή ή ενα μπλοκ εντολών με αγκύλες
ΑΛΛΙΩΣ
μια εντολή ή ενα μπλοκ εντολών με αγκύλες
ΤΕΛΟΣ ΕΠΙΛΟΓΗΣ


στο τύπο_εκφρασης και στις δυο γλώσσες υπάρχουν τρία είδη:
1. έκφραση
2. μισή έκφραση σύγκρισης πχ. >100 (στη Μ2000 μπορούμε να βάλουμε μια ΚΑΙ ή μια Η και μια άλλη έκφραση στη συνέχεια, πράγμα που δεν γίνεται στην ΓΛΩΣΣΑ)
3. διάστημα τιμών όπου στη ΓΛΩΣΣΑ δηλώνεται με δυο τελείες ενώ στην Μ2000 με την ΕΩΣ



Η Με εκτός δομής Επίλεξε έχει άλλη λειτουργία στη Μ2000 (σχετίζεται με ιδιότητες αντικειμένων)



Η εντολή ΓΙΑ στη ΓΛΩΣΣΑ:

Εδώ υπάρχουν διαφοροποιήσεις, και σε αναγνωριστικά και σε λειτουργία.
ΓΙΑ π ΑΠΟ 10 ΜΕΧΡΙ 1 ΜΕ_ΒΗΜΑ -0.5
ΓΡΑΨΕ π
ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ

Το ΜΕ_ΒΗΜΑ μπορεί να γραφεί χωρίς την κάτω παύλα, και είναι προαιρετικό (οπότε νοείται ως ένα).



Στη Μ2000 το αναγνωριστκό ΑΠΟ είναι η πύλη XOR ( όπως το ΚΑΙ είναι η πύλη AND) και χρησιμοποιείται σε λογικές εκφράσεις. (ΚΑΙ, Η, ΑΠΟ), όταν βρίσκεται σε αριθμητικές εκφράσεις. Επίσης υπάρχει και εντολή ΑΠΟ: Από Έκφραση Προς Ετικέτα1, .... και Από Έκφραση Διαμέσου Ετικέτα1, Ετικέτα2, .....



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



ΓΙΑ π=10 ΕΩΣ 1 ΑΝΑ 0.5
      ΤΥΠΩΣΕ π
ΕΠΟΜΕΝΟ π
ή το πιο γρήγορο:
ΓΙΑ π=10 ΕΩΣ 1 ΑΝΑ 0.5 {
      ΤΥΠΩΣΕ π
}


Αν το βήμα δεν δοθεί τότε θεωρείται ως 1 (πάντα το θετικό). Στη ΓΛΩΣΣΑ μπορεί θα πάρει αρχική τιμή ο μετρητής όπως και να έχει, ακόμα και να δεν εκτελεστούν οι εντολές εντός της ΓΙΑ. Στη Μ2000 και ο μετρητής θα πάρει την αρχική τιμή και δεν υπάρχει περίπτωση να μην εκτελεστεί μια φορά η ΓΙΑ, γιατί ο έλεγχος γίνεται στο τέλος κάθε εκτέλεσης και όχι στην αρχή.
Επιπλέον μια διαφοροποίηση σε σχέση με την ΓΛΩΣΣΑ είναι η έξοδος από μπλοκ με αγκύλες με την ΕΞΟΔΟΣ και η έξοδος από το ΓΙΑ ...ΕΠΟΜΕΝΟ με την ΕΞΟΔΟΣ ΓΙΑ, όπως επίσης και η έξοδος με ΠΡΟΣ (GOTO) από μπλοκ με αγκύλες (τερματίζει και την μέτρηση χωρίς αλλαγή του μετρητή, από την τελευταία)



Μπορεί να αλλάξει ο τρόπος της Για Εως Ανά Επόμενο ή Για Εώς Ενά {} με αλλαγή διακόπτη ώστε να λειτουργεί όπως στην BASIC δηλαδή στο βήμα να μετράει το πρόσημο κάθε φορά και έτσι να υπάρχει περίπτωση να μην εκτελεστή η Για. Ο διερμηνευτής έχει ορισμένους διακόπτες για να προσαρμόζουν την συμπεριφορά του. Υπάρχει επιλογή για το τρόπο που δουλεύουν οι Div Mod (Δια και Υπόλοιπο ή Υπολ), όπως στη VB6 ή όπως στην Python. Επιπλέον υπάρχει επιλογή για το αν οι συγκρίσεις των αλφαριθμητικών θα γίνονται δυαδικά ή βάσει σειράς ταξινόμησης.


Υπάρχει στη Μ2000 μια άλλη δομή Για όπου παίρνει ονόματα αντικειμένων και ακολουθεί μπλοκ εντολών που σχετίζονται με αυτά τα ονόματα.



Ομάδα Αλφα {
      Χ=10, Ψ=30
}
Για Αλφα {
      Τύπωσε .Χ,
}


Στη Μ2000 αν χρησιμοποιήσουμε ακέραιο για μετρητή θα έχουμε πρώτα μετατροπή σε ακέραιο τα όρια και το βήμα:



για ι%=0.2 εως 10.3 ανά .6 {
      Τύπωσε ι%
}



θα τυπώσει από το 0 έως το 10
Επίσης στη Μ2000 αν πειράξουμε το μετρητή στο μπλοκ δεν υπάρχουν επιπτώσεις, γιατί αυτό που διαβάζουμε είναι το αντίγραφο του κανονικού μετρητή και ενημερώνεται στο τέλος του μπλοκΟ μ
Το παρακάτω θα τρέξει στη Μ2000



Για χ=1 έως 3 {
      ν=χ
      Για χ=5 εως 2 {
            Τύπωσε χ, ν
      }    
}



όπως και αυτό:



Για χ=1 έως 3
      ν=χ
      Για χ=5 εως 2
            Τύπωσε χ, ν
      Επόμενο χ
Επόμενο χ

Ο μόνος τρόπος να αλλάξει ο μετρητής ενώ τερματίσουμε το μπλοκ σε νούμερο που θέλουμε και δεν βγαίνει με την μέτρηση, είναι με την χρήση της ΠΡΟΣ, όπου εδώ λέμε ότι αν το ι=5 τότε κάνουμε το ι=100 (που γίνεται) και κάνουμε άμεση έξοδο με την προς ααα ή με απλή εντολή Έξοδος. (με την Προς κατευθύνουμε τη ροή εκεί που θέλουμε)






Για ι=1 εως 10 {
      αν ι=5 τότε ι=100 : προς ααα
}
ααα:
Τύπωσε ι



ή



Για ι=1 εως 10 {
      αν ι=5 τότε ι=100 : έξοδος
}
Τύπωσε ι



Η ΓΛΩΣΣΑ δεν έχει την ΠΡΟΣ (GOTO). Η Μ2000 υποστηρίζει και ρουτίνες με κλήση ετικετών με την ΔΙΑΜΕΣΟΥ ή GOSUB (εντολές της BASIC). Οι ετικέτες στην Μ2000 είναι ονόματα με το διαχωρισιτκό άνω και κάτω τελεία. Στη κλήση δεν βάζουμε το διαχωριστικό στο όνομα. Όπως στο παράδειγμα το Προς γίνεται προς ααα και παρακάτω υπάρχει το ααα: Μετά από μια ετικέτα στην ίδια γραμμή μπορούμε να βάλουμε μόνο σημειώσεις με ' ή με \



Εντολή Όσο στη ΓΛΩΣΣΑ:
Χρησιμοποιεί τα ΕΠΑΝΑΛΑΒΕ και ΤΕΛΟΣ ΕΠΑΝΑΛΗΨΗΣ. Στο παράδειγμα βλέπουμε το DIV, το οποίο έχει παραμείνει με την αγγλική ονομασία. Στην Μ2000 είναι το ΔΙΑ και εφαρμόζεται οπουδήποτε, δηλαδή και σε πραγματικούς. Το Mod είναι το Υπόλοιπο ή Υπολ (στη Μ2000 μπορούμε να βάζουμε τόνους στις εντολές, και κατά την εκτέλεση ο διερμηνευτής τους αφαιρεί, δουλεύοντας με κεφαλαία)




ΟΣΟ α >= 2 ΕΠΑΝΑΛΑΒΕ
α <- α DIV 2
ι <- ι + 1
ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ


Η αντίστοιχη στη Μ2000 είναι η Ενώ



Ενώ α>=2 {
εντολές
}

Γράφεται και έτσι
Ενώ α>=2
εντολές
Τέλος Ενώ


Η ενώ δουλεύει και με ένα αντικείμενο που λέγεται επαναλήπτης. Η μεταβλητή Α είναι δείκτης σε Πίνακα. Η ΚΑΘΕ() παράγει ένα αντικείμενο επαναλήπτη που συνδέεται με ένα αντικείμενο και κρατάει δικό του δρομέα. Υπάρχουν δυο τρόποι να δώσουμε αρχή και τέλος, με λέξεις ή με αριθμούς όπου το -1 είναι το τέλος, και το 1 η αρχή. Τα Γ^ και Β^ είναι οι μετρητές. Μπορούμε να αλλάξουμε τα Γ και Β μέσα στις ΕΝΩ {} με νέα ΚΑΘΕ(). Εκτός από δείκτη σε πίνακα η ΚΑΘΕ() δουλεύει με Κατάσταση (λίστα με κλειδί και τιμή) και Σωρό (συνδεδεμένη λίστα τιμών)



Α=(10, 15, 20)
Β=ΚΑΘΕ(Α ΤΕΛΟΣ ΕΩΣ ΑΡΧΗ)
Γ=ΚΑΘΕ(Α, 1, 3)
ΕΝΩ Γ {
      ΕΝΩ Β {
          ΤΥΠΩΣΕ ΠΙΝΑΚΑΣ(Γ), ΠΙΝΑΚΑΣ(Β)
      }
}




Πώς γίνεται και η αριθμητική έκφραση στη Ενώ μπορεί να γυρίσει αντικείμενο; Στη Μ2000 όλες οι παραστάσεις μπορούν να γυρίζουν αντικείμενο. Όταν δεν επιστρέφουν αντικείμενο τότε αυτό είναι "ΤΙΠΟΤΑ" και ο διερμηνευτής δίνει τον αριθμό ή το αλφαριθμητικό και όχι το "ΤΙΠΟΤΑ".
Στη Μ2000 δεν μπορούμε να πειράξουμε δείκτες σε αντικείμενα, αλλά μπορούμε να αλλάξουμε ένα δείκτη με έναν άλλο δείκτη. Εκτός από ειδικά αντικείμενα, όσα είδαμε εδώ όπως ο δείκτης σε πίνακας, σε Κατάσταση και σε Σωρό, δεν μπορούν να πάρουν "τίποτα" αλλά μπορούν να πάρουν νέο πίνακα, κατάσταση, σωρό και ο παλιός να "εξαφανιστεί" αν δεν υπάρχει άλλος δείκτης να τον "κρατάει" εν ζωή.
Τα βασικά αντικείμενα, οι Ομάδες, δεν έχουν πολλαπλούς δείκτες, δηλαδή δεν γίνεται να κρατηθεί μια ομάδα αν χαθεί ο δείκτης σε αυτήν, διότι ποτέ δεν υπάρχει δεύτερος. Έτσι στις ομάδες δεν γίνεται να έχουμε κυκλικές αναφορές! Όλα αυτά περί ομάδων και αντικειμένων δεν έχουν καμία αντιστοιχία με τη ΓΛΩΣΣΑ του σχολείου. Δεν υποστηρίζει αντικείμενα!



Η εντολή ΑΡΧΗ_ΕΠΑΝΑΛΗΨΗΣ στη ΓΛΩΣΣΑ
Για να έχουμε επανάληψη ενός αριθμού εντολών με έλεγχο συνθήκες στο τέλος, χρειάζεται να γραφτεί το ΑΡΧΗ_ΕΠΑΝΑΛΗΨΗΣ ώστε να μαρκάρει την αρχή, και στο τέλος των εντολών που ενδέχεται να εκτελεστούν ξανά θα έχουμε την ΜΕΧΡΙΣ_ΟΤΟΥ με την συνθήκη προς έλεγχο. 


ΑΡΧΗ_ΕΠΑΝΑΛΗΨΗΣ
ΓΡΑΨΕ 'Δώσε βαθμό:  '
ΔΙΑΒΑΣΕ βαθμός
ΜΕΧΡΙΣ_ΟΤΟΥ βαθμός >= 0 




Η Μ2000 έχει την εντολή ΕΠΑΝΑΛΑΒΕ (ή ΕΠΑΝΕΛΑΒΕ) με ένα μπλοκ και μια από τις δυο συνέχειες: Μέχρι συνθήκη ή Πάντα:



ΕΠΑΝΑΛΑΒΕ {
εντολές....
} ΜΕΧΡΙ συνθήκη



ή χωρίς συνθήκη
ΕΠΑΝΑΛΑΒΕ {
εντολές....
} ΠΑΝΤΑ


Γράφονται και χωρίς μπλοκ  { }

ΕΠΑΝΑΛΑΒΕ
εντολές....
ΜΕΧΡΙ συνθήκη



ή χωρίς συνθήκη
ΕΠΑΝΑΛΑΒΕ
εντολές....
ΠΑΝΤΑ



Η δεύτερη γράφεται και έτσι:


{
εντολές...
Κυκλικά
}



Η εντολή Κυκλικά σηκώνει μια "σημαία" μέσα στο μπλοκ και όταν το μπλοκ φθάσει στο τέλος του τότε κοιτάει την σημαία και ανάλογα συνεχίζει εκτός μπλοκ ή εκτελεί το μπλοκ πάλι.
Ο διερμηνευτής ξεχωρίζει πάντα ποιο μπλοκ με αγκύλες είναι σταθερά αλφαριθμητική και ποιο είναι εντολές. (και ο χρωματιστής του διορθωτή). Αυτό συμβαίνει γιατί είναι γνωστό που ακριβώς μπαίνουν τα μπλοκ εντολών, σε ποιες εντολές δηλαδή. Μπορούμε όμως να ξεκινήσουμε ένα μπλοκ οπουδήποτε θα ξεκινούσαμε με μια εντολή. Οι εντολές για τα μπλοκ (οποιοδήποτε ακόμα και αυτό του ΓΙΑ), είναι η ΚΥΚΛΙΚΑ,. η ΞΕΚΙΝΑ (κάνει άμεση εκκίνηση ξανά του μπλοκ, η ΣΥΝΕΧΙΣΕ η οποία αν έχει σηκωθεί σημαία κάνει ότι η ΞΕΚΙΝΑ ενώ αν όχι κάνει ότι η ΕΞΟΔΟΣ, και η ΕΞΟΔΟΣ η οποία κάνει άμεση έξοδο από το μπλοκ. Υπάρχει και η ΔΙΕΚΟΨΕ που σπάει πολλά μπλοκ μαζί. Οι εντολές ΣΥΝΕΧΙΣΕ και ΔΙΕΚΟΨΕ έχουν άλλη σημασία στην ΕΠΙΛΕΞΕ ΜΕ όπου μπορούμε με την ΔΙΕΚΟΨΕ να κάνουμε εκτέλεση όλων των εντολών ΜΕ που ακολουθούν, μέχρι το τέλος ή να βρεθεί η ΣΥΝΕΧΙΣΕ και να το σταματήσει!


Χ=10
Κ=50 \\ με Κ=20 το οκ2 δεν θα εμφανιστεί
ΕΠΙΛΕΞΕ ΜΕ Χ
ΜΕ 10
{
      ΤΥΠΩΣΕ "ΘΑ ΕΜΦΑΝΙΣΩ ΤΑ οκ1 ΚΑΙ οκ2"
      ΔΙΕΚΟΨΕ
}
ΜΕ 100
{
      ΤΥΠΩΣΕ "οκ1"
      ΑΝ Κ=20 ΤΟΤΕ ΣΥΝΕΧΙΣΕ
}
ΜΕ 200
      ΤΥΠΩΣΕ "οκ2"
ΑΛΛΙΩΣ
      ΤΥΠΩΣΕ "οκ3"
ΤΕΛΟΣ ΕΠΙΛΟΓΗΣ



Η εντολή ΚΑΛΕΣΕ στη ΓΛΩΣΣΑ
Στη ΓΛΩΣΣΑ για να καλέσουμε ένα υποπρόγραμμα πρέπει να χρησιμοποιήσουμε την ΚΑΛΕΣΕ



ΠΡΟΓΡΑΜΜΑ ΗΕντολήΚάλεσε
!Επιδεικνύει απλά τη χρήση της εντολής.
ΑΡΧΗ
ΚΑΛΕΣΕ ΓράψεΌνομα('My name is Bond. James Bond.')
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ


ΔΙΑΔΙΚΑΣΙΑ ΓράψεΌνομα(όνομα)

ΜΕΤΑΒΛΗΤΕΣ
ΧΑΡΑΚΤΗΡΕΣ: όνομα
ΑΡΧΗ
ΓΡΑΨΕ όνομα
ΤΕΛΟΣ_ΔΙΑΔΙΚΑΣΙΑΣ 
 
Σε Μ2000, υπάρχει η ΚΑΛΕΣΕ και καλεί με έναν δεύτερο τρόπο την ΑΛΦΑ. Ο κανονικός είναι χωρίς την ΚΑΛΕΣΕ. Για να καταλάβουμε τη διαφορά αρκεί να βάλουμε στην ΡΟΥΤΙΝΑ, μετά την ΤΥΠΩΣΕ Α$ την εντολή ΛΙΣΤΑ η οποία δείχνει τα ονόματα των μεταβλητών.
Δείτε επίσης ότι η Ρουτίνα μπορεί να κληθεί με την ΔΙΑΜΕΣΟΥ, και πως η Α$ στην ρουτίνα είναι τοπική μεταβλητή. Μπορούμε να έχουμε όσα τμήματα θέλουμε και σε κάθε τμήμα να έχουμε τμήματα και ρουτίνες, και συναρτήσεις. Οι ρουτίνες είναι μέρη τμημάτων και συναρτήσεων και βλέπουν τις μεταβλητές τους. Έτσι αυτό που γίνεται και στη ΓΛΩΣΣΑ μπορεί να γίνει σε τμήμα της Μ2000. Στο τμήμα ΑΛΦΑ έχουμε το (Α$) το οποίο θα γίνει ΔΙΑΒΑΣΕ Α$ όταν θα γραφτεί στη λίστα τμημάτων από τον διερμηνευτή.



ΤΜΗΜΑ ΑΛΦΑ (Α$) {
      ΔΙΑΜΕΣΟΥ ΓράψεΌνομα(Α$)
      ΓράψεΌνομα("My name is Bond. James Bond.")
      ΤΥΠΩΣΕ Α$+"-"+Α$
      ΡΟΥΤΙΝΑ ΓράψεΌνομα(Α$)
            ΤΥΠΩΣΕ Α$
      ΤΕΛΟΣ ΡΟΥΤΙΝΑΣ
}


ΑΛΦΑ "ΟΚ1"
ΚΑΛΕΣΕ ΑΛΦΑ, "ΟΚ2"



Δείτε σε συνάρτηση πως ορίζουμε προαιρετικό όρισμα:
Το ** όπως και το ^ δίνει την ύψωση σε δύναμη
Συνάρτηση Αλφα {
      Διάβασε Χ
      Υ=2
      Διάβασε ? Υ
      =Χ**Υ
}
Τύπωσε Αλφα(4), Αλφα(4, 3) \\ 16  64



Το ίδιο πρόγραμμα με ρουτίνα στη συνάρτηση:
Συνάρτηση Αλφα {
      Διάβασε Χ
      Υ=2
      Διάβασε ? Υ
      ΚάνεΚάτι()
      Ρουτίνα ΚάνεΚάτι()
            =Χ**Υ
      Τέλος Ρουτίνας
}
Τύπωσε Αλφα(4), Αλφα(4, 3) \\ 16  64



Κυριακή 10 Σεπτεμβρίου 2017

Using Lambda functions to get data

This is an example of creating a group Em as Function Employes() prepate (a Class in M2000 is a function to construct an object). As we see inside Em we have two inventories (lists with keys and data). In EmployId we put objects constructed with internal class Info. In Info class there is a Module Info after a Class: label. This means that this module exist only in first call (at construction). So a Info class create a group with two members, the N$ for Name and Salary for Salary.
We have two inventories, one for sorting names, and one for place info groups (objects in M2000). We use an id, as key in EmploId inventory, and Name as key in EmployName. In EmployName we put as data the id. So we can get from name the id.  (also we can get from id the name and the salary, from EmployId inventory).

We use Add module (in Em object) to add some names and salaries. So now we can pass lambda functions for searching and for display purposes.
Last lines show how to get copies of internal groups, by using name and how to get id by name

Flush
Class Employes {
      id=0
      Inventory EmployId, EmployName
      Class Info {
           N$, Salary
           Class:
           Module Info (.N$, .Salary) {}
      }
      Function NewId {
             .id++
             =.id
      }
      Module Add {
            If Match("SN") then {
                  emp=.Info(Letter$, Number)
                  id=.NewId()
                  Append .EmployId, id:=emp
                  Append .EmployName, emp.n$:=id
                  Sort ascending .EmployName as text
            }
      }
      Module ListAll {
            N=each(.EmployName)
            While N {
                  For This {
                        M=.EmployId(Eval(N))
                        Print  "[";Eval(N);"]", M.N$, M.Salary
                  }
            }
      }
      Function SelectSome {
            Read f \\ a lambda function
            Flush \\ empty stack
            N=each(.EmployId)
            While N {
                  For This {
                        M=Eval(N)
                        If f(&M) Then Data Eval$(N!) \\ put key to end of stack
                  }
            }
            =[] \\ return stack as object
      }
      Module ListIndirect {
            \\ using a stack object
            Read S
            If Match("F") Then {
                  Read f
            } else {
                  f=lambda (M, X)-> {
                        Print X, M.N$, M.Salary
                  }
            }
            N=Each(S)
            While N {
                        Call f(.EmployId(StackItem$(N)), N^+1)
            }
      }
      Property GetName {
            Value (name$) {
                  Link parent EmployName to EmployName
                  Link parent EmployId to EmployId
                  If exist(EmployName, name$) then {
                        Value=EmployId(Eval$(EmployName))
                  }          
            }
      }
      Property GetID {
                  Value (name$) {
                        Link parent EmployName to EmployName

                        If exist(EmployName, name$) then {
                              Value=val(Eval$(EmployName))
                        }    
                  }
            }
}
Em=Employes()
Em.Add "Peter", 3000
Em.Add "Susan", 2000
Em.Add "George", 1000
Em.ListAll
Print "Find all names with salary > 1000"
Em.ListIndirect Em.SelectSome(lambda (&M)->M.Salary>1000), lambda (m)->{Print m.N$}
\\ using default lambda inside ListIndirect
Em.ListIndirect Em.SelectSome(lambda (&M)->M.Salary>1000)

Print "Find all names with salary < 3000"
Print "Using Em.SelectSome and external Stack Object"
St=Em.SelectSome(lambda (&M)->M.Salary<3000)
D=Each(St)
While D {
      For Em.EmployId(StackItem$(D)) {
           Print .N$, .Salary
      }
}
Print "Using Em.ListIndirect and Em.SelectSome together"
Em.ListIndirect Em.SelectSome(lambda (&M)->M.Salary<3000), lambda (m)->{Print m.N$, m.Salary}

Print "Using GetName to get a copy of Employ Info"
Print Em.GetName("George").Salary, Em.GetName("George").N$
Print Em.GetName("Susan").Salary, Em.GetName("Susan").N$
Print "Using Em.GetId to get Id from name"
Print Em.GetId("Peter") \\ 1


We can get names through sorted inventory using alternate SelectSome:
Eval$(N) return data as string, so return key for .EmployId() which return group. Data command push to end - or bottom- of stack (Push command push in front or top of stack). [] is stack as object, which make two things, first return a pointer to stack, and second, place a new stack to current stack (here in this function). Functions have new stack when we call them through expression, but modules have parent stack as current stack.
For This { } open a block for temporary definitions. Here M is always a fresh variable, and after For This {} variable M deleted.
Symbol & before M means pass by reference. We can pass by reference any named variable (we can't pass by reference an item in a position in an array or in an inventory or in a stack object). Objects like array, inventory and stack can be passed by pointer, like passing by reference but not in every aspect. (if we change pointer by point to a new object then we "break" reference). This not happen with M which we pass it by Reference and every member of M passed by reference too. We can also pass only a member of M by reference.
Look f is a variable and read from stack an object, a lambda object. So at "read" interpreter make two things. Moving object from stack to variable f and making a new function f() to call this object. So when we call f(&M) interpreter pass &M as a weak reference to stack (its a string) and call f(), which call specific object. In lambda object, a read command make weak reference a normal reference to a new name, and execute code and then return true (-1) or false (0)
Because we want to use current stack as collection of selected employees. after reading the f (lambda function)  perform a Flush command which empty the stack. So if no employee founded, we return an empty Stack

Function SelectSome {
            Read f \\ a lambda function
            Flush \\ empty stack
            N=each(.EmployName)
            While N {
                  For This {
                        M=.EmployId(Eval$(N))
                        If f(&M) Then Data Eval$(N) \\ put key to end of stack
                  }
            }
            =[] \\ return stack as object
      }


Παρασκευή 8 Σεπτεμβρίου 2017

Use of Lambda functions in M2000 Interpreter

A function inside a lambda function see capture values as local variables. In this example x,y are local to firsr lambda,and captured by value in second lambda (first lambda return a lambda function)

\\ lambda function
b=lambda (x,y) -> {
            =lambda x, y (n) -> {
                  =X**n+Y
            }
}
a=b(10,5)
Print a(2), a(3) \\ 105   1005
a=b(5, 2)
Print a(2), a(3) \\ 27   127


We can add a lambda function in a Group (an object in M2000)

Group alpha {
      N=lambda->0
}
Print alpha.N() \\0
alpha.N=lambda (x)->x**2
Print alpha.N(3) \\ 9

 

Lambda functions are first citizens, so we can assign anytime a diffrent lambda, and maybe with diffrent number of parametes. In M2000 if we place more parameters in a function, is no problem. Stack for parametes is private for a function and always deleted after the call.

Now we make another lambda, with X where we put a 5. Interpreter first make X=100 and in lambda definiton "capture" X in a new X with value 100. But we can change it to value 5. So captured means "new scope", internal to lambda.
X=100
A=lambda X=5 -> {
            X--
            =X \\ change this line with X--
            If x<0 then Error "!!!!write an error string here!!!!!"
      }
While A() {
      Print "ok"
}
Print X \\ X=100

We can pass lambda as parameter without using to bind lambda to name

Module Beta (a) {
      Print a(2,3)
}
Beta lambda (x,y)->x**y+100
Beta lambda (x,y)->x+y
Beta lambda (x,y)->(x*2+y*2)/(x*2-y*2)

Using a pointer to array as captured variable. Here we get fibonacci number but we place it in an array first.. Also for demonstration we use a global var to identify if we pick a new one or pick from array.
M is an new lambda, but because A is a pointer to Array in F we get same pointer to M, so in M we get 20 values without calculations, just reading array.

Global PickNew=0
F=lambda A=(1,1) (x) ->{
      PickNew<=False
      if x<=0 then =Array(A) : Exit
      if x<=Len(A) then =Array(A,x-1) : Exit
      PickNew<=True
      For i=Len(A) to x-1 {
            A=Cons(A,(Array(A,i-1)+Array(A,i-2),))
      }
      =Array(A,Len(A)-1)
}
n=1
For i=1 to 20 step n {
      Print i, F(i), PickNew
}
For i=1 to 20 step n {
      Print i, F(i), PickNew
}
M=F
For i=1 to 20 step n {
      Print i, M(i), PickNew
}


We can place lambda in Array positions. Here we put 10 FibonacciNext in an array, but each one one step next. Then for 5 times we "run" each of these functions.

FibonacciNext=lambda A=0, B=1-> {
      =A
      Push B : B+=A: Read A
}
Dim Base 1, A(10)
For i=1 to 10 {
      A(i)=FibonacciNext
      Print FibonacciNext()
}
For j=1 to 5 {
      For i=1 to 10 {
            Print A(i)(),
      }
      Print
}



Lambda for strings. In M2000 we have to place $ to show in expression evaluator the type of value is string
.
a$=lambda$ (what$)-> what$+" George"
Print a$("Hello")
Print a$("GoodBye")

Call lambda as module:

m=lambda (x)->{
      Print "hello", x
}
call m(200)

Put a lambda in a inventory:

inventory something
append something, "m":=lambda (x,y) ->{
      =x**y
}
print something("m")(2,3)

Put a lambda in an array

Dim arr(3)
arr(0)=lambda (x,y) ->{
      =x**y
}
Print arr(0)(2,3)

Fill Array using a lambda function

c=lambda x=1 ->{=x: x++}
Dim A(100)<<c()
Print A()


Recursion in lambda

p=lambda (x)-> {
      if x<2 then =1 : exit
      =x*lambda(x-1)
}

print p(5)

group M {
      n=lambda->0
      module testme {
            print .n(5)
      }
}
M.testme    \\ print 0
M.n=p
M.testme   \\ print 120




 

Πέμπτη 7 Σεπτεμβρίου 2017

Group Objects Animal-Dog

Clasic Animal-Dog classes example.

We make two classes. Each class is global until module where created erased. A class is a group constructor (group is the object). A group no need  a class to exist. Group are prototypes objects, all with a common interface. We can use labels Public (by default), Private and Class to separate definitions in a group to specific zones. A module with class name is the constructor (is optional). If constructor is part of a Class: zone then this exist only in construct time, and not in the final group. When we call Dog() class function, M2000 interpreter pass parameters to Dog module in a group made in this function (as we call it).
So first we make Alfa as an empty Animal() and then read Alfa.name$, and optionally we can read a boolean for .longtail (look the dot in name).
Secondly we have to change saySomething so we use an extra Group Alfa {} command for adding or changing definitions.
Last is the merging function, we put Alfa to This (This is the current group, which class return).


Class Animal {
      name$=""
      module saySomething {
            print "I am "+.name$
      }
}
Class Dog {
      longtail
Class:
      Module Dog {
            Alfa=Animal()
            Read Alfa.name$
            Read ? .longtail
            Group Alfa {
                  module saySomething {
                        print "I am "+.name$+ ", and I can bark"
                  }
            }
            This<=Alfa
      }
}

dog = Dog("Chiwawa")
dog.saySomething


Another way. Look differences. Dog class not now what group we put in, but  know that a saySomething module must be added or altered. There we use .name$ as part of final group from class.
Dog3 is a copy of Dog1 (not a reference Dog1


Class Animal {
      name$=""
      module saySomething {
            print "I am "+.name$
      }
Class:
      Module Animal (.name$) {}
}
Class Dog {
      longtail
Class:
      Module Dog (Alfa) {
            Read ? .longtail
            \\ change module in Alfa
            Group Alfa {
                  module saySomething {
                        print "I am "+.name$+ ", and I can bark"
                  }
            }
            \\ merge Alfa to This     
            This<=Alfa
      }
}

dog1 = Dog(Animal("Chiwawa"))
dog1.saySomething
dog2 = Dog(Animal("Saluki"),True)
dog2.saySomething
Print dog1.longtail, dog2.longtail
Print dog1.name$, dog2.name$
dog3=dog1
dog3.saySomething
Print dog3.longtail



Τρίτη 5 Σεπτεμβρίου 2017

Χρήση αντικειμένων Com (εδώ Dictionary)

Πώς βρίσκουμε τα αντικείμενα τύπου Com
Στη γραμμή εντολών γράφουμε
Λίστα Com Στο AAAA
Θα ανοίξει ένα μενού και θα επιλέξουμε το αντικείμενο που θέλουμε
Στο τμήμα ΑΑΑΑ θα έχουν γραφτεί όλα τα αντικείμενα του αντικειμένου που διαλέξαμε.
Έστω διαλέγουμε το Scripting RunTime
με Λιστα ΑΑΑΑ θα δούμε τα παρακάτω
Όρισε Dictionary "{EE09B103-97E0-11CF-978F-00A02463E06F}"
Όρισε FileSystemObject "{0D43FE01-F093-11CF-8940-00A0C9054228}"
Όρισε Drive "{C7C3F5B1-88A3-11D0-ABCB-00A0C90FFFC0}"
Όρισε Drives "{C7C3F5B2-88A3-11D0-ABCB-00A0C90FFFC0}"
Όρισε Folder "{C7C3F5B3-88A3-11D0-ABCB-00A0C90FFFC0}"
Όρισε Folders "{C7C3F5B4-88A3-11D0-ABCB-00A0C90FFFC0}"
Όρισε File "{C7C3F5B5-88A3-11D0-ABCB-00A0C90FFFC0}"
Όρισε Files "{C7C3F5B6-88A3-11D0-ABCB-00A0C90FFFC0}"
Όρισε TextStream "{0BB02EC0-EF49-11CF-8940-00A0C9054228}"
Όρισε Encoder "{32DA2B15-CFED-11D1-B747-00C04FC2B085}"

Τώρα μας ενδιαφέρει να βρούμε στο Dictionary τι μεθόδους και ιδιότητες έχει, και σε ένα τμήμα γράφουμε τα παρακάτω (έχουμε βρει τον αριθμό του Dicitonary). Μπορούμε να διαβάσουμε το τι έχει ένα αντικείμενο αν μπορούμε να το φορτώσουμε, δηλαδή να το ορίσουμε ουσιαστικά σε ένα όνομα!


Όρισε Dictionary "{EE09B103-97E0-11CF-978F-00A02463E06F}"
α=Παραμ(Dictionary)
Τύπωσε Μήκος(α)
Ν=Κάθε(α)
Έγγραφο Ολα$
Ενώ Ν {
      Όλα$=Εκφρ$(Ν)+{
      }
}
Πρόχειρο Όλα$

Τώρα έχουμε βάλει στο πρόχειρα το έγγραφο Όλα$
Μπορούμε να δούμε τι έχει σε ένα τμήμα που ανοίγουμε και κάνουμε επικόλληση. Τα πρώτα 7 δεν τα χρησιμοποιούμε. Στην ουσία με αυτά βρήκαμε τα ονόματα και το τι παραμέτρους ζητάει το καθένα. Εδώ ξεκινάμε με το Property Item (Get σημαίνει ότι διαβάζεται, ενώ Let σημαίνει ότι γράφεται, αν λείπει κάποιο σημαίνει ότι δεν μπορούμε να κάνουμε αυτή την λειτουργία). To _NewEnum είναι interface Που δεν μπορούμε να το χειριστούμε (αν υπήρχε διπλή κάτω παύλα __ τότε θα ήταν γεγονός και θα μπορούσαμε να το πάρουμε με την Όρισε ΜεΓεγονότα.... και μετά με συναρτήσεις με _όνομα_γεγονότος - μια κάτω παύλα)



Function QueryInterface(riid, ppvObj)
Function AddRef
Function Release
Function GetTypeInfoCount(pctinfo)
Function GetTypeInfo(itinfo, lcid, pptinfo)
Function GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid)
Function Invoke(dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr)
Property Get Item(Key)
Function Add(Key, Item)
Property Get Count
Function Exists(Key)
Function Items
Property Let Key(Key, )
Function Keys
Function Remove(Key)
Function RemoveAll
Property Get CompareMode
Function _NewEnum
Property Get HashVal(Key)


Τώρα κάνουμε την δοκιμή μας! Σε ένα τμήμα γράφουμε τα παρακάτω:

Όρισε Dictionary "{EE09B103-97E0-11CF-978F-00A02463E06F}"
Μέθοδος Dictionary, "Add", "12345","κάτι1"
Μέθοδος Dictionary, "Add", "12345423","κάτι2"
Μέθοδος Dictionary, "Add", "12345231","κάτι3"
Με Dictionary,"Count" ως Πόσα, "Item" ως Κάτι$()
Τύπωσε Πόσα
Μέθοδος Dictionary, "Exists", "12345423" ως Υπάρχει
Τύπωσε Υπάρχει
Τύπωσε Κάτι$("12345")
Τύπωσε Κάτι$("12345231")



Κυριακή 3 Σεπτεμβρίου 2017

Αναθεώρηση 30 (Έκδοση 8.9)

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

Συνάρτηση Άλφα (κ, λ) {
      =κ*λ
}
Συνάρτηση Άλφα (κ, λ){
      =κ*λ+100
}

Τύπωσε Άλφα(2,3)

Δεν υπήρχε λάθος σε περίπτωση που οι συναρτήσεις ήταν σε ομάδα:
Ομάδα ΑΑ {
      Συνάρτηση Άλφα (κ, λ) {
            =κ*λ
      }
      Συνάρτηση Άλφα (κ, λ) {
            =κ*λ+100
      }
}

Τύπωσε ΑΑ.Άλφα(2,3)

Ομοίως δεν υπήρχε λάθος αν είχαμε τμήματα, εντός ή εκτός ομάδας!