Παρασκευή 27 Απριλίου 2018

Example for 9.3 version (rev 5), with group pointers and lambda function

I minor revision change to 5,  with Wine support, and a small bug in Module.Name$ when used with non secure interpreter option.

In this example we will see how M2000 Interpreter can use recursion in lambda function, as a member of group. There are two examples. At the first example we see a static group, with a name Alfa, which is not movables, and dies when going out of scope (at the end of module's code). For these examples we have an assumption that the code are in a module named A
And let say that we have this to try out with "secure names" (+sec) or "non secure names" (-sec). Using set switches from module we turn switch for the running session of interpreter. But if we use it (without set) in M2000 console, this will be the setting for all new instances of interpreter. Not all of switches have global rights. Switches can be placed in command line, for temporary use, when open a gsb file, e.g "c:\.....\testme.gsb" -sec
Also in the compact snippet bellow we can learn about the two calling procedures for modules (also we can Call a function, but this we will see another time). Faster call is the first one. We can place this code in a Module A (no worry about the same name).

set switches "+sec"   ' try with -sec
Module A {
Print Module$ ' this is a Global Name assigned from Interpreter
Print Module.Name$ ' this is the "nice name"
\\ we can't call, normal way,  A from here
\\ we can get recursion using Call A
\\ place here any example

}
A  ' this is a normal call for modules

Module B {
Print Module$ ' this is a Global Name assigned from Interpreter
Print Module.Name$ ' this is the "nice name", only for display
\\ place here any example

}
Call B
' using Call is slight different, inside, from a normal call
' A call to a module place the interpreter to give recursion acces






First Example


Group alfa {
      N=5
      b=lambda ->0
}
\\ we can manke a lambda with access to group N
\\ as is we can't use it
b=lambda Z=100 -> {
      if .N<2 then =Z : exit
      .N--
      =(.N+1)*lambda()
}
\\ but we can copy it ro alfa.b which is a lambda also
alfa.b=b
\\ now alfa.b( ) run using .N of alfa
M=alfa.b()
Print alfa.N, M
\\ And now the 9.3 version part
\\ we make a pointer to a copy of alfa
k->(alfa)
Print Alfa.N=5 ' false
\\ we set  the N member
k=>N=5
\\ and we call it
Print k=>b()
\\ Now we set
\\ pointer to alfa
k->alfa
k=>N=5
Print Alfa.N=5 ' true
Print k=>b()
k->0
Print Type$(k)="Group" ' True is a group but an empty one
Print valid(k=>N)=false ' Return true





Second Example



Group alfa {
      N=5
      b=lambda ->0

}
Dim A(10)=alfa
b=lambda Z=100 -> {
      if .N<2 then =Z : exit
      .N--
      =(.N+1)*lambda()
}
A(3).b=b
M=A(3).b()
Print A(3).N, M
\\ And now the 9.3 version part
\\ we make a pointer to a copy of A(3)
k->(A(3))
Print A(3).N=5 ' false
\\ we set  the N member
k=>N=5
\\ and we call it
Print k=>b()
\\ Now we set
\\ pointer to alfa
k->A(3)
k=>N=5
Print A(3).N=5 ' true
Print k=>b()
k->0
Print Type$(k)="Group" ' True is a group but an empty one
Print valid(k=>N)=false ' Return true




Αναθεώρηση 4 (Έκδοση 9.3)

Το αρχείο εγκατάστασης ενημερώθηκε στην αναθεώρηση 4.

Λάθη:
1. Επαναφορά του Εγγράφου στις ομάδες. Είχε από λάθος βγει εκτός, από την 9.3 αναθεώρηση. 0, διορθώθηκε
2. Εύρεση ενός δύσκολου λάθους, που εμφανίζονταν σε ορισμένες περιπτώσεις σε ομάδες όπου κατά την αντιγραφή έχαναν σε συναρτήσεις τον κώδικά τους! Για να συμβεί αυτό έπρεπε να γίνει ένας συνδυασμός "προγραμματισμού". Τώρα άλλαξε εσωτερικά το σύστημα πιο γενικά:

Global group m {
      function k {
            =1000
      }
}
class alfa1 {
      m=100
      function k {
            =500
      }
      N=10
      module alfa1 {
            \\ in this line was the problem
            \\ code to prevent alter global group m
             m=this ' copy this group to m
            m=m
            m.N=500
            this=m ' copy m to this group
            Modules ?
      }
}
alfa=alfa1()
Print m.k()
Print alfa.N, alfa.k()
Report &alfa.k()
alfa=alfa
Modules ?
Report &alfa.k()
Print alfa.N, alfa.k()
\\ also
Print m.k()

3 Διορθώθηκαν όλα τα ελληνικά μηνύματα (σε Word).
4. Το F12 στην βοήθεια δείχνει σωστότερα τα τμήματα/τις συναρτήσεις και με κλικ ανοίγει το κώδικά τους.
5.Νέος Διακόπτης "ext"  ( +ext, -ext με το δεύτερο  ως η εξ ορισμού επιλογή). Η επιλογή +ext  επεκτείνει την εμβέλεια (scope) των μεταβλητών τμημάτων (προς το παρόν όχι των πινάκων), ώστε να είναι θεατά με πρόθεμα το όνομα του τμήματος σε τμήματα που δημιουργούνται εντός των τμημάτων και εκτελούνται εκεί. Ο διακόπτης +ext χριάζεται και τον +sec (που είναι εξ ορισμού έτσι), γιατί μόνο στο secure interpreter μπορεί να έχει αποτέλεσμα.
Οι διακόπτες  φαίνονται με την εντολή Monitor ή Έλεγχος στη γραμμή εντολών (ή από κώδικα με την Set ή Θέσε  πχ Set Monitor. Μην το μπερδεύεται με την δεύτερη ή τρίτη οθόνη προβολής. Για να εμφανίσουμε τη φόρμα (κονσόλα) της Μ2000 σε άλλη οθόνη (pc monitor) δίνουμε την εντολή Παράθυρο (Window) με τον αριθμό μεγέθους χαρακτήρων και το νούμερο της οθόνης: Πχ Παράθυρο 16, 1 θα κάνει τα γράμματα 16pt και θα ανοίξει την κονσόλα (ή θα την μεταφέρει, καθαρίζοντάς την) στο δεύτερο μόνιτορ (αν υπάρχει). Όλες οι φόρμες και η κονσόλα υποσηρίζουν πολλαπλά μόνιτορ. Πχ μια φόρμα που κάνει αλλαγή μεγέθους μπορεί να επεκταθεί με το πάτημα ενός κουμπιού στο μέγεθος της οθόνης (μόνιτορ) όπου δώσαμε την "εντολή".

Στο παρακάτω παράδειγμα οι alfa.kappa και alfa.beta και η Alfa.N είναι θεατά από το τμήμα beta (όταν εκτελείται).  Τον πίνακα Α(10) τον περάσαμε με δείκτη (τον Ν).
Δεν χρειάζεται στην ουσία αυτός το τρόπος, γιατί μπορούμε να περνάμε με αναφορά:

set switches "+sec +ext"   ' need secure interprer (default) and extended scope ( -ext is the default)
Module alfa {
      kappa=10
      beta$="ok"
      \\ we can't pass arrays with that way
      Dim A(10)=5
      \\ we have to use a pointer
      N=A()
      Module beta {
            Print alfa.kappa, alfa.beta$
            alfa.kappa++
            Dim K()
            K()=Alfa.N
            Print K(4)
      }
      beta    ' 10
      beta    ' 11
      Print kappa '12
      Module zeta {
            ' we use <= same for globals
            alfa.kappa<=500
            ' using = we make a local variable
      }
      zeta
      Print kappa
}
alfa

Second Example (same output)

set switches "-ext -sec"   ' reset  ext enter to non secure
\\ using by reference
Module alfa {
      kappa=10
      beta$="ok"
      Dim A(10)=5
      Module beta (&kappaRef, &betaRef$, &Aref()) {
            Print alfa.kappa, alfa.beta$
            kappaRef++
            Print Aref(4)
      }
      beta &kappa, &Beta$, &A()
      beta &kappa, &Beta$, &A()
      Print kappa '12
      Module zeta (&kappa) {
            kappa=500
      }
      zeta &kappa
      Print kappa
}
alfa



6. Βελτιώσεις στις φόρμες χρήστη.
6.1 Η λίστα επιλογών πάνω στην επικεφαλίδα, για αλλαγή μεγέθους, μετακίνηση παραθύρου και άλλα βασικά, ανοίγει με κλικ σε ένα εικονίδιο με τρεις οριζόντιες γραμμές. Όταν είναι επιλεγμένη η επικεφαλίδα της φόρμας, τότε αυτό είναι σε άσπρο χρώμα. Αν πατήσουμε το κάτω βελάκι θα ανοίξει  η λίστα. Αν πατήσουμε στην ανοικτή λίστα τα αριστερά - δεξιά βελάκια, τότε κλείνει η λίστα και επιλέγεται από την φόρμα το τελευταίο στοιχείο που είχε επιλεχθεί.


6.2Στο στοιχείο Κείμενο (EditBox) η εισαγωγή νέου κειμένου (από αρχείο) επαναφέρει τον δρομέα στην θέση 1,1.


7. Πώς ορίζουμε μεταβλητές (με αγγλικές εντολές)

\\ Definition of variables
\\ Locals/Gobals with shadow function
\\ In this example we see how to define variables
\\ by using an assignment of a numeric literal of specific type
\\ And what happen if we assign another type
\\ We set a switch to get True/False for booleans at Print
\\ we use Set to send line to Command Line Interpreter (CLI)
\\ SBL means Show BooLeans
Set switches "+SBL"
Module AnyName {
      A=100&
      Print Type$(A) 'Long
      A=2+3 ' 2 and 3 are doubles
      Print Type$(A) ' Long
      A=2%+3% ' 2% and 3% are integers 16 bit
      Print Type$(A) ' Long
      For This {
            \\ This is a block for temporary variables
            \\ Local has the ability to make new variable
            \\ without erasing the old one, with same name
            \\ it is not good to use it in loop, because we will fill the memory
            Local A=100@
            Print Type$(A) ' Decimal
            Set Push Valid(A)
            Read ok as boolean
            Print ok, type$(ok) ' false - there is no global with A name
            \\ Old A shadowed
            \\ Global variable can't changed, if a same local exist before
            Global A=100
            Print Type$(A) ' Decimal
            Set Push Valid(A)
            Read ok
            Print ok, "Global A exist" ' true
            Global A as Double=100
            Print Type$(A) ' Decimal
            \\ now we have 1 local more, and 2 global more
      }
      \\ now all temporary variables erased
      \\ so we get the old value
      Print Type$(A) ' Long
      \\ Now we define a global one
      Global B as Currency=100
      Print Type$(B), B
      \\ To change a global we use <=, because = make a local one which hide global
      B<=10000@
      Print Type$(B), B
      \\ Using Set statement

   \\ We send line to CLI, so anything has to be global (we can't place a local variable)
      \\ Also if Global C exist, no new global declared, we overwrite in it
      Set C=100@
      Print Type$(C) ' Decimal
      Set C=200%
      Print Type$(C) ' Integer
      Set C=200&
      Print Type$(C) ' Long  
      Set C=100@
      Print Type$(C) ' Long can't be changed if chosen once.
      \\ To place Local A to C
      C<=A*2
      Print C
      Let C=A*2
      Print C
      \\ we can observe the variables using List
      List
      \\ We can usine Set. We can send weak referencre to stack
      Push Weak$(A)
      \\ and read it as Letter$, and resolve with Eval()
      Set C=Eval(Letter$)*2
      Print C
      \\ Or better
      Push A : Set Read C
      \\ Or make a link from a local to global one
      \\ we have to use New, because no 2nd reference allowed
      Print A
      Push &A : Set Read &C1
      A++ : Print C1
      C1<=10
      Print A=10 ' true
}
\\ we call AnyName
AnyName
Print "Done"
List
\\ we get an empty list, no variables exist from AnyName


Υπάρχει και δεύτερο παράδειγμα:

\\ Example 2
\\ define variables once
\\ we can't call def for same variable in same scope
Form 80, 40 ' we need some lines more
Flush
def a as boolean
def integer c, d
def currency c1, d1
Print type$(c), type$(d), type$(c1), type$(d1)
Print a
Push 100
read k as boolean
Print K
\\ we can use Module Z(k as boolean)
\\ but is better for Modules to have a space between Z and left parenthesis
\\ for seaching through F2/F3 (and shift F2/F3) from internal code editor
Module Z (k as boolean) {
      Print k
}
Z 100 ' show true
Module Z {
      Read k as boolean
      Print "Second Definition, replace old one"
}
Z 200
Module Z {
      Read k ' no type ' can't be string
      Print Type$(K), K

}
Z 100@ ' decimal
Z 100# ' Currency
Z 100& ' Long
Z 100~ ' Single  ' no need decimal part
Z 100 ' double  ' no need decimal part
Z 100% ' Integer
Z 0xFFFFFFFF ' double - used as unsigned
Z 0xFFFFFFFF& ' Long  - signed
Z 0xFFFF%'  Integer - signed
Z ! 100 ' ! convert to long
Z %K=123456789123456@ ' decimal, passing by name
\\ passing by name can't be used with a Call to a module
Call Z, 123456789.12# ' currency
\\ Calling a module in any of two types of calls, send current stack of values
\\ It is duty of calling module to leave stack as expected
Push 12344&
Call Z ' long
Push 1234%
Z  ' integer
\\ some magic here
Module Z (x as integer=100) {
      If Valid(K) Then {Print "K exist as ";Type$(K), K} Else Def K=10%
 
      Print Type$(x), x
      If Module(M) Then Print "I Found M" : Call M, K
}
Z %K=100@, %X=500@ ' show K as Decimal and X as Integer
\\ this is a risk call, if we have something in stack
Z  ' show X as Integer with value 100
\\ this is no risk call, we place ? as "get your optional value"
Z ?
Push 500
Z %K=100& ' using a pass by name insert a ?
Print Number=500 'true
Z 200, %K=200~
Module B (k){
           Print Type$(k), k, "(I am B)"
}
\\ Using this type of call we can place a module before call
\\ this "simple" call (without Call), can't be used for recursive call in modules
Z 200, %K=100; M as B
Z ? ; M as B
Module EatNumbers {
      While IsNum {
            Print Number,
      }
      Print
}
\\ there is no actual number for parameter passing
\\ If we read, using Read or Number, or Letter$ from Stack and there is no value we get an error
EatNumbers 1,2,3,4,5
\\ define again same module
Module EatNumbers {
      If Empty Then Exit
      Read x
      Call EatNumbers
      Print x,
}
\\ Reverse order using recursion
EatNumbers 1,2,3,4,5
\\ we have to exclude Print to be used at the end
Print
\\ we can redefine module to include Print, using an inner module
Function Z {
             Module Inside {
                  If Empty Then Exit
                  Read x=100
                  Call Inside
                  Print x,
            }
            Inside
            Print
}
M=Z(1,2,3,4,5)


Τέλος θα βάλω και ένα παράδειγμα με δείκτες Ομάδων (νέα δυνατότητα στην έκδοση 9.3):
 Βάζουμε ένα αντίγραφο της ομάδας alfa στη Κατάσταση beta, στο κλειδί "10".   Φτιάχνουμε έναν δείκτη a με το βελάκι (δυο χαρακτήρες ->) . Με τη χρήση του For (Για) ανοίγουμε την ομάδα και εμφανίζουμε το .χ που είναι 10. Πριν κλείσει το beta("10") πειράζουμε την χ από το δείκτη a, το οποίο γίνεται 11. Βγαίνουμε εκτός της For (τώρα το beta("10") κλείνει (από στατικό πρόσκαιρα γίνεται "κινητό", πάει όπου πάει και ο πίνακας). Αυξάνουμε την α=>χ κατά 100 και βλέπουμε ότι έχει την ίδια τιμή με την beta("10").x. Αυξάνουμε το α=>χ κατά 1 και το beta("10").x  ακολουθεί. Μετά κάνουμε την αύξηση από το beta("!0").x και φαίνεται αμέσως στο α=>χ.



 Group alfa {
      x=10
}
inventory beta="10":=alfa
Group n=beta("10")
Print n.x=10
Print beta("10").x=10
a->Beta("10")
for beta("10") {
      Print .x=10
       a=>x++
      Print a=>x=11
}
a=>x+=100
Print a=>x=beta("10").x ' true
a=>x++
Print beta("10").x=112
beta("10").x++
Print beta("10").x=113
Print a=>x=113


Και πιο ωραίο ακόμα. Εδώ στην συνάρτηση alfa αντί για = έχουμε το -> για να επιστρέψουμε δείκτη. Αν βάζαμε το ->κ θα επιστρέφαμε δείκτη σε στατικό αντικείμενο, πράγμα που θα έβγαζε λάθος στη πρώτη χρήση, γιατί το k θα διαγραφεί στον τερματισμό της alfa(). Η επιστροφή τιμής δεν προκαλεί τερματισμό στην Μ2000. Με την παρένθεση παίρνουμε αντίγραφο του αντικειμένου, και με το βελάκι παίρνουμε δείκτη σε αυτό το αντίγραφο, το οποίο θα παραδωθεί από την alfa(). Έτσι η m θα γίνει δείκτης σε ομάδα!
Η συνάρτηση Ομάδα() ή Group() επιστρέφει πάντα ομάδα. Έτσι η Group(m) θα δώσει αντίγραφο της ομάδας που δείχνει η m. Χωρίς την χρήση της συνάρτησης, με μια stat=m θα παίρναμε έναν δείκτη ακόμα. Η m->Stat βγάζει δείκτη αλλά για στατικό αντικείμενο. Όταν "πεθάνει" η Stat η m θα είναι άχρηστη γιατί δεν κρατάει πραγματική αναφορά σε αντικείμενο, αλλά ισχνή αναφορά στο "απόλυτο όνομα" του στατικού αντικειμένου. Όπως έχουμε δυο είδη ομάδων έτσι έχουμε και δυο είδη δεικτών στις ομάδες, απλά δεν φαίνεται άμεσα η διαφορά τους, αφού ένας δείκτης του ενός είδους γίνεται να δείξει αργότερα με το άλλο είδος.
Μετά δείχνουμε πώς μηδνίζουμε το δείκτη ώστε να μην έχει αναφορά σε ομάδα. Και μετά φιτάχνουμε ένα δείκτη στην ομάδα, ο οποίος είναι σε στοιχείο πίνακα.

function alfa {
      group k {
            x=10
            module alfa {
                  Print .x
                  Print this.x
            }
      }
      ->(k) ' use of () to produce a copy of k
}
m=alfa()
Print m=>x
m=>alfa
For m {
      Print .x
      Call .alfa
}
List  ' only m pointer in List
Stat=Group(m)
List  ' Now exist Stat (Group), Stat.X
Modules ? ' Exist Stat.Alfa
m->Stat ' Pointer can change where points to
m=>x=500
Print Stat.x=500 ' True
\\ we can add two more variables
Group Stat {
      y=10200@, z as integer=200
}
\\ So now pointer know about this;
Print Stat.z = m=>z ' true
\\ we can place null to drop the reference
m->0
Print Valid(m=>z)=false ' true, is not valid
Dim A(39)
A(3)->Stat
Print A(3)=>z=200 ' We can place pointers in arrays
Def ExpType$(x)=Type$(x)
Print ExpType$(A(3)=>z)="Integer"  ' true
For A(3) {
      Print ExpType$(.y)="Decimal"  ' true
}
 


Αυτά για την ώρα..θα ετοιμάσω και άλλα παραδείγματα με δείκτες!

Τετάρτη 25 Απριλίου 2018

Αναθεώρηση 3, Έκδοση 9.3

Σε αυτήν την αναθεώρηση τέλειωσε η επέκταση για τους δείκτες.
Το -> σημαίνει εχκώρηση δείκτη από ομάδα
Το = κάνει εκχώρηση από άλλο δείκτη , την ομάδα που δείχνει ο τελευταίος(το κάνει και το ->)
Το => χρησιμοποιείται για τα μέλη. Σε πίνακες/καταστάσεις  μπορούν να χρησιμοποιηθούν και οι τελείες.
Η Ομάδα() ή Group() εξάγει την ομάδα ως ατίγραφο από το δείκτη.
Οι δείκτες μπορούν να δείχνουν "πτητικές" ομάδες (ανώνυμες) ή να δείχνουν με ισχή αναφορά εσωτερικά επώνυμη ομάδα. Οι επώνυμες ομάδες θα βγουν εκτός σκοπού, με το πέρας εκτέλεσης του τμήματος που τις δημιούργησε. Έτσι η χρήση δεικτών σε αυτές περιορίζεται μόνο σε κλήσεις μέσα από το τμήμα δημιουργίας τους. Οι ανώνυμες δεν έχουν περιορισμό χώρου.

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

Στο παράδειγμα η "πατάτα" έχει μόνο ένα μέλος το κ. Θα μπορούσε όμως να είχε πολλά!



\\ two kinds of pointers
\\ this is a named group, non movable,  and deleted at the exit of scope.
group potato {
      k=10
}
\\ m pointer point to named group
m->potato
Print m=>k
m=>k++
Print potato.k = m=>k ' true
m1=m ' this is a copy of pointer, so m1 points to potato too
m1=>k+=100
Print m1=>k = potato.k ' true
\\ we can use this pointer until original group get out of scope
\\ m get a pointer from a copy of group potato.
\\ a copy is a floating group, a nameless group, which can be  moved
m->(potato)
m=>k*=100
Print m=>k \\ 11100
\\ we can get a copy of the pointed group by m
\\ to a new named group, potato2
potato2=group(m)
Print potato2.k \\ 11100
b->m
Print b=>k =11100 ' true
\\ a pointer can get a new pointer
m->m1
Print m=>k = 111 ' true
\\ so now b points to old m
Print b=>k= 11100 ' true
m1->potato2 ' true
Print potato2.k=11100 'true
Print m1=>k=potato2.k ' true
\\ change pointer b to point to new m
b->m
Print b=>k=111 ' true
\\ a pointer can use = to get a value from other pointer
b=m1
Print m=>k=111
Print b=>k=11100
\\ this is the null pointer
m->0
Print type$(m) ' it is a group, with no members
\\ we can check if member k exist
Print valid(m=>k)=false ' give true
\\ so now we change  the pointer
m->b
Print valid(m=>k)=true ' give true
\\ passing pointer by value (as pointer)
Module ByValue (x) {
      x=>k++
}
ByValue m
\\m has same pointer as before, so b points to m
Print m=>k=11101 ' true
Print b=>k=11101 ' true
Module ByRef (&x) {
     class NewX {
            k=20000
      }
      x->NewX()
}
ByRef &m
\\ m change pointer
\\ so b points to old m
Print m=>k=20000 ' true
Print b=>k=11101
Dim a(100)
\\ we can set pointers for groups to array items
a(3)->b
Print a(3)=>k ' 11101
a(3)=>k++
Print b=>k '11102
\\ as usual we can push a copy of potato to container a()
Print potato.k=111
a(4)=potato
\\ we can set pointer to groups in other array items
a(10)->a(4)
b->a(4)
potato.k=20
Print potato.k=20
Print a(10)=>k=20 ' false
\\ we can change a(4) without change any pointer to it
For a(4) {
      \ this is the a(4)
      this=potato
      \\ no use of =>
      \\ we can use a(4) inside for too
      Print .k=20, a(4)=>k=20 \\ true  true
}
\\ so now a(10) points to same a(4), but as a copy of potato;
Print a(10)=>k=20 ' true
\\ and b points to a(4) too
Print b=>k=20 ' true
\\ we can place pointers to groups in any container
\\ in each of the two kinds, but the non moveable has a risk
\\ to get out of scope.
Inventory banana= 1:=b
Print banana(1).k = 20 ' true
a(4)=>k+=30
Print banana(1).k = 50 ' true
banana(1).k+=50
Print a(10)=>k=100 ' true



Άλλο παράδειγμα με συνδεδεμένη λίστα. Η κλάση AnyName, δεν έχει το pnext. Χρησιμοποιούμε την InsertPnext για να ετοιμάσουμε το τελικό πρώτυπο για τη συνδεδεμένη λίστα.

flush
class AnyName {
      name$
class:
      module AnyName {
            Read .name$
      }
}
Class Null {
      IsNull=true
}
Class InsertPnext {
      Group pnext
      IsNull=false
      class:
            module InsertPnext {
                  Read this
                  .pnext->Null()
             }      
}
\ Linked List
a1->InsertPnext(AnyName("George"))
a1=>pnext->InsertPnext(AnyName("Peter"))


Function Count(x as pointer) {
            Count=0
            While not x=>isNull {
            Count++
            x=x=>pnext
      }
      =Count
}
Function Item(x as pointer, index) {
            While not x=>isNull {
                  index--
                  if index else exit
                  x=x=>pnext
            }
             print x=>name$
            ->x
}
Function PopItem(&x as group) {
      m->x
      x=x=>pnext
      Print x=>name$
      \\ new operator -> for returning pointers
      ->m
}
second=Item(a1, 2)
Print second=>name$="Peter"
Print Count(a1)=2
PrintList(a1)
\\ we can get one item as pointer to group
pop1=PopItem(&a1)
Print pop1=>name$
Print a1=>name$
Print "Second try"
PrintList(a1)
Sub PrintList(k1 as pointer)
Print "List Start"
      While not k1=>isNull {
            Print k1=>name$
            k1=k1=>pnext
      }
Print "List End"
end sub



 

Τετάρτη 11 Απριλίου 2018

Έκδοση 9.3 (Πασχαλινή)

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

1. Χρήση Png, με διαφάνεια, τόσο σαν εικόνες όσο και σαν sprites (διάφανα).

2. Χρήση της εντολής Smooth On  (Off) ή Ομαλά Ναι (Όχι) για τα γραφικά όπου οι γραμμές γράφονται με χρωματική εξομάλυνση σε σχέση με τα ήδη τυπωμένα. (anti-aliasing).

3. Χρήση των Διαρθρώσεων για εικόνες (φορτώνονται ως αρχεία, και χρησιμοποιούνται απευθείας σαν να ήταν αρχεία από το δίσκο).

4. Ανανέωση στις φόρμες χρήστη. Όλες οι φόρμες τώρα έχουν τίτλο στην γραμμή εργασιών (task bar) ενώ παλιά μοιράζονταν τον ίδιο τίτλο. Όλες οι φόρμες έχουν Minimized, Maximized (αν μεγαλώνουν), και μπορούν να εμφανίζουν εικονίδιο και μενού επιλογών στην επικεφαλίδα.

5. Δείκτες στις Ομάδες. Μέχρι πριν την 9.3 δεν μπορούσαμε να χρησιμοποιήσουμε δείκτες σε ομάδες. Έπρεπε να βάζαμε μια ομάδα σε ένα στοιχείο πίνακα και να χρησιμοποιούσαμε το δείκτη του πίνακα. Θα δούμε παραδείγματα για το πώς βγαίνουν δείκτες σε ομάδες και πώς χρησιμοποιούνται σε επόμενες αναρτήσεις.