Logicielsmoto.com

Nous sommes le 28 Mar 2024, 13:37

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 18 messages ]  Aller à la page 1, 2  Suivante
Auteur Message
MessagePosté: 06 Sep 2009, 14:39 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Je butte sur un truc en basic. Comment déterminer si un disk est présent en "0:" ou en "1:" .. "3:" ? Je vois bien une solutions en utilisant le fait que DSKF(no) produit une erreur, mais ca ne me plait pas car j'aime pas l'utilisation de "on error goto".

Une idée?


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 06 Sep 2009, 21:23 
Hors ligne

Inscription: 27 Juin 2006, 19:44
Messages: 1061
Localisation: France (24)
Hmm... Ca ne va pas être facile, puisque même le hardware est obligé de lancer le moteur pour détecter la présence d'une disquette dans un lecteur... Donc la meilleure solution reste encore celle à laquelle tu cherches à échapper :)

Qu'est-ce qui te gênes dans ON ERROR GOTO ?


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 06 Sep 2009, 21:49 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Prehisto a écrit:
Hmm... Ca ne va pas être facile, puisque même le hardware est obligé de lancer le moteur pour détecter la présence d'une disquette dans un lecteur... Donc la meilleure solution reste encore celle à laquelle tu cherches à échapper :)


Groumph... :(

Prehisto a écrit:
Qu'est-ce qui te gênes dans ON ERROR GOTO ?


Ben c'est que je ne me rappelle plus comment cette instruction fonctionne et qu'il me semble me souvenir qu'elle est de portée arbitraire, à la différence des blocks try/catch des langages modernes. Donc son usage est délicat.

Bon j'imagine un code comme ceci
Code:
10 FOR DISK=0 TO 3
20   PRESENT = 0
30   ON ERROR GOTO 60 ' NdSam: BERK
40   TMP = DSKF(DISK)
50   PRESENT = 1
60   IF NOT PRESENT THEN 100
70   ' ...code... (si disk present)
80   ' ...code... (si disk present)
100 NEXT

Mais que se passe t'il si on ajoute les lignes suivantes:
Code:
110 X = 1
120 Y = 1/(X*X-1)
130 ? X, Y
140 END

La ligne 120 va (volontairement) produire une erreur et du coup l'execution reprend en ligne 100... Ce qui n'est pas du tout ce qu'on veut. En fait je ne me souviens plus si le ON ERROR est débrayable pour revenir au fonctionnement normal.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 06 Sep 2009, 22:01 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Code:
10 FOR DISK=0 TO 3
20   PRESENT = 0
30   ON ERROR GOTO 60 ' NdSam: BERK
40   TMP = DSKF(DISK)
50   PRESENT = 1
60   IF NOT PRESENT THEN 100
70   ' ...code... (si disk present)
80   ' ...code... (si disk present)
100 NEXT
Bon en fait c'est pas du bon code.. la doc dit que le code de traitement d'un exception doit se terminer par un "RESUME".. donc il faut ecrire le code comme suit:
Code:
10 FOR DISK=0 TO 3
20   PRESENT = 0
30   ON ERROR GOTO 9999 ' NdSam: BERK
40   TMP = DSKF(DISK)
50   PRESENT = 1
60   ON ERROR GOTO 0 ' annule le on error goto precedent
60   IF NOT PRESENT THEN 100
70   ' ...code... (si disk present)
80   ' ...code... (si disk present)
100 NEXT
110 ' suite code
120 ' suite code
1000 END
9999 RESUME 60
C'est pas super clean. Et puis il y a quelque inconvenients:
    On ne peut utiliser la ligne 9999 que pour un seul ON ERROR GOTO à cause du RESUME qui forcerait à repartir en 60.
    On ne peut pas "empiler" les sections "ON ERROR GOTO/RESUME" les unes dans les autres. Il n'y a pas de piles du numéro de lignes sur lequelles on branche le RESUME.
    Tout ceci fait que le code n'est pas super maintenable
En fait ce que je voudrais c'est une gestion de blocs de code comme dans les langages de plus haut niveau. Bref je voudrais pouvoir écrire un truc dans le genre
Code:
TRY
... code qui peut planter
CATCH ' optionnel auquel cas on ignore l'erreur
... code d'exception
END


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 06 Sep 2009, 23:19 
Hors ligne

Inscription: 27 Juin 2006, 19:44
Messages: 1061
Localisation: France (24)
Il y a peut-être quelque chose qui ressemble plus à ce que tu cherches :
Code:
10 ON ERROR GOTO 50
20 '
30 FOR DISK=0 TO 3
40 TMP=DSKF(DISK)
50 IF ERR THEN RESUME 70
60 PRINT"Disque";DISK;"présent"
70 NEXT
80 '
90 ON ERROR GOTO 0

Tu places donc ton interruption d'erreur avant la boucle, et tu en abolis l'effet en sortie.
Dans la boucle, tu testes simplement ERR (qui contient le numéro d'erreur, sinon nul) et tu résumes en fonction.
Evidemment, il ne faut pas avoir d'erreur de syntaxe dans la boucle :D Pour les tests, tu peux toujours ajouter ON ERROR GOTO 0 en ligne 55, et tu l'enlèves une fois que ton programme est prêt.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 06 Sep 2009, 23:35 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Prehisto a écrit:
Code:
10 ON ERROR GOTO 50
20 '
30 FOR DISK=0 TO 3
40 TMP=DSKF(DISK)
50 IF ERR THEN RESUME 70
60 PRINT"Disque";DISK;"présent"
70 NEXT
80 '
90 ON ERROR GOTO 0

Evidemment, il ne faut pas avoir d'erreur de syntaxe dans la boucle :D Pour les tests, tu peux toujours ajouter ON ERROR GOTO 0 en ligne 55, et tu l'enlèves une fois que ton programme est prêt.


Oui.. il y a de l'idée.. mais ce qui me gène est le "GOTO 50" qui ne rend pas la structure réutilisable facilement.

En revanche, ton code m'inspire ceci:
Code:
10 ON ERROR GOTO 9999
20 '
30 FOR DISK=0 TO 3
40 TMP=DSKF(DISK)
50 IF ERR THEN ? "Disk "; DISK; " Absent" ELSE ? "Disk"; DISK; " Present"
60 ' CODE
70 ' ...
80 ' ...
90 END
9999 RESUME NEXT
Du coup la construction est systématique. Le 9999 est une ligne réservée une fois pour toutes les interruptions et "RESUME NEXT" fait reprendre juste après l'instruction qui plante. Il suffit alors de lire ERR comme tu l'indiques pour savoir si une interruption a eu lieu ou pas. Ca marche à 100% et utilisable en plusieurs endroit du code. C'est la solution que je cherchais.

Merci Préhisto! :) :tourne:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 06 Sep 2009, 23:46 
Hors ligne

Inscription: 27 Juin 2006, 19:44
Messages: 1061
Localisation: France (24)
Désolé de te contredire, Samuel, mais tes lecteurs seront toujours détectés comme étant présents puisque le RESUME remet systématiquement ERR à 0 (programme testé sur un TO8D)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 06 Sep 2009, 23:58 
Hors ligne

Inscription: 27 Juin 2006, 19:44
Messages: 1061
Localisation: France (24)
... à moins que tu fasses :
Code:
10 ON ERROR GOTO 9999
20 '
30 FOR DISK=0 TO 3
25 MYERR=0
40 TMP=DSKF(DISK)
50 IF MYERR THEN ? "Disk "; DISK; " Absent" ELSE ? "Disk"; DISK; " Present"
60 ' CODE
70 ' ...
80 ' ...
90 END
9999 MYERR=ERR:RESUME NEXT


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 07 Sep 2009, 01:02 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Prehisto a écrit:
Désolé de te contredire, Samuel, mais tes lecteurs seront toujours détectés comme étant présents puisque le RESUME remet systématiquement ERR à 0 (programme testé sur un TO8D)

Exact... je m'appetais à poster un patch:
Code:
10 ON ERROR GOTO 9999
...
60 TMP = DSKF(I)
70 IF KO THEN KO=0:? DISK; " absent": GOTO 90
...
9999 KO=ERR: RESUME NEXT
J'aurais bien aimé utiliser ERRNO (comme en C), mais apparement toutes les variables qui commencent avec ERR ou ERL sont interdites dans le basic Thomson. Du coup je reserve KO a cet usage.. et c'est au code de nettoyer cette variable au bon moment. Ca peut avoir des avantages de tester le même KO à plusieurs endroits. Bon a voir. Les 2 approches ont leurs avantages et inconvénients.

Une autre possibilité est de mettre le "ON ERROR GOTO 50" juste avant l'instruction qui peut planter et pas en début de code comme dans ton exemple. On retrouve alors une structure type TRY/CATCH/END qui me plait bien (c'est structuré):
Code:
...
30 FOR DISK=0 TO 3
40 'TRY
41 ON ERROR GOTO 60
50       TMP=DSKF(DISK)
51       ? DISK; " Présent"
52       '... etc
53       '... etc
60 'CATCH
61 IF ERR THEN RESUME 61 ELSE 80
70       ? DISK; " Absent"
71       '... etc
72       '... etc
80 'END
81 ON ERROR GOTO 0
C'est rigolo car le RESUME 61 efface ERR.. on aurait pu aussi faire RESUME 70.. c'est juste une variation. (et j'aurais pu mieux choisir mes numéros de lignes; hélas "RENUM" ne marche pas dans php-bb :p )

J'avais fait dans le temps un pseudo editeur "basic" avec bloc et labels largement inspirés du GFA-BASIC. Il "compilait" ce pseudo GFA-BASIC avec blocs imbriqués etc en gérant lui même les numéros de lignes dans un code basic standard qu'il mergeait à son propre code avant d'executer le code source édité (note: le code produit était aussi executable depuis le disk il me semble).. Je devrais voir pour lui rajouter cette construction TRY/CATCH/END. Ca serait marrant! Allez en cadeau bonux, voici le code d'un raytracer que j'avais écrit pour cet editeur GFA-BASIC thomson (ou à l'epoque je n'hesitais pas à faire du raytracing en basic :tourne:). Voyez l'absence de numéros de lignes, les labels "symboliques", les IF/ELSE/ENDIF sur plusieurs lignes facon blocs, etc...

Usage: sur TO9 (ou sinon la palette 6 et 1 sont inversées; modifier la routine 160x200 pour TO8 et 9+), lancer GFA.BAS, entrer RAYTR, pour executer faire ctrl-R, sauver avec ctrl-S. D'autres CTRL- existent, mais je ne sais plus lesquels et comme le code de l'editeur est crado sans commentaire, je ne sais plus trop. Le zip avec tout dedans est dispo: ici.

Soyez patient, c'est lent.. a l'époque je faisais tourner le TO9 toute la nuit, voire tout le weekend pour avoir l'image :) Ca n'était même pas le programme le plus lent que je faisait à l'époque dans ce pseudo-gfa.. je faisait aussi beaucoup de mandelbrot/julia animés ou en 3D.. bref toute une époque ou programmer n'était pas encore mon métier, et était donc beaucoup plus FUN.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 07 Sep 2009, 08:50 
Hors ligne

Inscription: 27 Juin 2006, 19:44
Messages: 1061
Localisation: France (24)
Samuel Devulder a écrit:
Une autre possibilité est de mettre le "ON ERROR GOTO 50" juste avant l'instruction qui peut planter et pas en début de code comme dans ton exemple.

Ca ne change pas grand chose, puisque le ONERRORGOTO0 est exécuté seulement hors boucle. Le ONERRORGOTO50 est donc toujours actif, inutile de le réinstaller à chaque fois.

Samuel Devulder a écrit:
On retrouve alors une structure type TRY/CATCH/END qui me plait bien (c'est structuré):
Code:
...
30 FOR DISK=0 TO 3
40 'TRY
41 ON ERROR GOTO 60
50       TMP=DSKF(DISK)
51       ? DISK; " Présent"
52       '... etc
53       '... etc
60 'CATCH
61 IF ERR THEN RESUME 61 ELSE 80
70       ? DISK; " Absent"
71       '... etc
72       '... etc
80 'END
81 ON ERROR GOTO 0
C'est rigolo car le RESUME 61 efface ERR..

Oui, et c'est le seul moyen de l'effacer, cette variable ne pouvant pas être effacée à la main. Mais dans ton programme, les lignes 70 à 72 sont inutiles puisqu'elles ne sont jamais exécutées. De plus, le ELSE 80 ne doit-il pas brancher sur un NEXT (je m'y perds un peu...) ?

Samuel Devulder a écrit:
on aurait pu aussi faire RESUME 70..

A mon avis, on DOIT faire un RESUME 70. Là, les lignes pour le disque absent seraient exécutées :)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 07 Sep 2009, 09:28 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Prehisto a écrit:
Code:
61 IF ERR THEN RESUME 61 ELSE 80
70       ? DISK; " Absent"
71       '... etc
72       '... etc
80 'END
81 ON ERROR GOTO 0
C'est rigolo car le RESUME 61 efface ERR..


Oui, et c'est le seul moyen de l'effacer, cette variable ne pouvant pas être effacée à la main. Mais dans ton programme, les lignes 70 à 72 sont inutiles puisqu'elles ne sont jamais exécutées.

Sisi c'est une fantaisie.. RESUME 61 fait revenir à la même ligne, et comme ERR est remis à 0, on passe à la 70.
Prehisto a écrit:
Samuel Devulder a écrit:
on aurait pu aussi faire RESUME 70..

A mon avis, on DOIT faire un RESUME 70. Là, les lignes pour le disque absent seraient exécutées :)


Oui oui le RESUME 61 c'est un gadget qui complique inutilement les choses. Pour le next oui il manque dans le code. Perso je le mettrais après le "ON ERROR GOTO 0" cad après le "END" du "TRY/CATCH".

Donc rebelotte:
Code:
...
30 FOR DISK=0 TO 3
40 'TRY
41 ON ERROR GOTO 60
50       TMP=DSKF(DISK)
51       ? DISK; " Présent"
52       '... etc
53       '... etc
60 'CATCH
61 IF ERR THEN RESUME 61 ELSE 80
70       ? DISK; " Absent"
71       '... etc
72       '... etc
80 'END
81 ON ERROR GOTO 0
90 NEXT
...


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 07 Sep 2009, 09:34 
Hors ligne

