Main Menu

Recent posts

#41
Deutsches Board (IT-Themen) / Re: Der Neue
Last post by Norbert Spoerl - September 23, 2025, 08:51:14 PM
Hi Peter,
vorab, mit PROFAN habe ich vor vielen Jahren auch gearbeitet.
Noch einmal zur INFO. Der Befehls- und Funktionsumfang von PBWin 10 wird durch JKBasic fast zu 100 % umgesetzt werden, nur bei den DDT bezogenen Funktionen bin ich mir nicht sicher, bzw. wird wohl noch etwas dauern. D.h., Du kannst die Handbücher von PB für JKBasic weiter benutzen. Vermutlich wird es später Ergänzungen zum Sprachumfang von PB PBWin 10 geben. Damit wird PB in gewisser Wiese weiterleben und sich weiter entwickeln. Die letzten Versionen von PB erzeugen 32 bit Code. JKBasic kann wahlweise 32 oder 64 bit Code erzeugen. Das mit den 32 bit wird in einigen Jahren aussterben, so wie es zuvor den 16 bit Abwendungen erging. Mit einem XP-PC kommst Du allerdings nicht weit. JKBasic wird vermutlich nicht darauf laufen.
Gruß
Norbert
#42
Deutsches Board (IT-Themen) / Re: Der Neue
Last post by Peter Salomon - September 23, 2025, 10:40:56 AM
Leider wird der Link zu der PDF-Datei "Auszug aus der PBWin10-Referenz" nicht abgebildet - warum?
Meine anderen Links gehen doch auch!

Grüsse aus Ahrensfelde

Peter Salomon
www.ps-blnkd.de
#43
Deutsches Board (IT-Themen) / Re: Der Neue
Last post by Peter Salomon - September 23, 2025, 10:19:29 AM
@Theo <#13>
Ja, so wird es sein, mein XP kann Unicode nicht lesen. Auf'm Handy gehts auch nicht, weil das Teil zu alt ist und es keine Updates dafür mehr gibt ... nur auf dem Linux-PC geht es, aber den nehme ich nur selten, weil der Startvorgang immer eine Ewigkeit dauert.
Bei mir gibt es nur ein "Insert Image", wo auch eine URL angegeben werden muß, wo das Bild liegt. Also kann ich auch gleich ein Link auf meine HP einfügen ...
Sei's drum - irgendwie weiß man sich immer zu helfen.

@Norbert <#16>
1985 bin ich zwar noch nicht beim Programmieren gewesen, aber schwerpunktmäßig in der HW-Entwicklung. Kannst Du alles nachlesen auf meiner HP -> www.ps-blnkd.de.
Meine Programmierversuche sind in -> http://www.ps-blnkd.de/AutoIt.htm ausführlich dokumentiert. Noch nicht enthalten ist der Weg zu PowerBASIC.
Daß diese - aus meiner Sicht - geniale IDE nun plötzlich nicht mehr seitens des Herstellers unterstützt wird, ist zwar sehr ärgerlich, ändert aber nichts an der Tatsache des Bestehens der SW.
Je länger ich mich damit beschäftige, umso mehr bin ich der Überzeugung: das isses!
Sicherlich gibt es, oder soll es demnächst, bald oder wann auch immer irgendwelche Alternativen dazu geben. Aber bei über 30 Jahren Entwicklung, dabei gesammelten Erfahrungen, die immer wieder in neuen Versionen Eingang fanden, so daß in der 10er Version nun über 1200 Befehle auf über 2000 Seiten Doku ausführlichst beschrieben (die Referenzdatei hat "nur" ~700 Seiten) zur Verfügung stehen. Dabei ist die Compiler-Größe mit 1,5 + 0,8MB extrem klein und läuft auf jedem Windows-PC - naja, vielleicht nicht mehr auf den ganz alten (Win3.1) und möglicherweise auf den "neuzeitlichen" 10er und 11ern vielleicht auch nicht, weil deren überzogene "Sicherheitsbarieren" das verhindern.
Das soll erstmal jemand nachmachen!
Zum Überblick über die Leistungsfähigkeit von PBWin10 hier mal ein Auszug aus der (in Arbeit befindlichen) deutschen Version der diesbezüglichen Referenzdatei -> .
Die roten xxx-Seitenangaben sind die, die noch nicht bearbeitet sind.
Gedacht ist das für diejenigen, die vielleicht schon mal was von PowerBASIC gehört haben, aber "mainstream"-mäßig ablehnend dem gegenüberstehen.

