Πρώτο παράδειγμα με την νέα λειτουργία Union. Η ένωση σημαίνει ότι την ίδια μνήμη μπορούμε να την προσεγγίζουμε με διαφορετικές "μεταθέσεις" από την αρχή (offsets), και σε κάθε περίπτωση να έχουμε δώσει και το τύπο αυτού που περιλαμβάνεται εκεί.
Δεν γράφουμε την λέξη Union, απλά όταν δει την λέξη structure (μπορούμε να ονομάσουμε την αρχή, για να ξεχωρίζουν τα ονόματα αν είναι ίδια τα εσωτερικά με τα εξωτερικά) ή μια αρχή μπλοκ ο διερμηνευτής τότε ξέρει ότι έχει Union. Αν θέλουμε τριπλό τότε πρέπει τα δυο πρώτα μέρη να είναι σε μπλοκ
structure alfa {
{
low as integer
high as integer
}
value as long
}
Buffer Clear one as alfa *100
Return one, 20!Value:=0xFFFFAACC
Hex Eval(one, 20!high),"", Eval(one, 20!Low), "",Eval(one, 20!value)
// new from version 13
Hex one[20]|high,"", one[20]|Low,"", one[20]|value
Στο παράδειγμα παραπάνω έχουμε ορίσει το alfa να το διαβάζουμε και σαν long (unsigned long) και σαν integer (unsigned integer) από τα δυο μισά. Η εντολή Hex είναι η Print αλλά για δεκαεξαδικό (unsigned , όπου βρει αρνητικούς ή μεγαλύτερο από 0xFFFFFFFF τότε εμφανίζει αντί για αριθμό ένδειξη λάθους --- ή +++). Δείτε ότι το High όχι μόνο του λέει πόσο θα μετατεθεί από το 20 *4 που είναι η μετάθεση από την θέση του πρώτου ψηφίου (Byte) αλλά και το μέγεθος που θα πάρει, εδώ τον ακέραιο των 2 Bytes (ψηφίων). (Προστέθηκε και ο τρόπος της έκδοσης 13).
Τι θα γίνει όμως αν βάλουμε κάτι πίσω από το Value (ενώ τώρα Value και Low είναι ίδιες μεταθέσεις, δείχνουν στο 0)
Για να γίνει πιο ωραίο, βάζουμε το value ως πίνακα 20 long (Μακρύς). Τα μέρη που απαρτίζουν την ένωση, "ξεχειλώνουν" όσο το μεγαλύτερο. Όμως στο πρώτο μέρος, με τα Low και High έχουμε μεταθέσεις από την αρχή. Πώς θα βρούμε ας πούμε το 3 στοιχείο. Και αν υποθέσουμε ότι έχουμε 100 από το alfa, τότε ας βάλουμε στόχο να βρούμε το alfa[10]high[3], alfa[10]low[3], alfa[10]Value[3].
Εδώ το πρόβλημα λύνεται με μια συνάρτηση! το Value[3] έχει μεν το 3 αλλά αυτό δεν είναι καθαρός αριθμός, έχει μονάδες, έχει το Long το οποίο είναι 4*byte. Και το low[3] έχει και αυτό μονάδες είναι το Integer ή το 2*byte. Για να λειτουργήσει εδώ σωστά η μετάθεση πρέπει για κάθε πραγματική μετάθεση στο value να έχουμε ισοδύναμη στο low, και ομοίως και στο high. Αν είχαμε Long στο παράλληλο, ή κατ΄ένωση μέρος, τότε θα ένα προς ένα ισοδυναμία. άρα το 3 στο ένα και το 3 στο άλλο θα ήταν ταυτόσημα. Τώρα χρειάζεται η συνάρτηση Mult() που μας δίνει το νούμερο για πολλαπλασιασμό. Αυτό βγαίνει από την αναλογία, 4 προς 2 και έτσι μας δίνει τον παράγοντα 2 που πολλαπλασιάζουμε στο 3 στο Low. Το 30!high!mul*M g είναι στην ουσία:
To M=3 επειδή ζητάμε το 4o στοιχείο (στο 0 είναι το πρώτο)
Δείκτης βάσης+30*μέγεθος(alfa)+μετάθεση(high)+μέγεθος(high)*2*3
Ο τύπος στο mult() δεν είναι γενικός. Μας βολεύει εδώ γιατί το μέγεθος 4 που επαναλαμβάνεται είναι το άθροισμα του μήκους σε bytes (bytes) των δυο ακεραίων (integer), και τόσο είναι και το μήκος του μακρύ ή long στο δεύτερο μέρος (και τα δυο μέρη δείχνουν την ίδια μνήμη, ο τρόπος που διαβάζεται και γράφεται έχει να κάνει με την χρήση του offset, ή μετάθεσης). Αν βάζαμε στο low as integer πολλαπλασιαστή έστω 20 τότε αντί να έχουμε το high ακριβώς 2 Byte μετά θα το έχουμε 2*20, ή 40 byte μετά. Αν μάλιστα στο long δεν βάζαμε το *20 αλλά το βάζαμε στο high, τότε και το value θα ήταν εκ των πραγμάτων *20 εκτός να προσθέταμε και κάτι άλλο.
low as integer
high as integer
}
structure alfa {
base1 as integer*30
{
val2 as Union1*20
}
{
low as integer
High as integer
}
\\ now we extend to 20 items as Long or High-Low integers
value as long*20
}
Buffer Clear one as alfa *100
Return one, 20!Value:=0xFFFFAACC
Hex Eval(one, 20!high),"", Eval(one, 20!Low), "",Eval(one, 20!value)
Pen 15 {Hex one[20]|high,"", one[20]|Low,"", one[20]|value}
N=10 \\ is a multiplier alfa
M=3 \\ is a multiplier Long
\\ offsets maths
\\ we use a multiplier based on the ratio
\\ value is long (4 bytes)
\\ if we make low as byte and high as byte then we use mult(4,1)
def mult(From1, to1)=From1 div to1
mul=mult(4,2)
Return one, N!Value!M:=0xFF1FA5BB
HEX Eval(one, N!high!mul*M),"",Eval(one, N!low!mul*M), "",Eval(one, N!value!M)
Pen 15 {Hex one[N]|val2[M]|High,"", one[N]|val2[M]|Low,"", one[N]|value[M]}
\\ offsets
Print alfa("high"),alfa("low"), alfa("value"), alfa("base1")
\\ real pointer
Print one(0), one(4)-one(3)=len(alfa)
Print Len(one) \\ 14000 bytes
structure beta {
low as integer
high as integer
}
structure delta {
low as byte
middle1 as byte
middle2 as byte
high as byte
}
value as long
}
\\ len in bytes, number of offsets
Print len(alfa), len.disp(alfa)
For i=0 to len.disp(alfa)-1
\\ print names and offsets and length of offsets
Print format$("{0:20} {1::4}{2::4}", eval$(alfa, i), eval(alfa), alfa(eval$(alfa, i)))
next i
Structure beta {
aname as integer *50
one as alfa*2
}
Buffer Clear alfa1 as alfa, alfa2 as alfa*2
Print len(alfa1), len(alfa2)
Buffer Clear kappa as beta*100
\\ len in bytes (10800), number of parts (100)
Print Len(kappa), Len.disp(kappa)
Return alfa1,0!delta.middle1:=0xFF
Hex eval(alfa1,0!value)
Return alfa1,0!delta.high:=0xFF
Hex eval(alfa1,0!value)
\\ new from version 13 rev 10
alfa1[0]|delta.high=alfa1[0]|delta.high-1
Hex alfa1[0]|value
\\
Return alfa2,1:=eval$(alfa1) \\ make a copy
\\ new copy of alfa1 to alfa2(0)
alfa2[0]=alfa1
Hex alfa1[0]|value
Hex alfa2[0]|value
'Return kappa, 24!one!1:=eval$(alfa1)
kappa[24]|one[1]=alfa1
Hex eval(kappa, 24*len(beta)+beta("one")+len(alfa)*1+alfa("beta.high") as integer)
\\ new:
Hex kappa[24]|one[1]|beta.high
? "------------Copy part to CastAlfa--------------"
buffer clear castAlfa as alfa*8
castAlfa[0]|value=kappa[24]|one[1]
Hex castAlfa[0]|beta.high
\\ offset here is in item len, 24 for (beta) and for item one 1 for (alfa)
\\ because alfa has 4 bytes automatic return long
Hex eval(kappa,24!one!1)
Return kappa, 24*len(beta)+beta("one")+len(alfa)*1+alfa("delta.middle2") !:=0x33 as byte
Hex eval(kappa,24!one!1)
Hex eval(kappa, 24*len(beta)+beta("one")+len(alfa)*1+alfa("delta.middle2") as byte)
Hex kappa[24]|one[1]|delta.middle2
kappa[24]|one[1]|delta.middle2= kappa[24]|one[1]|delta.middle2+1
Hex eval(kappa, 24*len(beta)+beta("one")+len(alfa)*1+alfa("delta.middle2") as byte)
Hex kappa[24]|one[1]|delta.middle2
Hex kappa[24]|one[1]|value
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου
You can feel free to write any suggestion, or idea on the subject.