1049 lines
21 KiB
QBasic
1049 lines
21 KiB
QBasic
' ============================================================
|
|
' Comprehensive BASIC Test Program
|
|
' Tests all features of the basic2c transpiler extensively
|
|
' ============================================================
|
|
|
|
' ---- Global variable declarations ----
|
|
DIM i AS INTEGER
|
|
DIM j AS INTEGER
|
|
DIM k AS INTEGER
|
|
DIM n AS INTEGER
|
|
DIM temp AS INTEGER
|
|
DIM total AS INTEGER
|
|
DIM found AS INTEGER
|
|
DIM flag AS INTEGER
|
|
|
|
DIM x AS DOUBLE
|
|
DIM y AS DOUBLE
|
|
DIM z AS DOUBLE
|
|
DIM avg AS DOUBLE
|
|
DIM pi AS DOUBLE
|
|
DIM area AS DOUBLE
|
|
|
|
DIM s$ AS STRING
|
|
DIM t$ AS STRING
|
|
DIM u$ AS STRING
|
|
DIM line$ AS STRING
|
|
DIM result$ AS STRING
|
|
|
|
' ============================================================
|
|
' PART 1: Arithmetic and operator precedence
|
|
' ============================================================
|
|
PRINT "==== PART 1: Arithmetic ===="
|
|
|
|
i = 2 + 3 * 4
|
|
PRINT "2 + 3 * 4 = "; i
|
|
|
|
i = (2 + 3) * 4
|
|
PRINT "(2 + 3) * 4 = "; i
|
|
|
|
x = 10.0 / 3.0
|
|
PRINT "10.0 / 3.0 = "; x
|
|
|
|
i = 17 \ 5
|
|
PRINT "17 \\ 5 = "; i
|
|
|
|
i = 17 MOD 5
|
|
PRINT "17 MOD 5 = "; i
|
|
|
|
x = 2.0 ^ 10
|
|
PRINT "2 ^ 10 = "; x
|
|
|
|
x = -5.5 + 3.2
|
|
PRINT "-5.5 + 3.2 = "; x
|
|
|
|
i = 100 - 30 - 20 - 10
|
|
PRINT "100 - 30 - 20 - 10 = "; i
|
|
|
|
x = 1.0 + 2.0 * 3.0 - 4.0 / 2.0
|
|
PRINT "1 + 2*3 - 4/2 = "; x
|
|
|
|
' Nested parentheses
|
|
i = ((((5 + 3) * 2) - 1) * 3)
|
|
PRINT "((((5+3)*2)-1)*3) = "; i
|
|
|
|
' Integer division chain
|
|
i = 100 \ 3 \ 2
|
|
PRINT "100 \\ 3 \\ 2 = "; i
|
|
|
|
' MOD chain
|
|
i = 100 MOD 17 MOD 5
|
|
PRINT "100 MOD 17 MOD 5 = "; i
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 2: String operations
|
|
' ============================================================
|
|
PRINT "==== PART 2: Strings ===="
|
|
|
|
s$ = "Hello, World!"
|
|
PRINT "Original: "; s$
|
|
PRINT "Length: "; LEN(s$)
|
|
PRINT "Left 5: "; LEFT$(s$, 5)
|
|
PRINT "Right 6: "; RIGHT$(s$, 6)
|
|
PRINT "Mid(8,5): "; MID$(s$, 8, 5)
|
|
PRINT "Upper: "; UCASE$(s$)
|
|
PRINT "Lower: "; LCASE$(s$)
|
|
|
|
' String concatenation
|
|
t$ = "foo"
|
|
u$ = "bar"
|
|
result$ = t$ + u$
|
|
PRINT "foo + bar = "; result$
|
|
|
|
' Multi-concat
|
|
result$ = "A" + "B" + "C" + "D" + "E"
|
|
PRINT "A+B+C+D+E = "; result$
|
|
|
|
' String with & operator
|
|
result$ = "Hello" & " " & "World"
|
|
PRINT "Hello & World = "; result$
|
|
|
|
' String comparison
|
|
s$ = "apple"
|
|
t$ = "banana"
|
|
IF s$ < t$ THEN
|
|
PRINT "apple < banana: TRUE"
|
|
ELSE
|
|
PRINT "apple < banana: FALSE"
|
|
END IF
|
|
|
|
IF s$ = "apple" THEN
|
|
PRINT "s$ equals apple: TRUE"
|
|
END IF
|
|
|
|
IF s$ <> "orange" THEN
|
|
PRINT "s$ <> orange: TRUE"
|
|
END IF
|
|
|
|
' INSTR
|
|
s$ = "Hello World Hello"
|
|
PRINT "INSTR(Hello World Hello, World) = "; INSTR(s$, "World")
|
|
PRINT "INSTR(Hello World Hello, xyz) = "; INSTR(s$, "xyz")
|
|
|
|
' CHR$ and ASC
|
|
PRINT "CHR$(65) = "; CHR$(65)
|
|
PRINT "ASC(A) = "; ASC("A")
|
|
|
|
' STR$ and VAL
|
|
PRINT "STR$(42) = ["; STR$(42); "]"
|
|
PRINT "VAL(3.14) = "; VAL("3.14")
|
|
|
|
' MID$ without length (to end of string)
|
|
s$ = "ABCDEFGHIJ"
|
|
PRINT "MID$(ABCDEFGHIJ, 4) = "; MID$(s$, 4)
|
|
|
|
' Edge cases
|
|
PRINT "LEFT$ empty: ["; LEFT$("hello", 0); "]"
|
|
PRINT "RIGHT$ more than len: "; RIGHT$("hi", 10)
|
|
PRINT "LEN empty: "; LEN("")
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 3: Control flow - IF/ELSEIF/ELSE
|
|
' ============================================================
|
|
PRINT "==== PART 3: IF/ELSEIF/ELSE ===="
|
|
|
|
' Nested IF
|
|
i = 42
|
|
IF i > 0 THEN
|
|
IF i > 10 THEN
|
|
IF i > 100 THEN
|
|
PRINT "i > 100"
|
|
ELSE
|
|
PRINT "10 < i <= 100: "; i
|
|
END IF
|
|
ELSE
|
|
PRINT "0 < i <= 10"
|
|
END IF
|
|
ELSE
|
|
PRINT "i <= 0"
|
|
END IF
|
|
|
|
' Long ELSEIF chain
|
|
n = 7
|
|
IF n = 1 THEN
|
|
PRINT "one"
|
|
ELSEIF n = 2 THEN
|
|
PRINT "two"
|
|
ELSEIF n = 3 THEN
|
|
PRINT "three"
|
|
ELSEIF n = 4 THEN
|
|
PRINT "four"
|
|
ELSEIF n = 5 THEN
|
|
PRINT "five"
|
|
ELSEIF n = 6 THEN
|
|
PRINT "six"
|
|
ELSEIF n = 7 THEN
|
|
PRINT "seven"
|
|
ELSEIF n = 8 THEN
|
|
PRINT "eight"
|
|
ELSE
|
|
PRINT "other"
|
|
END IF
|
|
|
|
' Single-line IF variations
|
|
IF 1 = 1 THEN PRINT "single-line IF works"
|
|
IF 0 = 1 THEN PRINT "THIS SHOULD NOT PRINT"
|
|
|
|
' Boolean operators in conditions
|
|
i = 15
|
|
IF i > 10 AND i < 20 THEN
|
|
PRINT "15 is between 10 and 20"
|
|
END IF
|
|
|
|
IF i < 5 OR i > 10 THEN
|
|
PRINT "15 is outside 5..10"
|
|
END IF
|
|
|
|
IF NOT (i = 0) THEN
|
|
PRINT "i is not zero"
|
|
END IF
|
|
|
|
' Combined boolean
|
|
IF (i > 10 AND i < 20) OR i = 0 THEN
|
|
PRINT "complex boolean: TRUE"
|
|
END IF
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 4: Loops
|
|
' ============================================================
|
|
PRINT "==== PART 4: Loops ===="
|
|
|
|
' FOR loop basic
|
|
PRINT "FOR 1 to 10: ";
|
|
FOR i = 1 TO 10
|
|
PRINT i;
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
' FOR with STEP
|
|
PRINT "FOR 0 to 20 STEP 3: ";
|
|
FOR i = 0 TO 20 STEP 3
|
|
PRINT i;
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
' FOR negative step
|
|
PRINT "FOR 10 to 1 STEP -1: ";
|
|
FOR i = 10 TO 1 STEP -1
|
|
PRINT i;
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
' FOR step 2
|
|
PRINT "FOR 1 to 10 STEP 2: ";
|
|
FOR i = 1 TO 10 STEP 2
|
|
PRINT i;
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
' WHILE loop
|
|
PRINT "WHILE countdown: ";
|
|
i = 10
|
|
WHILE i > 0
|
|
PRINT i;
|
|
i = i - 2
|
|
WEND
|
|
PRINT ""
|
|
|
|
' DO WHILE at top
|
|
PRINT "DO WHILE top: ";
|
|
i = 1
|
|
DO WHILE i <= 5
|
|
PRINT i;
|
|
i = i + 1
|
|
LOOP
|
|
PRINT ""
|
|
|
|
' DO UNTIL at top
|
|
PRINT "DO UNTIL top: ";
|
|
i = 1
|
|
DO UNTIL i > 5
|
|
PRINT i;
|
|
i = i + 1
|
|
LOOP
|
|
PRINT ""
|
|
|
|
' DO LOOP WHILE at bottom
|
|
PRINT "DO LOOP WHILE bottom: ";
|
|
i = 1
|
|
DO
|
|
PRINT i;
|
|
i = i + 1
|
|
LOOP WHILE i <= 5
|
|
PRINT ""
|
|
|
|
' DO LOOP UNTIL at bottom
|
|
PRINT "DO LOOP UNTIL bottom: ";
|
|
i = 10
|
|
DO
|
|
PRINT i;
|
|
i = i - 3
|
|
LOOP UNTIL i <= 0
|
|
PRINT ""
|
|
|
|
' Infinite DO with EXIT
|
|
PRINT "DO with EXIT: ";
|
|
i = 0
|
|
DO
|
|
i = i + 1
|
|
IF i > 5 THEN EXIT DO
|
|
PRINT i;
|
|
LOOP
|
|
PRINT ""
|
|
|
|
' Nested FOR loops
|
|
PRINT "Multiplication table 1-4:"
|
|
FOR i = 1 TO 4
|
|
FOR j = 1 TO 4
|
|
k = i * j
|
|
PRINT k; " ";
|
|
NEXT j
|
|
PRINT ""
|
|
NEXT i
|
|
|
|
' EXIT FOR
|
|
PRINT "EXIT FOR test: ";
|
|
FOR i = 1 TO 100
|
|
IF i > 5 THEN EXIT FOR
|
|
PRINT i;
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
' Nested loops with EXIT
|
|
PRINT "Nested EXIT: ";
|
|
FOR i = 1 TO 3
|
|
FOR j = 1 TO 10
|
|
IF j > 3 THEN EXIT FOR
|
|
PRINT i * 10 + j;
|
|
NEXT j
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 5: Arrays
|
|
' ============================================================
|
|
PRINT "==== PART 5: Arrays ===="
|
|
|
|
' Integer array
|
|
DIM nums(20) AS INTEGER
|
|
FOR i = 0 TO 20
|
|
nums(i) = i * i
|
|
NEXT i
|
|
PRINT "Squares 0-10: ";
|
|
FOR i = 0 TO 10
|
|
PRINT nums(i);
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
' Double array
|
|
DIM reals(5) AS DOUBLE
|
|
reals(0) = 1.1
|
|
reals(1) = 2.2
|
|
reals(2) = 3.3
|
|
reals(3) = 4.4
|
|
reals(4) = 5.5
|
|
reals(5) = 6.6
|
|
PRINT "Doubles: ";
|
|
FOR i = 0 TO 5
|
|
PRINT reals(i);
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
' String array
|
|
DIM words(4) AS STRING
|
|
words(0) = "the"
|
|
words(1) = "quick"
|
|
words(2) = "brown"
|
|
words(3) = "fox"
|
|
words(4) = "jumps"
|
|
PRINT "Words: ";
|
|
FOR i = 0 TO 4
|
|
PRINT words(i); " ";
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
' Array element operations
|
|
DIM data(10) AS INTEGER
|
|
FOR i = 0 TO 10
|
|
data(i) = (i + 1) * 5
|
|
NEXT i
|
|
|
|
' Sum array
|
|
total = 0
|
|
FOR i = 0 TO 10
|
|
total = total + data(i)
|
|
NEXT i
|
|
PRINT "Sum of data: "; total
|
|
|
|
' Find max
|
|
temp = data(0)
|
|
FOR i = 1 TO 10
|
|
IF data(i) > temp THEN temp = data(i)
|
|
NEXT i
|
|
PRINT "Max of data: "; temp
|
|
|
|
' Find min
|
|
temp = data(0)
|
|
FOR i = 1 TO 10
|
|
IF data(i) < temp THEN temp = data(i)
|
|
NEXT i
|
|
PRINT "Min of data: "; temp
|
|
|
|
' Average
|
|
avg = 0.0
|
|
FOR i = 0 TO 10
|
|
avg = avg + data(i)
|
|
NEXT i
|
|
avg = avg / 11
|
|
PRINT "Average: "; avg
|
|
|
|
' REDIM - grow array
|
|
DIM growArr(5) AS INTEGER
|
|
FOR i = 0 TO 5
|
|
growArr(i) = i * 100
|
|
NEXT i
|
|
PRINT "Before REDIM: ";
|
|
FOR i = 0 TO 5
|
|
PRINT growArr(i);
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
REDIM growArr(10) AS INTEGER
|
|
growArr(7) = 777
|
|
growArr(10) = 1000
|
|
PRINT "After REDIM: ";
|
|
FOR i = 0 TO 10
|
|
PRINT growArr(i);
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
' Bubble sort on an array
|
|
DIM sortArr(9) AS INTEGER
|
|
sortArr(0) = 64
|
|
sortArr(1) = 34
|
|
sortArr(2) = 25
|
|
sortArr(3) = 12
|
|
sortArr(4) = 22
|
|
sortArr(5) = 11
|
|
sortArr(6) = 90
|
|
sortArr(7) = 1
|
|
sortArr(8) = 45
|
|
sortArr(9) = 78
|
|
|
|
PRINT "Before sort: ";
|
|
FOR i = 0 TO 9
|
|
PRINT sortArr(i); " ";
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
' Bubble sort
|
|
FOR i = 0 TO 8
|
|
FOR j = 0 TO 8 - i
|
|
IF sortArr(j) > sortArr(j + 1) THEN
|
|
temp = sortArr(j)
|
|
sortArr(j) = sortArr(j + 1)
|
|
sortArr(j + 1) = temp
|
|
END IF
|
|
NEXT j
|
|
NEXT i
|
|
|
|
PRINT "After sort: ";
|
|
FOR i = 0 TO 9
|
|
PRINT sortArr(i); " ";
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 6: Functions (BYVAL)
|
|
' ============================================================
|
|
PRINT "==== PART 6: Functions ===="
|
|
|
|
FUNCTION Max(BYVAL a AS INTEGER, BYVAL b AS INTEGER) AS INTEGER
|
|
IF a > b THEN
|
|
Max = a
|
|
ELSE
|
|
Max = b
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION Min(BYVAL a AS INTEGER, BYVAL b AS INTEGER) AS INTEGER
|
|
IF a < b THEN
|
|
Min = a
|
|
ELSE
|
|
Min = b
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION Clamp(BYVAL val AS INTEGER, BYVAL lo AS INTEGER, BYVAL hi AS INTEGER) AS INTEGER
|
|
IF val < lo THEN
|
|
Clamp = lo
|
|
ELSEIF val > hi THEN
|
|
Clamp = hi
|
|
ELSE
|
|
Clamp = val
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION Abs2(BYVAL n AS INTEGER) AS INTEGER
|
|
IF n < 0 THEN
|
|
Abs2 = -n
|
|
ELSE
|
|
Abs2 = n
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION Factorial(BYVAL n AS INTEGER) AS INTEGER
|
|
IF n <= 1 THEN
|
|
Factorial = 1
|
|
ELSE
|
|
Factorial = n * Factorial(n - 1)
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION Fibonacci(BYVAL n AS INTEGER) AS INTEGER
|
|
IF n <= 0 THEN
|
|
Fibonacci = 0
|
|
ELSEIF n = 1 THEN
|
|
Fibonacci = 1
|
|
ELSE
|
|
Fibonacci = Fibonacci(n - 1) + Fibonacci(n - 2)
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION IsPrime(BYVAL n AS INTEGER) AS INTEGER
|
|
LOCAL d AS INTEGER
|
|
IF n < 2 THEN
|
|
IsPrime = 0
|
|
EXIT FUNCTION
|
|
END IF
|
|
IF n = 2 THEN
|
|
IsPrime = 1
|
|
EXIT FUNCTION
|
|
END IF
|
|
IF n MOD 2 = 0 THEN
|
|
IsPrime = 0
|
|
EXIT FUNCTION
|
|
END IF
|
|
d = 3
|
|
WHILE d * d <= n
|
|
IF n MOD d = 0 THEN
|
|
IsPrime = 0
|
|
EXIT FUNCTION
|
|
END IF
|
|
d = d + 2
|
|
WEND
|
|
IsPrime = 1
|
|
END FUNCTION
|
|
|
|
FUNCTION GCD(BYVAL a AS INTEGER, BYVAL b AS INTEGER) AS INTEGER
|
|
WHILE b <> 0
|
|
LOCAL t AS INTEGER
|
|
t = b
|
|
b = a MOD b
|
|
a = t
|
|
WEND
|
|
GCD = a
|
|
END FUNCTION
|
|
|
|
FUNCTION Power(BYVAL base AS DOUBLE, BYVAL exp AS INTEGER) AS DOUBLE
|
|
LOCAL result AS DOUBLE
|
|
result = 1.0
|
|
IF exp < 0 THEN
|
|
Power = 1.0 / Power(base, -exp)
|
|
EXIT FUNCTION
|
|
END IF
|
|
FOR i = 1 TO exp
|
|
result = result * base
|
|
NEXT i
|
|
Power = result
|
|
END FUNCTION
|
|
|
|
PRINT "Max(10, 20) = "; Max(10, 20)
|
|
PRINT "Min(10, 20) = "; Min(10, 20)
|
|
PRINT "Clamp(50, 0, 100) = "; Clamp(50, 0, 100)
|
|
PRINT "Clamp(-5, 0, 100) = "; Clamp(-5, 0, 100)
|
|
PRINT "Clamp(150, 0, 100) = "; Clamp(150, 0, 100)
|
|
PRINT "Abs2(-42) = "; Abs2(-42)
|
|
PRINT "Abs2(42) = "; Abs2(42)
|
|
|
|
PRINT "Factorials: ";
|
|
FOR i = 1 TO 10
|
|
PRINT Factorial(i);
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
PRINT "Fibonacci 0-12: ";
|
|
FOR i = 0 TO 12
|
|
PRINT Fibonacci(i);
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
PRINT "Primes up to 50: ";
|
|
FOR i = 2 TO 50
|
|
IF IsPrime(i) THEN PRINT i;
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
PRINT "GCD(48, 18) = "; GCD(48, 18)
|
|
PRINT "GCD(100, 75) = "; GCD(100, 75)
|
|
PRINT "GCD(17, 13) = "; GCD(17, 13)
|
|
|
|
PRINT "Power(2, 10) = "; Power(2.0, 10)
|
|
PRINT "Power(3, 5) = "; Power(3.0, 5)
|
|
PRINT "Power(10, 0) = "; Power(10.0, 0)
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 7: Functions returning DOUBLE
|
|
' ============================================================
|
|
PRINT "==== PART 7: Double Functions ===="
|
|
|
|
FUNCTION Distance(BYVAL x1 AS DOUBLE, BYVAL y1 AS DOUBLE, BYVAL x2 AS DOUBLE, BYVAL y2 AS DOUBLE) AS DOUBLE
|
|
LOCAL dx AS DOUBLE
|
|
LOCAL dy AS DOUBLE
|
|
dx = x2 - x1
|
|
dy = y2 - y1
|
|
Distance = SQR(dx * dx + dy * dy)
|
|
END FUNCTION
|
|
|
|
FUNCTION DegToRad(BYVAL deg AS DOUBLE) AS DOUBLE
|
|
DegToRad = deg * 3.14159265358979 / 180.0
|
|
END FUNCTION
|
|
|
|
FUNCTION CircleArea(BYVAL r AS DOUBLE) AS DOUBLE
|
|
CircleArea = 3.14159265358979 * r * r
|
|
END FUNCTION
|
|
|
|
FUNCTION CelsiusToFahr(BYVAL c AS DOUBLE) AS DOUBLE
|
|
CelsiusToFahr = c * 9.0 / 5.0 + 32.0
|
|
END FUNCTION
|
|
|
|
FUNCTION FahrToCelsius(BYVAL f AS DOUBLE) AS DOUBLE
|
|
FahrToCelsius = (f - 32.0) * 5.0 / 9.0
|
|
END FUNCTION
|
|
|
|
PRINT "Distance (0,0)-(3,4) = "; Distance(0.0, 0.0, 3.0, 4.0)
|
|
PRINT "Distance (1,1)-(4,5) = "; Distance(1.0, 1.0, 4.0, 5.0)
|
|
PRINT "90 degrees in radians = "; DegToRad(90.0)
|
|
PRINT "Circle area r=10 = "; CircleArea(10.0)
|
|
PRINT "100C in F = "; CelsiusToFahr(100.0)
|
|
PRINT "212F in C = "; FahrToCelsius(212.0)
|
|
PRINT "0C in F = "; CelsiusToFahr(0.0)
|
|
PRINT "32F in C = "; FahrToCelsius(32.0)
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 8: Functions returning STRING
|
|
' ============================================================
|
|
PRINT "==== PART 8: String Functions ===="
|
|
|
|
FUNCTION Repeat$(BYVAL s AS STRING, BYVAL count AS INTEGER) AS STRING
|
|
LOCAL result$ AS STRING
|
|
LOCAL idx AS INTEGER
|
|
result$ = ""
|
|
FOR idx = 1 TO count
|
|
result$ = result$ + s
|
|
NEXT idx
|
|
Repeat$ = result$
|
|
END FUNCTION
|
|
|
|
FUNCTION Reverse$(BYVAL s AS STRING) AS STRING
|
|
LOCAL result$ AS STRING
|
|
LOCAL idx AS INTEGER
|
|
LOCAL ln AS INTEGER
|
|
result$ = ""
|
|
ln = LEN(s)
|
|
FOR idx = ln TO 1 STEP -1
|
|
result$ = result$ + MID$(s, idx, 1)
|
|
NEXT idx
|
|
Reverse$ = result$
|
|
END FUNCTION
|
|
|
|
FUNCTION PadRight$(BYVAL s AS STRING, BYVAL width AS INTEGER) AS STRING
|
|
LOCAL result$ AS STRING
|
|
LOCAL idx AS INTEGER
|
|
result$ = s
|
|
FOR idx = LEN(s) TO width - 1
|
|
result$ = result$ + " "
|
|
NEXT idx
|
|
PadRight$ = result$
|
|
END FUNCTION
|
|
|
|
FUNCTION ReplaceAll$(BYVAL src AS STRING, BYVAL find AS STRING, BYVAL repl AS STRING) AS STRING
|
|
LOCAL result$ AS STRING
|
|
LOCAL pos AS INTEGER
|
|
LOCAL findLen AS INTEGER
|
|
result$ = src
|
|
findLen = LEN(find)
|
|
pos = INSTR(result$, find)
|
|
WHILE pos > 0
|
|
result$ = LEFT$(result$, pos - 1) + repl + MID$(result$, pos + findLen)
|
|
pos = INSTR(result$, find)
|
|
WEND
|
|
ReplaceAll$ = result$
|
|
END FUNCTION
|
|
|
|
PRINT "Repeat(abc, 4) = "; Repeat$("abc", 4)
|
|
PRINT "Repeat(XY, 5) = "; Repeat$("XY", 5)
|
|
PRINT "Reverse(Hello) = "; Reverse$("Hello")
|
|
PRINT "Reverse(abcdef) = "; Reverse$("abcdef")
|
|
PRINT "PadRight(hi, 10) = ["; PadRight$("hi", 10); "]"
|
|
PRINT "Replace(aabbcc, bb, XX) = "; ReplaceAll$("aabbcc", "bb", "XX")
|
|
PRINT "Replace(abcabc, abc, x) = "; ReplaceAll$("abcabc", "abc", "x")
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 9: Subroutines with BYREF
|
|
' ============================================================
|
|
PRINT "==== PART 9: BYREF ===="
|
|
|
|
SUB Swap(BYREF a AS INTEGER, BYREF b AS INTEGER)
|
|
LOCAL t AS INTEGER
|
|
t = a
|
|
a = b
|
|
b = t
|
|
END SUB
|
|
|
|
SUB Increment(BYREF val AS INTEGER, BYVAL amount AS INTEGER)
|
|
val = val + amount
|
|
END SUB
|
|
|
|
SUB Triple(BYREF a AS INTEGER, BYREF b AS INTEGER, BYREF c AS INTEGER)
|
|
a = a * 3
|
|
b = b * 3
|
|
c = c * 3
|
|
END SUB
|
|
|
|
SUB MinMax(BYVAL a AS INTEGER, BYVAL b AS INTEGER, BYREF outMin AS INTEGER, BYREF outMax AS INTEGER)
|
|
IF a < b THEN
|
|
outMin = a
|
|
outMax = b
|
|
ELSE
|
|
outMin = b
|
|
outMax = a
|
|
END IF
|
|
END SUB
|
|
|
|
DIM p AS INTEGER
|
|
DIM q AS INTEGER
|
|
DIM r AS INTEGER
|
|
DIM mn AS INTEGER
|
|
DIM mx AS INTEGER
|
|
|
|
p = 100
|
|
q = 200
|
|
PRINT "Before Swap: p="; p; " q="; q
|
|
CALL Swap(p, q)
|
|
PRINT "After Swap: p="; p; " q="; q
|
|
|
|
p = 10
|
|
CALL Increment(p, 5)
|
|
PRINT "After Increment(10, 5): "; p
|
|
CALL Increment(p, 100)
|
|
PRINT "After Increment(15, 100): "; p
|
|
|
|
p = 2
|
|
q = 3
|
|
r = 4
|
|
PRINT "Before Triple: "; p; " "; q; " "; r
|
|
CALL Triple(p, q, r)
|
|
PRINT "After Triple: "; p; " "; q; " "; r
|
|
|
|
CALL MinMax(42, 17, mn, mx)
|
|
PRINT "MinMax(42, 17): min="; mn; " max="; mx
|
|
|
|
CALL MinMax(3, 99, mn, mx)
|
|
PRINT "MinMax(3, 99): min="; mn; " max="; mx
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 10: STATIC variables
|
|
' ============================================================
|
|
PRINT "==== PART 10: STATIC ===="
|
|
|
|
FUNCTION Counter() AS INTEGER
|
|
STATIC c AS INTEGER
|
|
c = c + 1
|
|
Counter = c
|
|
END FUNCTION
|
|
|
|
FUNCTION Accumulator(BYVAL val AS DOUBLE) AS DOUBLE
|
|
STATIC sum AS DOUBLE
|
|
sum = sum + val
|
|
Accumulator = sum
|
|
END FUNCTION
|
|
|
|
FUNCTION CallTracker(BYVAL name AS STRING) AS INTEGER
|
|
STATIC calls AS INTEGER
|
|
calls = calls + 1
|
|
PRINT " CallTracker("; name; ") call #"; calls
|
|
CallTracker = calls
|
|
END FUNCTION
|
|
|
|
PRINT "Counter sequence: ";
|
|
FOR i = 1 TO 8
|
|
PRINT Counter();
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
PRINT "Accumulator: ";
|
|
x = Accumulator(10.0)
|
|
PRINT x;
|
|
x = Accumulator(20.0)
|
|
PRINT x;
|
|
x = Accumulator(30.0)
|
|
PRINT x;
|
|
x = Accumulator(5.5)
|
|
PRINT x;
|
|
PRINT ""
|
|
|
|
i = CallTracker("first")
|
|
i = CallTracker("second")
|
|
i = CallTracker("third")
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 11: Classic BASIC with line numbers
|
|
' ============================================================
|
|
PRINT "==== PART 11: Line Numbers ===="
|
|
|
|
' Mix of modern and classic
|
|
DIM classicVar AS INTEGER
|
|
classicVar = 0
|
|
|
|
1000 classicVar = classicVar + 1
|
|
1010 IF classicVar >= 5 THEN GOTO 1030
|
|
1020 GOTO 1000
|
|
1030 PRINT "Classic loop result: "; classicVar
|
|
|
|
' GOSUB/RETURN
|
|
DIM gosubResult AS INTEGER
|
|
gosubResult = 0
|
|
|
|
1100 PRINT "Before GOSUB"
|
|
1110 GOSUB 1200
|
|
1120 PRINT "gosubResult = "; gosubResult
|
|
1130 GOSUB 1200
|
|
1140 PRINT "gosubResult = "; gosubResult
|
|
1150 GOTO 1300
|
|
|
|
1200 gosubResult = gosubResult + 100
|
|
1210 PRINT " In GOSUB, gosubResult = "; gosubResult
|
|
1220 RETURN
|
|
|
|
1300 PRINT "After all GOSUBs"
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 12: Complex nested structures
|
|
' ============================================================
|
|
PRINT "==== PART 12: Nested Structures ===="
|
|
|
|
' Nested loops with conditions
|
|
DIM count AS INTEGER
|
|
count = 0
|
|
FOR i = 1 TO 10
|
|
FOR j = 1 TO 10
|
|
IF i + j = 10 THEN
|
|
PRINT i; "+"; j; "=10 ";
|
|
count = count + 1
|
|
END IF
|
|
NEXT j
|
|
NEXT i
|
|
PRINT ""
|
|
PRINT "Found "; count; " pairs"
|
|
|
|
' FizzBuzz
|
|
PRINT "FizzBuzz 1-30:"
|
|
FOR i = 1 TO 30
|
|
IF i MOD 15 = 0 THEN
|
|
PRINT "FizzBuzz";
|
|
ELSEIF i MOD 3 = 0 THEN
|
|
PRINT "Fizz";
|
|
ELSEIF i MOD 5 = 0 THEN
|
|
PRINT "Buzz";
|
|
ELSE
|
|
PRINT i;
|
|
END IF
|
|
IF i < 30 THEN PRINT ",";
|
|
NEXT i
|
|
PRINT ""
|
|
|
|
' Pascal's triangle
|
|
PRINT "Pascal's triangle (6 rows):"
|
|
DIM pascal(10) AS INTEGER
|
|
DIM newPascal(10) AS INTEGER
|
|
pascal(0) = 1
|
|
|
|
FOR i = 0 TO 5
|
|
' Print leading spaces
|
|
FOR j = 0 TO 4 - i
|
|
PRINT " ";
|
|
NEXT j
|
|
' Print values
|
|
FOR j = 0 TO i
|
|
PRINT pascal(j); " ";
|
|
NEXT j
|
|
PRINT ""
|
|
' Compute next row
|
|
newPascal(0) = 1
|
|
FOR j = 1 TO i
|
|
newPascal(j) = pascal(j - 1) + pascal(j)
|
|
NEXT j
|
|
newPascal(i + 1) = 1
|
|
FOR j = 0 TO i + 1
|
|
pascal(j) = newPascal(j)
|
|
NEXT j
|
|
NEXT i
|
|
|
|
' Sieve of Eratosthenes
|
|
DIM sieve(100) AS INTEGER
|
|
FOR i = 0 TO 100
|
|
sieve(i) = 1
|
|
NEXT i
|
|
sieve(0) = 0
|
|
sieve(1) = 0
|
|
|
|
FOR i = 2 TO 10
|
|
IF sieve(i) = 1 THEN
|
|
j = i * i
|
|
WHILE j <= 100
|
|
sieve(j) = 0
|
|
j = j + i
|
|
WEND
|
|
END IF
|
|
NEXT i
|
|
|
|
PRINT "Primes to 100 (sieve): ";
|
|
count = 0
|
|
FOR i = 2 TO 100
|
|
IF sieve(i) = 1 THEN
|
|
PRINT i;
|
|
count = count + 1
|
|
END IF
|
|
NEXT i
|
|
PRINT ""
|
|
PRINT "Count: "; count
|
|
|
|
' Collatz sequence
|
|
FUNCTION Collatz(BYVAL n AS INTEGER) AS INTEGER
|
|
LOCAL steps AS INTEGER
|
|
steps = 0
|
|
WHILE n <> 1
|
|
IF n MOD 2 = 0 THEN
|
|
n = n / 2
|
|
ELSE
|
|
n = n * 3 + 1
|
|
END IF
|
|
steps = steps + 1
|
|
WEND
|
|
Collatz = steps
|
|
END FUNCTION
|
|
|
|
PRINT ""
|
|
PRINT "Collatz steps:"
|
|
FOR i = 1 TO 20
|
|
PRINT " n="; i; " steps="; Collatz(i)
|
|
NEXT i
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 13: SUB with no parameters
|
|
' ============================================================
|
|
PRINT "==== PART 13: Parameterless SUB ===="
|
|
|
|
SUB PrintSeparator()
|
|
PRINT "--------------------"
|
|
END SUB
|
|
|
|
SUB PrintBanner()
|
|
CALL PrintSeparator()
|
|
PRINT " BASIC 2 C"
|
|
CALL PrintSeparator()
|
|
END SUB
|
|
|
|
CALL PrintBanner()
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' PART 14: Edge cases and stress tests
|
|
' ============================================================
|
|
PRINT "==== PART 14: Edge Cases ===="
|
|
|
|
' Zero iterations
|
|
PRINT "Zero-iteration FOR: [";
|
|
FOR i = 10 TO 5
|
|
PRINT "SHOULD NOT PRINT";
|
|
NEXT i
|
|
PRINT "]"
|
|
|
|
' Single iteration
|
|
PRINT "Single-iteration FOR: [";
|
|
FOR i = 5 TO 5
|
|
PRINT i;
|
|
NEXT i
|
|
PRINT "]"
|
|
|
|
' Deeply nested IF
|
|
n = 5
|
|
IF n > 0 THEN
|
|
IF n > 1 THEN
|
|
IF n > 2 THEN
|
|
IF n > 3 THEN
|
|
IF n > 4 THEN
|
|
PRINT "n > 4 (deeply nested)"
|
|
END IF
|
|
END IF
|
|
END IF
|
|
END IF
|
|
END IF
|
|
|
|
' Long expression
|
|
x = 1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0 + 8.0 + 9.0 + 10.0
|
|
PRINT "Sum 1..10 (doubles) = "; x
|
|
|
|
' Integer overflow test (within int range)
|
|
i = 32000
|
|
i = i * 2
|
|
PRINT "32000 * 2 = "; i
|
|
|
|
' Negative number operations
|
|
i = -10
|
|
PRINT "Abs(-10) = "; Abs2(-10)
|
|
PRINT "-(-10) = "; -i
|
|
|
|
' Multiple function calls in one expression
|
|
i = Max(Min(100, 50), Max(20, 30))
|
|
PRINT "Max(Min(100,50), Max(20,30)) = "; i
|
|
|
|
' Function as argument to function
|
|
PRINT "Factorial(Max(3, 4)) = "; Factorial(Max(3, 4))
|
|
|
|
' String function chaining
|
|
PRINT "UCASE$(LEFT$(hello world, 5)) = "; UCASE$(LEFT$("hello world", 5))
|
|
|
|
PRINT ""
|
|
|
|
' ============================================================
|
|
' FINAL SUMMARY
|
|
' ============================================================
|
|
PRINT "==== ALL TESTS COMPLETE ===="
|
|
PRINT "If you see this, all features work!"
|