Παρασκευή 23 Μαρτίου 2018

Revision 3 (Version 9.2) Operators and Light Events for Groups

Revision 3 for Version 9.2 remove a bug in events, and has two implementations, one for operators in groups (a better code, and use of priorities)


1) New extension for operators, using unary, and priorities (low standard, High for * and /), and we can define a right operator for higher priority, and this used for power.
Comparison Operators are always lower priority, and return boolean value (not Group). All other operators return group. Here group has one value (just a public variable), so we can check the evaluation easy.

group alfa {
      n=10
      operator unary {
            .n-!
      }
      operator "-" {
            read b
            .n-=b.n
      }
      operator "=" {
            read b
            push .n=b.n
      }
      operator ">" {
            read b
            push .n>b.n
      }
      operator "<" {
            read b
            push .n<b.n
      }
      operator  "+" {
             read b
              .n+=b.n
      }
      operator right "**" {
             read b
              .n<=.n**b.n
      }
      operator high "*" {
             read b
              .n*=b.n
      }
      operator high "/" {
             read b
              .n/=b.n
      }
      Function Bigger {
            call operator ">", group
            =Number
      }
    
      module operations {
            read z
            call operator "+", z
            call operator "+", z
            call operator "*", z
            call operator "-", z
            m=z
            m.n=100
            call operator "/", m
      }
}

Group Alfa {
      operator "/" {
             read b
              .n/=b.n
      }      
}
z=alfa
k=alfa
k.n=2
z.n=30
m=alfa**k**k+z**k
Print alfa.n**k.n**k.n+z.n**k.n
Print m.n
m=-alfa/-k*-z
Print -z.n*-alfa.n/-k.n
Print m.n
m=alfa*z+alfa*z+z
Print m.n ',  z*ALFA+alfa*z+z>z and 10>2  ' try this
Print alfa.n*z.n+alfa.n*z.n+z.n
Print alfa.n*z.n+alfa.n*z.n+z.n
m=(alfa+z+z)*z
Print m.n, "=(alfa+z+z)*z"
Print (alfa.n+z.n+z.n)*z.n
m=z*(alfa+z+z)
Print m.n, "=z*(alfa+z+z)"
Print z.n*(alfa.n+z.n+z.n)
Print alfa.n
alfa.operations z
Print alfa.n, z.n
alfa*z
Print alfa.n, z.n
alfa-z
Print alfa.n, z.n
m=alfa-z
Print m.n
Print alfa.bigger(z), alfa>z
m=m/z
Print m.n, z.n



2)Light Events for groups:
Group WithEvents Alfa {
      Events "a", "b"
      Χ=10
      Module Check {
            Def M as long
            call event "a", &M, 20
            Print stack.size, M
       }
       Module CheckB(what$) {
            call event "b", what$
      }
}
M=100
a=500
b=4000
Function Alfa_a(New &a,b) {
      M++
      a=M
      Print "ok", a, b, M
      push 500 ' can't return using stack, stack is private
}
Function Alfa_b(a$) {
      Print "From Event:";a$
}
Alfa.Check
Stack ' print empty line, stack is empty
dim k(10)=alfa
Module Z (M()){
      For i=0 to 9{
                  For M(i) {
                        .check
                  }
      }
      M(5).checkb "This is M(5)"
}
Z K()
Beta=k(3)
Beta.checkb "Hello There"
Print a, b ' not changed




The same ouput can we have using Event objects. Event objects have commands like these
Event A Hold
Event A Clear
Event A Release
Event A New aaa() [, bbb()]   ' we can bind some functions for multicast purposes
Event A Drop aaa() [, bbb()] ' we can drop any function
Also These events need to have a signature using a Read command, without "as type". Only the number and kind (by reference using &, $ for strings, ( ) for arrays)
So in Event A variable b can be a number or an object.
In function Alfa_a we have to place New because events call functions as code in module where the function belong, so we have same scope, a New in front in parameter list means Read New &a, b



Group Alfa {
      Event A {
            Read &a, b
      }
      Event B {
            Read a$
      }
      Χ=10
      Module Check {
            Def M as long
            call event .A, &M, 20
            Print stack.size, M
       }
       Module CheckB (what$) {
                  call event .B, what$
      }
}
M=100
a=500
b=4000
Function Alfa_a(New &a, b as long) {
      M++
      a=M
      Print "ok", a, b, M
      push 500 ' can't return using stack, stack is private
}
Function Alfa_b(New zz$) {
      Print "From Event:";zz$
}

Event Alfa.A New Lazy$(&Alfa_a())
Event Alfa.B New Lazy$(&Alfa_b())
Alfa.Check
Stack ' print empty line, stack is empty
dim k(10)=alfa
Module Z (M()){
      For i=0 to 9{
                  For M(i) {
                        .check
                  }
      }
      M(5).checkb "This is M(5)"
}
Z K()
Beta=k(3)
Beta.checkb "Hello There"
Print a, b ' not changed

Τρίτη 20 Μαρτίου 2018

Αναθεώρηση 2 (Έκδοση 9.2)

Έγιναν ενδιαφέρουσες προσθήκες!
1) Οι μεταβλητές στη κονσόλα αναγνωρίζονται από τον διερμηνευτή τμημάτων ως γενικές ώστε να μην αφήνει σε πέρασμα με τιμή, με ίδιο όνομα γενικής, να χρησιμοποιεί την γενική αλλά να φτιάχνει νέα (αυτό είχε προβλεφθεί από την αρχική 9.2 έκδοση, αλλά δεν είχε υλοποιηθεί, δούλευε μόνο για τις γενικές που φτιάχναμε μέσα σε πρόγραμμα).
2) Νέος Έλεγχος, με δυνατότητα να εκτελεί εντολές και κατά το σταμάτημα, αλλά και κατά την αργή εκτέλεση. Μπορούμε πχ να αλλάξουμε τιμή σε μεταβλητή ή να καλέσουμε κάποιο τμήμα. Για να αλλάξουμε την επιλογή από προβολή σε εκτέλεση αρκεί να πατήσουμε το BackSpace μέχρι να σβήσει όλη η γραμμή και μια ακόμα! Το στοιχείο λειτουργεί όπως και η φόρμα ακόμα και αν τρέχει πρόγραμμα σε αργή ταχύτητα (η δεύτερη επιλογή από τη λίστα πάνω δεξιά στη φόρμα). Η εντολή Δοκιμή ή Test ανοίγει τον έλεγχο, αλλά μπορούμε να τον ανοίξουμε και με συνδυασμό πλήκτρων γραμμάτων και το Ctrl. (τα γράμματα παίζουν όλα όσα δεν χρησιμοποιούνται αλλού, όπως τα C, F, L, M, N, A, V στη κονσόλα). Μπορούμε να καλέσουμε την εντολή και από το πρόγραμμα, ώστε να σταματήσει όπου θέλουμε και υπάρχει και τρόπος για να σταματάει και να συνεχίζει μέχρι μια επόμενη εντολή με συγκεκριμένη ετικέτα. Οι βασικές φόρμες του περιβάλλοντος έχουν την ιδιότητα να μεγαλώνουν, μεγαλώνοντας τα γράμματα, για να είναι θεατά από κάθε χρήστη! Αυτό δεν ισχύει στις φόρμες χρήστη, που δουλεύουν όπως όλες οι φόρμες, αν είναι φόρμες που αλλάζουν μέγεθος στέλνουν γεγονός και κάνουμε ότι θέλουμε. Οι φόρμες περιβάλλοντος έχουν το σκούρο πλαίσιο.



Εικόνα με το τελευταίο στοιχείο να έχει αριστερά το ? και αμέσως μετά γράφουμε μια λίστα στοιχείων για να μας δείξει (πατάμε enter, και παραμένουν σε κάθε επόμενη εκτέλεση, ώστε να βλέπουμε την εξέλιξη). Τα αποτελέσματα φαίνονται στο πεδίο που τώρα δείχνει κώδικα. Αυτό το πεδίο αλλάζει και με κλικ στο Next: (τρίτο στοιχείο της λίστας αριστερά). Επιπλέον τώρα μπήκε και μια προσθήκη, όταν κάνουμε κλικ στο κώδικα να μας δείχνει το κώδικα στη φόρμα της βοήθειας, με την εντολή προς εκτέλεση με κόκκινο χρώμα, ώστε να έχουμε καλύτερη θέαση (απλά σε αυτή την φόρμα δεν έχουμε μετακίνηση του κόκκινου δρομέα, κάτι δηλαδή που έχουμε στο πεδίο αυτό, και επίσης δεν έχουμε χρωματισμένο κώδικα)


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


3) Νέο χαρακτηριστικό στο Combo στοιχείο ελέγχου, το οποίο βέβαια σχετίζεται με το TextBox (το Combo είναι δυο στοιχεία, ένα που βάζουμε πάνω στη φόρμα και ένα δεύτερο που ανοίγει για να επιλέξουμε στοιχείο. Εδώ στην εικόνα έχουμε αυτόματη συμπλήρωση, και το νέο είναι ότι χρωματίζεται το συμπλήρωμα με γκρι χρώμα. (φαίνεται ο ίδιος μηχανισμός και στην φόρμα ελέγχου).


Το πρόγραμμα για τη φόρμα. Είναι με αγγλικές εντολές αλλά μπορεί να γραφτεί και με ελληνικές. Αυτό που δεν φαίνεται στην εικόνα είναι ότι στα στοιχεία  παίζει το Ctrl+F1, το οποίο το φτιάχνει η About (ή Περί). Επίσης εκτός από αυτόματη συμπλήρωση έχουμε προσθήκη νέων λέξεων και ταξινόμηση. Είναι απλός ο κώδικας και γράφεται σε ένα τμήμα Α (με Edit A ή Σ Α) και μετά βγαίνουμε από το διορθωτή με Esc και δίνουμε το όνομα του τμήματος και το enter και τρέχει. Δεν χρειάζεται να βγούμε από την κονσόλα της Μ2000 για να τρέξουμε διαφορετικά προγράμματα. Απλά με τη Σώσε και το όνομα σώνουμε  και με τη Φόρτωσε και το όνομα φορτώνουμε (καλύτερα να δώσουμε Νέο για να σβήσει το παλιά τμήματα και τις συναρτήσεις, γιατί αν υπάρχουν τμήματα με ίδια ονόματα, η φόρτωσε από τη κονσόλα τα "πατάει"). Μπορούμε όμως σε κάθε τμήμα να έχουμε ένα πρόγραμμα (τα τμήματα από τη κονσόλα είναι γενικά, δηλαδή μπορεί ένα οποιοδήποτε τοπικό τμήμα, να τα καλέσει, εκτός και αν υπάρχει τοπικό με ίδιο όνομα, οπότε σκιάζεται το γενικό)

Ενώ η θέαση μεταβλητών περιορίζεται στα τμήματα και στις συναρτήσεις στα τοπικά και σε ότι είναι γενικό, στις συναρτήσεις γεγονότων (καλούνται σαν τμήματα) η θέαση είναι κοινή με την θέαση στο τμήμα που βρίσκονται αυτές. Πχ στη συνάρτηση combo1.dblclick (την οποία καλεί το γεγονός
dblclick του combo1, η τελεία και τα ονόματα πρέπει να είναι ίδια με το στοιχείο και το γεγονός που διαθέτει αυτό αλλιώς δεν μπορεί να κληθεί)  αυτό text1.text$=combo1$  μπορεί να γίνει γιατί το δεξιό μέρος είναι θεατό, και εδώ είναι και το αριστερό. Το text1.text$ είναι ένα αντικείμενο ιδιότητα. Η τελεία στο όνομα μπήκε για γούστο, θα μπορούσαμε να μην τη βάζαμε. Ο διερμηνευτής συνδέει την πραγματική ιδιότητα "text" του στοιχείου text1 που ορίσαμε ότι είναι textbox της φόρμας form1 με την εντολή Declare (Όρισε στο ελληνικό λεξιλόγιο της γλώσσας Μ2000). Η σύνδεση θα τερματίσει όταν τερματίσει το τμήμα ή όταν το στοιχείο δηλωθεί ως τίποτα (δείτε τις τρεις τελευταίες εντολές Declare ....nothing). Η εντολή With (ή Με στο ελλ. λεξ.) χειρίζεται ιδιότητες των αντικειμένων. Ο διερμηνευτής κάθε φορά που χρησιμοποιούμε μια νεα ιδιότητα την θυμάται, οπότε ακόμα και αν δεν την συνδέσουμε με μεταβλητή, στην δεύτερη και επόμενες χρήσεις θα εκτελεί πιο γρήγορα. Οι φόρμες και τα στοιχεία ελέγχου είναι αντικείμενα COM και οι εντολές Method (Μέθοδος) και With (Με) τα χειρίζονται (όπως και κάθε άλλο αντικείμενο COM, όπως το Word). Ορισμένες ιδιότητες τις έχουμε σαν πίνακες, όπως τον πίνακα list$(), για την ιδιότητα "List" του Combo1. Αυτό μπορούμε να το κάνουμε όταν μια ιδιότητα παίρνει παράμετρο.Η Find() αν και είναι ιδιότητα λειτουργεί στην ουσία ως συνάρτηση με μια παράμετρο. Η Μέθοδος μπορεί να καλεί μεθόδους που επιστρέφουν τιμές, και μάλιστα και αντικείμενα και επιπλέον μπορούμε να δηλώσουμε την επιστροφή ΜεΓεγονότα, οπότε θα παίρνουμε και γεγονότα. (αυτά ξεχωρίζουν γιατί δεν δηλώνονται στις συναρτήσεις με τελεία , μεταξύ αντικειμένου και ονόματος γεγονότος αλλά με κάτω παύλα _). Στα αντικείμενα για το παραθυρικό περιβάλλον δεν χρειάζεται τόση εμβάθυνση, λειτουργούν πολύ απλά. Τα νούμερα πχ 8000 είναι σε twips.
Υπάρχει και ένα αστείο στο πρόγραμμα. Την φόρμα την ανοίγουμε και την κρατάμε σε βρόχο (βασικό στοιχείο για να πάρουμε τα γεγονότα) με μια εντολή που περιμένει να πατήσουμε ένα πλήκτρο (Στη φόρμα της κονσόλας). Αν κάνουμε κλικ στην κονσόλα και πατήσουμε ένα πλήκτρο θα κλείσει η φόρμα. Στο γεγονός Unload στέλνω ένα χαρακτήρα στο πληκτρολόγιο με την Keyboard ή Πληκτρολόγιο  η οποία το στέλνει στη κονσόλα και η εντολή Get$ διαβάζει από αυτήν και μόνο, ενώ στις φόρμες έχουμε εισαγωγές από γεγονότα (εδώ για απλοποίηση δεν χρησιμοποιώ τα στοιχεία που δίνει το γεγονός, τα αφήνω δηλαδή στο σωρό τιμών που συνοδεύει τη κλήση, αλλά σε αυτά είναι και μεταβλητή με αναφορά για να ακυρώσει κανείς το τερματισμό της φόρμας).

About call {
      select case About$
      case "is a big name here"
            About  "Title: is a big name here", 8000,6000,"that [is a big name here] easy [too]"
      else
            About  "Title: too", 8000,6000,"that [is a big name here] easy"+About$
      end select
}

Declare form1 form
Declare combo1 combobox form form1
Declare text1 textbox form form1
With form1,"Title" as title$
With combo1,"Edit", True,"UseOnlyTheList", false,"autocomplete", True, "listIndex" as ListIndex,"ShowAlways", True
With combo1,"label","Combo1", "ListText" as item$, "list" as list$(), "text" as combo1$
item$={alfa
            delta
            gamma
            beta
            }
With combo1,"Find" as Find()
Method combo1,"Sort"
combo1$=list$(find("gam*"))

Method combo1,"Move", 1000,1000,6000,600
Method text1, "Move", 1000,2900,6000,600

With text1, "left" as left, "text" as text1.text$ , "ShowAlways", True
Print left
Method form1, "show"
Method text1,"GetFocus"
function form1.unload {
      About
      Keyboard "!"
      show
}
function combo1.about {
      About show "is a big name here"
}
function text1.about {
      About show ""
}
Function combo1.dblclick {
        text1.text$=combo1$
        title$=combo1$
        if find(title$)= -1 then {
         method combo1,"additem",title$
         Method combo1,"Sort"
         listindex=find(title$)
         }
         combo1$=combo1$
          Method text1,"GetFocus"
}
Function combo1.click {
      if listindex>=0 then text1.text$=list$(listindex)
}
Function combo1.scroll {
      if listindex>=0 then text1.text$=list$(listindex)
}
a$=key$ ' loop for holding Forms; Is a joke but works.
Declare Text1 nothing
Declare combo1 nothing
Declare form1 nothing




4) Όπου έχουμε στοιχείο εισαγωγής κειμένου, η λειτουργία Drag and Drop βελτιώθηκε, ώστε σε περίπτωση ακύρωσης της μεταφοράς από ή πρός τη φόρμα, να επαναφέρει τον δρομέα στο σημείο που ήταν. Πχ όταν από μια γραμμή μεταφέρουμε προς τα κάτω κείμενο, τότε οι γραμμές αλλάζουν εμφανίζοντας έναν δρομέα που θα γίνει η εισαγωγή. Αν πατήσουμε Escape ακυρώνουμε την μεταφορά και το στοιχείο γυρίζει στην θέση που ήταν πριν. Αυτό γίνεται στο EditBox, και στο διορθωτή της κονσόλας (είναι διαφορετικά στοιχεία). Το στοιχείο του διορθωτή κονσόλας χρησιμοποιείται και για εισαγωγή κειμένου σε πλαίσιο μέσα στη κονσόλα, οπότε και εκεί έχει την νέα λειτουργία. Αν και λέμε για διαφορετικά στοιχεία, εντούτοις αυτό που διαφοροποιεί είναι η subclass (όρος της VB6) ενός και μόνο UserControl, το οποίο αναβαθμίστηκε σε αυτή την αναθεώρηση. Πχ ο τίτλος της φόρμας alfa είναι το ίδιο usercontrol με το combo1 και το Textbox από κάτω. Όλο το σύστημα παραθύρων είναι "ιδιοκατασκευή", και υπάρχει από την έκδοση 8.1. Υπάρχουν ακόμα περιθώρια βελτίωσης! Η εμφάνιση των στοιχείων είναι ίδια σε όλα τα λειτουργικά που τρέχει το περιβάλλον. Κάτι νέο που έχουν αυτά τα στοιχεία, είναι ότι μοιάζουν περισσότερο με στοιχεία του Android. Πχ τα Buttons (και άλλα στοιχεία) μπορούν να δεχθούν εκτός από κλικ και ολίσθηση δεξιά. Στο κείμενο με κράτημα του αριστερού πλήκτρου του ποντικιού και ολίσθηση προς τα πάνω μετακινούμε το κείμενο προς τα πάνω, το ανάποδο για προς τα κάτω. Το Drag and Drop μεταξύ των στοιχείων γίνεται με πάτημα μια φορά (χωρίς να πιέζουμε συνέχεια το πλήκτρο του ποντικού). Όλα τα στοιχεία υποστηρίζουν unicode χαρακτήρες και αντιγραφές από το πρόχειρο, αλλά δεν υποστηρίζουν γλώσσες που γράφουν από δεξιά (δεν μπορώ να φτιάξω κάτι που δεν μπορώ να το δοκιμάσω).

