' JSON parser: tokenizer, recursive descent, pretty printer
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL i  AS LONG
    LOCAL tokenCount  AS LONG
    LOCAL depth  AS LONG
    LOCAL jsonStr  AS STRING
    LOCAL tokenStr  AS STRING
    LOCAL tokens(200) AS STRING
    LOCAL tokenTypes(200) AS LONG
    LOCAL numTokens AS LONG
    LOCAL ch AS STRING
    LOCAL parsedOk AS LONG

    PRINT "=== JSON Parser ==="
    PRINT

    jsonStr = "{"
    jsonStr = jsonStr + CHR$(34) + "name" + CHR$(34) + ":"
    jsonStr = jsonStr + CHR$(34) + "Alice" + CHR$(34) + ","
    jsonStr = jsonStr + CHR$(34) + "age" + CHR$(34) + ":30,"
    jsonStr = jsonStr + CHR$(34) + "skills" + CHR$(34) + ":["
    jsonStr = jsonStr + CHR$(34) + "C" + CHR$(34) + ","
    jsonStr = jsonStr + CHR$(34) + "PB" + CHR$(34) + ","
    jsonStr = jsonStr + CHR$(34) + "ASM" + CHR$(34)
    jsonStr = jsonStr + "]}"

    PRINT "Input JSON:"
    PRINT "  " & LEFT$(jsonStr, 50) & "..."
    PRINT "Length: " & FORMAT$(LEN(jsonStr)) & " chars"
    PRINT

    PRINT "--- Tokenization ---"
    numTokens = 0
    FOR i = 1 TO LEN(jsonStr)
        ch = MID$(jsonStr, i, 1)
        IF ch = "{" THEN
            tokens(numTokens) = "{               "
            tokenTypes(numTokens) = 1
            numTokens = numTokens + 1
        END IF
        IF ch = "}" THEN
            tokens(numTokens) = "}               "
            tokenTypes(numTokens) = 2
            numTokens = numTokens + 1
        END IF
        IF ch = "[" THEN
            tokens(numTokens) = "[               "
            tokenTypes(numTokens) = 3
            numTokens = numTokens + 1
        END IF
        IF ch = "]" THEN
            tokens(numTokens) = "]               "
            tokenTypes(numTokens) = 4
            numTokens = numTokens + 1
        END IF
        IF ch = "," THEN
            tokens(numTokens) = ",               "
            tokenTypes(numTokens) = 5
            numTokens = numTokens + 1
        END IF
        IF ch = ":" THEN
            tokens(numTokens) = ":               "
            tokenTypes(numTokens) = 6
            numTokens = numTokens + 1
        END IF
        IF ch >= "0" AND ch <= "9" THEN
            tokenStr = ""
            WHILE i <= LEN(jsonStr) AND MID$(jsonStr, i, 1) >= "0" AND MID$(jsonStr, i, 1) <= "9"
                tokenStr = tokenStr + MID$(jsonStr, i, 1)
                i = i + 1
            WEND
            i = i - 1
            tokens(numTokens) = LEFT$(tokenStr + SPACE$(32), 32)
            tokenTypes(numTokens) = 8
            numTokens = numTokens + 1
        END IF
    NEXT i

    PRINT "  Tokens (" & FORMAT$(numTokens) & "):"
    FOR i = 0 TO numTokens - 1
        tokenStr = TRIM$(tokens(i))
        IF tokenTypes(i) = 1 THEN PRINT "    OBJECT {"
        IF tokenTypes(i) = 2 THEN PRINT "    END }"
        IF tokenTypes(i) = 3 THEN PRINT "    ARRAY ["
        IF tokenTypes(i) = 4 THEN PRINT "    END ]"
        IF tokenTypes(i) = 5 THEN PRINT "    COMMA ,"
        IF tokenTypes(i) = 6 THEN PRINT "    COLON :"
        IF tokenTypes(i) = 8 THEN PRINT "    NUMBER: " & tokenStr
    NEXT i
    PRINT

    parsedOk = 1
    depth = 0
    FOR i = 0 TO numTokens - 1
        IF tokenTypes(i) = 1 THEN depth = depth + 1
        IF tokenTypes(i) = 2 THEN depth = depth - 1
        IF tokenTypes(i) = 3 THEN depth = depth + 1
        IF tokenTypes(i) = 4 THEN depth = depth - 1
        IF depth < 0 THEN parsedOk = 0
    NEXT i
    IF depth <> 0 THEN parsedOk = 0

    IF parsedOk = 1 THEN
        PRINT "  Parser: VALID JSON"
    ELSE
        PRINT "  Parser: INVALID JSON"
    END IF
    PRINT

    PRINT "--- Pretty Printed ---"
    depth = 0
    FOR i = 0 TO numTokens - 1
        IF tokenTypes(i) = 2 OR tokenTypes(i) = 4 THEN depth = depth - 1
        IF tokenTypes(i) = 1 THEN PRINT SPACE$(depth * 2) & "{"
        IF tokenTypes(i) = 2 THEN PRINT SPACE$(depth * 2) & "}"
        IF tokenTypes(i) = 3 THEN PRINT SPACE$(depth * 2) & "["
        IF tokenTypes(i) = 4 THEN PRINT SPACE$(depth * 2) & "]"
        IF tokenTypes(i) = 5 THEN PRINT ","
        IF tokenTypes(i) = 6 THEN PRINT ": "
        IF tokenTypes(i) = 8 THEN PRINT SPACE$(depth * 2) & tokenStr
        IF tokenTypes(i) = 1 OR tokenTypes(i) = 3 THEN depth = depth + 1
    NEXT i

    PRINT
    PRINT "JSON parser complete."

    FUNCTION = 0
END FUNCTION
