Τρίτη, 4 Δεκεμβρίου 2018

Αναθεώρηση 1 Έκδοση 9.6

1. Διορθώθηκε ένα λάθος που έγινε στην 9.6 στο αντικείμενο Γεγονός. Τώρα δουλεύει κανονικά.
2. Εμπλουτίστηκαν τα αντικείμενα τύπου Ομάδα, για τα γενικά (global) αντικείμενα. Επιπλέον αν κάπου τοπικά συγχωνεύσουμε μια άλλη ομάδα στην γενική, αυτή η συγχώνευση θα μείνει τοπικά, η γενική ομάδα δεν θα πάρει περισσότερα μέλη, αλλά θα αλλάξει μόνο όσα μέλη βρέθηκαν κοινά με την ομάδα που συγχωνεύτηκε.
3. Φτιάχτηκε το Δες { } ή Try {} ώστε αν το λάθος γίνει μέσα σε δομή που χρησιμοποιεί μια στοίβα επιστροφής όπως οι ρουτίνες με παρενθέσεις Ρουτίνα Τέλος Ρουτίνας (Sub End Sub), οι απλές ρουτίνες με όνομα  Διαμέσου Επιστροφή (Gosub Return), Για  Επόμενο (For Next), καθώς και η νέα Αν Τέλος Αν (χωρίς μπλοκ κώδικα {}).  Στην ουσία πριν εκτελεστεί το μπλοκ της Δες έχει περάσει στη στοίβα μια δική του σειρά με ένα αναγνωριστικό αριθμό, και αν στην εκτέλεση εντός βγει λάθος τότε ο διερμηνευτής την χρησιμοποιεί αδειάζοντάς την μέχρι να βρει τη δική του σειρά και έτσι κάνει αποκατάσταση. Τα τμήματα/Συναρτήσεις επειδή καλούνται με εσωτερικές συναρτήσεις, χρησιμοποιείται η στοίβα επιστροφής του διερμηνευτή, και εδώ αν γίνει λάθος έχουμε άμεση επιστροφή από την εσωτερική συνάρτηση με αναφορά σφάλματος, δηλαδή ο αρχικός σχεδιασμός ήταν πιο απλός και εύκολος. Απλά οι νέες δομές επειδή δεν καλούν την περιορισμένη στοίβα του διερμηνευτή, και επειδή κάνουν χρήση μεταβλητών που υπάρχουν ήδη σε αυτές τις εσωτερικές συναρτήσεις για τμήματα και συναρτήσεις της Μ2000, καταναλώνουν λιγότερη μνήμη. Επειδή η στοίβα για αυτές έχει την δυνατότητα να χρησιμοποιεί όλη την μνήμη, έχουμε επιπλέον το κέρδος για μεγάλο βάθος αναδρομής στις ρουτίνες. Η εντολή Όριο.Αναδρομής αρχικά είναι ρυθμισμένη στο 10000, αλλά μπορούμε άνετα να το βάλουμε στο ένα εκατομμύριο. Σημαίνει ότι θα κάνει μέχρι το ένα εκατομμύριο διαδοχικές κλήσεις είτε με μια ρουτίνα ή με ομάδες ρουτινών (η μία καλεί την άλλη και η τελευταία την πρώτη, και όλες έχουν ένα τρόπο να μην καλέσουν και να επιστρέψουν)

Στο παράδειγμα έχουμε μια γενική ομάδα, την άλφα με ένα μέλος το χ. Μετά έχουμε μια δομή Αν Τέλος Αν. Δεν μας ενδιαφέρει η συνθήκη απλά θέλουμε να εκτελεστεί κώδικας, οπότε το Αληθές είναι αρκετό. Μετά έχουμε την Δες {} χωρίς παράμετρο, οπότε θα συνεχίσει οπωσδήποτε ακόμα και αν βρεθεί λάθος. στο πρώτο καλούμε την ρουτίνα m(). Όλες οι ρουτίνες καθαρίζουν ότι νέο κάνουν πριν την επιστροφή, εκτός από αυτά που εκχωρούν σε υπάρχουσες μεταβλητές ή σε αυτά που βάζουν στο κοινό σωρό τιμών (και τα οποία δίνουν την δυνατότητα στις ρουτίνες να εξάγουν αποτελέσματα). Μπορούμε να χρησιμοποιούμε παραμέτρους με αναφορά με χρήση του & πριν το όνομα). Η m() καλεί την k() (θα μπορούσε να την καλέσει με Gosub k(), απλά είναι προαιρετικό, αλλά επιβάλλεται αν υπάρχει ήδη πίνακας με το ίδιο όνομα - ο διερμηνευτής δίνει προτεραιότητα στους πίνακες). Εκεί στην k() φτιάχνουμε μια ομάδα και την συγχωνεύουμε  με την γενικά άλφα με χρήση του τελεστή <= (αν είχαμε χρησιμοποιήσει το = απλά θα φτιάχναμε μια τοπική για την ρουτίνα). Οι τοπικές των ρουτινών είναι θεατές και από τις άλλες ρουτίνες όταν τις καλούμε, οπότε επειδή και εκεί φτιάχνουμε τοπικές, τελικά οι προηγούμενες σκιάζονται πρόσκαιρα, μέχρι να τερματίσουν οι ρουτίνες που τις σκίασαν (πάντα σε επίπεδο τμήματος). Με τα άλλα τμήματα δεν υπάρχει ίδιος σκοπός ή θέαση μεταβλητών. Έχουμε βάλει μια Για Επόμενο (For Next) και  εκεί έχουμε βάλει την Λάθος ή Error για να παράγει  λάθος. Ο διερμηνευτής άμεσα θα γυρίσει στην Δες αλλά η στοίβα επιστροφής θα έχει αφεθεί στην μοίρα της. Θα έχει την επιστροφή του Για, την επιστροφή της δεύτερης στη κλήση ρουτίνας και της πρώτης καθώς και το κομμάτι του Δες. Αυτό συμβαίνει γιατί όταν βγαίνει λάθος τερματίζει η εσωτερική συνάρτηση, και είναι αυτή που τρέχει το μπλοκ της Δες. Αν δεν υπήρχε αυτό θα έβγαινε λάθος επειδή τα Τέλος Αν τα μετράει το τμήμα (για να δείξει ότι λείπει ή ότι έχει μπει επιπλέον), και φυσικά αν το Δες βρίσκονταν σε ρουτίνα θα υπήρχε επίσης πρόβλημα από τη γεμάτη στοίβα επιστροφής.

Το δεύτερο Δες χρησιμοποιεί τις απλές ρουτίνες τύπου BASIC. Αυτές εκτελούν απλά κώδικα και επιστρέφουν χωρίς να σβήσουν κάτι. Εκεί έχω αλλάξει την Για Επόμενο με μια ακόμα Αν Τέλος Αν. Το λάθος βγαίνει μέσα σε αυτή τη δομή και επιστρέφουμε στο τερματισμό του μπλοκ της Δες και επίσης καθαρίζεται η στοίβα επιστροφή.


global group alfa {
      x=10
}
If true then
      try {
       gosub m()
      }
      Try {
            gosub alfa1
      }
      end if
m=alfa
list
End
sub m()
      k()
end sub
sub k()
      group z {
            y=20
      }
      alfa<=z
      for i=1 to 3
              error "10"
      next i
end sub

alfa1:
      group z {
            y=20
      }
      alfa<=z
      Print alfa.y
      if true then
      error "10"
      end if
Return

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου