Τρίτη, 24 Απριλίου 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