Inscription: 27 Juin 2006, 19:44
Messages: 1061
Localisation: France (24)
Samuel Devulder a écrit:
Sisi c'est une fantaisie.. RESUME 61 fait revenir à la même ligne, et comme ERR est remis à 0, on passe à la 70.

D'après ton code, on passe directement à la ligne 80...


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 07 Sep 2009, 09:39 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Prehisto a écrit:
Samuel Devulder a écrit:
Sisi c'est une fantaisie.. RESUME 61 fait revenir à la même ligne, et comme ERR est remis à 0, on passe à la 70.

D'après ton code, on passe directement à la ligne 80...


:eek: Je comprends pas?

S'il y a une erreur, on fait ligne 61, ERR<>0, donc resume 61, là ERR=0, et on passe en 70...

S'il n'y a pas d'erreur, on fait ligne 61 goto 80 directement.

Donc on passe soit en 70 en cas d'erreur, soit en 80 si pas d'erreur.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 07 Sep 2009, 09:43 
Hors ligne

Inscription: 27 Juin 2006, 19:44
Messages: 1061
Localisation: France (24)
Non.

Si une erreur est détectée :
* Passage dans la ligne 61 : Le RESUME 61 met ERR à 0 et rebranche en début de ligne 61.
* Deuxième passage, donc : ERR est à 0 et le ELSE 80 branche en ligne 80.