Δευτέρα 19 Μαρτίου 2018

Έκδοση 9.2 (Αναθεώρηση 1)

Ολοκληρώθηκε η έκδοση 9.2. Πιθανές αναθεωρήσεις θα γίνουν σε περίπτωση που βρεθούν λάθη. Έχει γίνει αρκετός έλεγχος, και διορθώσεις, ώστε να υπάρχει συμβατότητα με τις παλαιότερες εκδόσεις.

Αν και η έκδοση 9.1 μπήκε με την υποστήριξη διάφορων τύπων μεταβλητών, όπως Decimal, Currency, Double, Single, Long, Boolean, ως προς τις σταθερές τιμές πχ το 10000@ είναι Decimal (ή όπως τον λέμε στα ελληνικά στη Μ2000, Αριθμός), για τις μεταβλητές δεν είχε ξεκαθαριστεί ως προς το πότε θα γίνονται μετατροπές τύπων. Γίνονται μετατροπές αυτόματα όταν πχ πολλαπλασιάσουμε έναν Currency (Λογιστικό το λέμε στη Μ2000) με έναν Double θα πάρουμε Double. Το ζήτημα είναι τι γίνεται κατά το πέρασμα με τιμή (by value), και τι γίνεται στο πέρασμα με αναφορά (by reference) που υποστηρίζει η γλώσσα. Αν μια εκχώρηση τιμής αλλάξει το τύπο στην μεταβλητή που προκύπτει από αναφορά τότε αυτό θα είναι άμεσο και στην αναφερόμενη. Αυτό δεν το θέλουμε! Επιπλέον όταν περνάμε με τιμή ενδέχεται να περάσουμε απλά μια έκφραση αντί για μια μεταβλητή (που και αυτή σαν έκφραση θα την δει ο διερμηνευτής) και αυτή να βγάλει έναν τύπο πχ Μακρύς (Long). Αυτό που θέλουμε είναι να μπορούμε να πάρουμε στην παράμετρο την τιμή με το τύπο που θέλουμε, δηλαδή να γίνει μετατροπή κατά τη κλήση.

Στην πρότερη κατάσταση η γλώσσα είχε στο βασικό της σύστημα επεξεργασίας αριθμητικών και λογικών εκφράσεων σαν βάση τον διπλό ή Double (ή πραγματικός σε άλλες γλώσσες, όπως η ΓΛΩΣΣΑ του σχολείου). Μπορούσε να αποθηκεύσει σε Μακρύ ή Long, αλλά οι όποιες πράξεις γίνονταν με Διπλούς. Αυτός ο τύπος (32bit ακέραιος με πρόσημο) είναι χρήσιμος κατά τις κλήσεις εξωτερικών συναρτήσεων σε βιβλιοθήκες "dll". Επίσης για τους λογικούς ή Boolean, απλά χρησιμοποιούσε το 0 και -1, δηλαδή αρθμούς, και έτσι οποιαδήποτε μεταβλητή μπορούσε να παίξει τον ρόλο του Λογικού. Επιγραμματικά δυο ακόμα παρατηρήσεις ως προς το πως ήταν η γλώσσα πριν την 9.2 (1) έκδοση. Οι μεταβλητές (και οι πίνακες) με το % έπαιρναν διπλό εσωτερικά αλλά στις εκχωρήσεις έκαναν αυτόματη αποκοπή δεκαδικών με στρογγυλοποίηση στο μισό. Τα αλφαριθμητικά πάντα ξεχωρίζουν στην γλώσσα γιατί έχουν το $ στο τέλος του ονόματος. Έγινε αναφορά εδώ για τις απλές μεταβλητές (αριθμοί και γράμματα). Περί αντικειμένων θα τα δούμε σε άλλη ανάρτηση, γιατί έχουμε προσθήκες, προχωρημένες, όπως στις ομάδες τελεστής μοναδιαίος, και εκτέλεση εκφράσεων με ομάδες που δεν επιστρέφουν τιμή αλλά κάνουν πράξεις μεταξύ τους και επιστρέφουν αποτέλεσμα ομάδα. Οι ομάδες που επιστρέφουν ιιμή, απλή, λειτουργούν σαν μεταβλητές, με την διαφορά ότι μπορούν να έχουν τμήματα, συναρτήσεις, ιδιότητες.

Για να δούμε τις προσθήκες θα ξεκινήσουμε από το πώς ορίζουμε μια συνάρτηση (οι συναρτήσεις ορίζονται μέσα σε τμήματα, σε συναρτήσεις, σε ομάδες με τον ίδιο τρόπο)

 Στο ξεκίνημα της συγγραφής της γλώσσας οι συναρτήσεις γραφόντουσαν έτσι απλά. Η λέξη Συνάρτηση (Function), μετά ένα όνομα που μπορούσε να είχε τόνους και μπορούσε να κληθεί και χωρίς τόνους, ή και με λάθος τόνους, με μικρά ή μεγάλα, όπως θέλουμε, δεν έχει διαφορά. Και μετά το μπλόκ εντολών, ή σώμα της συνάρτησης. Κάπου μέσα στην συνάρτηση η επιστροφή τιμή γίνεται με ένα = χωρίς κάτι αριστερά, δηλαδή αναφέρεται στη συνάρτηση. Παρατηρήστε ότι έξω από το σώμα δεν φαίνονται οι τυχόν παράμετροι. Οποιαδήποτε συνάρτηση μπορούσε (και μπορεί) να πάρει οπιοδήποτε αριθμό παραμέτρων, και τύπων. Κάθε συνάρτηση έχει έναν σωρό τιμών, και αυτός "γενννιέται" κατά την κλήση. Εκεί μπαίνουν όλες οι τιμές που θέλουμε να δώσουμε. Για να τις διαβάσουμε αρκή η χρήση της Διάβασε.


Συνάρτηση Ένα {
      =100
}

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

Συνάρτηση ΚυβικήΡίζα {
      =Αριθμός^(1/3)
}
Τύπωσε ΚυβικήΡίζα(8)

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

Συνάρτηση ΚυβικήΡίζα {
      Πάνω  ' διπλασιάζει την κορυφή του σωρού
      =Σημ(Αριθμός)*Απολ(Αριθμός)^(1/3)
}
Ν=ΚυβικήΡίζα(-8)
Τύπωσε Ν**3 ' και το ** σημαίνει δύναμη, όπως το ^

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

Ν=Στρογγ(ΚυβικήΡίζα(ΚυβικήΡίζα(512))^3^3)
Τύπωσε Ν, Τύπος$(Ν) ' δίνει 512 και Double

 Με χρήση μεταβλητής, δηλαδή θα πάρουμε την τιμή του σωρού σε μια μεταβλητή και θα την δώσουμε δυο φορές στην έκφραση στην εντολή επιστροφής τιμής:
Συνάρτηση ΚυβικήΡίζα {
       Διάβασε χ
      =Σημ(χ)*Απολ(χ)^(1/3)
}

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