@Theo
Du hattest mal was von PBWin11 geschrieben - hast Du diese wirklich letzte Version? - Welche Unterschiede/Ergänzungen gibt es dort? 
Hattest Du damals noch Kontakt zu Kirschbaum-Software - was gehörte alles zu deren Lieferumfang?

So viel für heute ...

Grüsse aus Ahrensfelde

Peter Salomon
www.ps-blnkd.de
#44
Deutsches Board (IT-Themen) / Re: Der Neue
Last post by Norbert Spoerl - September 22, 2025, 07:39:02 PM
Hi Theo,

nur zur Info, ich programmiere seit 1985, im Laufe der Zeit mit unterschiedlichen Sprachen, und kenne auch alle Deine aufgeführten Punkte zum Syntaxcheck. Okay, das mit den Syntaxdiagrammen kannte ich so noch nicht. Im Falle von JKBasic wird erst die Syntax geprüft, das Compilieren erfolgt danach. Von daher kann man annehmen, dass  der Check übersprungen werden könnte. Oder es geht aus irgendwelchen Gründen eben nicht.
Du hast doch von extrem großen Projekten und der Compilerzeit im Beitrag gesprochen.
>>>
𝑀𝑒𝑖𝑛 𝐶𝑜𝑑𝑒 𝑤𝑖𝑟𝑑 𝑚𝑖𝑡 𝑃𝑜𝑤𝑒𝑟𝐵𝑎𝑠𝑖𝑐 10 𝑣𝑜𝑛 𝑇𝑜𝑚 𝑖𝑛 ü𝑏𝑒𝑟 120 𝑆𝑒𝑘𝑢𝑛𝑑𝑒𝑛 𝑘𝑜𝑚𝑝𝑖𝑙𝑖𝑒𝑟𝑡 – 𝑑𝑎𝑠 𝑖𝑠𝑡 𝑠𝑐𝘩𝑜𝑛 𝑒𝑖𝑛𝑒 𝐿𝑒𝑖𝑠𝑡𝑢𝑛𝑔! 𝑀𝑎𝑙 𝑠𝑒𝘩𝑒𝑛, 𝑜𝑏 𝑎𝑛𝑑𝑒𝑟𝑒 𝑃𝑟𝑜𝑔𝑟𝑎𝑚𝑚𝑒 𝑑𝑎 𝑚𝑖𝑡𝘩𝑎𝑙𝑡𝑒𝑛 𝑘ö𝑛𝑛𝑒𝑛, 𝑑𝑒𝑛𝑛 𝑚𝑒𝑖𝑛 𝑃𝑟𝑜𝑗𝑒𝑘𝑡 𝑖𝑠𝑡 𝑤𝑖𝑟𝑘𝑙𝑖𝑐𝘩 𝑠𝑒𝘩𝑟 𝑘𝑜𝑚𝑝𝑙𝑒𝑥.
<<<
Da finde ich meine Überlegung nicht unlogisch. Und ich habe in meinem letzten Beitrag einen Fall genannt, wo ein Syntaxcheck nicht zwingend erforderlich ist. Eine solche  Option setzt natürlich ein verantwortliches Handeln des Programmierers voraus.
Aber egal, wir müssen nicht länger darüber reden - ist eh nur theoretischer Natur.

Ansonsten freue ich mich jetzt schon auf die Reaktionen der PB-Gemeinde, wenn JKBasic allgemein zugänglich sein wird. Problematisch sehe ich die Deaktivierung des amerikanischen PB-Forums. Nur aus diesem Grund wird noch einmal eine nicht geringe Anzahl an PB-Usern eine Alternative suchen und PB den Rücken kehren. Ob sie dann nach Start JKBasic zurück kommen, ist fraglich. Das war auch die Intension für meinen 1. Beitrag in diesem Thread.

LG
Norbert   


#45
Deutsches Board (IT-Themen) / Re: Der Neue
Last post by Theo Gottwald - September 21, 2025, 06:11:44 PM
Warum Compiler eine Syntaxprüfung brauchen

Liebe Norbert,
das Problem ist grundlegend: Ohne Syntaxprüfung würde der Compiler selbst instabil werden. Hier die Gründe:
1. Vermeidung von Systemabstürzen

     Wenn du die Syntaxprüfung abschaltest, erzeugt der Compiler ungeprüften Code – ein "logisches Wirrwarr". 
     Beispiel: Fehlende Klammern oder falsche Befehlsstrukturen führen zu unvorhersehbarem Maschinencode. 
     Folge: Der Compiler verarbeitet inkonsistente Daten → Absturz des gesamten Systems (z. B. Segmentation Fault, Speicherlecks).
     

