' Finite State Machine — SELECT CASE based parsing
#COMPILE EXE
#DIM ALL

%STATE_IDLE = 0
%STATE_READING = 1
%STATE_COMMENT = 2
%STATE_STRING = 3
%STATE_NUMBER = 4

SUB SimpleTokenizer(text AS STRING)
    LOCAL i AS LONG
    LOCAL ch AS STRING
    LOCAL state AS LONG
    LOCAL token AS STRING
    LOCAL quoteChar AS STRING
    quoteChar = CHR$(34)
    state = %STATE_IDLE
    token = ""
    PRINT "=== TOKENIZER STATE MACHINE ==="
    PRINT "Input: " & text
    PRINT "Tokens:"
    FOR i = 1 TO LEN(text)
        ch = MID$(text, i, 1)
        SELECT CASE state
            CASE %STATE_IDLE
                IF ch >= "A" AND ch <= "Z" OR ch >= "a" AND ch <= "z" THEN
                    state = %STATE_READING
                    token = ch
                ELSEIF ch >= "0" AND ch <= "9" THEN
                    state = %STATE_NUMBER
                    token = ch
                ELSEIF ch = "'" THEN
                    state = %STATE_COMMENT
                ELSEIF ch = quoteChar THEN
                    state = %STATE_STRING
                    token = ""
                END IF
            CASE %STATE_READING
                IF ch >= "A" AND ch <= "Z" OR ch >= "a" AND ch <= "z" OR ch >= "0" AND ch <= "9" THEN
                    token = token & ch
                ELSE
                    PRINT "  [IDENT] " & token
                    state = %STATE_IDLE
                END IF
            CASE %STATE_NUMBER
                IF ch >= "0" AND ch <= "9" OR ch = "." THEN
                    token = token & ch
                ELSE
                    PRINT "  [NUMBER] " & token
                    state = %STATE_IDLE
                END IF
            CASE %STATE_COMMENT
                PRINT "  [COMMENT] " & MID$(text, i)
                EXIT FOR
            CASE %STATE_STRING
                IF ch <> quoteChar THEN
                    token = token & ch
                ELSE
                    PRINT "  [STRING] " & token
                    state = %STATE_IDLE
                END IF
        END SELECT
    NEXT i
    IF state = %STATE_READING THEN PRINT "  [IDENT] " & token
    IF state = %STATE_NUMBER THEN PRINT "  [NUMBER] " & token
    PRINT
END SUB

SUB CSVParser()
    LOCAL line AS STRING
    LOCAL i AS LONG
    LOCAL ch AS STRING
    LOCAL csvField AS STRING
    LOCAL fieldCount AS LONG
    LOCAL inQuotes AS LONG
    LOCAL quoteChar AS STRING
    quoteChar = CHR$(34)
    line = "John,Doe,42,Engineer"
    inQuotes = 0
    csvField = ""
    fieldCount = 0
    PRINT "=== CSV PARSER ==="
    PRINT "Input: " & line
    PRINT "Fields:"
    FOR i = 1 TO LEN(line)
        ch = MID$(line, i, 1)
        IF ch = "," AND inQuotes = 0 THEN
            fieldCount = fieldCount + 1
            PRINT "  Field " & STR$(fieldCount) & ": " & csvField
            csvField = ""
        ELSEIF ch = quoteChar THEN
            IF inQuotes THEN inQuotes = 0 ELSE inQuotes = 1
        ELSE
            csvField = csvField & ch
        END IF
    NEXT i
    IF LEN(csvField) > 0 THEN
        fieldCount = fieldCount + 1
        PRINT "  Field " & STR$(fieldCount) & ": " & csvField
    END IF
    PRINT
END SUB

SUB BinaryCounter()
    LOCAL i AS LONG
    LOCAL bit AS LONG
    LOCAL state AS LONG
    LOCAL line AS STRING
    PRINT "=== BINARY COUNTER (3-bit) ==="
    state = 0
    FOR i = 0 TO 7
        line = "State " & STR$(state) & " (binary: "
        FOR bit = 2 TO 0 STEP -1
            IF state AND (1 SHL bit) THEN
                line = line & "1"
            ELSE
                line = line & "0"
            END IF
        NEXT bit
        line = line & ")"
        PRINT line
        state = state + 1
    NEXT i
    PRINT
END SUB

SUB TrafficLight()
    LOCAL i AS LONG
    LOCAL state AS LONG
    PRINT "=== TRAFFIC LIGHT FSM ==="
    state = 0
    FOR i = 1 TO 10
        SELECT CASE state
            CASE 0
                PRINT "Cycle " & STR$(i) & ": GREEN"
                state = 1
            CASE 1
                PRINT "Cycle " & STR$(i) & ": YELLOW"
                state = 2
            CASE 2
                PRINT "Cycle " & STR$(i) & ": RED"
                state = 0
        END SELECT
    NEXT i
    PRINT
END SUB

SUB ParseExpression(expr AS STRING)
    LOCAL i AS LONG
    LOCAL ch AS STRING
    LOCAL state AS LONG
    LOCAL result AS LONG
    LOCAL currentOp AS LONG
    LOCAL currentVal AS LONG
    state = 0
    currentOp = 0
    result = 0
    currentVal = 0
    PRINT "=== EXPRESSION PARSER ==="
    PRINT "Input: " & expr
    FOR i = 1 TO LEN(expr)
        ch = MID$(expr, i, 1)
        SELECT CASE state
            CASE 0
                IF ch >= "0" AND ch <= "9" THEN
                    currentVal = VAL(ch)
                    state = 1
                END IF
            CASE 1
                IF ch = "+" THEN
                    IF currentOp = 0 THEN result = currentVal
                    IF currentOp = 1 THEN result = result + currentVal
                    IF currentOp = 2 THEN result = result - currentVal
                    currentOp = 1
                    currentVal = 0
                    state = 0
                ELSEIF ch = "-" THEN
                    IF currentOp = 0 THEN result = currentVal
                    IF currentOp = 1 THEN result = result + currentVal
                    IF currentOp = 2 THEN result = result - currentVal
                    currentOp = 2
                    currentVal = 0
                    state = 0
                ELSEIF ch >= "0" AND ch <= "9" THEN
                    currentVal = currentVal * 10 + VAL(ch)
                END IF
        END SELECT
    NEXT i
    IF currentOp = 0 THEN result = currentVal
    IF currentOp = 1 THEN result = result + currentVal
    IF currentOp = 2 THEN result = result - currentVal
    PRINT "Result = " & STR$(result)
    PRINT
END SUB

FUNCTION PBMAIN() AS LONG
    PRINT "========================"
    PRINT " Finite State Machine"
    PRINT "========================"
    PRINT
    CALL SimpleTokenizer("count = 42 ' this is a comment")
    CALL CSVParser()
    CALL BinaryCounter()
    CALL TrafficLight()
    CALL ParseExpression("10+25-7")
    PRINT "FSM demos complete."
    FUNCTION = 0
END FUNCTION
