[uBasic] "Nested if" Bug

CHDK-Skripte, CHDK-Entwicklung, PC-Zusatzprogramme, Informationen für Tüftler

Beitragvon gehtnix » 17.09.2009, 12:31

Hi Rudi,

super Arbeit =D>

Mit Susi läuft es wenn ich unter dem Z=10 eine Zeile mit endif einfügen würde. Es darf ja nur 4x endif verschachtelt werden. Habe aber das Z auf 4 gesetzt, reicht allemal.

[EDIT]
Nun habe ich mal zwei alte if-Leichen ( http://doxygen.chdk-treff.de/viewtopic.php?t=529 ) getestet, die Einzeilen-endif´s gelöscht und läuft.
Die geänderten Dateien anbei.
Code: Alles auswählen
@title IF-Fehler
@param x Start um x Uhr
@default x 0
@param y Start um x Minuten
@default y 0
@param t Zyklus-Dauer Std
@default t 0
@param w Zyklus-Dauer Min
@default w 0
@param v Intervalllänge x Min
@default v 4

v=60
w=120
t=t*3600+w

if x>0 or y>0 then
   if t>0 then A=v/2
   print "Das darf nicht"
   print "ausgegeben werden!"
   goto "sprung1"
endif

print "Richtig!"

:sprung1

end



Code: Alles auswählen
@title IF-Fehler

d=120
x=0
y=0
t=0
w=0

v=60

if t<>0 or w<>0 then
   if d>=v*60 and v*60<120 then d=v*60
endif

t=1

if x<>0 or y<>0 then
   if t>0 then A=v/2
   print "Das darf nicht"
   print "ausgegeben werden!"
   if t>0 then B=v/2
   print "A=",A
   print "B=",B
   goto "sprung1"
endif

print "Richtig!"

:sprung1

end



Bei Sevenup ebenso die Einzeilen-endif´s gelöscht, es läuft.
Bei Md-Six die Einzeilen-endif´s gelöscht, es läuft.
[/EDIT]

So weit, so gut.

Fällt er mir doch gerade siedend heiß ein! Wenn das jetzt im Build geändert wird, da werden auf einmal massenweise Skripte zunächst mal nicht mehr funktionieren!
Und bevor wir hier jetzt weiter werkeln, wäre es doch hilfreich wenn Du mal abklärst inwieweit setepontos bereit ist das zu übernehmen.


gruss gehtnix Bild
Bild
Benutzeravatar
gehtnix
CHDK-Legende
CHDK-Legende
 
Beiträge: 2406
Bilder: 8
Registriert: 17.04.2008, 12:42
Wohnort: München
Kamera(s): A610 100e+f + IXUS50 101b

Beitragvon rudi » 17.09.2009, 22:39

Hallo,
erst einmal vielen Dank gehtnix für dein unermüdliches Testen. Das sieht ja gut aus. Bestimmt wird es Probleme mit bestehenden Scripten geben, da einige Codezeilen nur dem kompensieren von Unzulänglichkeiten dienen.
Ungeschickt finde ich die Codewahl mit GOTO-Zielen ausserhalb von IF-ENDIF-Bereiche. Bei GOSUB-Routinen würde man diese auch nicht in Erwegung ziehen. Das fördert in jedem Fall Stack-Probleme, welche zu unerklärlichen Ablauffehler führen können.
Für die Susi schlage ich folgende Anpassung vor:
Code: Alles auswählen
44 if S<>0 then goto "Zeile 55"
       .
       .
55 :Zeile 55
Das sollte doch auch funktionieren? Zumindest müsste man mit Z und ENDIF nicht schon wieder tricksen, da der IF-ENDIF-Bereich aufgelöst werden würde.

@gehtnix, @BigDaddy
Ich habe in meinem letzten Post noch zwei Nachträge eingefügt gehabt.

Gruß Rudi
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 507
Registriert: 11.09.2009, 11:27
Kamera(s): A590IS_101B, SX260_100B

Beitragvon gehtnix » 17.09.2009, 23:12

Hi Rudi,

wenn Du diese alten Fehler beseitigst, stehe ich doch dann ein bisschen in der Pflicht.

rudi hat geschrieben:.....mit GOTO-Zielen ausserhalb von IF-ENDIF-Bereiche.
Da meintest Du wohl "innerhalb"?

Das mit dem Sprung ist bei mir angekommen, OK.

Aber Anhänge bitte immer gleich hier einstellen und die alten löschen, such ich mich doch tot.

gruss gehtnix
Bild
Benutzeravatar
gehtnix
CHDK-Legende
CHDK-Legende
 
Beiträge: 2406
Bilder: 8
Registriert: 17.04.2008, 12:42
Wohnort: München
Kamera(s): A610 100e+f + IXUS50 101b

Beitragvon rudi » 18.09.2009, 07:59

Hallo gehtnix

OK, das mit den Anhängen macht Sinn und ist übersichtlicher - verstanden.
Da meintest Du wohl "innerhalb"?
Möglicherweise können wir uns auf diese Formulierung einigen? Sprungbefehle "innerhalb" von IF-ENDIF-Bereichen, deren Sprungziel "ausserhalb" dieser Bereiche liegt sind potenzielle Fehlerqellen.
Zum Thema passend habe ich mir alle Befehle mit Stack angesehen. Dabei het jeder Befehl seinen eigenen Stacks, die sich nicht gegenseitig beeinflussen.
Bitte keine GOTO "ausserhalb" bei den Befehlen:
Code: Alles auswählen
ohne Stack-Fehlermeldung:
  WHILE - WEND
  DO - UNTIL
  IF - ENDIF (aktuelle Version)

mit Stack-Fehlermeldung:
  :Label - RETURN (GOSUB)
  IF - ENDIF ("rudi" Version)
  FOR - NEXT

Sonderfall mit Stackfehlermeldung:
  SELECT - END_SELECT
     - GOTO/GOSUB-Befehl einzeln in CASE[_ELSE]-Zeile - OK
     - GOTO/GOSUB-Befehl in einzeiligem IF verschachtelt - NICHT OK


Gruß Rudi
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 507
Registriert: 11.09.2009, 11:27
Kamera(s): A590IS_101B, SX260_100B

Beitragvon BigDaddy » 18.09.2009, 10:19

Hi,

sieht sehr gut aus jetzt!

Ich habe noch einmal Dutzende Varianten meiner Testcodes durchgespielt, und alles funktioniert perfekt!

Ich denke also, wir könnten uns allmählich daran machen, die finale und vollständige Definition der "If-Regeln" zu formulieren. Wenn ich das richtig sehe, dann sind die:
    1. Einzeiler immer ohne "endif"
    2. Bei Mehrzeilern: "if..then", "else" (falls vorhanden) und "endif" immer jeweils *alleine* in einer Zeile
    3. Max. Verschachtelungstiefe = 4

Stimmt ihr dem zu?

Ich habe zwei Anmerkungen / Fragen zu den obigen Regeln:

zu 2: Hier ist von den Usern insb. ernst zu nehmen, dass auch "else" alleine stehen muss. Wenn es das nicht tut, gibt es nämlich (im Gegensatz zu wenn "if..then" nicht alleine steht) *keinen* parse error, aber falsch laufenden Code! Beispiel hänge ich ganz unten an diese Message an.

zu 3: Gibt es eigentlich einen tiefen/guten Grund, dass diese Zahl so niedrig ist? Mir ist schon klar, dass die Stacktiefe nicht beliebig groß sein kann. Aber 4 ist doch schon sehr klein. Wäre es nicht zu überlegen, ob man bei dieser Gelegenheit das nicht zumindest auf 10 oder so erweitern sollte?
(Habe übrigens mal geprüft, ob es die selbe Grenze beim "gosub..return" Stack gibt. Dem ist aber nicht so. Habe bis zu einer Verschachtelungstiefe von 6 manuell getestet, und das läuft ohne Probleme. Wenn hier das Stacklimit kein Problem ist, warum dann bei "if"? Oder lässt sich das gar nicht so vergleichen?)
Dies ist aber natürlich nicht soo wichtig...

Noch ein Kommentar/Frage zu folgendem:

Wenn das jetzt im Build geändert wird, da werden auf einmal massenweise Skripte zunächst mal nicht mehr funktionieren!

Das sehe ich eigentlich gar nicht. Ich würde eher folgendes annehmen: Code, der mit der rudi-Version anders läuft als vorher, war schon vorher defekt. Mit "defekt" meine ich hier, dass solcher Code (u.U. natürlich abhängig vom aktuellen Inhalt der benutzten Vergleichsvariablen) in der alten uBasic-Version entweder parse errors oder falsche Verzweigungen erzeugt. Oder sehe ich das verkehrt?


Zum Schluss noch ein anderer kleiner "Fund" (hat jetzt mit dem "if" gar nix zu tun):
Ich habe schon gesehen, dass sich mancher gefragt hat, was denn die Limitierungen der Namensgebung von Labels sind (wie lang sie sein dürfen usw.). War erstaunt, folgendes zu finden:
(a) Es sind auch numerische Zeichen und Underscore erlaubt, also z.B. 'gosub "Switch_ON"' und 'gosub "case1"' usw. Das ist sicher manchmal nützlich, Code lesbarer zu machen.
(b) Labels können sogar rein numerisch sein, d.h. müssen nicht mit einem Buchstaben anfangen, also z.B. 'gosub "123"' ist OK.
(c) Habe bis zu Label-Längen von 40 Zeichen erfolgreich getestet! (Macht den Code wahrsch. nicht gerade schneller.)



Hier das Beispiel, wo "else" nicht alleine steht:
Code: Alles auswählen
size: 256, read: 256
Program:
rem Testing IF constructs
@title TestIF06
a=0
b=0
gosub "tryif"
a=0
b=1
gosub "tryif"
a=1
b=0
gosub "tryif"
a=1
b=1
gosub "tryif"
end

:tryif
print ""
print "case", a, b
if a then
  print "if a"
else print "a else"
endif   
return

=====================================

[]
[case 0 0]
[a else]
[]
[case 0 1]
[a else]
[]
[case 1 0]
[if a]
[a else]
[]
[case 1 1]
[if a]
[a else]
Grüße
BigDaddy
__________________
A620 Firmware v100f
CHDK v0.9.8-794
BigDaddy
CHDK-Einsteiger
CHDK-Einsteiger
 
Beiträge: 32
Registriert: 04.09.2009, 15:05
Wohnort: München

Beitragvon rudi » 18.09.2009, 12:03

Hallo BigDaddy,
sehr schön und du hast gleich noch eine fehlende Fehlerausgabe gefunden, denn die ELSE-Abarbeitung wird an dieser Stelle ordnungsgemäß abgebrochen (nur es sag einem ja keiner). Für den Interpreter steht der PRINT-Befehl auf der nächsten Zeile und wird immer mit abgearbeitet. Das habe ich korregiert und alle Dateien hier angehängt.
Die Stack-Tiefe ist bei GOSUB =10 ansonsten =4. Änderungen lassen sich bestimmt vornehmen.
Laut "tokenizer.c" ist die LABEL-Länge nicht eingeschränkt und es werden alle Zeichen gelesen bis ein Leerzeichen, Tab, CR oder LF kommt.

Gruß Rudi
Dateianhänge
ubasic.zip
DOS-uBasic (Version 18.09.09)
(14.38 KiB) 131-mal heruntergeladen
Zuletzt geändert von rudi am 18.09.2009, 17:52, insgesamt 1-mal geändert.
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 507
Registriert: 11.09.2009, 11:27
Kamera(s): A590IS_101B, SX260_100B

Beitragvon BigDaddy » 18.09.2009, 12:47

Hi rudi,

du bist schnell!

... die ELSE-Abarbeitung wird an dieser Stelle ordnungsgemäß abgebrochen (nur es sag einem ja keiner). ... Das habe ich korregiert und alle Dateien hier angehängt.

OK, super. Jetzt kriegt man eine ordentliche Fehlermeldung!

Die Stack-Tiefe ist bei GOSUB =10 ansonsten =4. Änderungen lassen sich bestimmt vornehmen.

Ich hab' mal in den C-Code reingesehen, den du angehängt hast. Da sehe ich nun, dass diese Rekursionstiefe auf 4 limitiert ist nicht nur beim if sondern auch allen anderen Kontrollbefehlen wie select, while, usw. (*) Macht also eher wenig Sinn, nur bei if was zu ändern. Wenn schon, dann bei allen gleichermaßen.
Bin aber nun total unentschlossen, ob ich so eine Änderung wirklich befürworten sollte. Einerseits stößt man wahrsch. in der Praxis sehr selten an diesem Limit an (aber wer weiß? ...), was eine solch gravierende Änderung nicht rechtfertigt. Andererseits finde ich dieses niedrige Limit recht unverständlich, und ich sehe nicht, was dagegen spräche, es ein wenig anzuheben. (Zumal keinerlei Kompatibiltätsprobleme mit alten Scripts zu erwarten sind in diesem Fall.)
Hmm..., was meinst du?

Laut "tokenizer.c" ist die LABEL-Länge nicht eingeschränkt und es werden alle Zeichen gelesen bis ein Leerzeichen, Tab, CR oder LF kommt.

OK. Aber andererseits habe ich nun im C-Code gesehen, dass die max. Stringlänge auf 40 begrenzt ist. (*) Das führt dazu, dass Labels, deren Namen sich ersr nach der 40. Stelle unterscheiden, als identisch behandelt werden. (Lustig, dass ich gestern zufällig nur bis genau 40 getestet hatte.) Also praktisch bedeutet das, dass max. 40 Zeichen sinnvoll sind.

(*) Solche Infos gehören später mal ins uBasic-Manual.
Grüße
BigDaddy
__________________
A620 Firmware v100f
CHDK v0.9.8-794
BigDaddy
CHDK-Einsteiger
CHDK-Einsteiger
 
Beiträge: 32
Registriert: 04.09.2009, 15:05
Wohnort: München

Beitragvon gehtnix » 18.09.2009, 13:51

Hi,

mei Liaba, jetzt geht´s aber rund.

Habe von Alldem noch gar nix gelesen, habe aber was Neues aufgetan.

Da kam ja gestern S2user mit einer Abwandlung und einem ganz anderen Thema daher. Habe mir mal das Original besorgt .

Das hier:
Code: Alles auswählen
if a <=5 then gosub "ch1up" else if a <=9 then gosub "ch1mid" else if a <=13 then gosub "ch1down" else if a <=17 then gosub "ch2up" else if a <=21 then gosub "ch2mid" else if a <=25 then gosub "ch2down" else print "error" endif

Das ist eine Zeile aus einem Script was zur Zeit "läuft". Wohl deshalb weil bisher Keiner einen Error gehabt hat.

So, habe das abgewandelt, mit rechtsklick hangelt man sich jetzt in der Kamera nach oben und das wird schön brav ausgeführt, bis zum letzten "print error". Dann kommt der berühmte Pars err mit Angabe der Zeile unter dem If.
Verringerung der "Else if" lassen den "Pars err" nicht Verschwinden.
Löscht man jedoch das Endif geht die ganze Zeile mit 6x "else if", mit CHDK und Rudi´s Version.

Die a-Werte habe ich gegenüber dem Original angepasst.

gruß gehtnix
Dateianhänge
If-Band1.bas
(849 Bytes) 142-mal heruntergeladen
Bild
Benutzeravatar
gehtnix
CHDK-Legende
CHDK-Legende
 
Beiträge: 2406
Bilder: 8
Registriert: 17.04.2008, 12:42
Wohnort: München
Kamera(s): A610 100e+f + IXUS50 101b

Beitragvon rudi » 18.09.2009, 14:20

Hallo gehtnix,

das ist ja wirklich eine tolle Konstruktion.
Sie funktioniert solange kein Zeilenumbruch im Script ist, denn dann wird alles als einzeilige IF-Anweisung ausgewertet. Dabei wird der Stack nicht benutzt, da nach dem THEN jeweils das Ergebnis des zuvor berechneten Ausdrucks schon nicht mehr benötigt wird. Aus diesem Grund ist auch das ENDIF nicht zulässig.

Gruß Rudi
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 507
Registriert: 11.09.2009, 11:27
Kamera(s): A590IS_101B, SX260_100B

Beitragvon gehtnix » 18.09.2009, 15:15

Hi Rudi,

mit CHDK läuft das durch, also alle werden nacheinander ausgegeben, samt print error.
Code: Alles auswählen
if a <=5 then gosub "ch1up"
      else if a <=9 then gosub "ch1mid"
      else if a <=13 then gosub "ch1down"
      else if a <=17 then gosub "ch2up"
      else if a <=21 then gosub "ch2mid"
      else if a <=25 then gosub "ch2down"
      else print "error"
   endif


Mit Deiner Version Fehler 23 Pars err auch wenn man so
Code: Alles auswählen
   if a <=5 then gosub "ch1up"
      else if a <=9 then gosub "ch1mid"
      else if a <=13 then gosub "ch1down"
      else print "error"
   endif
reduziert.

gruß gehtnix
Bild
Benutzeravatar
gehtnix
CHDK-Legende
CHDK-Legende
 
Beiträge: 2406
Bilder: 8
Registriert: 17.04.2008, 12:42
Wohnort: München
Kamera(s): A610 100e+f + IXUS50 101b

Beitragvon BigDaddy » 18.09.2009, 15:45

Hi gehtnix,

ist klar, weil Verstoss gegen "Regel 2" (siehe weiter oben im Thread).

Andere Frage: sind solche schrecklichen "else if" Konstrukte in der freien Wildbahn häufig? (Falls ja, dann wäre das mit der Kompatibilität vielleicht doch etwas problematischer als ich dachte.)
Das gegebene Beispiel wäre aber eigentlich das Paradebeispiel dafür, wann man ohnehin "select" benutzen sollte, oder?
Grüße
BigDaddy
__________________
A620 Firmware v100f
CHDK v0.9.8-794
BigDaddy
CHDK-Einsteiger
CHDK-Einsteiger
 
Beiträge: 32
Registriert: 04.09.2009, 15:05
Wohnort: München

Beitragvon rudi » 18.09.2009, 16:47

Hallo gehtnix,
jetzt war BigDaddy schneller, aber grundsätzlich mit gleicher Meinung.
Zu deinen letzten Versuchen möchte ich folgendes bemerken:
Auch die aktuelle IF-Version erkennt am Zeilenende nach dem THEN, ob es sich um einzeiligen oder mehrzeiligen Code handelt und benutzt den Stack oder nicht. Daher kann beim ELSE auf der nächsten Zeile kein Ausdrucksergebnis vom Stack geholt werden. Das Script läuft zwar durch, bei mir aber mit falschen Ergebnissen (siehe Anhang).
Ich würde dann auch lieber SELECT einsetzen. [EDIT] Ich habe gerade gesehen, dass du das auch so machst (siehe S2user). [/EDIT]

Gruß Rudi
Dateianhänge
if-band1.3.txt
Debuggerausgabe
(1.22 KiB) 131-mal heruntergeladen
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 507
Registriert: 11.09.2009, 11:27
Kamera(s): A590IS_101B, SX260_100B

Beitragvon gehtnix » 18.09.2009, 17:13

Hi BigDaddy,

was da so in freier Wildbahn rum geifft wurde, da habe ich wirklich keine Ahnung. Diesen Bandwurm habe ich ja auch erst gestern entdeckt.

Ich schaue mir auch nicht jedes Skript an. Was da bei seteponots so alles stehen könnte, so habe ich auch hier keine Ahnung.

Was die CHDK-User alles selber gemacht haben aber nicht hochgeladen haben? I don´t know!

Deshalb ja mein Gedanke, dass erst einmal mit setepontos abzuklären ob das übernommen wird. DanielF, der das Draft schrieb, der hat ja auch noch uBasic-Fehler im Bugtracker gemeldet.

Mal ein anderer Vorschlag. Wie wäre es wenn Du den Titel mit "nested-if" auf einen generellen Titel zu dem If-Thema (IF-Regeln) abänderst und die neuen If-Regeln dann oben in Deinem ersten Fred einträgst. Der Rest, inzwischen eh überflüssig (?), nach unten verschiebst oder ganz löscht.
Ich würde dann im uBasic-Archiv einen Link dahin setzen. Ist aber erst vonnöten wenn Rudi´s Änderungen angenommen werden.

@Rudi,
Mit Select, ist schon klar, habe ich ja gestern auch bei S2user ohnehin gemacht als ich dieses Konstrukt sah.
Und klar doch sind die Ergebnisse "falsch" werden aber durch den Aufbau der Abfrage richtig "falsch" ausgegeben.

gruß gehtnix
Bild
Benutzeravatar
gehtnix
CHDK-Legende
CHDK-Legende
 
Beiträge: 2406
Bilder: 8
Registriert: 17.04.2008, 12:42
Wohnort: München
Kamera(s): A610 100e+f + IXUS50 101b

Beitragvon rudi » 18.09.2009, 17:57

Hallo,
ich bitte um Entschuldigung. Die heute Mittag angehängten Dateien mit der falschen uBacic.c versehen.

Habe ich geändert.

Gruß Rudi
Dateianhänge
a610-100e-0.9.8-801.rudi.zip
A610-100E_801_rudi
(415.83 KiB) 131-mal heruntergeladen
a620-100f-0.9.8-801.rudi.zip
A620-100F_801_rudi
(415.82 KiB) 127-mal heruntergeladen
ubasic.c
Änderung: IF-Anweisung überarbeitet (18.09.09)
(64.86 KiB) 135-mal heruntergeladen
Benutzeravatar
rudi
CHDK-Spezialist
CHDK-Spezialist
 
Beiträge: 507
Registriert: 11.09.2009, 11:27
Kamera(s): A590IS_101B, SX260_100B

Beitragvon BigDaddy » 18.09.2009, 18:00

Hi gehtnix,

Ich schaue mir auch nicht jedes Skript an.

Ist schon klar. Ich wollte auch keine "sichere Aussage" von dir, sondern nur ein Bauchgefühl, weil ich dachte, dass du als alter Script-Freak das am ehesten einschätzen könntest.

Deshalb ja mein Gedanke, dass erst einmal mit setepontos abzuklären ob das übernommen wird.

Ich vermute, je "fertiger" das angeboten werden kann, umso besser sind die Chancen dafür.

DanielF, der das Draft schrieb, der hat ja auch noch uBasic-Fehler im Bugtracker gemeldet.

Ja, weiß ich. Die meisten würde ich allerdings eher nicht als Bugs sondern als Feature-Wünsche ansehen. Er hat ja auch quasi einen "Alternativvorschlag" zum Fixen des IF da drin, nämlich die Erweiterung auf mehrere Kommandos in einer Zeile. Sofern das wirklich als Alternative betrachtet würde, fände ich das klar als nur zweitbeste (bzw. gar keine) Lösung. Von daher sollte man wahrsch. nicht zu lange warten, den Vorschlag von Rudi einzureichen.

Wie wäre es wenn Du den Titel mit "nested-if" auf einen generellen Titel zu dem If-Thema

Ja klar, habe ich natürlich nichts dagegen. (Aber vielleicht ist es im Moment noch ein paar Tage zu früh, weil es gerade noch etwas im Fluss ist.)
Aber unabhängig davon würde ich es besser finden, wenn das jemand anderer machen würde, denn
1. will ich beim Umbenennen/Verschieben/Löschen usw. keinen dummen techn. Fehler machen, und
2. sollte Rudi die Formulierung der "Regeln" übernehmen. Es ist ja schlie0lich sein Baby hier, und er weiß das auch am allerbesten.
Grüße
BigDaddy
__________________
A620 Firmware v100f
CHDK v0.9.8-794
BigDaddy
CHDK-Einsteiger
CHDK-Einsteiger
 
Beiträge: 32
Registriert: 04.09.2009, 15:05
Wohnort: München

VorherigeNächste

Zurück zu Code-Ecke

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast