Πέμπτη, 25 Μαΐου 2017

Αναθεώρηση 5 (Έκδοση 8.8)

Ενώ έγραψα ότι δεν θα προχωρήσω τη γλώσσα. τελικά οι ιδέες δεν με αφήνουν! Το παρακάτω είναι κάπως "μπέρδεμα", αλλά γίνεται!
Κανονικά ένα τμήμα κώδικα (με όνομα δηλαδή) δεν μπορεί να καλέσει άλλο τμήμα που βρίσκεται σε άλλο τμήμα. Μπορεί να καλεί μόνο τα δικά του, που έχει δημιουργήσει (όπως λέει ο κώδικας), ή ό,τι είναι γενικό, που μπορεί να ορίστηκε σε άλλο τμήμα που καλεί το συγκεκριμένο ή να είναι απλά γενικό επειδή είναι στην αρχική λίστα τμημάτων - ή όπως το ονομάζω στο επίπεδο 0.

Η ιδέα ήταν να μπορώ πριν καλέσω ένα τμήμα, το οποίο έχει δικά του τμήματα, και τα δημιουργεί στην εκτέλεση), να του δώσω στη κλήση άλλα τμήματα "αντικαταστάτες" αυτών που "θα" δημιουργήσει!
Ίσχυε ότι αν ένα τμήμα οριστεί δυο φορές σε ένα τμήμα τότε ο δεύτερος ορισμός ισχύει (στην ουσία ο κώδικας του πρώτου εξαφανίζεται, και στη θέση του έρχεται ο νέος κώδικας)
Η ιδέα ήταν απλή: Θα βάλω σε κάθε τμήμα μια "σημαία" που θα λέει "δεν αλλάζω κώδικα", έτσι ώστε σε "επόμενη" αλλαγή να μην επιδέχεται νέο κώδικα.
Αυτό λοιπόν θα μπορούσε να γίνει αν ήδη πριν τον πρώτο ορισμό ενός τμήματος, με κάποιο τρόπο υπήρχε το τμήμα!

Ένα τμήμα Α δεν μπορεί να καλέσει τον εαυτό του, με τον κανονικό τρόπο κλήσης, με το όνομά του μόνο. Με τη χρήση της Κάλεσε ή Call μπορεί όμως να το κάνει, και αυτό γιατί αλλάζουν μερικά πράγματα εσωτερικά και έτσι μπορεί να εκτελεί πολλές φορές. Σε αυτόν τον δεύτερο τρόπο δεν ισχύει η δυνατότητα αλλαγής τμημάτων.

Η αλλαγή τμημάτων πριν την χρήση λέγεται "decoration" αλλά εδώ ελληνικά θα το λέγαμε διαμόρφωση! Προϋπόθεση είναι να γνωρίζουμε τα ονόματα των τμημάτων ενός τμήματος. Αλλά εδώ δεν υπάρχει θέμα, ο κώδικας των τμημάτων είναι ανοικτός! Από το να γράψουμε νέο κώδικα ή να βάλουμε στον υπάρχον κώδικα λογική για το τι θα χρησιμοποιεί και να έχουμε ένα "σεντόνι" κώδικα, μπορούμε να δώσουμε την διαμόρωσή του κατά την κλήση.

Το παρακάτω είναι ένα παράδειγμα με εντολές στα αγγλικά. Το ενδιαφέρον εδώ είναι ότι αλλάζουμε κατά την κλήση και το τμήμα ενός αντικειμένου (Ομάδα ή Group). Αυτό γίνεται γιατί το αντικείμενο αυτό είναι στατικό, δηλαδή δημιουργείται κατά την εκτέλεση στο τμήματος, και παραμένει ως έχει μέχρι το τμήμα να τερματίσει (στατικό δεν σημαίνει ότι δεν αλλάζει τιμές, αλλά ότι έχει συγκεκριμένο χώρο και δεν μπορεί να μετακινηθεί, δεν αποτελεί αντικείμενο με δείκτη - μπορεί όμως να αντιγραφεί σε άλλο που μετακινείται εντός πινάκων ή καταστάσεων ή σωρών, δηλαδή αντικειμένων που δέχονται αντικείμενα με δείκτη).

