Evolution des structures depuis la version 7.0.7.21
publication: 9 décembre 2024 / mis à jour 9 décembre 2024
Dans le précédent chapitre, on a abordé le problème de la taille des champs dans une structure. Il était recommandé de définir des mots spécifiques pour lire ou écrire dans ces champs.
Dans la version eForth Windows 7.0.7.21 les @field
et !field
apparaissent dans le
vocabulaire structures
. Ces mots apportent une solution élégante pour lire ou écrire des données depuis des accesseurs.
Les types de champs dans les structures
Il y a quatre types de champs connus: i8
, i16
, i32
et i64
, gérant respectivement
des champs de 8, 16, 32 et 64 bits. Ces quatre types sont complétés par trois nouveaux types:
u8
pour un champ 8 bits non signésu16
pour un champ 16 bits non signésu32
pour un champ 32 bits non signés
Il n'y a pas de mot u64.
Cette panoplie de champs est complétée du mot sc@
qui exécute une récupération d'octet signé dans le contenu d'un
champ huit bits.
structures struct 8BXY i8 field ->8bx i8 field ->8by create XY-offset -3 c, 12 c, XY-offset ->8bx sc@ . \ display -3 XY-offset ->8by sc@ . \ display 12
Le typage des données 8, 16, 32 ou 64 bits, signés ou non signés, rajoute de la complexité dans le choix adaptés des mots effectuant une lecture ou écriture dans les champs d'une structure.
Accès simplifié aux données d'un champ de structure
Heureusement, les deux nouveaux mots @field
et !field
apportent uen solution qui simplifie l'accès
au contenu des champs en s'adaptant automatiquement à la taille et au type des champs définis:
XY-offset @field ->8bx . XY-offset @field ->8by .
Les mots @field
et !field
doivent être suivis de l'accesseur correspondant.
Utilisons @field
dans une définition:
: getXY ( -- x y ) XY-offset @field ->8bx XY-offset @field ->8by ; getXY \ leave -3 12 on stack
Si on décompile notre mot getXY
, on retrouve le mot sc@
au lieu de @field
:
see getXY \ display:
: getXY
XY-offset ->8bx sc@ XY-offset ->8by sc@
;
Les mots @field
et !field
sont donc particulièrement utiles pour gérer les accès à des champs de taille hétérogène
dans des structures. La modification du type dans une structure ne nécessite pas la modification des définitions
qui utilisent @field
ou !field
.
Les alias de type de données
Partons d'une structure écrite en langage C:
typedef struct _DCB { DWORD DCBlength; DWORD BaudRate; DWORD fBinary : 1; DWORD fParity : 1; DWORD fOutxCtsFlow : 1; DWORD fOutxDsrFlow : 1; DWORD fDtrControl : 2; DWORD fDsrSensitivity : 1; DWORD fTXContinueOnXoff : 1; DWORD fOutX : 1; DWORD fInX : 1; DWORD fErrorChar : 1; DWORD fNull : 1; DWORD fRtsControl : 2; DWORD fAbortOnError : 1; DWORD fDummy2 : 17; WORD wReserved; WORD XonLim; WORD XoffLim; BYTE ByteSize; BYTE Parity; BYTE StopBits; char XonChar; char XoffChar; char ErrorChar; char EofChar; char EvtChar; WORD wReserved1; } DCB, *LPDCB;
Pour utiliser cette même structure avec eForth Windows, il est nécessaire de traduire la taille de chaque
type de donnée (DWORD, WORD, BYTE...) en son type de données i8 i16 i32
. C'est long, fastidieux,
et sujet à erreurs.
La solution est de définir des alias:
( Windows handles bottom out as void pointers. ) : HANDLE ptr ; : DWORD u32 ; : WINLONG i32 ; : UINT u32 ; : WPARAM ptr ; : LPARAM ptr ; : WINBOOL i32 ; : WINWORD u16 ; : WORD u16 ; : BYTE u8 ; \ char use u8 or BYTE
Il n'y a que pour le type char pour lequel on ne définit pas d'alias, car il y a risque de colision avec le
mot char
du vocabulaire FORTH
. Voici comment on peut réécrire en Forth la structure DCB
si on utilise ces alias:
structures struct DCB DWORD field ->DCBlength DWORD field ->BaudRate DWORD field ->fBinary DWORD field ->fParity DWORD field ->fOutxCtsFlow DWORD field ->fOutxDsrFlow DWORD field ->fDtrControl DWORD field ->fDsrSensitivity DWORD field ->fTXContinueOnXoff DWORD field ->fOutX DWORD field ->fInX DWORD field ->fErrorChar DWORD field ->fNull DWORD field ->fRtsControl DWORD field ->fAbortOnError DWORD field ->fDummy2 WORD field ->wReserved WORD field ->XonLim WORD field ->XoffLim BYTE field ->ByteSize BYTE field ->Parity BYTE field ->StopBits BYTE field ->XonChar BYTE field ->XoffChar BYTE field ->ErrorChar BYTE field ->EofChar BYTE field ->EvtChar WORD field ->wReserved1
Dans la version de DCB en langage C, nous avons un certain nombre de champs avec des
valeurs par défaut. Voici comment initialiser une structure DCB en Forth avec !field
:
: DCB.init ( DCBaddr -- )
>r
1 r@ !field ->fBinary
1 r@ !field ->fParity
1 r@ !field ->fOutxCtsFlow
1 r@ !field ->fOutxDsrFlow
2 r@ !field ->fDtrControl
1 r@ !field ->fDsrSensitivity
1 r@ !field ->fTXContinueOnXoff
1 r@ !field ->fOutX
1 r@ !field ->fInX
1 r@ !field ->fErrorChar
1 r@ !field ->fNull
2 r@ !field ->fRtsControl
1 r@ !field ->fAbortOnError
17 r> !field ->fDummy2
;
create COM5-DCB
DCB allot
COM5-DCB DCB.init
En résumé, avec cette évolution, la gestion des champs dans les structures devient infiniment plus simple et beaucoup plus souple. Cette évolution reste compatible avec les codes sources Forth plus anciens exploitant les structures sans nécessiter la réécriture de ces fichiers source.
Legal: site web personnel sans commerce / personal site without seling