so hatte gestern keine Zeit mehr, es zu testen.
Zum ersten Punkt: Ja es ist ein Bug. Normalerweise macht der Interpreter bei jeder Operation die richtige Typenumwandung. Ich hab sie nur bei der Rückgabe einer Funktion vergessen. Im ersten Beispiel interpretiert der Compiler '3.14' als Double, und speichert ihn so dann in den Bytecode. Deswegen ist dann in 'value\double' der richtige Wert. Im zweiten ist '3' ein Byte, also wäre 'value\byte' das richtige ('value\integer' funktioniert auch, da das erste byte ja 3 ist). Im letzten ist es eine Operation mit mindestens einem Double, daher auch hier 'value\double' richtig. Wird zur neuen Version gefixed.
Zum zweiten Punkt: Hm, naja, erstmal ist es eine Scriptsprache. Scriptsprachen sollte man nicht für zeitaufwändige Operationen benutzen. Das erste Problem ist, dass ich einen Funktionaufruf vorbereiten muss, also speichern, wie viele lokale Variablen es z.z. gibt, damit ich das am ende wiederherstellen kann (ähnlich dem Stack in ASM). Am Ende muss ich halt alle lokalen Variablen freigeben, und, wie gesagt, den Kontext wiederherstellen. Dieser Overhead wird es leider immer geben.
Das zweite Problem ist, dass der Interpreter nicht sooo, bzw. garnicht, optimiert ist (das könnte man noch verbessern). Also wenn er diese Zeile ausführen will, passiert folgendes:
- Zeile ausführen (Funktionsaufruf)
- Zeile ist 'ProcedureReturn'. Diese Zeile braucht einen Ausdruck (Funktionsaufruf)
- Ausdruck ist eine Konstante. Welchen Typ hat Konstante? (Funktionsaufruf) Welchen Wert hat Konstante? (Funktionsaufruf)
Somit gibt es in meinem Interpreter 4 Funktionsaufrufe, um diese Zeile ausführen zu können. Wie gesagt, daran könnte man noch arbeiten, z.b. dass der Code komplett in einer Funktion abläuft. Ob das so einfach geht, werde ich dann mal sehen.
btw.: Der Compiler optimiert schon soweit, dass er es direkt als Konstante '30' speichert.
Es hat mich aber schon überrascht, dass es sooo langsam ist. Allerdings sagen meine Messungen 300-500mal langsamer (nicht 5000). Was es auch nochmal ein wenig schneller macht, ist, nicht PBSCallProcedure() zu verwenden, sondern PBSStartScriptCode():
Code: Alles auswählen
*ByteCode = PBSCompileScriptString("Procedure.i Test() : ProcedureReturn 10+20 : EndProcedure : Test()")
S = PBSOpenByteMemory(#PB_Any, *ByteCode)
Time = ElapsedMilliseconds()
For n = 1 To #Size1
PBSStartByteCode(S)
Next
So und da ich grad schon so schön schreibe, kann ich ja noch ein kleinen Ausblick geben, was es in der nächsten Version gibt. Daran arbeite ich nämlich fleißig schon seit ein paar Wochen. Es geht nämlich um die größte Neuheit bei PB seit Jahren und auch jetzt bei PBS, nämlich Arrays und Listen in Structuren. Und ich kann sagen, das is echt ne s*** Arbeit. Komplettes rewrite beim Compilieren und Interpretieren von Variablen.
Naja da funktioniert auch schon einiges, kann aber noch ein bisschen dauern
lg kevin