Τετάρτη, 30 Σεπτεμβρίου 2015

Ο Πέτρος, ο λύκος και το πρόβατο! (Μ2000)

Προσοχή χρειάζεται την αναθεώρηση 58. Έχει ανέβει! Διόρθωσα ένα μικρό πρόβλημα, π.χ. στη συνάρτηση Βγάλε.άτομο η επιστροφή τιμής έχανε το αντικείμενο επειδή γίνονταν πράξεις μέχρι να τελειώσει τη συνάρτηση. Τώρα ο μεταφραστής κρατάει χωριστά τη τιμή επιστροφής και στο αντικείμενο (δούλευε σε απλού τύπου τιμές).

Παρακάτω είναι η αυτόματη επίλυση του προβλήματος, όπου ο Πέτρος, ο λύκος και το πρόβατο πρέπει να περάσουν το ποτάμι, αλλά δεν πρέπει να μείνουν μόνα τους ο λύκος και το πρόβατο.
(υπάρχει και πιο δύσκολο, αλλά εδώ είναι το απλό πρόβλημα...)
Χρησιμοποιούμε αντικείμενα για να διευκολυνθούμε στην ανάπτυξη της λογικής. Το κυρίως πρόγραμμα είναι στο Επανάλαβε { } Πάντα, το οποίο τελειώνει με μια Προς στο τελικο: (η ετικέτα πρέπει να έχει τα ίδια γράμματα για να λειτουργήσει η Προς).

Ο αλγόριθμος θα τερματίσει χωρίς να χρειάζεται να προκαθορίσουμε τα βήματα!

Στο χρωματισμένο κείμενο είναι ο καθορισμός των τριών μερών, της όχθης Α, της βάρκας και της όχθης Β. Βάζουμε το όνομα και τα τυχόν άτομα, με τις ιδιότητές τους.

φορμα 60,30
\\ Τύπωσε $(4)   \\ βγάλε τα πρώτα \\  και θα έχεις Αναλογική γραφή στη Τύπωσε
οθονη 1 : Πενα 14
γενικό ενέργεια$(3), ιδιότητα$(2)
ενέργεια$(0)="Τρώει","Τρώγεται","Αδιάφορο"
ιδιότητα$(0)="Οδηγός","Επιβάτης"
κλάση άτομο {
όνομα$, τύπος$, ιδιότητα$
      τμήμα άτομο {
                  αν ταύτιση("S") τότε διάβασε .όνομα$
                  αν ταύτιση("S") τότε διάβασε .τύπος$
                  αν ταύτιση("S") τότε διάβασε .ιδιότητα$
      }
}
κλάση μέρος {
      όνομα$, υπάρχουν_άτομα
      πινακας ατομο()
      τμημα βάλε.άτομο {
            Διάβασε άτομο
            .υπάρχουν_άτομα++
             πίνακας .άτομο( .υπάρχουν_άτομα)
            .άτομο(.υπάρχουν_άτομα-1)=άτομο
      }
      τμημα μέρος {
            αν ταύτιση("S") τότε διάβασε .όνομα$
            .υπάρχουν_άτομα <= μέγεθος.σωρού
            αν .υπάρχουν_άτομα τότε {
                  πίνακας .άτομο(.υπάρχουν_άτομα)
                  ι=0 : ενώ όχι κενό { διάβασε .άτομο(ι) : ι++}
            }
      }
      Συνάρτηση Θα.βγει { Διάβασε Ποιος
           καθαρο υπολογισε
             αν .υπάρχουν_άτομα>2 τότε {
                  πίνακας α(2)
                        καθαρο κ
                        για ι=0 εως 2 {
                              αν ποιος<>ι τότε α(κ)=ι : κ++
                        }
                        \\ Τρώει -1
                        \\ Τρώγεται 0
                        \\ Αδιάφορο 1
                        για ι=0 εως 1 {
                        αν .άτομο(α(ι)).τύπος$=ενέργεια$(0) τότε {υπολογισε-=1
                        } αλλιώς.αν .άτομο(α(ι)).τύπος$=ενέργεια$(2) τότε υπολογισε+=1
                        }
                 }      
          =υπολογισε>=0
      }
     συνάρτηση Βγάλε.άτομο {
            διάβασε ποιος
            = .άτομο(ποιος)
            αν ποιος+1<.υπάρχουν_άτομα τότε {
                  άλλαξε .άτομο(.υπάρχουν_άτομα-1), .άτομο(ποιος)
            }
            .υπάρχουν_άτομα--
            Πίνακας .άτομο(.υπάρχουν_άτομα)
      }
     
}


Γενική Θέση_επιβατών(3)
Θέση_επιβατών(0)=μέρος("Όχθη Α", άτομο("Πέτρος","Αδιάφορο","Οδηγός"),άτομο("λύκος","Τρώει","Επιβάτης"), άτομο("πρόβατο","Τρώγεται","Επιβάτης"))
Θέση_επιβατών(1)=μέρος("Βάρκα")
Θέση_επιβατών(2)=μέρος("Όχθη Β")

Πίνακας Προορισμός$(4)
Προορισμός$(0)="Προς Όχθη Β","Άφιξη στην Όχθη Β","Προς Όχθη Α","Άφιξη στην Όχθη Α"
Θέση_βάρκας=0 \\ από 0 έως 3