2. Undefinierte Zustände verhindern

     Code ohne syntaktische Korrektheit bringt den Compiler in undefinierte Zustände. 
     Der Compiler weiß nicht, wie er den Code übersetzen soll → willkürliche Fehlverhalten (z. B. Endlosschleifen im Parser). 
     Ziel: Sicherstellen, dass der Compiler vorhersagbar und stabil läuft – nicht willkürlich.
     

3. Keine Alternative zur Korrektheit

     Es gibt keinen "Workaround": Entweder Code ist syntaktisch korrekt → er funktioniert. 
     Oder er ist fehlerhaft → er muss abgelehnt werden. 
     Kompromisse (z. B. "fehlerhaft aber trotzdem kompilieren") gefährden die Integrität des Compilers.
     

4. Syntaxprüfung ≠ "Schikane" für Nutzer

     Die Prüfung dient nicht primär, um Nutzer zu ärgern oder zu schützen. 
     Ihr Hauptzweck: Den Compiler vor sich selbst zu schützen. 
     Ein stabiler Compiler ist die Voraussetzung dafür, dass überhaupt zuverlässiger Code erzeugt werden kann.
     
Zusammenfassung in einem Satz
    Syntaxprüfung ist der "Notaus-Schalter" des Compilers: Sie verhindert, dass fehlerhafter Code den Compiler selbst zum Absturz bringt – denn ein instabiler Compiler nutzt niemandem.
     
Beim SPR zum Beispiel ist die Syntaxprüfung nicht getrennt von der Speed-Code Generierung.
Im Idealfall ist es so, dass bei der Code-Generierung eben unerwartete Zeichen auftreten und dann wird eine FM generiert.
Es gibt eigentlich - im Idelafall - keine separate Syyntax-Prüfung, die man abschalten könnte um das schneller zu machen.
#46
Deutsches Board (IT-Themen) / Re: Der Neue
Last post by Norbert Spoerl - September 21, 2025, 09:46:41 AM
Hi Theo,

>>>
Sollte Jürgen jedoch tatsächlich ein neues, PowerBASIC-kompatibles System mit verbesserten Makros und neuen Datentypen schaffen – Bereiche, in denen er ohnehin stark ist, wie beim Debugging –, dann wäre die Performancefrage zunächst zweitrangig.
<<<
Es geht erst einmal um die möglichst 1:1 Umsetzung des Sprachumfangs von PB. Verbesserte Datentypen, etc. könne nur in einem 2. Entwicklungsschritt erfolgen. Bzgl. Performancefrage gebe ich Dir Recht, wobei der compilierte Code sicherlich sehr schnell sein wird, da ja ein Assembler-Compiler verwendet wird. Bei meinem Gedanken mit der optionalen Abschaltung des Syntax-Checks dachte ich an Fälle wie z.B. Änderungen im eigenen Quellcode, die nur auf die Layout-Gestaltung abzielen. Wenn ich Objekte platziere und nach Zahlenänderungen der Pixelkoordinaten schnell das Ergebnis sehen will, muß ich nicht unbedingt einen Syntaxcheck durchlaufen. 
#47
Low Level Code Optimization PB 10 / UNICODE-ASM Replacements
Last post by Theo Gottwald - September 20, 2025, 09:46:47 PM
I tried
Chat_GLM
today so here are some results. The times you have to code thes by hand are over.

However all untested. So you may need to test it first.

UTF-16 to UTF-8
'######################################################################################################################
'######################################################################################################################
' ===============================================================================
' SUB: ASM_UTF16ToUTF8
' PURPOSE: Convert UTF-16 string to UTF-8 with full special case handling
' PARAMS:
'   U01 (STRING In/Out, BYREF) - String to convert (UTF-16 encoded)
' NOTES:
'   - Handles surrogate pairs for characters beyond BMP
'   - Properly validates UTF-16 sequences
'   - Uses assembly for maximum performance
'   - In-place conversion with minimal memory overhead
'   - Handles all Unicode code points (U+0000 to U+10FFFF)
' ===============================================================================
    ' UTF-16 constants
    %HIGH_SURROGATE_START = &HD800
    %HIGH_SURROGATE_END = &HDBFF
    %LOW_SURROGATE_START = &HDC00
    %LOW_SURROGATE_END = &HDFFF
    %UNICODE_MAX_BMP = &HFFFF
    %UNICODE_MAX = &H10FFFF
    %REPLACEMENT_CHAR = &HFFFD

    ' UTF-8 bit patterns
    %UTF8_1BYTE = &H00      ' 0xxxxxxx
    %UTF8_2BYTE = &HC0      ' 110xxxxx
    %UTF8_3BYTE = &HE0      ' 1110xxxx
    %UTF8_4BYTE = &HF0      ' 11110xxx
    %UTF8_CONT = &H80       ' 10xxxxxx
