' MIN/MAX Macros — demonstrates macro-based min/max operations
#COMPILE EXE
#DIM ALL

MACRO m_min(a, b) = IIF((a) < (b), (a), (b))
MACRO m_max(a, b) = IIF((a) > (b), (a), (b))
MACRO m_abs(x) = IIF((x) < 0, -(x), (x))
MACRO m_clamp(v, lo, hi) = IIF((v) < (lo), (lo), IIF((v) > (hi), (hi), (v)))
MACRO m_bound(v, lo, hi) = IIF((v) < (lo), (lo), IIF((v) > (hi), (hi), (v)))

FUNCTION PBMAIN() AS LONG
    LOCAL a AS LONG
    LOCAL b AS LONG
    LOCAL c AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL k AS LONG
    LOCAL result AS LONG
    LOCAL minVal AS LONG
    LOCAL maxVal AS LONG
    LOCAL lineStr AS STRING
    LOCAL arr(100) AS LONG
    LOCAL valStr AS STRING
    PRINT "============================================"
    PRINT "       MIN/MAX MACRO DEMONSTRATION"
    PRINT "============================================"
    PRINT ""
    PRINT "Basic MIN and MAX operations"
    PRINT ""
    FOR i = 0 TO 9
        a = i * 7
        b = i * 5 + 20
        minVal = m_min(a, b)
        maxVal = m_max(a, b)
        PRINT " min(" + STR$(a) + ", " + STR$(b) + ") = " + STR$(minVal) + "  max = " + STR$(maxVal)
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "       NESTED MIN/MAX"
    PRINT "============================================"
    PRINT ""
    FOR i = 0 TO 9
        a = i * 3 + 5
        b = i * 4 + 2
        c = i * 5 + 8
        result = m_min(m_max(a, b), c)
        PRINT " min(max(" + STR$(a) + ", " + STR$(b) + "), " + STR$(c) + ") = " + STR$(result)
        result = m_max(m_min(a, b), c)
        PRINT " max(min(" + STR$(a) + ", " + STR$(b) + "), " + STR$(c) + ") = " + STR$(result)
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "       ABSOLUTE VALUE MACRO"
    PRINT "============================================"
    PRINT ""
    FOR i = -5 TO 5
        result = m_abs(i)
        PRINT " abs(" + STR$(i) + ") = " + STR$(result)
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "       THREE-VALUE MIN AND MAX"
    PRINT "============================================"
    PRINT ""
    FOR i = 0 TO 9
        a = i * 5 + 3
        b = i * 7 + 1
        c = i * 3 + 9
        minVal = m_min(a, m_min(b, c))
        maxVal = m_max(a, m_max(b, c))
        PRINT " values: " + STR$(a) + ", " + STR$(b) + ", " + STR$(c) + " -> min=" + STR$(minVal) + " max=" + STR$(maxVal)
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "       ARRAY MIN AND MAX"
    PRINT "============================================"
    PRINT ""
    FOR i = 0 TO 19
        arr(i) = (i * 13 + 7) MOD 100
    NEXT i
    PRINT "Array values:"
    lineStr = ""
    FOR i = 0 TO 19
        valStr = STR$(arr(i))
        DO WHILE LEN(valStr) < 3
            valStr = " " + valStr
        LOOP
        lineStr = lineStr + valStr + " "
    NEXT i
    PRINT lineStr
    PRINT ""
    minVal = arr(0)
    maxVal = arr(0)
    FOR i = 1 TO 19
        minVal = m_min(minVal, arr(i))
        maxVal = m_max(maxVal, arr(i))
    NEXT i
    PRINT " Array min: " + STR$(minVal) + "  Array max: " + STR$(maxVal)
    PRINT ""
    PRINT "============================================"
    PRINT "       RUNNING MIN AND MAX"
    PRINT "============================================"
    PRINT ""
    LOCAL runningMin AS LONG
    LOCAL runningMax AS LONG
    LOCAL randomVal AS LONG
    runningMin = 9999
    runningMax = -9999
    PRINT "Running min/max of sequence:"
    PRINT ""
    FOR i = 0 TO 19
        randomVal = (i * 31 + 17) MOD 75
        runningMin = m_min(runningMin, randomVal)
        runningMax = m_max(runningMax, randomVal)
        PRINT " value=" + STR$(randomVal) + " running_min=" + STR$(runningMin) + " running_max=" + STR$(runningMax)
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "       COMPARISON WITH EXPLICIT CODE"
    PRINT "============================================"
    PRINT ""
    LOCAL errors AS LONG
    errors = 0
    PRINT "Verifying macro correctness:"
    PRINT ""
    FOR a = -10 TO 10
        FOR b = -10 TO 10
            result = m_min(a, b)
            IF a < b THEN
                minVal = a
            ELSE
                minVal = b
            END IF
            IF result <> minVal THEN
                errors = errors + 1
            END IF
            result = m_max(a, b)
            IF a > b THEN
                maxVal = a
            ELSE
                maxVal = b
            END IF
            IF result <> maxVal THEN
                errors = errors + 1
            END IF
        NEXT b
    NEXT a
    IF errors = 0 THEN
        PRINT " PASS: " + STR$(441) + " tests passed"
    ELSE
        PRINT " FAIL: " + STR$(errors) + " errors found"
    END IF
    PRINT ""
    PRINT "============================================"
    PRINT "       BOUND/CLAMP MACRO"
    PRINT "============================================"
    PRINT ""
    PRINT "Clamping values to range [10, 90]:"
    PRINT ""
    FOR i = 0 TO 10
        a = i * 10 + 5
        result = m_clamp(a, 10, 90)
        PRINT " clamp(" + STR$(a) + ", 10, 90) = " + STR$(result)
    NEXT i
    PRINT ""
    PRINT "Clamping negative values:"
    PRINT ""
    FOR i = -5 TO 5
        a = i * 10
        result = m_clamp(a, 0, 50)
        PRINT " clamp(" + STR$(a) + ", 0, 50) = " + STR$(result)
    NEXT i
    PRINT ""
    PRINT "Macro demonstration complete"
    FUNCTION = 0
END FUNCTION