\\Διαμέσου Τύπωσε.Θέσεις()


     
επανάλαβε {


Αν θέση_βάρκας υπολοιπο 2 =1 τότε {
      τύπωσε "κατεβάζω από βάρκα"
      για Θέση_επιβατών(1) {
      τοπικη όχθη=0
      αν θέση_βάρκας =1 τότε όχθη=2
      τοπικη κ =.υπάρχουν_άτομα -1
       ενω κ>=0 {
            Θέση_επιβατών(όχθη).βαλε.άτομο .βγάλε.άτομο(κ)
            κ--
      }
                               θέση_βάρκας++ : αν θέση_βάρκας>3 τότε θέση_βάρκας=0
      }
}
Διαμέσου Τύπωσε.Θέσεις()
            Αν θέση_βάρκας=0 τότε {
                  πένα 12 {Τύπωσε "Χρειάζομαι Επιβάτη" }
                        \\όχθη=0
                        για Θέση_επιβατών(0) {
                              τοπικη κ
                              ενω κ<.υπάρχουν_άτομα {
                                    Αν .άτομο(κ).ιδιότητα$=ιδιότητα$(0) τότε { κ++ } αλλιώς έξοδος
                              }                        
                              Αν κ<.υπάρχουν_άτομα Τότε {
                              Τύπωσε "βρήκα επιβάτη! ";.άτομο(κ).όνομα$
                                     Θέση_επιβατών(1).βαλε.άτομο .βγάλε.άτομο(κ)
                              }
                        }
                  }
          
          
                  όχθη=0
                  αν θέση_βάρκας>1 τότε όχθη=2
                 
                  για Θέση_επιβατών(όχθη) {
               αν όχθη=2 και .υπάρχουν_άτομα=3 τότε προς τελικο
                        πένα 12 {Τύπωσε "Χρειάζομαι οδηγό" }
                        τοπικη κ
                        ενω κ<.υπάρχουν_άτομα {
                              Αν .άτομο(κ).ιδιότητα$=ιδιότητα$(1) τότε { κ++ } αλλιώς έξοδος
                        }                        
                        Αν κ<.υπάρχουν_άτομα Τότε {
                        Τύπωσε "βρήκα οδηγό, ο γνωστός ";.άτομο(κ).όνομα$
                               Θέση_επιβατών(1).βαλε.άτομο .βγάλε.άτομο(κ)
                               θέση_βάρκας++ : αν θέση_βάρκας>3 τότε θέση_βάρκας=0
                        }
                  }
Διαμέσου Τύπωσε.Θέσεις()
     Πλάγια 1: Τύπωσε "Πάτα ένα πλήκτρο" : Πλάγια 0
     α$=κομ$
     οθονη
} πάντα
τελικο:
Τύπωσε "Όλοι έφθασαν σώοι!"
\\ εδώ κάνει έξοδο το πρόγραμμα..(με το που δει την Ρουτίνα.τερματίζει)


Ρουτινα Τύπωσε.Θέσεις()
\\ η λέξη ρουτινα εδώ δεν θέλει τόνο...γιατί την ψάχνει ο διερμηνευτής χωρίς τόνο
\\ οι τόνοι στο όνομα πρέπει να συμφωνούν με το όνομα στην ΔΙΑΜΕΣΟΥ
τοπικη κ
Για ι=0 έως 2 {
      για Θέση_επιβατών(ι) {
    πενα 7 { Τύπωσε "Θέση:"; .όνομα$}
            αν .υπάρχουν_άτομα τότε {
                  για κ=0 έως .υπάρχουν_άτομα-1 {τύπωσε .άτομο(κ).όνομα$;" ";}
                  τύπωσε
            } αλλιώς {
            Τύπωσε "Κανένας"
            }
         αν ι=1 τότε τύπωσε "Προορισμός:", Προορισμός$(θέση_βάρκας)
      }
}
Τελος Ρουτινας





Προγραμματισμός 0004

Νέα αναθεώρηση 57
Μία βελτίωση, μια επαναφορά, μια διόρθωση (ένας προγραμματιστής...)
Οι αναθεωρήσεις λέγονται και "συντήρηση"..τεχνηέντως...Μεγάλες επιχειρήσεις τις λένε Service Release, ή Patch αν είναι κάτι σύντομο και απαραίτητο, ή επίκαιρο (update) αν είναι κάτι που πρέπει να συμβαδίζει με κάτι νέο (δηλαδή μια βελτίωση ουσιαστικά). Συντήρηση γενικά λέμε την διατήρηση ενός προγράμματος και των απαραίτητων δεδομένων του σε καλή λειτουργία. Για εμπορικά προγράμματα που στηρίζονται σε βάσεις δεδομένων, όταν λέμε συντήρηση σημαίνει ότι κάνουμε καθάρισμα της βάσης (και ότι άλλο μπορεί να την κάνει περισσότερο γρήγορη άρα και λειτουργική)

1. Τώρα η συνάρτηση Ταύτιση() παίρνει και ελληνικούς χαρακτήρες, το ίδιο ισχύει και για την εντολή Σωρός.

αδειασε           \\ αδειάζει το σωρό
\\ μετά φτιάχνουμε μια λίστα και την περνάμε σε ένα αλφαριθμητικό
α$=παραθεση$(1,2,"αλφα", 45*56)
Τύπωσε α$   \\ εδώ τυπώνουμε τη λίστα ως έχει
σωρος α$,"αα"   \\ εδώ ζητάμε από τη λίστα δυο αριθμούς (και το "νν" δουλεύει)
\\ προσοχή όμως εδώ τους αναστρέφει, δηλαδή βάζει το τελευταίο ως πρώτο (στη κορυφή)
σωρος    \\ χωρίς παράμετρο βλέπουμε το σωρό στην οθόνη
\\ εδώ κοιτάμε αν ο σωρός έχει δυο αριθμούς, αλλά δεν τους τραβάμε
Τύπωσε Ταύτιση("αα")
\\ εδώ διαβάζουμε τους δυο αριθμούς
διαβασε Α, Β
σωρος α$,"γ"               \\ γ από το γράμμα ή γράμματα
διάβασε Β$
Τύπωσε Α, Β,Β$, α$
         1        2αλφα             2520

πριν την αναθεώρηση ήθελε N αγγλικό για αριθμό και S για αλφαριθμητικό
Παρόλα αυτά η Φάκελος$() γυρίζει πάντα N ή S (αγγλικά).
α$=παραθεση$(1,2,"αλφα", 45*56)
τύπωσε φάκελος$(α$)  \\ θα δώσει τα αγγλικά
NNSN 
Επειδή για κάθε στοιχείο επιστρέφει η φάκελος$() ένα γράμμα, μπορούμε να ξέρουμε πόσα στοιχεία έχει μέσα το αλφαριθμητικό:
τύπωσε μήκος(φάκελος$(α$))
αν θέλουμε να ξέρουμε τι έχει το πρώτο στοιχείο
Τύπωσε φάκελος$(α$,"α")<>""      \\ τυπώνει -1 (αληθές)
Τύπωσε φάκελος$(α$,"γ")<>""       \\ τυπώνει 0 (ψευδές)

Οι λίστες στα αλφαριθμητικά δεν μπορούν να έχουν ομάδες ή πίνακες, όπως μπορεί να έχει ο σωρός, για στοιχεία.
β$=α$+","+α$  ενώνουμε δυο λίστες
β$=α$+","+α$ 
α$="1 1 2;σκουπίδια"   \\ το κόμμα δεν είναι απαραίτητο, μπορούμε να βάλουμε "σκουπίδια".

Τύπωσε φακελος$(α$)
σωρος α$,"ααα"

Τύπωσε α$     \\ τυπώνει το ";σκουπίδια".

α$="1 1 2;5 6 7"
σωρος α$     \\ αν δεν δώσουμε επακριβώς τι θέλουμε..τα σκουπίδια θα χαθούν...

Τύπωσε α$
Μέχρι εδώ είδαμε την απλή μορφή λίστας
Η συνάρτηση σωρός$() φτιάχνει σωρούς με αλφαριθμητικά που δεν βρίσκονται εντός εισαγωγικών αλλά με αριθμό στοιχείων πρώτα. Έτσι η εντολή σωρός και η φάκελος() λειτουργούν τώρα με δυνατότητα να έχουμε λίστες σε λίστες.
α$=σωρος$(1,2,3,4,"άλφα")
τυπωσε α$
β$=σωρος$(α$,10, σωρος$(1,2,3))
Τύπωσε φακελος$(β$)   \\ SNS
Σωρος Νεος { Σωρος β$,"γν" }  \\ πετάω τα πρώτα δύο στοιχεία
Σωρος β$ : Διαβασε β$
Σωρος β$
Διαβασε Α,Β,Γ
Τύπωσε Α,Β,Γ   \\ τυπώνει το 1 2 3


Ο λόγος που χρησιμοποιούμε τα αλφαριθμητικά ως λίστες είναι για να τα περάσουμε σε αρχεία, ή σε πίνακες ή να τα στείλουμε μέσω αυλών (pipes) σε άλλο πρόγραμμα που τρέχει στο δίκτυο. Οι αυλοί στην Μ2000 (είναι στοιχεία των Windows) χρησιμοποιούνται μόνο για να "ακούνε" για στοιχεία. Έτσι μια εφαρμογή μπορεί να στήσει έναν αυλό και να περιμένει να πάρει "εντολές". Αυτές τις εντολές έρχονται σε λίστα και εκεί μπορεί ένα άλλο πρόγραμμα να γνωστοποιήσει τον δικό του αυλό "επικοινωνίας". Με αυτό το τρόπο φτιάχνουμε συστήματα (δηλαδή τουλάχιστον δυο εφαρμογές σε M2000 να τρέχουν) ως "πελάτη-εξυπηρετητή". Δείτε εντολές USE και PIPE (Χρήση και Αυλός).


2. Επιπλέον επανήλθε η Βοήθεια με κανονική χρήση των τόνων. π.χ. (είχε "σπάσει" μετά την 44).
Βοήθεια Φάκελος δίνει το Φάκελος$()

3. Επιπλέον διορθώθηκε αυτό (το περιγράφω για να δει κανείς πόσο εύκολα γίνονται λάθη. Εδώ δεν το είχα προσέξει μέχρι που το χρησιμοποίησα...):
class aa {name$, module aa { read .name$ }} 
dim a(1)=aa("OK")
' είχαμε λάθος στις επόμενες γραμμές γιατί δεν δέχονταν τα \ και ; όταν
' χρησιμοποιούσαμε τη μορφή ανάγνωσης ιδιότητας από αντικείμενο στην εκτύπωσε!
'  ενώ δέχονταν αυτό for a(0) { print .name$; }
' το πρόβλημα ήταν ότι μια συνάρτηση που "κοίταζε μπροστά"...όταν έφθανε στην ). 
' μετά έπαιρνε όχι μόνο το .name$ αλλά και το ; μαζί και αναζητούσε την "name$;"
' το ίδιο έκανε για την ' και την \ (που χρησιμοποιούμε για σημειώσεις στο κώδικα).
' το ? είναι η Τύπωσε (Print)
? a(0).name$  \\ hello
? a(0).name$;"..."

Τρίτη, 29 Σεπτεμβρίου 2015

Συναρτησιακός Προγραμματισμός (Μ2000-Προχωρημένο Επίπεδο)

(το παρακάτω πρόγραμμα γράφτηκε πριν φτιαχτούν οι συναρτήσεις λάμδα που είναι τιμές πρώτης τάξεως, δηλαδή μπορούν να επιστραφούν ως τιμές, μπορούν να περαστούν ως ορίσματα και μπορούν να έχουν κλείσιμο μεταβλητών. Δείτε το παράδειγμα με χρήση αντικειμένου Σωρού και συναρτήσεων Λάμδα
Συναρτησιακός Προγραμματισμός ΙΙ
)

Εδώ υπάρχει ένα πρόγραμμα που αρχικά γράφτηκε στην αγγλική (η Μ2000 έχει όλες τις εντολές και στα αγγλικά), όμως έκανα αλλαγές και ό,τι έχει μείνει στα αγγλικά...δεν είναι εντολές! Άφησα δηλαδή επίτηδες τα ονόματα στα αγγλικά για να καταλάβει κανείς ποιες είναι εντολές και ποια ονόματα (αναγνωριστικά μπορούμε να τα λέμε) που ορίζουμε εμείς.
Σε  μια γραμμή Συναρτησιακός Προγραμματισμός:
Γενικό ThisString$ : Goal "{Κάλεσε integer(25)}"  , "{qubic_of &ThisString$}" : Τύπωσε ThisString$
Παίρνουμε  τους κύβους (χ^3) των αριθμών 1...25.
Goal &ThisString
Παίρνουμε τη λίστα το ένα στοιχείο κάτω από το άλλο (αν υπήρχαν πράξεις θα εκτελούνταν πριν την εξαγωγή (Οκνηρή αποτίμηση - Lazy evaluation)

Στον Συναρτησιακό Προγραμματισμό δεν υπάρχουν αντικαταστάσεις π.χ. Χ=10.
Εδώ φτιάξαμε μια κενή ThisSring$ την βάλαμε στη Goal και τη πήραμε γεμάτη.

Η Μ2000 δεν είναι Συναρτησιακή Γλώσσα. Αυτό που κάνουμε εδώ είναι να φτιάξουμε εργαλεία που να κάνουν αυτό που δεν μπορεί η Μ2000 με τις έτοιμες εντολές. Ομοίως και η Μ2000 είναι γραμμένη με Visual Basic 6 (ο κώδικας συνοδεύεται μαζί με το εκτελέσιμο), και κάνει πράγματα που χωρίς κώδικα δεν μπορεί άμεσα να τα κάνει η Vb6.

Προσθήκη:
Εκτός από τις συναρτήσεις που ορίζουμε με την εντολή Συνάρτηση, καθώς και τις μεταβλητές που ορίζονται ως συναρτήσεις (όταν φτιάχτηκε το παρακάτω πρόγραμμα δεν υποστήριζε η Μ2000 τέτοιες μεταβλητές), υπάρχουν οι συναρτήσεις εντός αλφαριθμητικού ως ανώνυμες συναρτήσεις. 
Πχ το "{=3+5}"  αν το βάλουμε στο σωρό τιμών με την ΒΑΛΕ τότε μπορούμε να την διαβάσουμε ως αλφαριθμητικό πχ Διάβασε Α$ αλλά και εδώ αυτό μας ενδιαφέρει να την διαβάσουμε ως ορισμό συνάρτησης: Διάβασε &Α().
Ομοίως αν έχουμε μια συνάρτηση Α(), που είχαμε ορίσει πιο πριν τότε με Βάλε &Α() μπαίνει ο ορισμός της ως αλφαριθμητικό στο σωρό. Ειδικά στις συναρτήσεις ενός αντικειμένου (ομάδα) το πέρασμα στο σωρό βάζει επιπλέον στοιχεία μετά τη τελευταία αγκύλη έτσι ώστε όταν τρέξει να έχει η συνάρτηση πρόσβαση στα μέλη της ομάδας, άλλες συναρτήσεις και μεταβλητές. Με αυτό τον τρόπο περνάμε συνάρτηση ομάδας  με αναφορά στην ομάδα (αντικείμενο) κατά την κλήση άλλης συνάρτησης ή τμήματος, ακόμα και αν αυτό είναι σε άλλο αντικείμενο, χωρίς να περάσουμε όλο το αντικείμενο, δηλαδή εκθέτουμε με αναφορά σε μια λειτουργία που θα παραλάβει κάποια δεδομένα, από εκεί που εκθέτουμε, θα τα επεξεργαστεί και θα δώσει αποτέλεσμα, όσες φορές θέλουμε πριν επιστρέψει η ροή στην επόμενη εντολή. Πχ αντικ2.τμημα1 &αντικ1.συναρτ1() όπου στο 2 και στο τμήμα του 1 εκθέτουμε το αντικείμενο 1 μέσω της συνάρτησης του 1. Στην Μ2000 όλα τα αντικείμενα έχουν τον τύπο Ομάδα, ανεξάρτητα από το τι μέλη έχουν (η Μ2000 έχει και ειδικά αντικείμενα που σχετίζονται με το σύστημα COM, για τις φόρμες και για επικοινωνία με προγράμματα όπως το Word)


Η πρώτη έκδοση του προγράμματος έγινε εδώ  στο Vbforums

\\ Συναρτησιακός προγραμματισμός
\\ γραμμένος στη γλώσσα Μ2000
\\ Με F1 ο διορθωτής αλλάζει την αναδίπλωση λέξεων (τη βάζει ή τη βγάζει)
\\ Αν θέλουμε Ελληνικά στα μενού τότε γράφουμε Ελληνικά στην γραμμή εντολών
\\ ή με το Ρυθμισεις (ctrl U) βάζουμε ελληνικά εξ αρχής


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



\****************** Τμήμα Γενικό Pack ******************************************
\* Η Pack δέχεται με αναφορά μια μεταβλητή αλφαριθμητική και βάζει ένα στοιχείο
\* που διαβάζει από το σωρό κατάλληλα διαμορφωμένο.
\* Δεν επιστρέφει τιμή στο σωρό
\**************************************************************************
Τμημα Γενικό Pack {
            Διάβασε &a$
            Αν Ειναρ Τότε Βάλε trim$(str$(αριθμός)) \\ η Ειναρ γυρίζει αληθές η κορυφή του σωρού είναι αριθμός  (για αλφαριθμητικό είναι το Εινγρ.
            Αν a$="" Τότε { a$="{"+γράμμα$+"}"
             } Αλλιώς a$=a$+", {"+γράμμα$+"}"
      }
\********************Τμήμα Γενικό Unpack********************************
\* Αυτά που είχε βάλει το Pack τα διαμορφώνει το Unpack
\*  ώστε σίγουρα να αποτελούν συναρτήσεις!
\* ο χειριστής ~ είναι ίδιος με την Like της VB6
\* το b$ ~ "*=*"  δίνει αληθές (-1) αν υπάρχει το
\* ίσον κάπου μέσα στο κείμενό του B$, αλλά όχι σε άκρες
\* το ? "=12" ~ "*=*" τυπώνει 0 (ψευδές) γιατί δεν έχει γράμματα
\* αριστερά του ίσον
\**************************************************************************
Τμήμα Γενικό Unpack {
      Διάβασε b$
      Αν b$ ~ "*=*" Τότε {
       b$="{"+b$+"}"
      } Αλλιώς b$="{= "+b$+"}"
      Βάλε b$
}     
\**********************Συνάρτηση Γενικό List$******************************
\* Δημιουργεί μια λίστα συναρτήσεων (χωρίς όνομα)
\* γενική b=10
\* a$=list$(b+12,{b**2})
\* όταν χρησιμοποιήσουμε τη λίστα το b**2  (ίδιο με το b^2)
\* θα υπολογιστεί τότε, ενώ το b+12 υπολογίζεται στη δημιουργία
\* Έτσι υλοποιούμε τις eager και lazy επεξεργασίες (evaluations).
\*************************************************************************************
Συνάρτηση Γενική List$ {
      s$=""
                        \\ ο σωρός της συνάρτησης κληρονομείται στην Pack
                        \\ έτσι οι παρέμετροι ένας προς έναν πάνε στην Pack
                        \\ με πρώτο όμως μια αναφορά την s$ για να μαζέψουμε τη λίστα.
      Αν Μέγεθος.Σωρού =0 Τότε Βάλε ""
      Για i=1 Έως Μέγεθος.Σωρού { Pack &s$ }
      =s$
}
\**************************** Συνάρτηση List.count************************************
\* Διαβάζουμε τον αριθμό στοιχείων στην λίστα
\* Η εντολή ένθεση εκτελεί ένα αλφαριθμητικό ως κώδικα
\* Με την Pack κάναμε όλη τη λίστα να έχει αλφαριθμητικά
\* (οι αγκύλες { } ορίζουν και αλφαριθμητικά εκτός από μπλοκ εντολών)
\* Η συνάρτηση έχει δικό της σωρό και στο πέρας θα διαγραφεί
\* Έτσι παίρνουμε μόνο το μέγεθος σωρού που μας ενδιαφέρει.
\**************************************************************************************
Συνάρτηση List.count {
      Διάβασε a$
      Ένθεση "Βάλε "+a$
      =Μέγεθος.Σωρού
}
\*******************************Τμήμα  Goal******************************************
\* Με παράμετρο μια αναφορά σε λίστα μας δίνει τα στοιχεία της ένα προς ένα
\* στην τρέχουσα έξοδο που είναι μέσω της Τύπωσε
\* (εξ ορισμού η τύπωσε εξάγει στην οθόνη αλλά μπορεί να αλλάξει αυτό)
\* Μπορούμε να δώσουμε μια δεύτερη παράμετρο και να αλλάξουμε το τι θα κάνουμε
\* σε κάθε στοιχείο της λίστας. Ουσιαστικά αυτό το τμήμα τρέχει τις λίστες.

\* Η εντολή Πάνω χωρίς παραμέτρους διπλασιάζει τη κορυφή
\* του σωρού τιμών (ειδική στοίβα της Μ2000)
\**************************************************************************************
Τμήμα Γενικό Goal {
      Πάνω : Διάβασε test$
      Αν Θέση(test$,"{")=1 Τότε {
            Διάβασε &a() \\ Συνάρτηση
            Σωρός νέος {
            a$=""
            Κάλεσε a()
            Αν Μέγεθος.Σωρού=0 Τότε Διέκοψε \\ η Διέκοψε (break) **σπάει** πολλά μπλοκ μαζί
            Για i=1 Έως Μέγεθος.Σωρού {pack &a$}
            }
      } Αλλιώς Διάβασε &a$
      Αν a$="" Τότε Έξοδος \\ η έξοδος **σπάει** μόνο το τρέχον μπλοκ
      Αν ταύτιση("S") Τότε { Διάβασε &redirect() } Αλλιώς Συνάρτηση redirect {Διάβασε a: Τύπωσε a}
      Σωρός νέος {
            Ένθεση "Σειρά "+a$ \\ Η εντολή σειρά βάζει στο σωρό ως FiFo  \\ Η Βάλε ως  LiFo
            Ενώ Όχι Κενό {
                  Για Αυτό { \\  δημιουργούμε ένα μπλοκ για προσωρινά ονόματα.
                        Unpack
                        Διάβασε &pp() \\ μόνο σε ονόματα που δεν υπάρχουν βάζουμε αναφορές
                        \\ εδώ έχουμε τους δυο τρόπους κλήσης συνάρτησης
                        \\ ο πρώτος δίνει νέο σωρό και περιμένει τιμή.
                    
                          Βάλε pp() \\ βάζουμε το αποτέλεσμα στο σωρό
                      
                        \\ ο δεύτερος καλεί τη συνάρτηση ως τμήμα, παρέχοντας το σωρό
                    
                          Κάλεσε redirect() \\  μη μηδενική τιμή αν επιστραφεί (π.χ. με =10) θα δώσει Λάθος
                    
                        \\\  κάποιος θα έβαζε π.χ. kk=redirect(pp()) και θα δούλευε...στο παράδειγμα
                        \\ kk=redirect(pp())     \\ σκίασε τα παραπάνω Βάλε και Κάλεσε και αποκάλυψε αυτό εδώ!
                    
                        \\ πράγματι δουλεύει για αυτά τα παραδείγματα. Αλλά με τον παραπάνω τρόπο
                        \\\ εκθέτουμε το σωρό στην redirect() που σημαίνει ότι παρέχουμε δυνατότητα να
                        \\ "διαβάσει μπροστά"...ή look ahead, να δουλεύει ανά δυο στοιχεία.
                        \\ να γιατί παραπάνω έχουμ εμια Ενώ όχι κενό { } και όχι μια Για ι=1 Έως Μέγεθος.Σωρού {}
                    
                        \\ τώρα η pp() θα διαγραφεί. Και έτσι την επόμενη φορά θα της δώσουμε αναφορά!
                  }
            }
      }


}
\********************************Τμήμα Γενικό Process*******************************
\* Δέχεται μια λίστα ή μια συνάρτηση και μια πράξη.
\* Επιπλέον διαβάζει έναν αριθμό (αυτός δίνεται στην Goal ως αποτέλεσμα
\* από κάθε συναρτηση (η λίστα της Goal είναι μια λίστα συναρτήσεων)
\* Αν με την Process περάσουμε λίστα έχουμε για κάθε αποτέλεσμα πράξη..
\* με κάθε στοιχείο στη λίστα
\**************************************************************************************
Τμήμα Γενικό Process {
      Διάβασε mylist$, op$
      Διάβασε a
      Σωρός νέος {
            Ένθεση "Σειρά "+ mylist$
            Διάβασε where$
            Ενώ Όχι Κενό {
                  Για Αυτό {
                        Unpack
                        Διάβασε &bb()
                        Ένθεση " Pack "+where$+", a"+op$+"(bb())"                       
                  }
            }
      }
}
\**************************************************************************************
\* Σε μια γραμμή Συναρτησιακός Προγραμματισμός:
\* Γενικό ThisString$ : Goal "{Κάλεσε integer(25)}"  , "{qubic_of &ThisString$}" : Τύπωσε ThisString$
\**************************************************************************************


Φόρμα 60,28 \\ οθόνη με φόρμα 60 χαρακτήρες πλάτος επί 28 γραμμές
Άδειασε   \\ ο σωρός τώρα αδειάζει από οτιδήποτε
Τύπωσε list.count("") \\ 0
Γενικό ab=10, bb=30
      a$=List$({bb+=ab : =sqrt(ab)},40,{ab**2+bb-20}, 50,60)
            Goal &a$
Γενικό sss$
      Goal &a$,  "{Pack &sss$}"  \\ δίνουμε συνάρτηση για να πάρουμε μια λίστα
            Τύπωσε sss$ \\ τυπώνουμε τη λίστα


Τύπωσε ab, bb



Γενικό add$, mul$
a$=List$(1,2,3)
Γενικό b=10, a=25


\\ Θα προσθέσουμε κάθε στοιχείο της λίστας a$ με άλλη λίστα
\\ η εξαγωγή θα πάει στο add$
\\ ουσιαστικά εδώ με το b++ σπάμε το κανόνα που θέλει να μην γίνονται αντικαταστάσεις


Goal &a$ ,  "{Process List$({&add$},{b++: =b},5,{a/2+b},20, a),{+} }"
Τύπωσε add$


\\ Θα πολλαπλασιάσουμε κάθε στοιχείο της λίστας a$ με άλλη λίστα
\\ η εξαγωγή θα πάει στη λίστα mul$
Goal &a$ ,  "{Process List$({&mul$},{b++: =b},5,{a/2+b},20),{*} }"
Τύπωσε mul$


Γενικό Result$, Result1$, Result3$
      zero$=list$(25)
      Goal &zero$, "{Διάβασε kl : Για i=1 Έως kl {Σειρά i*i : Pack &Result$}}"
      Τύπωσε Result$
  
      Goal "{Για i=1 Έως 25 {Σειρά i*i}}", "{Pack &Result1$}"
      Τύπωσε Result1$


Συνάρτηση Γενική integer { Διάβασε x : Ενώ x>0 { Βάλε x : x--}}
Τμήμα Γενικό square_of { Διάβασε &S$, x: Pack &S$, x*x}
Τμήμα Γενικό qubic_of { Διάβασε &S$, x: Pack &S$, x*x*x}


      Goal "{Κάλεσε integer(25)}"  , "{square_of &Result3$}"
      Τύπωσε Result3$


Καθαρό Result3$ 


      Goal "{Κάλεσε integer(25)}"  , "{qubic_of &Result3$}"
      Τύπωσε Result3$
      Τύπωσε "ok"


Βασικές γνώσεις (Τμήματα) στη Μ2000

Σημ 1. Μπορούμε να γράφουμε σημειώσεις με την Σημ (REM)
\\ και χωρίς αυτήν με το \ ή και το '
' και αυτή είναι σημείωση


Σημ 1.1 για να εκτελέσουμε αυτό το παράδειγμα:
\\ τρέχουμε το m2000.exe
\\ γράφουμε   σ α   (ανοίγει ο διορθωτής για το τμήμα α)
\\ κάνουμε επικόλληση και πατάμε Esc
\\ γράφουμε το όνομα του τμήματος:  α (και πατάμε Enter)
\\ τόσο απλά.
\\Με βελάκια πάνω-κάτω βλέπουμε τις παλαιότερες εντολες.
\\ Σώνουμε με Σώσε ενα_ονομα
\\ Φορτώνουμε με Φόρτωσε ενα_ονομα
\\ Βλέπουμε τι τμήματα έχουμε με Τμήματα  και Τμήματα ?
\\ Για συναρτήσεις γενικές γράφουμε Σ α( ή Σ α$( ή Σα%(
\\ (πρέπει να δηλώνουμε τι επιστρέφει αριθμό ή γράμματα
\\ Μπορούν να επιστρέφουν πίνακες και αντικείμενα, αλλά αυτό
\\ δεν φαίνεται από το όνομα αλλά από το πρόγραμμα!
\\ Γράψε: Βοήθεια Όλα και κάνε κλικ σε κάτι απ' όλα!

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


Σημ 3. Μπορούμε να φτιάχνουμε γενικούς πίνακες με μια τιμή
θεσε πίνακας α(10,5)=100


Σημ 3.1. Ή χωρίς τιμή
Γενικό β(10,10), δ(20,20), κ()
Πίνακας β(5,5) =20 \\ εδώ σκιάσαμε τον γενικό με ένα τοπικό
κ()=β() \\ αλλά εδώ βγάλαμε ένα αντίγραφο και τον δώσαμε στον γενικό
Τύπωσε β(3,3) \\ τοπικό


Σημ 4. Τεκμηρίωση: καλούμε το τμήμα άλφα και βλέπουμε αποτελέσματα
τμήμα γενικό άλφα { \\ στον ορισμό συνάρτησης βάζουμε συνάρτηση γενική
      τυπωσε 123, α(1,1), β(3,3), κ(3,3)
}


άλφα    \\ καλούμε την άλφα


Σημ 5. Τώρα θα καλέσουμε την άλφα από ένα τοπικό τμήμα βήτα


Τμήμα βήτα {
      διάβασε οδηγία$
      αν οδηγία$="οκ" τότε {
            άλφα
      } αλλιώς.αν οδηγία$="" τότε κάλεσε άλφα \\ άλλος τρόπος κλήσης
}


βήτα "οκ"
βήτα ""


Σημ 6. Τα τμήματα διαβάζουν τον σωρό τιμών


βάλε "οκ"
βήτα   \\ τώρα το "οκ" το βρήσκει στον σωρό
βάλε ""
κάλεσε βήτα


Σημ 7. Μπορούμε να περνάμε τιμές με αναφορά


Τμήμα δέλτα {
      Διάβασε &κάτι
      κάτι+=100
}
γενικό Άλφα
τοπική βήτα \\ εξ ορισμού είναι όλα τοπικά στο τμήμα   - δεν υπάρχει εντολή τοπικό!
Άλφα<=40 \\ τα γενικά θέλουν <= στην αντικατάσταση τιμής, αλλιώς θα φτιαχτεί τοπική
                  \\ Οι πίνακες δεν χρειάζονται το <= για αντικατάσταση σε γενικό
Στη Άλφα=50
                  \\ η Στη (LET) δουλεύει αλλιώς οπότε δεν φτιάχνει τοπική αν υπάρχει γενική
Άλφα+=20
Άλφα++ \\ =71
δέλτα &Άλφα
Τύπωσε Άλφα \\  171
δέλτα &βήτα
Τύπωσε βήτα



\\ Περί Τμημάτων (βασικά θέματα):
\\  Τα τμήματα διαφέρουν από τις Διαδικασίες άλλων γλωσσών γιατί:
\\  1. Μπορούν να επιστρέφουν τιμές εκτός με αναφορά και σε σωρό
\\  2. Βλέπουν μόνο τις δικές τους μεταβλητές και εκείνες του γενικού σκοπού.
\\  3. Μπορούν να δημιουργούν άλλα τμήματα ή να τα φορτώνουν
\\  4. Μπορούν να δημιουργούν σκιάζοντας γενικές μεταβλητές
\\ 5. Δεν έχουν αναδρομή εκτός και αν κληθούν ως συναρτήσεις (προχωρημένο θέμα).
\\ 6. Τα τμήματα μοιράζονται τον ίδιο σωρό αν είναι στην ίδια σειρά κλήσης
\\ 7. Τα τμήματα που ορίζουμε με τη συγγραφή (π.χ. σ Α) είναι γενικού σκοπού.


\\Περί σειράς κλήσης
\\ Αν το Α καλέσει το Β και το Β το Γ τότε λέμε ότι το Γ είναι σε σειρά κλήσης με το Α
\\ Επειδή η Μ2000 έχει νήματα...ενδέχεται ένα νήμα στη Γ να καλέσει την Α
\\ Αυτό το νήμα ξεκινάει νέα σειρά κλήσης. Η Α που κάλεσε έχει απλά το ίδιο πρόγραμμα.
\\ Αυτό που τρέχει ως Α στο νήμα του Γ και οι μεταβλητές του....
\\ .......(τα ονόματά του) είναι σε άλλο "χώρο ονομάτων", και επιπλέον έχουν άλλο σωρό.
\\ Εκτός από τα νήματα αυτό συμβαίνει και με τις συναρτήσεις που φτιάχνουμε.
\\ Κάθε δική μας συναρτηση όταν τρέχει ξεκινάει την δική της σειρά κλήσης με δικό της σωρό.
\\ Ακόμα και αν καλέσει τον εαυτό της, κάθε κλήση θα είναι μια νέα σειρά κλήσης, νέος σωρός.
            Συνάρτηση Άλφα {
                  διάβασε Α
                  =Α+1
            }
            Τύπωσε Άλφα(Άλφα(Άλφα(1))) \\ κάθε διάβασε στην Άλφα γίνεται σε νέο σωρό.
\\                                  4
\\ μπορούμε να φτιάχνουμε και συναρτήσεις σε μια γραμμή, αλλά θα δώσουμε τις παραμέτρους
\\ αυτή είναι μακροεντολή γιατί φτιάχνει ουσιαστικά μια Συνάρτηση βήτα {Διάβασε Χ : =Χ+1}
\\ επιπλέον αυτός ο τρόπος της μια γραμμής (από το DEF FN της παλιάς Basic) δεν παίρνει σήμα Γενική
\\ def beta(x)=x+1   \\ από την παλιά Basic (χωρίς το FN, η παλιά Basic το είχε απλά πρόσθετο στο όνομα)
κάνε βήτα(Χ)=Χ+1
Τύπωσε βήτα(2)


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


Τμήμα έψιλον {
       \\ η διάβασε ξεχωρίζει αν έχουμε αναφορά πίνακα ή συνάρτησης
      Διάβασε &Οποιοδήποτε_Όνομα(), &ΚάτιΑλλο()
      ? Οποιοδήποτε_Όνομα(ΚάτιΑλλο(1)) \\ το ? είναι Τύπωσε
}
πίνακας κλ(10)=20
\\ Το &κλ(1) είναι --ΛΑΘΟΣ--- δεν μπορούμε να το περάσουμε, αναφορές σε στοιχεία πίνακα δεν γίνονται
\\ ούτε αναφορές συνάρτησης με πέρασμα μεταβλητών έτσι &βήτα(1,2,4) ---ΛΑΘΟΣ---
έψιλον &βήτα(), &κλ()
\\              21


\\ Περί Σκοπού:
\\  Αν  τα παρακάτω έχουν οριστεί γενικού σκοπού φαίνονται παντού
\\  Μεταβλητές, Πίνακες, Τμήματα, Συναρτήσεις, Κλάσεις
\\ (οι κλάσεις στην Μ2000 είναι συναρτήσεις που κατασκευάζουν αντικείμενα)
\\ Βασικοί Κανόνες:


\\*** Οτιδήποτε τοπικό με ίδιο όνομα κρύβει το αντίστοιχο γενικό****
\\ Αν ορίζουμε γενικές μεταβλητές ή πίνακες με την θέσε τότε κάνουμε αντικατάσταση
\\ Αν ορίζουμε με την γενικό (ή γενική) τότε δημιουργούμε νέα μεταβλητή/πίνακα
\\  που σκιάζει το προηγούμενο. Η σκίαση φεύγει αν η τοπική βγει εκτός σκοπού, σβηστεί.


\\ ***Οτιδήποτε ορίζεται εντός τμήματος, ακόμα και γενικό, θα σβηστεί στο πέρας**
\\ Ο σωρός τιμών δεν έχει όνομα! Έτσι δεν εμπίπτει στο κανόνα.
\\ μπορούμε να φτιάξουμε ένα πίνακα σε ένα τμήμα και να αφήσουμε ένα αντίγραφο στο σωρό.
\\ όμως ο αρχικός θα χαθεί! Θα μείνει το αντίγραφο. Λογικά λοιπόν μπορούμε να φτιάξουμε
\\ κάτι και να εξάγουμε. Άλλο σημαίνει φτιάχνω και άλλο ορίζω!