SUB ASM_UTF16ToUTF8(BYREF U01 AS STRING)
    #REGISTER NONE

    LOCAL T01 AS LONG        ' UTF-16 length (in bytes)
    LOCAL T02 AS LONG        ' UTF-8 length
    LOCAL T03 AS DWORD PTR   ' UTF-16 pointer
    LOCAL T04 AS DWORD PTR   ' UTF-8 pointer
    LOCAL T05 AS LONG        ' Current position
    LOCAL T06 AS WORD        ' Current UTF-16 char
    LOCAL T07 AS WORD        ' Next UTF-16 char
    LOCAL T08 AS DWORD       ' Combined code point
    LOCAL T09 AS DWORD       ' Temp for bit manipulation
    LOCAL S01 AS STRING      ' Result string

    ' Get UTF-16 length (must be even)
    T01 = LEN(U01)
    IF T01 = 0 THEN
        EXIT SUB
    END IF

    ' Check for odd length (invalid UTF-16)
    IF (T01 AND 1) THEN
        T01 = T01 - 1  ' Ignore last byte
        IF T01 = 0 THEN
            U01 = ""
            EXIT SUB
        END IF
    END IF

    ' Calculate maximum UTF-8 length (worst case: 4 bytes per UTF-16 char)
    T02 = T01 \ 2 * 4

    ' Create result buffer
    S01 = STRING$(T02, 0)

    ' Get pointers
    T03 = STRPTR(U01)
    T04 = STRPTR(S01)

    ' Initialize UTF-8 length counter
    T05 = 0

    ' Inline assembly for conversion
    ! push esi
    ! push edi
    ! push ebx
    ! mov esi, T03          ; UTF-16 pointer
    ! mov edi, T04          ; UTF-8 pointer
    ! mov ecx, T01          ; UTF-16 length in bytes

Lab_ConvertLoop:
    ! cmp ecx, 2            ; Need at least 2 bytes
    ! jb Lab_Done           ; Done if less

    ' Get current UTF-16 character
    ! mov ax, [esi]         ; Get 16-bit UTF-16 char
    ! mov T06, ax           ; Store in variable

    ' Check for high surrogate
    ! cmp ax, %HIGH_SURROGATE_START
    ! jb Lab_NormalChar     ; Below high surrogate range
    ! cmp ax, %HIGH_SURROGATE_END
    ! ja Lab_NormalChar     ; Above high surrogate range

    ' It's a high surrogate - check for low surrogate
    ! cmp ecx, 4            ; Need at least 4 bytes for surrogate pair
    ! jb Lab_InvalidSurrogate

    ' Get next character
    ! mov bx, [esi+2]       ; Get next 16-bit char
    ! mov T07, bx           ; Store in variable

    ' Check if it's a low surrogate
    ! cmp bx, %LOW_SURROGATE_START
    ! jb Lab_InvalidSurrogate
    ! cmp bx, %LOW_SURROGATE_END
    ! ja Lab_InvalidSurrogate

    ' Valid surrogate pair - combine to 32-bit code point
    ! movzx eax, ax         ; Zero-extend high surrogate
    ! sub eax, %HIGH_SURROGATE_START
    ! shl eax, 10           ; Shift left 10 bits
    ! movzx ebx, bx         ; Zero-extend low surrogate
    ! sub ebx, %LOW_SURROGATE_START
    ! or eax, ebx           ; Combine
    ! add eax, &H10000      ; Add base for surrogate pairs
    ! mov T08, eax          ; Store combined code point

    ' Advance past surrogate pair
    ! add esi, 4            ; Skip 4 bytes
    ! sub ecx, 4            ; Decrease counter
    ! jmp Lab_Encode4Byte   ; Encode as 4-byte UTF-8

Lab_NormalChar:
    ' Normal BMP character
    ! movzx eax, ax         ; Zero-extend to 32-bit
    ! mov T08, eax          ; Store as code point

    ' Advance past character
    ! add esi, 2            ; Skip 2 bytes
    ! sub ecx, 2            ; Decrease counter

    ' Determine UTF-8 encoding length
    ! cmp eax, &H7F         ; 0-127: 1 byte
    ! ja Lab_Check2Byte
    ! jmp Lab_Encode1Byte

Lab_Check2Byte:
    ! cmp eax, &H7FF        ; 128-2047: 2 bytes
    ! ja Lab_Check3Byte
    ! jmp Lab_Encode2Byte

Lab_Check3Byte:
    ! cmp eax, %UNICODE_MAX_BMP  ; 2048-65535: 3 bytes
    ! ja Lab_InvalidCodePoint
    ! jmp Lab_Encode3Byte

Lab_InvalidSurrogate:
    ' Invalid surrogate sequence - use replacement character
    ! mov eax, %REPLACEMENT_CHAR
    ! mov T08, eax
    ! add esi, 2            ; Skip 2 bytes
    ! sub ecx, 2            ; Decrease counter
    ! jmp Lab_Encode3Byte    ; Encode as 3-byte UTF-8

Lab_InvalidCodePoint:
    ' Invalid code point - use replacement character
    ! mov eax, %REPLACEMENT_CHAR
    ! mov T08, eax
    ! jmp Lab_Encode3Byte    ; Encode as 3-byte UTF-8

Lab_Encode1Byte:
    ' 1-byte UTF-8: 0xxxxxxx
    ! mov al, T08           ; Get code point
    ! mov [edi], al         ; Store directly
    ! inc edi               ; Advance output pointer
    ! inc T05               ; Increase count
    ! jmp Lab_ConvertLoop   ; Continue

Lab_Encode2Byte:
    ' 2-byte UTF-8: 110xxxxx 10xxxxxx
    ! mov eax, T08          ; Get code point
    ! mov ebx, eax          ; Copy to EBX
    ! shr eax, 6            ; Shift right 6 bits (get top 5 bits)
    ! or al, %UTF8_2BYTE    ; Add 2-byte prefix
    ! mov [edi], al         ; Store first byte
    ! mov al, bl            ; Get original value
    ! and al, &H3F          ; Mask to 6 bits
    ! or al, %UTF8_CONT     ; Add continuation byte prefix
    ! mov [edi+1], al       ; Store second byte
    ! add edi, 2            ; Advance 2 bytes
    ! add T05, 2            ; Increase count by 2
    ! jmp Lab_ConvertLoop   ; Continue

Lab_Encode3Byte:
    ' 3-byte UTF-8: 1110xxxx 10xxxxxx 10xxxxxx
    ! mov eax, T08          ; Get code point
    ! mov ebx, eax          ; Copy to EBX
    ! shr eax, 12           ; Shift right 12 bits (get top 4 bits)
    ! or al, %UTF8_3BYTE    ; Add 3-byte prefix
    ! mov [edi], al         ; Store first byte
    ! mov eax, ebx          ; Get original value
    ! shr eax, 6            ; Shift right 6 bits
    ! and al, &H3F          ; Mask to 6 bits
    ! or al, %UTF8_CONT     ; Add continuation byte prefix
    ! mov [edi+1], al       ; Store second byte
    ! mov al, bl            ; Get original value
    ! and al, &H3F          ; Mask to 6 bits
    ! or al, %UTF8_CONT     ; Add continuation byte prefix
    ! mov [edi+2], al       ; Store third byte
    ! add edi, 3            ; Advance 3 bytes
    ! add T05, 3            ; Increase count by 3
    ! jmp Lab_ConvertLoop   ; Continue

Lab_Encode4Byte:
    ' 4-byte UTF-8: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    ! mov eax, T08          ; Get code point
    ! mov ebx, eax          ; Copy to EBX
    ! shr eax, 18           ; Shift right 18 bits (get top 3 bits)
    ! or al, %UTF8_4BYTE    ; Add 4-byte prefix
    ! mov [edi], al         ; Store first byte
    ! mov eax, ebx          ; Get original value
    ! shr eax, 12           ; Shift right 12 bits
    ! and al, &H3F          ; Mask to 6 bits
    ! or al, %UTF8_CONT     ; Add continuation byte prefix
    ! mov [edi+1], al       ; Store second byte
    ! mov eax, ebx          ; Get original value
    ! shr eax, 6            ; Shift right 6 bits
    ! and al, &H3F          ; Mask to 6 bits
    ! or al, %UTF8_CONT     ; Add continuation byte prefix
    ! mov [edi+2], al       ; Store third byte
    ! mov al, bl            ; Get original value
    ! and al, &H3F          ; Mask to 6 bits
    ! or al, %UTF8_CONT     ; Add continuation byte prefix
    ! mov [edi+3], al       ; Store fourth byte
    ! add edi, 4            ; Advance 4 bytes
    ! add T05, 4            ; Increase count by 4
    ! jmp Lab_ConvertLoop   ; Continue

Lab_Done:
    ! pop ebx
    ! pop edi
    ! pop esi

    ' Update the string with the converted content
    IF T05 > 0 THEN
        U01 = LEFT$(S01, T05)
    ELSE
        U01 = ""
    END IF
END SUB                                           


