Τετάρτη, 25 Οκτωβρίου 2017

Έκδοση 9 του διερμηνευτή της γλώσσας Μ2000.


Νέα Έκδοση

Η αναθεώρηση 45 της έκδοσης 8.9, περιέχεται στην έκδοση 9. Η έκδοση άλλαξε γιατί στη τελευταία αναθεώρηση άλλαξε μια "συμπεριφορά" του διερμηνευτή. Η ανάθεση τιμής με το <= γίνεται για γενικές (και σε ορισμένες περιπτώσεις σε μεγαβλητές ομάδων), αυτό δεν άλλαξε. Αυτό που άλλαξε είναι ότι αν υπάρχει μια τοπική Χ και δώσουμε το Χ<=10 ενώ δεν υπάρχει γενική Χ δεν θα βγει λάθος (όπως έβγαινε σε <9 εκδόσεις). Αν δεν υπάρχει τοπική Χ και δεν υπάρχει γενική Χ τότε το Χ<=10 δίνει λάθος. Οι γενικές ορίζονται ή στη γραμμή εντολών πχ Χ=10 ή οπουδήποτε στο κώδικα (και είναι για προσωρινή χρήση) με τον προσδιορισμό Γενική (Global), πχ Γενική Χ=10.

Περισσότερο μας ενδιαφέρει αυτή η αλλαγή της συμπεριφοράς του διερμηνευτή στο παρακάτω πρόβλημα. Η λάμδα συνάρτηση περιμένει με αναφορά ένα αντικείμενο ομάδα και θέλει να αλλάξει τιμή στην Χ. Αν η συνάρτηση τρέξει μέσα σε τμήμα ή συνάρτηση μιας ομάδας, ας λέμε μέσα σε ομάδα, τότε δεν θα υπήρχε πρόβλημα με το <=, ενώ αν αυτή τρέξει έξω από ομάδα, θα χρειαζόταν το = και όχι το <=. Τώρα με την αλλαγή δεν υπάρχει θέμα!

Αυτή η αλλαγή αλλάζει μεν την συμπεριφορά του διερμηνευτή, αλλά δεν έχει βρεθεί ακόμα πρόγραμμα που να αλλάξει το αποτέλεσμά του από αυτήν την αλλαγή. Κύρια γιατί το διαφορετικό που φέρνει δεν αλλάζει το αποτέλεσμα αν όντως όπου χρησιμοποιούμε το <= έχουμε γενική ή μεταβλητή ομάδας (μέσα σε ομάδα).
Στους ορισμούς όπως το Group K { x=10 } δεν θα βάζαμε το <= έτσι και αλλιώς. Εκεί που παίζει είναι στην αλλαγή τιμής της Μ.χ το οποίο μπορεί να γίνει μέσα στο Alfa.CheckMe όπου περνάει το Κ ως &Κ στην λάμδα συνάρτηση .Ν() (εκεί ακριβώς στο .Ν() έχουμε συνάρτηση του Αλφα, θα μπορούσε να ήταν Αυτό.Ν(&Κ))
Παρακάτω εξάγουμε αντίγραφο της Alfa.N στην Ζ. Οι λάμδα συναρτήσεις είναι πολίτες πρώτης κατηγορίας, είναι αντικείμενα, και μπορούν να μετακινηθούν οπουδήποτε, με αντιγραφή (αν έχουν κλεισίματα με δείκτες τότε αυτά θα περάσουν ως δείκτες, πχ πίνακα με δείκτη, έτσι όλα τα αντίγραφα θα βλέπουν τον ίδιο πίνακα). Στη Ζ όμως δεν μπορούμε να βάλουμε άλλου τύπου αντικείμενο.

Η Μ2000 έχει μεν dynamic τύπο μεταβλητών, αλλά συνάμα και strong, δεν αλλάζουν τύπο μετά. Υπάρχουν τύποι που είναι "αποθήκες", όπως ο Πίνακας, ο οποίος μπορεί στις θέσεις του να έχει οτιδήποτε, και το όνομά του δηλώνει μόνο τον τρόπο ανάγνωσης (μπορούμε να συνδέσουμε άλλο όνομα για να αλλάξουμε την ανάγνωση).

Dim A(10)=1
Link A() to A$()
A$(5)="Hello There"
Print A(5) ' 0
Print Type$(A(5)) ' String
Print A() ' 1 1 1 1 Hello There 1 1 1 1 1



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

Η επιστροφή τιμής γίνεται με το =, και μπορούμε να το έχουμε όπου θέλουμε ή να μην το έχουμε καθόλου. Αν θέλουμε να καλέσουμε τη λάμδα ως διαδικασία (ως τμήμα δηλαδή) τότε μπορούμε να την καλέσουμε με την Κάλεσε και το όνομά της. Αν θέλουμε μπορούμε να δηλώσουμε εξ αρχής το με το Κάλεσε Κενή να μην λάβουμε υπόψιν την επιστροφή διαφορετικά μη μηδενική τιμή επιστροφής θεωρείται λάθος! Αν δεν βάλουμε =, δηλαδή επιστροφή τιμής, η μηδενική τιμή θα είναι οκ για κλήση της λάμδα ως διαδικασία (ως τμήμα)
Λάμδα Κ, Λ, Μ (Α,Β, Γ) -> {

}

Αν θέλουμε η λάμδα να γυρίζει αλφαριθμητικό τότε θα έχει το $
Λάμδα$ Κ, Λ, Μ (Α,Β, Γ) -> {

}

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


Και εδώ είναι το πρόγραμμα με την λάμδα συνάρτηση:

Group Alfa {
      N=Lambda->0
      x=30
      Module CheckMe {
            Group K {
                  x=10
            }
            Call .N(&K)
            Print K.x
      }
}
Alfa.N=lambda (&M) ->{
      M.x<=500
      list
}
Alfa.CheckMe
Z=Alfa.N
Call Z(Alfa)
Print Alfa.X