Για να γίνει πιο δύσκολο κάπως, το τμήμα recuirsive του m καλεί τον εαυτό του. Όμως εμείς θέλουμε να τρέξουμε το k χωρίς να συμβεί αυτό σίγουρα! Φτιάχνουμε το stop_recuirsive στο τμήμα έξω από το k και το περνάμε ως m.recuirsive. Τώρα τρέχει χωρίς να εκτελεί το κώδικα που είχε από "προγραμματισμό", αλλά με το κώδικα από "διαμόρφωση", ή decoration (η αντιστοιχία της αγγλικής δεν έχει σχέση με την διακόσμηση στο τρέχον κείμενο, αλλά με την διαμόρφωση).

Η διαμόρφωση ξεκινάει με ονόματα που δίνουμε. Θα μπορούσαμε να δίναμε ένα όνομα που δεν υπάρχει, αλλά θα έπρεπε να είχαμε "λογική" εντός του τμήματος για να κάνει κάτι γι΄αυτό, πράγμα όμως που μας βγάζει εκτός σκοπού. Μπορούμε να δώσουμε ένα  υπάρχον όνομα και στο τμήμα που καλούμε και στο τμήμα που καλεί, ή να δώσουμε ένα διαφορετικό από το τμήμα που καλεί και εκεί λέμε ΩΣ ή AS στα αγγλικά.
Στο παράδειγμα δίνουμε τρία τμήματα, το ένα είναι τμήμα αντικειμένου, και τα άλλα δυο είναι απλά τμήματα, το ένα όμως θα πάει και αυτό σαν τμήμα αντικειμένου.
Παρόλο που δώσαμε τμήμα αντικειμένου σε τμήμα αντικειμένου δεν έχουμε κάποια "Σύνδεση" με το τμήμα του τμήματους που καλεί γιατί συνδέεται αυτόματα με τμήμα αντικείμενου στο προορισμό.



form 60,32
module k {
      group m {
            z=500
            module recuirsive (x) {
                  Print x, .z
                  Modules ?
                  List
                  \\ just a waiting for keypress
                  Push Key$ : Drop
                  .z/=2
                  if x>0 then call .recuirsive x-1
            }
            module alfa {
                  print number
            }
            module alfa {
                  print number**2
            }
      }
      Modules ?
      m.recuirsive 10
      m.alfa number
      module kkk {
            print number/2
      }
      kkk 20
      Modules ?
}
group mine {
      z=1000
      module klm {
            drop
            print "error", .z
      }
}
module kkk {
      print number*20
}
module stop_recuirsive {
      drop
}
mine.klm 100
\\ decorated call for k
k 100 ; m.alfa as mine.klm, m.recuirsive as stop_recuirsive, kkk
\\ call can't be decorated
Report "Just Call K 100"
call k 100


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

Παρατηρούμε ότι η τιμή του a.x αλλάζει μετά την κλήση και αυτό φαίνεται ως πέρασμα με τιμή! Όμως στον αρχικό κώδικα του τμήματος alpha αυτό δεν είχε καν λογαριαστεί! Αυτή είναι η έννοια της διαμόρφωσης ή decoration, να προσδίδουμε λειτουργικότητα έξω από το σχεδιασμό του τμήματος.

Σκοπίμως έχει μπει η test "me"  (το τι θα γράψουμε στο αλφαριθμητικό δεν έχει σημασία, πέρα από το ότι θα φανεί στη φόρμα ελέγχου). Με το που θα εκτελεστεί η εντολή θα ανοίξει η φόρμα ελέγχου και μπορούμε να πατάμε το "Επόμενo Βήμα" και αν εκτελούμε μια προς μια τις εντολές και να βλέπουμε χρωματισμένο τον κώδικα και σημειωμένη την εντολή που εκτελούμε!



\\ Revision 5 Version 8.8
\\ Decorated modules
test "me"
Group a {
      x=100
      module finish (a) {
            .x+=a
            print "My good finish", .x
      }
}
module beta {
      print "beta"
}
module alpha (b){
      module finish (x){
            print "standard finish", x
      }
      module delta {
            print "internal delta"
      }
      print "ok", b
      delta
      finish 50
}
print a.x
alpha 100 ; delta as beta, finish as a.finish
print a.x
alpha 200
Modules ?