Unicode to ANSI
' ===============================================================================
' SUB: ASM_UnicodeToAnsi
' PURPOSE: Convert Unicode string to ANSI with full special case handling
' PARAMS:
'   U01 (STRING In/Out, BYREF) - String to convert (UTF-16 encoded)
' NOTES:
'   - Handles surrogate pairs for characters beyond BMP
'   - Properly validates UTF-16 sequences
'   - Maps common Unicode characters to ANSI equivalents
'   - Uses assembly for maximum performance
'   - In-place conversion with minimal memory overhead
' ===============================================================================
SUB ASM_UnicodeToAnsi(BYREF U01 AS STRING)
    #REGISTER NONE
    LOCAL T01 AS LONG        ' Unicode length (in bytes)
    LOCAL T02 AS LONG        ' ANSI length
    LOCAL T03 AS DWORD PTR   ' Unicode pointer
    LOCAL T04 AS DWORD PTR   ' ANSI pointer
    LOCAL T05 AS LONG        ' Current position
    LOCAL T06 AS WORD        ' Current Unicode char
    LOCAL T07 AS WORD        ' Next Unicode char
    LOCAL T08 AS DWORD       ' Combined code point
    LOCAL T09 AS BYTE        ' ANSI equivalent
    LOCAL S01 AS STRING      ' Result string

    ' Get Unicode length (must be even)
    T01 = LEN(U01)
    IF T01 = 0 THEN
        EXIT SUB
    END IF

    ' Check for odd length (invalid UTF-16)
    IF (T01 AND 1) THEN
        T01 = T01 - 1  ' Ignore last byte
        IF T01 = 0 THEN
            U01 = ""
            EXIT SUB
        END IF
    END IF

    ' Calculate maximum ANSI length (each Unicode char becomes at most 3 ANSI chars for ellipsis)
    T02 = T01 \ 2 * 3

    ' Create result buffer
    S01 = STRING$(T02, 0)

    ' Get pointers
    T03 = STRPTR(U01)
    T04 = STRPTR(S01)

    ' Initialize ANSI length counter
    T05 = 0

    ' Inline assembly for conversion
    ! push esi
    ! push edi
    ! push ebx
    ! mov esi, T03          ; Unicode pointer
    ! mov edi, T04          ; ANSI pointer
    ! mov ecx, T01          ; Unicode length in bytes
    ! xor edx, edx          ; Clear combined code point

Lab_ConvertLoop:
    ! cmp ecx, 2            ; Need at least 2 bytes
    ! jb Lab_Done           ; Done if less

    ' Get current Unicode character
    ! mov ax, [esi]         ; Get 16-bit Unicode char
    ! mov T06, ax           ; Store in variable

    ' Check for high surrogate
    ! cmp ax, %HIGH_SURROGATE_START
    ! jb Lab_NormalChar     ; Below high surrogate range
    ! cmp ax, %HIGH_SURROGATE_END
    ! ja Lab_NormalChar     ; Above high surrogate range

    ' It's a high surrogate - check for low surrogate
    ! cmp ecx, 4            ; Need at least 4 bytes for surrogate pair
    ! jb Lab_InvalidSurrogate

    ' Get next character
    ! mov bx, [esi+2]       ; Get next 16-bit char
    ! mov T07, bx           ; Store in variable

    ' Check if it's a low surrogate
    ! cmp bx, %LOW_SURROGATE_START
    ! jb Lab_InvalidSurrogate
    ! cmp bx, %LOW_SURROGATE_END
    ! ja Lab_InvalidSurrogate

    ' Valid surrogate pair - combine to 32-bit code point
    ! movzx eax, ax         ; Zero-extend high surrogate
    ! sub eax, %HIGH_SURROGATE_START
    ! shl eax, 10           ; Shift left 10 bits
    ! movzx ebx, bx         ; Zero-extend low surrogate
    ! sub ebx, %LOW_SURROGATE_START
    ! or eax, ebx           ; Combine
    ! add eax, &H10000      ; Add base for surrogate pairs
    ! mov T08, eax          ; Store combined code point

    ' Advance past surrogate pair
    ! add esi, 4            ; Skip 4 bytes
    ! sub ecx, 4            ; Decrease counter
    ! jmp Lab_ProcessCodePoint

Lab_NormalChar:
    ' Normal BMP character
    ! movzx eax, ax         ; Zero-extend to 32-bit
    ! mov T08, eax          ; Store as code point

    ' Advance past character
    ! add esi, 2            ; Skip 2 bytes
    ! sub ecx, 2            ; Decrease counter
    ! jmp Lab_ProcessCodePoint