Με μέλος της Alfa αλφαριθμητικό:

Group Alfa {
      N=Lambda->0
      a$="hello"
      Module CheckMe {
            Group K {
                  a$="bye"
            }
            Call .N(&K)
            Print K.a$
      }
}


Alfa.N=lambda (&M) ->{
      M.a$<="hello there"
      list
}


Alfa.CheckMe
Z=Alfa.N
Call Z(Alfa)
Print Alfa.a$



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

Group Alfa {
      N$=Lambda$->""
      a$="hello"
      Module CheckMe {
            Group K {
                  a$="bye"
            }
            Call .N$(&K)
            Print K.a$
      }
}


Alfa.N$=lambda$ (&M) ->{
      M.a$<="hello there"
      list
}


Alfa.CheckMe
Z$=Alfa.N$
Call Z$(Alfa)
Print Alfa.a$



Και μια διαφορά σε σχέση με τους πίνακες (με παρενθέσεις, γιατί υπάρχουν και αυτοί που δεν έχουν παρενθέσεις, αλλά δείκτη σε αυτούς). Στους πίνακες δεν χρησιμοποιούμε το <=, αλλά πάντα το =.


Group Alfa {
      N=Lambda->0
      Dim x$(10)="30"
      Module CheckMe {
            Group K {
                  Dim x$(10)="10"
            }
            Call .N(&K)
            Print K.x$(0)
      }
}


Alfa.N=lambda (&M) ->{
      M.x$(0)="500"
      list
}


Alfa.CheckMe
Z=Alfa.N
Call Z(Alfa)
Print Alfa.X$(0)



Ενώ εδώ είναι η άλλη περίπτωση με πίνακα με δείκτη, οπότε θέλουμε το <=. Οι πίνακες σε παρενθέσεις χωρίς όνομα λέγονται αυτόματοι πίνακες. Ο (,) είναι ο κενός πίνακας, ενώ το  (1,) είναι ο πίνακας με ένα στοιχείο, το ίδιο είναι και αυτός ((,),) αλλά έχει στο πρώτο στοιχείο έναν κενό πίνακα. Το ((1,2),(3,4)) είναι ένας πίνακας με δυο στοιχεία και κάθε στοιχείο είναι ένας πίνακας με δύο στοιχεία.Αν Α=(1,2,3) τότε το Α+=10 θα κάνει τον πίνακα να έχει τα 11,12,13, και μπορούμε να δούμε τα στοιχεία με την Πίνακας(), πχ Πίνακας(Α, 0) δίνει το 11. Επίσης μπορούμε να ενώσουμε ένα όνομα με παρενθέσεις πχ με το Ένωσε Α στο Α() θα έχουμε το Α(0) που θα δείχνει το 11 και θα μπορούμε να το αλλάζουμε Α(0)+=10 στο 21 (χωρίς να πειράζουμε άλλα στοιχεία). Επιστροφή στον Α εκτός με την χρήση του ονόματος που ενώσαμε γίνεται και με την Επιστοφή: Επιστροφή Α, 0:=500, 2:=1000  (μπορούμε να βάζουμε έναν αριθμό στοιχείων αρκεί να δίνουμε το κλειδί κάθε φορά).

Group Alfa {
      N=Lambda->0
      x=(6,7,8,9,10)
      Module CheckMe {
            Group K {
                  x=(1,2,3,4,5)
            }
            Call .N(&K)
            Print K.x
      }
}


Alfa.N=lambda (&M) ->{
      M.x<=(501,502, 503, 504, 505)
      list
}


Alfa.CheckMe
Z=Alfa.N
Call Z(Alfa)
Print Alfa.X




Σημείωση:

Όλα τα παραδείγματα τρέχουν σε ένα τμήμα που ανοίγουμε στον διερμηνευτή της Μ2000. Ο διερμηνευτής είναι πρόγραμμα εκτέλεσης - και περιβάλλον συνάμα. 
  • Μπορεί να εκτελεί αρχείο που περιλαμβάνει ένα τουλάχιστον τμήμα και μια εντολή (το όνομα του τμήματος εκκίνησης), καθώς και την εντολή Τέλος. Μέσα στο τμήμα αν θέλουμε να φανεί η κονσόλα δίνουμε την εντολή Άναψε. Μπορεί να τρέχουμε προγράμματα χωρίς διεπαφή, ή να ανοίγουμε παράθυρα (φόρμες που φτιάχνουμε με κώδικα της Μ2000),
  • Μπορούμε να τρέξουμε τον διερμηνευτή και να μπούμε στη γραμμή εντολών του διερμηνευτή. Εκεί γράφουμε το Σ Α ή edit A και ανοίγει ο ενσωματωμένος διερμηνευτής και αντιγράφουμε ένα από τα προγράμματα. Με Esc γυρνάμε στη γραμμή εντολών και γράφουμε A και πατάμε enter και τρέχει το πρόγραμμα. Μπορούμε να το τρέξουμε με Δοκιμή A ή Test A, και να εκτελούμε γραμμή - γραμμή το κώδικα. Σημαντικές εντολές από την γραμμή εντολών της Μ2000 είναι τα Φόρτωσε/Σώσε (χωρίς "" τα ονόματα), Σ ή Συγγραφή, Λίστα, Τμήματα (φορτωμένα και στο δίσκο), Τμήματα ? (μόνο τα φορτωμένα), Νέο, Καθαρό (σβήνει όλες τις μεταβλητές), Άδειασε (σβήνει τον τρέχοντα σωρό τιμών, από εκεί που παίρνει η  Διαβάσε), Αρχή.