Συνάρτηση ΚυβικήΡίζα (χ) {
      =Σημ(χ)*Απολ(χ)^(1/3)
}
ή πιο πρόσφατο (ισχύουν δε όλα τα προηγούμενα)
Συνάρτηση ΚυβικήΡίζα(χ) {
      =Σημ(χ)*Απολ(χ)^(1/3)
}

και επειδή αυτή είναι συνάρτηση μιας γραμμής μπορεί να δημιουργηθεί με την εντολή Κάνε (Def) :

Κάνε ΚυβικήΡίζα(χ)=Σημ(χ)*Απολ(χ)^(1/3)

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

Στο παράδειγμα, η ύψωση σε δύναμη ενώς Decimal (Αρθμός, έχει 29 ψηφία) δίνει πάντα διπλό. Η συνάρτηση αν και χρησιμοποίησε τον Decimal, γύρισε διπλό. Όμως η συνάρτηση έχει καλύτερη ακρίβεια υπολογισμού, και δεν χρειάζεται η στρογγυλοποίηση. Η Ν παραμένει ως Decimal, παρά την εκχώρηση Double από την ΚυβικήΡίζα(). Η Μ δείνχει ότι η ύψωση Decimal σε δύναμη δίνει Διπλό, ή Double.  Το ^3^3 είναι ισοδύναμο με αυτό ^9. Πράγματι 2^9 δίνει 512.

Κάνε Ν ως Αριθμός
Κάνε ΚυβικήΡίζα(χ ως αριθμός)=Σημ(χ)*Απολ(χ)^(1/3)
Ν=ΚυβικήΡίζα(8)
Τύπωσε Ν**3, Τύπος$(Ν) ' και το ** σημαίνει δύναμη, όπως το ^
Ν=ΚυβικήΡίζα(ΚυβικήΡίζα(512))^3^3
Τύπωσε Ν, Τύπος$(Ν) ' δίνει 512 και Decimal (Αριθμός)
Μ=Ν**3
Τύπωσε Τύπος$(Μ) ' Double

Όπως και αυτό (προσθήκη στο προηγούμενο), δείχνει ότι αν φτιάχναμε νέα μεταβλητή με το αποτέλεσμα της συνάρτησης θα γίνονταν Διπλός ή Double.
Ζ=ΚυβικήΡίζα(27)
Τύπωσε Τύπος$(Ζ)

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

Επιπλέον ενώ υπήρχε η Διάβασε ? η οποία δέχονταν τιμές προεραιτικά δηλαδή, κάποιες μεταβλητές να κρατούσαν την τιμή τους αν δεν δίναμε τιμή (πχ δίναμε συνεχόμενα κόμμα  κατά τη κλήση ή δίναμε το ? που σημαίνει αδιάφορο, πάντα κατά την κλήση), τώρα μια οποιαδήποτε Διάβασε αν έχει το = και έναν αριθμό ή σε αλφαριθμητικά ένα αλφαριθμητικό ως εναλλακτική τιμή τότε, αν οι μεταβλητές δεν υπάρχουν και βρεθεί στο σωρό τιμών αντί για μια τιμή ένας δείκτης που λέει "προαιρετικό" (optional), τότε θα πάρουν αυτές τις αρχικές τιμές.

Ο χαρακτήρας @ όταν ακολουθεί αριθμό σήμαίνει ότι ο αριθμός διαβάζεται ως Decimal (ή Αριθμός). Όταν ακολουθεί # σημαίνει ότι διαβάζεται ως Currency (Λογιστικό το λέμε στη Μ2000), Το σύμβολο ~ είναι  για τους απλούς, και το & για τους τύπου Μακρύς. Οι διπλοί δεν έχουν σύμβολο εδικό. Δείτε ότι ο ψ δεν δηλώθηκε ως τύπος με την Ως <Τύπος>, θα πάρει ότι του δώσουμε, και αν δεν του δώσουμε θα πάρει την δική του "επιλογή", και το τύπο της.


Κάνε ΝιΡίζα(χ ως αριθμός, ψ=2)=Σημ(χ)*Απολ(χ)^(1/ψ)
Ν%=ΝιΡίζα(2) ' χρήση Ν ως ακέραιος
Τύπωσε Ν%**2, Τύπος$(Ν%)
Ν%=ΝιΡίζα(ΝιΡίζα(512, 5), 2)^5^2
Τύπωσε Ν%, Τύπος$(Ν%) ' δίνει 512 και Double
\\ όλες οι μεταβλητές σε % είναι ακέραιες με οποιοδήποτε τύπο:
Μ%=1232133.12312322133321337@*10000000000000000000@
\\ δίνει τεράστιο νούμερο!
Τύπωσε Μ%, Τύπος$(Μ%) 'Decimal
Μ%+=99
Τύπωσε Μ%, Τύπος$(Μ%) 'Decimal


Συναρτήσεις μπορούμε να καλέσουμε και χωρίς να είναι σε έκφραση, και μπορούμε να μην έχουμε επιστροφή τιμής. Εδώ δίνουμε το Άδειασε στην αρχή για να καθαρίσουμε τον τρέχον σωρό τιμών ώστε με σιγουριά νε μην περάσουμε κάποια άλλη τιμή, η δεςμε κατά την κλήση, και να πάρει την προαιρετική (πάντα υπό τον έλεγχό μας, ως προγραμματιστές).

Άδειασε
Συνάρτηση δεςμε (κ ως Λογιστικό=2){
      Τύπωσε τύπος$(κ), κ
}
κάλεσε δεςμε(50&)
κάλεσε δεςμε()


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

Κάνε ΝιΡίζα(χ ως μακρύς, ψ ως μακρύς=2)=Σημ(χ)*Τιμή(Στρογγ(Απολ(χ)^(1/ψ),5)->μακρύς)
Ρ=ΝιΡίζα(2131233,8) ' χρήση της συνάρτησης να επιστρέφει Μακρύ  (LONG)
Τύπωσε Ρ**5, Τύπος$(Ρ)


Δείτε λοιπόν πως χρησιμοποιούμε το πέρασμα με αναφορά, με το χαρακτήρα &. Όλα τα αποτελέσματα είναι Decimal

Συνάρτηση ΑύξησεΜετά(&Ν) {
      =Ν
      Ν++
}
Κάνε Αριθμό Κ=2@, Λ, Μ
Τύπωσε Τύπος$(Κ), Τύπος$(Λ), Τύπος$(Μ)
Μ=ΑύξησεΜετά(&Κ)
Λ=ΑύξησεΜετά(&Κ)
Τύπωσε Τύπος$(Κ), Τύπος$(Λ), Τύπος$(Μ)
Τύπωσε Κ, Λ, Μ ' 4, 3, 2


Και τελευταίο για την ανάρτηση. Αλλάζουμε το τύπο της ΑύξησεΜετά(),  ώστε αν δοθεί αναφορά από αλλο τύπο να βγει λάθος,.

Συνάρτηση ΑύξησεΜετά(&Ν ως Λογιστικό) {
      =Ν
      Ν++
}
Κάνε Λογιστικό Κ=2#, Λ, Μ
Τύπωσε Τύπος$(Κ), Τύπος$(Λ), Τύπος$(Μ)
Μ=ΑύξησεΜετά(&Κ)
Λ=ΑύξησεΜετά(&Κ)
Τύπωσε Τύπος$(Κ), Τύπος$(Λ), Τύπος$(Μ)
Τύπωσε Κ, Λ, Μ ' 4, 3, 2

Ζ=10&
Δες οκ {
     Τύπωσε ΑύξησεΜετά(&Ζ)
}
Αν όχι οκ ή λάθος Τότε Τύπωσε Λάθος$
Τύπωσε Ζ ' δεν άλλαξε, γιατί βγήκε λάθος


ΓΚ



Τετάρτη 14 Μαρτίου 2018

Έκδοση 9.1

Επειδή έγιναν πολλές αλλαγές, για την υποστήριξη πολλών αριθμητικών τύπων, έγινε μια μικρή αλλαγή έκδοσης από την 9 στην 9.1
Έγιναν αλλαγές σε συναρτήσεις για να μπορούν να δουλέψουν κατάλληλα.
 
1) H συνάρτηση Τιμή() που έπαιρνε αλφαριθμητικό ή αλφαριθμητική και αριθμό ή αλφαριθμητικό και αλφαριθμητικό, τώρα παίρνει επιπλέον αριθμό βέλος και σήμανση για μετατροπή.

Α=Τιμή(Β->0@) είναι ισοδύναμο με αυτό Α=Τιμή(Β->Αριθμός) και μετρέπει την τιμή της παράστασης, εδώ μόνο το Β έχουμε, σε τύπο Decimal (λέγεται απλά Αριθμός στην Μ2000)
Συνολικά οι τύποι είναι:
Αριθμός (Decimal), Λογιστικό (Currency), Διπλός (Double), Απλός (Single), Μακρύς (Long), Λογικός (Boolean).

2) Μπορούμε να φτιάχνουμε μεταβλητές με την Κάνε (Def), που μέχρι την προηγούμενη αναθεώρηση, έφτιαχνε συναρτήσεις μιας γραμμής (και συνεχίζει να το κάνει αν θέλουμε).





Κάνε Αριθμό α, β, γ

Τα ονόματα είναι χωρίς τελικό σίγμα: Αριθμό (Decimal), Λογιστικό (Currency), Διπλό (Double), Απλό (Single), Μακρύς (Long), Λογικό (Boolean).
Σε κάθε εντολή δίνουμε έναν τύπο και ακολουθούν τα ονόματα. Οι μεταβλητές θα γίνουν τοπικές. Αν υπάρχει ήδη τοπική με το ίδιο όνομα θα βγει λάθος.

Όταν δίνουμε τιμές σε μεταβλητές όπου δώσαμε τύπο με την Κάνε, τότε αυτές θα μετατραπούν αυτόματα για να μπουν στον τύπο των μεταβλητών (ή θα βγει λάθος αν δεν χωράει η τιμή που δίνουμε).
Μπορούμε με τα @, #, & και ~ να φτιάχνουμε αριθμούς που να μην είναιΔιπλός  (Double), τον εξορισμού τυπο. Με @ για Αριθμός (29 ψηφία), με # για τον Λογιστικό (5 δεκαδικά), & για Μακρύ,  ~ για τον Απλό.

(συνεχίζεται)

Κυριακή 11 Μαρτίου 2018

Αναθεώρηση 55 (Έκδοση 9.0)

Συνέχισα την προσπάθεια να εντάξω τους Decimal και Currency (και εντέλει τους Long και Boolean). Οι σταθερές True και False τώρα είναι boolean τύποι, οπότε μια A=True θα κάνει το Α boolean (Από τις νεότερες εκδόσεις τα True και False δεν είναι boolean τύπος, για να υπάρχει συμβατότητα με τα παλιότερα προγράμματα, οι συγκρίσεις όμως γυρίζουν boolean, και υπάρχει τρόπος να δημιουργήσουμε απευθείας λογική μεταβλητή). Μόνο στην 9.1 εμφανίστηκαν ως boolean.   H M2000 συνεχίζει να έχει σταθερούς τύπους σε μεταβλητές που δηλώνουμε Long (Μακρύς) είτε με την δήλωση είτε με το να δώσουμε τιμη τέτοιου τύπου, πχ Β=100&  το & κάνει τον αριθμό να περιέχεται σε μακρύ, οπότε με την πρώτη δήλωση τιμής το Β θα γίνει μακρύς. Σε αυτές τις μεταβλητές αν δώσουμε τιμή μεγαλύτερη από αυτή που χωράει, τότε θα βγει λάθος υπερχείλισης.
H δήλωση Long δεν χρησιμοποιείται για πίνακες. Όμως εκεί μπορούμε με μια εντολή γεμίσματος να γεμίσουμε έναν πίνακα με τέτοιου τύπου τιμές (οι μεταβλητές και τα στοιχεία ενός πίνακα στην Μ2000 είναι τύπου Variant, οπότε επιδέχονται αλλαγές, πλην όμως οι τύπου Μακρύς δεν επιδέχονται!
Ακέραιοι (όνομα με % στο τέλος) στην γλώσσα μπορεί να είναι διαφόρων τύπων. Αυτοί έχουν την ιδιότητα να  στρογγυλοποιούν αυτόματα στην εκχώρηση. Εσωτερικά μπορεί είναι ή τύπου διπλού, ή Decimal (29 ψηφία) ή Currency (19 ψηφία, από τα οποία τα 14 για ακέραιο). Αυτές οι μεταβλητές δεν παίρνουν Μακρύ (οι οποίοι γράφονται σε μεταβλητές με κανονικά ονόματα).

Οι αριθμοί στον κώδικα όταν έχουν δεκαδικά γράφονται πάντα με τελεία. Η εμφάνιση στην οθόνη με την τύπωσε και με την εισαγωγή αλλάζει ανάλογα με το τι έχει επιλεχθεί στο λειτουργικό.

Για αριθμούς Decimal βάζουμε στο τέλος το @  πχ το Α=32232112312312.12312312@ θα πάρει Decimal. Για Currency βάζουμε στο τέλος το #, πχ το Α=23333121233.21231# θα πάρει Currency. Για Long (εκτός από την δήλωση, πχ Long A=10 θα κάνει ότι παίρνει ο Α να γίνεται Long αυτόματα, ή να βγαίνει υπερχείλιση ως λάθος), θα χρησιμοποιήσουμε το &, πχ το Α=100& σημαίνει ότι θα πάρει το 100 ως Long  ή Μακρύς.
Μεταβλητές με διπλό (double), Decimal, Currency μπορούν να αλλάζουν τύπο (αν πάρουν Long, δεν αλλάζουν ξανά). Όταν καλούμε μια συνάρτηση, και ζητάμε αριθμό σε μεταβλητή, τότε αυτή θα πάρει ότι της δώσουμε. Το μέρος της γλώσσας που επεξεργάζεται τις εκφράσεις θα λειτουργήσει κανονικά, και ενδέχεται να κάνει μετατροπές.
Στο πρόγραμμα παρακάτω δημιουργούμε μια συνάρτηση μιας γραμμής (αντί για Συνάρτηση όνομα { }, βάζουμε με την Def  ή την Κάνε (η αντίστοιχη ελληνική). Η έκφραση που θα δίνουμε στην Typename$() θα πηγαίνει στην Ν και από αυτή θα παίρνουμε τον τύπο της, άρα τον τύπο της έκφρασης. Επειδή κάθε φορά που καλούμε την συνάρτηση φτιάχνεται η Ν ξανά, δεν μας πειράζει αν γίνει Long, στην επόμενη κλήση θα είναι κάτι άλλο!
Αριθμοί σε @ είναι Decimal
σε # είναι Currency
σε & είναι Long
χωρίς κάτι είναι Double

Στο πρόγραμμα λοιπόν κάνουμε έλεγχο το τι θα βγεί βάσει των πράξεων.Οι decimal έχουν την μέγιστη προτεραιότητα επιλογής.


Form 100, 66 ' Display 100X66
Def Typename$(N)=Type$(N) ' Type$ return only Variable's and Array's Item type

Print Typename$(-(131231@*1221212)) ' decimal
Print Typename$(-(131231@/1221212)) 'decimal
Print Typename$(-(131231@*1221212@)) ' decimal
Print Typename$(-(131231@/1221212@)) 'decimal
Print Typename$(-(131231@*1221212#)) ' decimal
Print Typename$(-(131231@/1221212#)) 'decimal
Print Typename$(-(131231@*1221212&)) ' decimal
Print Typename$(-(131231@/1221212&)) 'decimal

Print Typename$(-(131231#*1221212)) ' double
Print Typename$(-(131231#/1221212)) 'double
Print Typename$(-(131231#*1221212@)) ' decimal
Print Typename$(-(131231#/1221212@)) 'decimal
Print Typename$(-(131231#*1221212#)) ' Currency
Print Typename$(-(131231#/1221212#)) 'double
Print Typename$(-(131231#*1221212&)) ' Currency
Print Typename$(-(131231#/1221212&)) 'double

Print Typename$(-(131231*1221212)) ' double
Print Typename$(-(131231/1221212)) 'double
Print Typename$(-(131231*1221212@)) ' decimal
Print Typename$(-(131231/1221212@)) 'decimal
Print Typename$(-(131231*1221212#)) ' double
Print Typename$(-(131231/1221212#)) 'double
Print Typename$(-(131231*1221212&)) ' double
Print Typename$(-(131231/1221212&)) 'double

Print Typename$(-(131231&*1221212)) ' double
Print Typename$(-(131231&/1221212)) 'double
Print Typename$(-(131231&*1221212@)) ' decimal
Print Typename$(-(131231&/1221212@)) 'decimal
Print Typename$(-(131231&*1221212#)) ' double
Print Typename$(-(131231&/1221212#)) 'double
Print Typename$(-(131231&*1221212&)) ' double
Print Typename$(-(131231&/1221212&)) 'double

Print Typename$(-(131231@+1221212)) ' decimal
Print Typename$(-(131231@-1221212)) 'decimal
Print Typename$(-(131231@+1221212@)) ' decimal
Print Typename$(-(131231@-1221212@)) 'decimal
Print Typename$(-(131231@+1221212#)) ' decimal
Print Typename$(-(131231@-1221212#)) 'decimal
Print Typename$(-(131231@+1221212&)) ' decimal
Print Typename$(-(131231@-1221212&)) 'decimal

Print Typename$(-(131231#+1221212)) ' Currency
Print Typename$(-(131231#-1221212)) ' Currency
Print Typename$(-(131231#+1221212@)) ' decimal
Print Typename$(-(131231#-1221212@)) 'decimal
Print Typename$(-(131231#+1221212#)) ' Currency
Print Typename$(-(131231#-1221212#)) 'Currency
Print Typename$(-(131231#+1221212&)) ' Currency
Print Typename$(-(131231#-1221212&)) 'Currency

Print Typename$(-(131231+1221212)) ' double
Print Typename$(-(131231-1221212)) 'double
Print Typename$(-(131231+1221212@)) ' decimal
Print Typename$(-(131231-1221212@)) 'decimal
Print Typename$(-(131231+1221212#)) ' Currency
Print Typename$(-(131231-1221212#)) ' Currency
Print Typename$(-(131231+1221212&)) ' double
Print Typename$(-(131231-1221212&)) 'double

Print Typename$(-(131231&+1221212)) ' double
Print Typename$(-(131231&-1221212)) 'double
Print Typename$(-(131231&+1221212@)) ' decimal
Print Typename$(-(131231&-1221212@)) 'decimal
Print Typename$(-(131231&+1221212#)) ' Currency
Print Typename$(-(131231&-1221212#)) 'Currency
Print Typename$(-(131231&+1221212&)) ' Long
Print Typename$(-(131231&-1221212&)) 'Long


Στο επόμενο πρόγραμμα θα στείλουμε μερικά νούμερα σε αρχείο csv, αλλά εδώ θα το λέμε τύπου dat. (data). Έχουν μπει δυο νέα πράγματα: μπορούμε στην εισαγωγή από αρχείο να δείξουμε τι τύπο ζητάμε. Εδώ λέμε το Μ1 να είναι Decimal, και το Ζ1 να είναι Currency. Όταν δε φτιάξαμε το αρχείο, η Γράψε αυτόματα μετέφερε βάσει του τύπου. Το δεύτερο είναι η Εισαγωγή με κατά το Γράψε με, που διαμορφώνει το πώς θα διαβάσουμε από το αρχείο. Εδώ έχω βάλει το TAB (χαρ$(9)) ως αλλαγή πεδίου και το κόμμα ως σημείο υποδιαστολής. Επίσης έχει επιλεχθεί τα αλφαριθμητικά να αποκωδικοποιούνται κατά json αλφαριθμητικά. Το αρχείο θα γραφτεί και θα διαβαστεί ανεξάρτητα από το τη υποδιαστολή χρημοποιεί το σύστημα. Το ότι υπάρχουν δυο εντολές η μια για διαμόρφωση διαβάσματος και η άλλη για γράψιμο, γίνεται να προγραμματίσουμε διαφορετικά στοιχεία, ώστε να κάνουμε αντιγραφές από το ένα αρχείο σε ένα άλλο.

Επειδή το αρχείο ανοίγει και με το Notepad, μπορούμε να το δούμε και εδώ:
"Row 1"    -213231313132312,23123    -52322323,32    -12121000000
"Line1\r\nLine2\r\nLine3\r\n"

Χωρίς το ευρεία (με κίτρινο) κάνουμε εξαγωγή σε Ansi, και ομοίως εισαγωγή σε Ansi (8bit κωδικοσελίδα)

Γράψε με χαρ$(9), ",", αληθές 'αληθές σημαίνει ότι τα αλφαριθμητικά θα κωδικοποιούνται κατά json
Άνοιξε "my.dat" για ευρεία εξαγωγή ως #κ
Γράψε #κ, "Row 1", -213231313132312.23123@, -52322323.32#, -1.2121e+10
Γράψε #κ, {Line1
                        Line2
                        Line3
                        }
Κλείσε #κ
\\ κατά json σημαίνει ότι ειδικοί χαρακτήρες κωδικοποιούνται ώστε να γράφεται
\\ το αλφαριθμητικό με πολλές γραμμές χωρίς να έχει μέσα του αλλαγές γραμμών
\\ και άλλοι χαρακτήρες κωδικοποιούνται αλλά εμάς μας ενδιαφέρει ότι βάζουμε
\\ ένα κείμενο σε μια γραμμή!
Εισαγωγή με χαρ$(9), ",", αληθές 'αληθές σημαίνει ότι τα αλφαριθμητικά θα διαβάζονται κατά json
Άνοιξε "my.dat" για ευρεία Εισαγωγή ως #κ
Εισαγωγή #κ, R$, M1=0@, Z1=0#, check
Εισαγωγή #κ, Txt$
Κλείσε #κ
Τύπωσε R$, M1, Z1, check
Τύπωσε Τύπος$(M1), Τύπος$(Z1)
Τύπωσε M1
Τύπωσε Z1
Αναφορά txt$ ' η αναφορά τυπώνει κείμενα
\\ αν το κείμενο έχει πολλές γραμμές σταματάει...
\\ για να μας δείξει μέρος και συνεχίζει με διάστημα, ή με πλήκτρο ποντικιού.


Write with chr$(9), ",", true ' true means that strings replaced as json strings
Open "my.dat" for output as #k
Write #k, "Row 1", -213231313132312.23123@, -52322323.32#, -1.2121e+10
Write #k, {Line1
                        Line2
                        Line3
                        }
Close #k
Open "my.dat" for input as #k
Line Input #k,All$
Close #k
Print All$
Input With chr$(9), ",", true ' true means that strings readed as json strings
Open "my.dat" for input as #k
Input #k, R$, M1=0@, Z1=0#, check
Input #k, Txt$
Close #k
Print R$, M1, Z1, check
Print Type$(M1), Type$(Z1)
Print M1
Print Z1
Report txt$



The Unicode Version
Write with chr$(9), ",", true ' true means that strings replaced as json strings
Open "my.dat" for wide output as #k
Write #k, "Row 1", -213231313132312.23123@, -52322323.32#, -1.2121e+10
Write #k, {Line1
                        Line2
                        Line3
                        }
Close #k
Open "my.dat" for wide input as #k
Line Input #k,All$
Close #k
Print All$
Input With chr$(9), ",", true ' true means that strings readed as json strings
Open "my.dat" for wide input as #k
Input #k, R$, M1=0@, Z1=0#, check
Input #k, Txt$
Close #k
Print R$, M1, Z1, check
Print Type$(M1), Type$(Z1)
Print M1
Print Z1
Report txt$


Πώς θα κάνουμε όμως μετατροπές από τον ένα τύπο στον άλλο;
Η συνάρτηση Τιμή() ή Val() μέχρι την προηγούμενη αναθεώρηση έπαιρνε αλφαριθμητικό. Τώρα παίρνει και αυτό αλλά και αριθμητική παράσταση. Αν δεν δώσουμε τίποτα άλλο τότε θα πάρουμε τον διπλό,  αλλιώς με το βελάκι θα δείξουμε το 0@ ή το 0#  ή το 0&.

Κάνε ΤύποςΠαράστασης$(Ν)=Τύπος$(Ν)
Τύπωσε ΤύποςΠαράστασης$(10) ' Double
Τύπωσε ΤύποςΠαράστασης$(Τιμή(10->0@)) ' Decimal
Τύπωσε ΤύποςΠαράστασης$(Τιμή(10->0#)) ' Currency
Τύπωσε ΤύποςΠαράστασης$(Τιμή(10->0&)) ' Long
Τύπωσε ΤύποςΠαράστασης$(Τιμή(10@)) ' Double
Τύπωσε ΤύποςΠαράστασης$(Τιμή(10#)) ' Double
Τύπωσε ΤύποςΠαράστασης$(Τιμή(10&)) ' Double
Τύπωσε ΤύποςΠαράστασης$(Τιμή(10#->0@)) ' Decimal
Τύπωσε ΤύποςΠαράστασης$(Τιμή(10&->0@)) ' Decimal
Τύπωσε ΤύποςΠαράστασης$(Τιμή(10@->0#)) ' Currency
Τύπωσε ΤύποςΠαράστασης$(Τιμή(10&->0#)) ' Currency
Τύπωσε ΤύποςΠαράστασης$(Τιμή(10@->0&)) ' Long
Τύπωσε ΤύποςΠαράστασης$(Τιμή(10#->0&)) ' Long


ή στα αγγλικά:

Def TypeOfExpression$(Ν)=Type$(Ν)
Print TypeOfExpression$(10) ' Double
Print TypeOfExpression$(Val(10->0@)) ' Decimal
Print TypeOfExpression$(Val(10->0#)) ' Currency
Print TypeOfExpression$(Val(10->0&)) ' Long
Print TypeOfExpression$(Val(10@)) ' Double
Print TypeOfExpression$(Val(10#)) ' Double
Print TypeOfExpression$(Val(10&)) ' Double
Print TypeOfExpression$(Val(10#->0@)) ' Decimal
Print TypeOfExpression$(Val(10&->0@)) ' Decimal
Print TypeOfExpression$(Val(10@->0#)) ' Currency
Print TypeOfExpression$(Val(10&->0#)) ' Currency
Print TypeOfExpression$(Val(10@->0&)) ' Long
Print TypeOfExpression$(Val(10#->0&)) ' Long


Όλοι οι τύποι χρησιμοποιούνται παντού!