Lab_InvalidSurrogate:
    ' Invalid surrogate sequence - treat as single character
    ! movzx eax, ax         ; Zero-extend to 32-bit
    ! mov T08, eax          ; Store as code point

    ' Advance past character
    ! add esi, 2            ; Skip 2 bytes
    ! sub ecx, 2            ; Decrease counter
    ! jmp Lab_ProcessCodePoint

Lab_ProcessCodePoint:
    ' Process the code point (T08)
    ! mov eax, T08          ; Get code point

    ' Check for special mappings
    ! cmp eax, %EURO_SIGN
    ! je Lab_EuroSign
    ! cmp eax, %BULLET
    ! je Lab_Bullet
    ! cmp eax, %ELLIPSIS
    ! je Lab_Ellipsis

    ' Check if within ANSI range
    ! cmp eax, %ANSI_MAX
    ! ja Lab_NonAnsi        ; Above ANSI range

    ' Direct ANSI mapping
    ! mov T09, al           ; Use low byte
    ! jmp Lab_StoreChar

Lab_EuroSign:
    ! mov T09, %EURO_ANSI   ; Map to ANSI 128
    ! jmp Lab_StoreChar

Lab_Bullet:
    ! mov T09, %BULLET_ANSI ; Map to ANSI 7
    ! jmp Lab_StoreChar

Lab_Ellipsis:
    ' Special case: map to "..." (3 characters)
    ! cmp T05, T02-2        ; Check if we have room for 3 chars
    ! jae Lab_Truncate      ; Truncate if no room

    ! mov byte ptr [edi], %DOT_CHAR  ; First dot
    ! mov byte ptr [edi+1], %DOT_CHAR ; Second dot
    ! mov byte ptr [edi+2], %DOT_CHAR ; Third dot
    ! add edi, 3            ; Advance 3 bytes
    ! add T05, 3            ; Increase count by 3
    ! jmp Lab_ConvertLoop   ; Continue

Lab_NonAnsi:
    ' Non-ANSI character - use replacement
    ! mov T09, %REPLACEMENT_CHAR
    ! jmp Lab_StoreChar

Lab_StoreChar:
    ' Store the ANSI character
    ! mov bl, T09
    ! mov [edi], bl
    ! inc edi               ; Advance output pointer
    ! inc T05               ; Increase count
    ! jmp Lab_ConvertLoop   ; Continue

Lab_Truncate:
    ' Output buffer full - stop processing
    ! jmp Lab_Done

Lab_Done:
    ! pop ebx
    ! pop edi
    ! pop esi

    ' Update the string with the converted content
    IF T05 > 0 THEN
        U01 = LEFT$(S01, T05)
    ELSE
        U01 = ""
    END IF
END SUB
                                         

#48
Deutsches Board (IT-Themen) / Re: Der Neue
Last post by Theo Gottwald - September 20, 2025, 08:26:59 AM
Hallo @Peter Salomon

1. es scheint dass dein alte Technik mit unicode nicht klar kommt? Norbert kann es lesen.

2. Da steht "Click or drag files here to attach them."" - also bei mir steht das wenn ich einen Post schreibe.Das bedeutet du kannst da Zum Beispiel ZIP-Dateien an einen Post anfügen.

3. Ja, das Doku Problem. Ändert nichts an der sehr guten Qualität der Software. Angesichts dessen dass Charles noc hseine kranke Oma nebenher pflegt und das als Nebenbei Projekt macht ist das ganz toll was er da macht.


@Norbert Spoerl
Ich hatte Jürgen schon vor längerer Zeit einen Vorschlag zur Performance-Optimierung gemacht. Allerdings ist es verständlich, dass man an seinem etablierten Programmierstil festhält, denn ein gewachsenes System nachträglich auf standardisierte Verfahren umzustellen, ist eine große Herausforderung.

Um die Grundlagen effizienter Syntaxanalyse (Parsing) zu verstehen, hilft oft ein Blick in die Originalliteratur, etwa von den C- oder Pascal-Autoren. Früher lag solchen Büchern oft ein großes Poster bei, das die gesamte Grammatik der Sprache visualisierte. Daran ließ sich exakt ablesen, welches Zeichen oder Keyword nach einer bestimmten Anweisung syntaktisch erlaubt ist.

Solche Grammatiken lassen sich mittels Assembler (ASM) extrem effizient parsen und erreichen dadurch eine enorme Geschwindigkeit. Dies ist eine klassische Programmiertechnik aus der Ära der 8-Bit-Systeme, wo Ressourcen knapp waren. Heutzutage wählt man oft den Umweg über zeitintensive String-Operationen, die für ein performantes Parsing jedoch unnötig sind. Im Grunde genügen eine zeichenweise Auswertung und die Suche nach dem nächsten Trennzeichen (Delimiter). Für komplexere Strukturen wie Formeln oder Schleifen kommen bewährte Konzepte wie Stacks zum Einsatz. Die ältesten und fundamentalsten Algorithmen sind hier oft die besten.

