Exemples
Utilitaires arithmétiques
Mise à la puissance d'un nombre.
: POW ( n1 n2 - n3 ) \ n1^n2 -> n3
DUP 0= IF 2DROP 1 ELSE
DUP 1 = IF DROP ELSE
SWAP DUP ROT \ base acc pow
1 DO \ base acc
OVER * \ base acc
LOOP
SDROP \ acc
ENDIF
ENDIF ;
2 15 POW U. \ affiche 32768
CASE: alternatif
La structure CASE
implémentée par PAMPUK Forth est similaire à celle proposée par les adhérants au Forth Interest Group après l'appel à contributions de Forth Dimension dans son volume de janvier/février 1980 (Volume 1, numéro 5).
Il existe une structure alternative proposée par la revue BYTE dans son numéro d'août 1980 (Volume 5, numéro 8, page 184).
Plutôt qu'une suite de tests imbriqués, cette version, nommée CASE:
, construit une table de CFA
s qui sera indexée par le nombre paramètre de CASE:
pour lancer l'exécution du cas approprié.
Le mot de définition est défini ainsi :
: CASE:
<BUILDS \ Créer l'entête du mot
[COMPILE] SMUDGE \ Afin que CASE: se compore comme un ':' (1)
] \ Passe en mode compilation, ce qui permet
\ la compilation des mots qui suivent
\ lors de la création du mot (voir utilisation
\ ci-dessous) (2)
DOES> \ Place (DOES) dans le CFA du mot créé
SWAP \ Lorsque le mot créé est appelé,
\ le PFA+2 est en haut de la pile
\ juste au dessous se trouve l'index
\ On récupère l'index
2* + \ On multiplie l'index par 2 et on l'ajoute
\ à l'adresse des paramètres du mot créé
\ afin de pointer sur le bon index du tableau
\ des adresses des mots compilés.
@ EXECUTE \ Récupération de la valeur CFA à cet index
\ puis exécution
; \ Fin de la définition de `CASE:`
En supposant que PROCEDURE1
, PROCEDURE2
, etc. sont des mots définis, CASE:
s'utilise comme ceci :
\ Définition du mot de répartition nommé MENU
CASE: MENU
PROCEDURE1
PROCEDURE2
PROCEDURE3
PROCEDURE4
PROCEDURE5 ;
\ Utilisation du mot nouvellement créé
0 MENU \ Lance PROCEDURE1
1 MENU \ Lance PROCEDURE2
\ ... et ainsi de suite
Attention cependant : ce mot n'a aucune protection de domaine de définition. Si l'index passé au mot créé est négatif ou va au delà du nombre de mots compilés, le comportement est indéfini (et rarement bon), puisqu'il va pointer sur une adresse qui n'a pas été compilée par CASE:
.
Il est donc nécessaire de s'assurer de la validité de l'index avant d'appeler le mot créé par CASE:
.
Notes (1) et (2) :
L'utilisation de CASE:
se comporte, par design, de manière similaire à :
. C'est-à-dire que l'on créer un mot avec son nom puis une suite de mots qui seront compilés dans le mot créé.
On peut voir la similarité d'utilisation :
: MOT .... mots compilés ... ;
CASE: MOT .... mots compilés ... ;
C'est d'ailleurs la raison du nommage de CASE:
avec un :
à la fin, pour rappeler que c'est un mot de définition qui se comporte comme :
.
Ainsi, tout comme :
, il faut se retrouver après le nom du mot dans le mode compilation (en employant ]
) avec un mot qui n'est pas encore reconnu (SMUDGE
bit à 1). Le ;
final permet de terminer la compilation du mot créé et fait à son tour SMUDGE
pour le rendre utilisable et passant le bit SMUDGE
à 0.
Place restante
( Source : Megahector volume 3, page 56 et 57 )
( Auteur : Jacques Moulinie )
: FREE FIRST HERE - U.
." OCTETS LIBRES" CR ;
FREE ( - )
affiche un message indiquant le nombre d'octets restats pour le dictionnaire.
Pour cela, la différence entre FIRST
et HERE
est calculée, puis affichée en décimal suivi d'un message.
Ce n'est pas l'intégralité de la place restante, puisqu'il est possible, si on ne les utilise pas, d'utiliser la mémoire des buffers, ainsi que de la pile d'images.
Sauver des mots
( Source : Megahector volume 1, page 45 )
( Auteur : la rédaction de Megahector )
: TOL
[ HEX LATEST PFA DUP CFA !
00 C, 0800 , 0000 , 0000 ,
FE C, 0800 , 0001 , 0000 ,
FE C, C000 , 3900 , 0000 ,
FB C, 1000 , 0001 , FEE4 ,
FB C, 1800 , 0001 , FEE5 ,
FB C, C000 , 0000 , C000 ,
FE C, 0808 , 0001 , 0000 ,
FF C, 6000 , 0000 , 6000 ,
FF C, FF42 , 0090 , FF42 ,
FD C, 0000 , 0000 , 0000 ,
] ;
: EXTOL
[ HEX LATEST PFA DUP CFA !
C5F5 , E5DD , 21DD , ' TOL ,
013E , 28CD , DD03 , C1E1 ,
FBF1 , E9DD ,
] ;
: MM HOME FF8E FFD0 @ ! 30A9 FF86 !
30A9 EXECUTE QUIT ;
: SAUVE [ HEX ]
DUP 0= IF DROP C000 1 C000 THEN
' TOL 24 + ! ' TOL 26 + !
' TOL 28 + !
[COMPILE] '
DUP LFA FFD0 ! NFA DUP DUP
' TOL 32 + ! ' TOL 36 + !
HERE - ABS 29 + ' TOL 34 + !
[COMPILE] ' CFA
DUP 306C = IF DROP 30A9 THEN
' MM NFA 21 + !
' MM NFA HERE 29 CMOVE
LATEST HERE 2DUP 3 + !
HERE FF9C !
HERE 5 + FF86 ! HERE 29 + DP !
FF42 @ 3F18 FF42 !
FF94 @ 3F26 FF94 !
EXTOL
FF94 ! FF42 !
DP ! FF9C ! 30A9 FF86 ! ;
Vocabulaire de chaînes de caractères
L'explication de ce vocabulaire se trouve dans le chapitre des explications de chaînes de caractères.
( Source : d'après le Forth-79 pour APPLE II - MicroMotion - Octobre 1980 )
( Adaptation : Dominique Contant )
BASE @ \ ces deux première ligne, avec la toute dernière,
HEX \ s'assurent que le code est en hexadécimal puis restaure
\ la base de numération.
: STRING <BUILDS 1 MAX 0FF MIN DUP C, 0 C, ALLOT DOES> 1+ COUNT ;
: (S") R COUNT DUP 1+ R> + >R ;
: TEXT PAD 1+ 40 BLANKS WORD HERE COUNT DUP PAD C! -DUP
IF PAD 1+ SWAP CMOVE
ELSE DROP
ENDIF ;
: S" 22 STATE @ IF COMPILE (S") WORD HERE C@ 1+ ALLOT ELSE
TEXT PAD COUNT ENDIF ; IMMEDIATE
: S! DROP DUP 2 - C@ ROT MIN DUP 3 PICK 1 - C! CMOVE ;
: LEN SWAP DROP ;
: MLEN DROP 2 - C@ ;
: MID$ >R OVER MIN 1 MAX 1 -
SWAP OVER - R> MIN >R + R> ;
: RIGHT$ OVER 1+ SWAP - 0FF MID$ ;
: LEFT$ 1 SWAP MID$ ;
: SUB! ROT MIN 0 MAX CMOVE ;
: S= ROT OVER =
IF -DUP
IF 1 SWAP 0
DO DROP OVER C@ OVER C@ =
IF 1+ SWAP 1+ SWAP 1
ELSE 0 LEAVE
ENDIF
LOOP
ELSE 1
ENDIF
ELSE DROP 0
ENDIF SWAP DROP SWAP DROP ;
: S< ROT OVER MIN SWAP OVER > >R -DUP
IF -1 SWAP 0
DO DROP OVER C@ OVER C@ =
IF 1+ SWAP 1+ SWAP -1
ELSE C@ SWAP C@ > LEAVE
ENDIF
LOOP DUP 0<
IF DROP DROP DROP R>
ELSE R> DROP
ENDIF
ELSE DROP DROP R>
ENDIF ;
: S+
>R OVER R + OVER 2 - C@ MIN OVER OVER SWAP 1 -
C! R> 1+ 0FF MID$ SUB! ;
: CHR$
PAD ! PAD 1 ;
: ASC
DROP C@ ;
: IN$
DUP 4 PICK - DUP 0>
IF SWAP OVER -
IF 0 SWAP 2+ 1
DO DROP 3 PICK C@ OVER C@ =
IF 3 PICK 3 PICK 3 PICK OVER S=
IF I LEAVE
ELSE 1+ 0
ENDIF
ELSE 1+ 0
ENDIF
LOOP
ELSE DROP 0
ENDIF
>R DROP DROP DROP R>
ELSE DROP S=
ENDIF ;
: VAL
DROP 0. ROT DUP C@ 2D = DUP >R + 1 -
(NUMBER) DROP R>
IF DMINUS ENDIF ;
: STRING-ARRAY
<BUILDS 0
DO DUP C, 0 C, DUP ALLOT
LOOP
DOES> DUP C@ 2+ ROT * + 1+ COUNT ;
: STR$
SWAP OVER DABS
<# #S SIGN #> ;
: SNULL 2DUP + 1- 0 SWAP C! ;
BASE !
<BUILDS ... DOES> en détails
Le couple <BUILDS ... DOES>
est un mécanisme puissant de Forth qui permet de créer des mots de définition. C'est-à-dire des mots qui créent à leur tour d'autres mots. Il peut être assez facile de se perdre dans le fonctionnement de ces mots. Cette partie donne un exemple pas à pas pour suivre ce qu'il se passe à chaque étape.
Pour cela, nous allons créer un mot qui permet de définir des constantes double précision, c'est-à-dire des constantes de 32 bits. Le mot s'appellera DCONSTANT
et fonctionnera d'une manière similaire à CONSTANT
.
Pour rappel, les nombres double en Forth sont signalés par la présence d'un point associé au nombre, généralement placé à la fin de celui-ci.
Ce que l'on veut obtenir est :
999999. DCONSTANT GRANDE-CONSTANTE \ Définit GRANDE-CONSTANTE comme 999999
GRANDE-CONSTANTE D. \ Affiche 999999
Il y a trois séquences différentes à avoir en tête.
Séquence 1 : définition du constructeur
Le constructeur, aussi mot de définition, doit d'abord être défini, tout comme n'importe quel mot Forth. On le nomme donc DCONSTANT
et il prend deux paramètres depuis la pile : les deux parties de la constante double (LSB et MSB, pour Less Significant Byte et Most Significant Byte).
En effet, en Forth, les valeurs doubles sont définies par 2 × 16 bits, la partie la plus significative (MSB, la plus « grande ») se trouvant au sommet de la pile et la moins significative en dessous (LSB, du côté des unités). On écrit : (LSB MSB - )
pour dire que le mot prend deux paramètres sur la pile et n'en place aucun.
: DCONSTANT ( LSB MSB - )
<BUILDS \ Crée l'entête de la constante double
SWAP \ Inversion de l'ordre pour optimiser la lecture.
\ La pile contient maintenant ( MSB LSB )
, \ Compile LSB dans le PFA du mot
, \ Compile MSB dans le PFA du mot
DOES> \ Place (DOES) dans le CFA du mot et un pointeur vers
\ les mots qui suivent dans le PFA du mot créé
\ Ce qui suit est compilé dans `DCONSTANT`, mais ne sera pas
\ exécuté lors de l'appel de `DCONSTANT`.
DUP \ Duplique l'adresse des paramètres
@ \ Récupère LSB depuis le PFA et le met sur la pile
SWAP \ Met l'adresse des paramètres en haut de la pile
2+ \ L'augmente de 2 pour passer au paramètre suivant (MSB)
@ \ Récupère MSB depuis le PFA et le met sur la pile
; \ Termine la définition du mot DCONSTANT, mais aussi
\ des mots qui seront crés par DCONSTANT.
Au moment de sa création, le mot DCONSTANT
sera compilé comme n'importe quel autre mot en Forth : une succession d'adresses CFA des mots qui le composent.
Voyons ce qui se retrouve en mémoire, en considérant que le mot DCONSTANT
est le tout premier mot crée, donc à l'adresse 6000
:
6000 NFA 89h \ Bit 7 à 1 et longueur du nom : 9
6001 44h 43h 4fh 4eh 53h 54h 41h 4eh d4h \ "DCONSTANT" avec bit 7 du dernier octet à 1
600A LFA FFh 8Eh \ Adresse du mot précédent : 8EFFh
600C CFA C2 25 \ Adresse CFA de DOCOL (mot placé par ':')
600E PFA 88 29 \ Adresse CFA de <BUILDS
6010 50 23 \ CFA de SWAP
6012 88 27 \ CFA de ,
6014 88 27 \ CFA de ,
6016 98 29 \ CFA de DOES>
6018 5D 23 \ CFA de DUP
601A 9D 23 \ CFA de @
601C 50 23 \ CFA de SWAP
601E 06 24 \ CFA de 2+
6020 9D 23 \ CFA de @
6022 73 22 \ CFA de ;S
Séquence 2 : utilisation du constructeur
À présent que le mot de définition est créé, nous pouvons l'utiliser pour créer des mots de constantes double précision. Pour cela, nous utilisons le mot DCONSTANT
tel qu'il a été prévu.
Exemple : vitesse de la lumière dans le vide en km/s.
DECIMAL
299792. DCONSTANT VLUMIERE
Forth appelle donc le mot DCONSTANT
, et celui-ci va créer le mot VLUMIERE
dans le dictionnaire. Les deux nombre sur la pile sont compilés dans le PFA
du mot VLUMIERE
, le CFA
de VLUMIERE
est mis à (DOES)
et le premier mot du PFA
pointe vers le code qui suit DOES>
dans DCONSTANT
.
On se retrouve en mémoire avec le mode VLUMIERE
comme ceci (en supposant qu'il a été créé directement après DCONSTANT
) :
6024 NFA 88h \ Bit 7 à 1 et longueur du nom : 8
6025 56h 4ch 55h 4dh 49h 45h 52h c5h \ "VLUMIERE" avec bit 7 du dernier octet à 1
602D LFA 00h 60h \ Adresse du mot précédent : 6000h (NFA de DCONSTANT)
602F CFA A4h 29h \ CFA de (DOES)
6031 PFA 18h 60h \ Adresse vers la liste de mots suivant le DOES> de DCONSTANT (6018h)
6033 10h 93h \ 9310h représentant le LSB de la constante qui était sur la pile
6035 04h 00h \ 0004h représentant le MSB de la constante qui était sur la pile
Séquence 3 : exécution du mot créé
Le mot VLUMIERE
est maintenant créé et peut être exécuté comme n'importe quel mot Forth. Le CFA
de VLUMIERE
est (DOES)
, qui va exécuter la liste de mots pointée par le PFA
de VLUMIERE
, après avoir placé sur la pile l'adresse PFA+2
, qui pointe donc vers les paramètres de la constante.
Ce code, que l'on peut relire dans la séquence 1, prend les deux parties de la constante (LSB et MSB) depuis le PFA
de VLUMIERE
et les place sur la pile.
(DOES) à la loupe
Pour bien comprendre ce qu'il se passe, déroulont ce qu'il se passe lors de l'appel de (DOES)
. Pour cela, créons un mot de test dont le seul rôle est d'exécuter VLUMIERE
, mais de fournir des adresses simples à suivre.
: TEST VLUMIERE ;
Ce qui donne en mémoire :
6037 NFA 83h \ Bit 7 à 1 et longueur : 4
6038 54h 45h 53h D4h \ "TEST" avec bit 7 du dernier octet à 1
603C LFA 60 24 \ NFA du mot VLUMIERE
603E CFA C2 25 \ Adresse CFA de DOCOL
6040 2F 60 \ CFA de VLUMIERE
6042 73 22 \ CFA de ;S
Lorsque TEST
exécute VLUMIERE
, voici ce qui se passe dans (DOES)
(qui est situé à l'adresse 29A4h
) :
; Tout d'abord, (DOES) sauve l'adresse de retour (présente dans BC)
; dans la pile retour
; Dans ce exemple, BC = 6042h, l'adresse retour vers TEST
29A4 LD HL,(RPP) ; Lit l'adresse du sommet de pile retour
29A7 DEC HL ; / Place BC
29A8 LD (HL),B ; | dans
29A9 DEC HL ; | la
29AA LD (HL),C ; \ pile retour
29AB LD (RPP),HL ; Met à jour le pointeur de pile retour
; À ce niveau, DE pointe sur le deuxième octet de l'adresse de (DOES)
; Placé par l'interpréteur Forth lors du décodage du CFA de VLUMIERE
; DE = 6030h
29AE INC DE ; Avance DE pour le faire pointer sur le PFA de VLUMIERE
29AF EX DE,HL ; / Lecture du premier paramètre du PFA
29B0 LD C,(HL) ; | qui est l'adresse de la liste de mots après DOES>
29B1 INC HL ; | dans le mot de définition DCONSTANT
29B2 LD B,(HL) ; \ BC=6018h
29B3 INC HL ; Avance HL vers PFA+2 (6033h), qui contient les paramètres de la constante
29B4 PUSH HL ; Met cette addresse sur la pile
29B5 JP (IX) ; Appelle l'interpréteur Forth qui continue donc avec les mots placés après
; le DOES> de DCONSTANT.
En résumé, (DOES)
place les paramètres de l'interpréteur pour que le mot suivant exécuté soit celui après le DOES>
du mot de définition, avec un pointeur vers le PFA+2
du mot créé sur la pile des paramètres, et comme adresse de retour l'adresse du mot qui a appelé le mot créé.
CREATE ... ;CODE en détails
Reprenons l'exemple de DCONSTANT
de la section sur <BUILDS
et DOES>
et voyons comment il peut être réécrit en utilisant CREATE ... ;CODE
.
: DCONSTANT \ Définition du mot de définition DCONSTANT
CREATE \ Créé le mot et le place dans le dictionnaire
[COMPILE] SMUDGE \ CREATE place le bit SMUDGE dans le NFA
\ du mot nouvellement créé à 1.
\ Pour le rendre visible, il faut inverser le
\ bit SMUDGE grâce au mot SMUDGE.
\ Comme SMUDGE est un mot immédiat, il est
\ nécessaire d'utiliser [COMPILE] pour
\ le compiler dans le mot DCONSTANT.
SWAP , , \ Compile LSB et MSB dans le PFA du mot
;CODE \ Mot immédiat qui compile le mot (;CODE)
\ (;CODE) placera le PFA dans le CFA du mot
\ nouvellement créé, permettant ainsi
\ l'exécution de la partie en code machine
\ qui suit.
\ Ici, la définition de DCONSTANT est terminée, cependant, il
\ reste à compiler à la suite du mot la partie code machine
13 C, \ INC DE Ajuste DE pour pointer sur le PFA du mot
EB C, \ EX DE,HL HL pointe sur le PFA
5E C, \ LD E,(HL) / Lecture
23 C, \ INC HL | du mot de poids
56 C, \ LD D,(HL) \ faible du double mot
D5 C, \ PUSH DE Place le mot de poids faible dans la pile
23 C, \ INC HL Avance HL pour le mot de poids fort
5E C, \ LD E,(HL) / Lecture
23 C, \ INC HL | du mot de poids
56 C, \ LD D,(HL) \ fort du double mot
D5 C, \ PUSH DE Place le mot de poids fort dans la pile
DD C, E9 C, \ JP (IX) Branche vers NEXT, pour continuer l'exécution
Ce mot s'utilise de la même manière que le mot DCONSTANT
défini précédemment :
DECIMAL
299792. DCONSTANT VLUMIERE
Demo Graph
Note : les écrans sont notés et séparés, cependant, le code est écrit sous une forme plus lisible.
Pour être utilisé, le code devra être re-tassé pour que chaque page puisse entrer dans un screen
.
( Source : HECTORIEN 1, page 35 et 36 )
( Auteur : Alain MARC )
( SCREEN 1 )
1 VARIABLE C
: COL 0 1 3 4 COLOR ;
: TSC
C @ 3 > IF
1 DUP C ! INK
ELSE
C @ INK
THEN ;
: AA
CLS
0 0 FROM
234 0 DO
228 0 DO
TSC
J 10 + I TO
J 10 + I 10 + TO
J 20 + I 10 + TO
1 C +!
10 +LOOP
10 +LOOP
KEY DROP ;
: BB
CLS
0 228 FROM
234 0 DO
0 228 DO
TSC
J 10 + I TO
J 10 + I 10 + TO
J 20 + I 10 + TO
1 C +!
-10 +LOOP
10 +LOOP
KEY DROP ;
: C?
C @ 3 > IF
0 DUP C ! INK
ELSE
C @ INK
THEN ;
: EE
CLS
3 C !
237 6 DO
8 228 DO
C?
J I J 10 + I 10 - BOX
1 C +!
-10 +LOOP
10 +LOOP
KEY DROP CLS ;
: KD
KEY DROP CLS ;
( SCREEN 2 )
32767 VARIABLE SINTT
1 VARIABLE FLAGC
0 VARIABLE TABLE 182 ALLOT
0 572 01144 01715 02286 02856 03423
03993 04560 05126 05690 06252 06613
07371 07927 08481 09032 09580 10126
10668 11207 11743 12275 12803 13328
13848 14364 14876 15383 15886 16384
16876 17364 17846 18323 18794 19260
19720 20173 20621 21062 21497 21925
22347 22762 23170 23571 23964 24351
24730 25101 25465 25821 26169 26509
26841 27165 27481 27788 28087 28377
28659 28932 29196 29451 29697 29934
30162 30381 30591 30791 30982 31163
31335 31490 31650 31794 31927 32051
32165 32269 32364 32448 32523 32587
32642 32687 32722 32747 32762 32757
: OUBLIE
0 0
TABLE 182 + TABLE DO
ROT DUP I ! ( place la valeur de la pile dans TABLE )
0 D+ ( maintient une somme de contrôle )
?STACK ( vérifie la pile )
2 +LOOP
+ 6765 + IF ( vérifie la somme de contrôle )
." ERREUR" QUIT
THEN ;
OUBLIE FORGET OUBLIE
( SCREEN 3 )
90 VARIABLE THETA
0 VARIABLE COSTT
115 VARIABLE XTORT
115 VARIABLE YTORT
: COS
180 - ABS
DUP 90 IF
180 - ABS 2* TABLE + @
ELSE
2* TABLE + @ MINUS
THEN ;
: SIN 180 -
DUP 0< IF
90 + ABS 2* TABLE + @
ELSE
90 - ABS 2* TABLE + @ MINUS
THEN ;
: 360MOD
BEGIN
DUP 0<
WHILE
360 +
REPEAT
BEGIN
DUP 359 >
WHILE
360 -
REPEAT ;
: XY
YTORT !
XTORT ! ;
: CAP
360MOD DUP THETA !
DUP
COS 63 100 */ COSTT !
SIN SINTT ! ;
: AV
XTORT @ YTORT @ FROM
DUP COSTT @
32767 */ XTORT +!
XTORT @ SWAP SINTT @
32767 */ YTORT +!
YTORT @ FLAGC @
IF
TO
ELSE
2DROP
THEN ;
: DEP CLS 121 115 XY 90 CAP ;
: RC MINUS RV ;
( SCREEN 4 )
37 VARIABLE FOIS
: PY1
SWAP FOIS @ 0 DO
2DUP AV DR
LOOP
2DROP ;
: PY2
SWAP FOIS @ 0 DO
2DUP RC GA
LOOP
2DROP ;
: CE1 CAP 10 10 PY1 ;
: II 121 85 XY BIG 217 INK LITTLE
180 CE1 160 CE1 140 CE1 120 CE1 100 CE1
80 CE1 60 CE1 40 CE1 20 CE1 0 CE1
340 CE1 320 CE1 300 CE1 280 CE1 260 CE1
240 CE1 220 CE1 200 CE1 KD ;
: CE2 CAP 5 10 PY1 ;
: CE3 CAP 5 10 PY2 ;
: FA 180 CE2 150 CE2 120 CE2 90 CE2 60 CE2
30 CE2 0 CE2 330 CE2 300 CE2 270 CE2
240 CE2 210 CE2 ;
: FR 180 CE3 210 CE3 240 CE3 270 CE3
300 CE3 330 CE3 0 CE3 30 CE3 60 CE3
90 CE3 120 CE3 150 CE3 ;
: B217 BIG 217 INK LITTLE ;
: B219 BIG 219 INK LITTLE ;
( SCREEN 5 )
: JJ 4 0 DO
I 0= IF
B217 98 150 XY FA
ELSE
I 1 = IF
B219 145 150 XY FR
ELSE
U 2 = IF
B217 149 72 XY FA
ELSE
B219 98 72 XY FR
THEN
THEN
THEN
LOOP KD ;
: CE4 CAP 10 10 PY2 ;
: KK
DEP 45 CE1 90 CE4 135 CE1 180 CE4
225 CE1 270 CE4 315 CE1 0 CE4
56 107 XY 90 CAP 20 10 PY1 40 FOIS !
77 123 XY 90 CAP 13 9 PY2 21 FOIS !
101 112 XY 90 CAP 12 17 PY1 37 FOIS ! KD ;
: LL
3 INK CLS 201 50 DO
I 0 I 200 LINE
10 +LOOP
230 0 DO
45 I 205 1 LINE
10 +LOOP
121 115 XY 90 CAP 1
INK 45 CE1 90 CE4 135 CE1 180 CE4
225 CE1 270 CE4 315 CE1 0 CE4
56 107 XY 90 CAP 20 10 PY1 40 FOIS !
77 123 XY 90 CAP 12 17 PY1 37 FOIS !
KD ;
( SCREEN 6 )
(?TODO?) À continuer