Conclusion : les lignes 70 à 72 ne sont jamais exécutées ;)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message:
MessagePosté: 07 Sep 2009, 10:43 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Prehisto a écrit:
Non.

Si une erreur est détectée :
* Passage dans la ligne 61 : Le RESUME 61 met ERR à 0 et rebranche en début de ligne 61.
* Deuxième passage, donc : ERR est à 0 et le ELSE 80 branche en ligne 80.

Conclusion : les lignes 70 à 72 ne sont jamais exécutées ;)


Arghh :L :oops: Punaise :evil: .. effectivement... tu as parfaitement raison. Oui j'ecris des conneries plus grosses que moi ce matin. Grrr voila à quoi ca mène de faire le malin avec les resume 61 au lieu de resume 70. J'aurais mieux fait de tester le code au lieu de jouer au plus fûté!

En plus je me suis rendu compte que l'image du raytracer n'est pas celle que je voulais.... Il faut que je retrouve la bonne version qui affiche un cylindre, une boule-miroir et une lampe.


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 18 messages ]  Aller à la page 1, 2  Suivante

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 44 invités


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages
Vous ne pouvez pas joindre des fichiers

Rechercher:
Aller à:  
cron
Développé par phpBB® Forum Software © phpBB Group
Traduction par phpBB-fr.com