Sollte Jürgen jedoch tatsächlich ein neues, PowerBASIC-kompatibles System mit verbesserten Makros und neuen Datentypen schaffen – Bereiche, in denen er ohnehin stark ist, wie beim Debugging –, dann wäre die Performancefrage zunächst zweitrangig.

Früher oder später wird er jedoch an einen Punkt gelangen, an dem er auf diese bewährten, zeitlosen Techniken zurückgreifen muss. Man kann es anders implementieren, aber nicht, ohne erhebliche Geschwindigkeitseinbußen in Kauf zu nehmen. Das ist im Assembler vergleichbar: Eine Version könnte einen SELECT CASE-Block mit 500 Fällen nutzen, was ineffizient ist. Der performante Ansatz hingegen wertet Zeichen für Zeichen aus und hat nach jedem Schritt nur eine kleine, überschaubare Menge an gültigen Folgeoptionen.

Im C-Syntaxdiagram sieht es dann so aus ...


Das lässt sich mit ASM-Macros oder Unterprogrammen nachbilden.


So gehts:
So ein Syntaxdiagram musst du machen dann wird daws genauso schnell.

Das hat seinen Ursprung in der Automatentheorie - das war damals als man die Dinger noch mit Lochkarten gefüttert hat. Da MUSSTE jedes Byte perfekt sitzen. Und das ist eben der Unterschied zu heute.

Alles Andere geht zwar benötigt aber "Memory Allocation" das ist da unnötiog und langsam-


#49
Deutsches Board (IT-Themen) / Re: Der Neue
Last post by Peter Salomon - September 18, 2025, 10:03:27 AM
@Theo
Deutsches Board -> deutsche Sprache, ja und warum kann ich Post #10 mit "chinesischen Hiroglyphen" nicht lesen?
Sogar auf meinem Handy mit aktuellem BS nicht lesbar!
In Post #5 hattest Du ja noch freundlicherweise die "Übersetzung" beigefügt ...
Meine Frage in Post #4 "Wie lade ich hier was hoch"? wurde leider auch noch nicht beantwortet.
Oxygen habe ich mir schon angesehen, aber wenn man nicht mal eine (ausführliche) Doku findet, kann's mit der SW nicht weit her sein - von COM mal ganz zu schweigen.
Die wirklich sehr verständlich und sehr ausführlich geschriebene Doku zu den über 1200 Befehle umfassenden Sprachumfang von PowerBASIC in der genannten Beschreibung (>2000 S) und dem Referenz-Handbuch (>700 S) wird bis jetzt - soweit ich das sehe - von keiner anderen IDE erreicht.

Wir werden sehen, wie's weiter geht ...

So viel für heute.

Grüsse aus Ahrensfelde (bei Berlin)


Peter Salomon
www.ps-blnkd.de
#50
Deutsches Board (IT-Themen) / Re: Der Neue
Last post by Norbert Spoerl - September 17, 2025, 11:15:35 PM
Hallo Theo,

>>>
𝑆𝑜𝑙𝑙𝑡𝑒 𝐽ü𝑟𝑔𝑒𝑛 𝑎𝑏𝑒𝑟 𝑒𝑡𝑤𝑎𝑠 𝘩𝑎𝑏𝑒𝑛, 𝑑𝑎𝑠 𝑘𝑜𝑚𝑝𝑙𝑒𝑥𝑒𝑛 𝑢𝑛𝑑 𝑔𝑟𝑜ß𝑒𝑛 𝑄𝑢𝑒𝑙𝑙𝑐𝑜𝑑𝑒 𝑒𝑏𝑒𝑛𝑓𝑎𝑙𝑙𝑠 𝑧𝑢𝑣𝑒𝑟𝑙ä𝑠𝑠𝑖𝑔 𝑘𝑜𝑚𝑝𝑖𝑙𝑖𝑒𝑟𝑒𝑛 𝑘𝑎𝑛𝑛,...
<<<
Das wird auf jeden Fall funktionieren.

Bei der Compilierzeit wird keiner an PB herankommen. Ich liebe das blitzschnelle Compilieren von PowerBasic. Der Syntaxcheck (reine Stringarbeit) des Source ist sicherlich ein Zeiträuber. Vielleicht kann man Jürgen dazu überreden, den Syntaxcheck optional ausschalten zu können.