(require 'basic)
(defun basic-test (program output &rest input)
"Run PROGRAM through the BASIC compiler and compare its output to OUTPUT.
\nAny optional INPUT parameters will be used to fill input prompts."
(let ((basic-debug-log t))
(save-excursion
(with-temp-buffer
(insert program)
(basic-run-test input))
(set-buffer "*basic-output*")
(let ((buffer-str (buffer-substring-no-properties (point-min) (point-max))))
(when (> (length buffer-str) (length output))
(setq output (concat output "\n")))
(assert (string= buffer-str output)))
)))
(basic-test
"
10 REM Remark Test
20 REM `1234567890-=
30 REM ~!@#$%^&*()_+
40 REM []\\;',./
50 REM {}|:\"<>?
"
"")
(basic-test
"
10 REM BASIC Test: Math
20 PRINT \"BASIC Test: Math\": PRINT
30 A = -1 * 10 + 6 * 10
40 PRINT A
50 A = 10 * -1 + 6 * 10
60 PRINT A
70 A = -5 + 6 * 20 / 2 - 5
80 PRINT A
90 A = ((-1 + 6) * 20) / (5 - 3)
100 PRINT A
"
"BASIC Test: Math
50
50
50
50
")
(basic-test
"
10 REM BASIC Test: Strings
20 PRINT \"BASIC Test: Strings\": PRINT
30 S$ = \"1\"
40 PRINT S$
50 T$ = \"2\"
60 PRINT S$ + T$
70 S$ = S$ + T$ + \"3\"
80 PRINT S$
"
"BASIC Test: Strings
1
12
123
")
(basic-test
"
10 REM BASIC Test: Undeclared Vars
20 PRINT \"BASIC Test: Undeclared Vars\": PRINT
30 A = A + 1
40 PRINT A
50 S$ = S$ + \"1\"
60 PRINT S$
"
"BASIC Test: Undeclared Vars
1
1
")
(basic-test
"
10 REM BASIC Test: DATA/READ/RESTORE
20 PRINT \"BASIC Test: DATA/READ/RESTORE\": PRINT
30 DATA 1, 2, 3
40 FOR I = 1 TO 3
50 READ A
60 PRINT \"#\" I \" = \" A
70 NEXT
80 FOR I = 4 TO 6
90 READ A
100 PRINT \"#\" I \" = \" A
110 NEXT
120 RESTORE
130 FOR I = 1 TO 6
140 READ A
150 PRINT \"#\" I \" = \" A
160 NEXT
170 DATA 4, 5, 6
"
"BASIC Test: DATA/READ/RESTORE
#1 = 1
#2 = 2
#3 = 3
#4 = 4
#5 = 5
#6 = 6
#1 = 1
#2 = 2
#3 = 3
#4 = 4
#5 = 5
#6 = 6
")
(basic-test
"
10 REM BASIC Test: DEF
20 PRINT \"BASIC Test: DEF\": PRINT
30 DEF FNA(X)=X+1
40 PRINT STR$(FNA(1)) + \" + \" + STR$(FNA(2)) + \" = \" + STR$(FNA(1)+FNA(2))
50 DEF FNB(Z)=2*Z+1
60 FOR I = 1 TO 5
70 Z=INT(10+FNB(I)-.5*I)
80 PRINT Z;
90 NEXT I
100 PRINT
"
"BASIC Test: DEF
2 + 3 = 5
1214151718
")
(basic-test
"
10 REM BASIC Test: DIM
20 PRINT \"BASIC Test: DIM\": PRINT
30 DIM A(10), B(10,10), C(10,10,10), S$(10), T$(10,10)
100 FOR I = 1 TO 10
110 A(I) = I
120 NEXT
130 FOR I = 6 TO 10
140 PRINT A(I-5)
150 NEXT
160 A = 100
170 PRINT A
180 PRINT A(10)
200 FOR I = 1 TO 10
210 S$(I) = CHR$(64+I)
220 NEXT
230 FOR I = 6 TO 10
240 PRINT S$(I-5)
250 NEXT
260 S$ = \"Z\"
270 PRINT S$
280 PRINT S$(10)
"
"BASIC Test: DIM
1
2
3
4
5
100
10
A
B
C
D
E
Z
J
")
(basic-test
"
10 REM BASIC Test: END
20 PRINT \"BASIC Test: END\": PRINT
30 END
40 PRINT \"Error\"
"
"BASIC Test: END
")
(basic-test
"
10 REM BASIC Test: FOR/NEXT
20 PRINT \"BASIC Test: FOR/NEXT\": PRINT
30 LET C = 0
40 FOR I = 1 TO 100
50 C = C + I
60 NEXT
70 PRINT C
80 FOR I = 0 TO -50 STEP -1
90 C = C + I
100 NEXT I
110 PRINT C
"
"BASIC Test: FOR/NEXT
5050
3775
")
(basic-test
"
10 REM BASIC Test: GOTO
20 PRINT \"BASIC Test: GOTO\": PRINT
20 GOTO 70
30 PRINT \"Error\"
40 PRINT \"Test 2\"
50 END
60 PRINT \"Error\"
70 PRINT \"Test 1\"
80 GOTO 40
90 PRINT \"Error\"
"
"BASIC Test: GOTO
Test 1
Test 2")
(basic-test
"
10 REM BASIC Test: GOSUB/RETURN
20 PRINT \"BASIC Test: GOSUB/RETURN\": PRINT
30 PRINT \"Pass 1\"
40 GOSUB 80
50 PRINT \"Pass 2\"
60 GOSUB 140
70 END
80 PRINT \"Test 1\"
90 GOSUB 140
100 RETURN
110 PRINT \"Test 3\"
120 GOSUB 170
130 RETURN
140 PRINT \"Test 2\"
150 GOSUB 110
160 RETURN
170 PRINT \"Test 4\"
180 RETURN
190 END
"
"BASIC Test: GOSUB/RETURN
Pass 1
Test 1
Test 2
Test 3
Test 4
Pass 2
Test 2
Test 3
Test 4
")
(basic-test
"
10 REM BASIC Test: INPUT
20 PRINT \"BASIC Test: INPUT\": PRINT
30 INPUT \"Input number: \", N
40 INPUT \"Input string: \"; S$
50 PRINT \"Number = \", N, \", String = \", \"'\" + S$ + \"'\"
"
"BASIC Test: INPUT
Input number: 1
Input string: test
Number = 1 , String = 'test'
"
1 "test")
(basic-test
"
10 REM BASIC Test: LET
20 PRINT \"BASIC Test: LET\": PRINT
30 LET A = 1
40 B = 2
50 PRINT \"A = \"; A; \", B = \"; B
"
"BASIC Test: LET
A = 1, B = 2
")
(basic-test
"
10 REM BASIC Test: PRINT
20 PRINT \"BASIC Test: PRINT\": PRINT
30 LET A = 1
40 LET B = 2
50 LET C$ = \"test\"
60 LET D$ = \"more\"
70 PRINT \"Print test, \"; A; \", \"; B;
80 PRINT \", \"; C$;
90 PRINT \", \"; D$
100 PRINT \"Print test 2, \" + STR$(A) + \", \" + STR$(B);
110 PRINT \", \"+C$;
120 PRINT \", \"+D$
130 PRINT \"Tab test:\"
140 PRINT TAB(5); \"*\"; TAB(10); \"*\"; TAB(15); \"*\"; TAB(20); \"*\"; TAB(25); \"*\"; TAB(30); \"*\"
150 PRINT \"123456789012345678901234567890\"
"
"BASIC Test: PRINT
Print test, 1, 2, test, more
Print test 2, 1, 2, test, more
Tab test:
* * * * * *
123456789012345678901234567890
")
(basic-test
"
10 REM BASIC Test: REM
20 PRINT \"BASIC Test: REM\": PRINT
30 REM REM Test
"
"BASIC Test: REM
")
(basic-test
"
10 REM BASIC Test: STOP
20 PRINT \"BASIC Test: STOP\": PRINT
30 STOP
40 PRINT \"Error\"
"
"BASIC Test: STOP
")
(basic-test
"
10 REM BASIC Test: Reserved Words
20 PRINT \"BASIC Test: Reserved Words\": PRINT
30 FOR I = 0 TO 100 STEP 2
40 IF I MOD 10 <> 0 THEN 70
50 IF (I <= 20 OR I >= 80) AND I <> 100 THEN 70
60 PRINT I
70 NEXT I
"
"BASIC Test: Reserved Words
30
40
50
60
70
100
")
(basic-test
"
10 REM BASIC Test: Functions
20 PRINT \"BASIC Test: Functions\": PRINT
30 PRINT \"ABS(10) = \"; ABS(10)
31 PRINT \"ABS(0) = \"; ABS(0)
32 PRINT \"ABS(-10) = \"; ABS(-10)
40 PRINT \"ASC('A') = \"; ASC(\"A\")
41 PRINT \"ASC('Z') = \"; ASC(\"Z\")
50 PRINT \"ATN(10) = \"; ATN(10)
51 PRINT \"ATN(0) = \"; ATN(0)
52 PRINT \"ATN(-10) = \"; ATN(-10)
60 PRINT \"CHR$(65) = \"; CHR$(65)
61 PRINT \"CHR$(90) = \"; CHR$(90)
70 PRINT \"COS(10) = \"; COS(10)
71 PRINT \"COS(0) = \"; COS(0)
72 PRINT \"COS(-10) = \"; COS(-10)
80 PRINT \"EXP(10) = \"; EXP(10)
81 PRINT \"EXP(0) = \"; EXP(0)
82 PRINT \"EXP(-10) = \"; EXP(-10)
90 PRINT \"INT(10.7) = \"; INT(10.7)
91 PRINT \"INT(0) = \"; INT(0)
92 PRINT \"INT(-10.2) = \"; INT(-10.2)
100 PRINT \"LEFT$('California', 2) = \"; LEFT$(\"California\", 2)
101 PRINT \"LEFT$('Minnesota', 3) = \"; LEFT$(\"Minnesota\", 3)
110 PRINT \"LEN('California') = \"; LEN(\"California\")
111 PRINT \"LEN('Minnesota') = \"; LEN(\"Minnesota\")
120 PRINT \"LOG(10) = \"; LOG(10)
121 PRINT \"LOG(0) = \"; LOG(0)
122 PRINT \"LOG(-10) = \"; LOG(-10)
130 PRINT \"MID$('California', 1) = \"; MID$(\"California\", 1)
130 PRINT \"MID$('California', 2, 3) = \"; MID$(\"California\", 2, 3)
130 PRINT \"MID$('California', 10) = \"; MID$(\"California\", 10)
130 PRINT \"MID$('California', 12) =\"; MID$(\"California\", 12)
131 PRINT \"MID$('Minnesota', 2) = \"; MID$(\"Minnesota\", 2)
131 PRINT \"MID$('Minnesota', 4, 5) = \"; MID$(\"Minnesota\", 4, 5)
131 PRINT \"MID$('Minnesota', 8) = \"; MID$(\"Minnesota\", 8)
131 PRINT \"MID$('Minnesota', 10) =\"; MID$(\"Minnesota\", 10)
140 PRINT \"RND(-10) = \"; RND(-10)
141 PRINT \"RND(0) = \"; RND(0)
150 PRINT \"RIGHT$('California', 2) = \"; RIGHT$(\"California\", 2)
151 PRINT \"RIGHT$('Minnesota', 3) = \"; RIGHT$(\"Minnesota\", 3)
160 PRINT \"SGN(10) = \"; SGN(10)
161 PRINT \"SGN(0) = \"; SGN(0)
162 PRINT \"SGN(-10) = \"; SGN(-10)
170 PRINT \"SIN(10) = \"; SIN(10)
171 PRINT \"SIN(0) = \"; SIN(0)
172 PRINT \"SIN(-10) = \"; SIN(-10)
180 PRINT \"SQR(10) = \"; SQR(10)
181 PRINT \"SQR(0) = \"; SQR(0)
182 PRINT \"SQR(-10) = \"; SQR(-10)
190 PRINT \"STR$(10) = \"; STR$(10)
191 PRINT \"STR$(0) = \"; STR$(0)
192 PRINT \"STR$(-10) = \"; STR$(-10)
200 PRINT \"TAB(1) =\"; TAB(1); \"Tabbed 1\"
201 PRINT \"TAB(5) =\"; TAB(5); \"Tabbed 5\"
202 PRINT \"TAB(10) =\"; TAB(10); \"Tabbed 10\"
203 PRINT \"TAB(20) = \"; TAB(20); \"Tabbed 20\"
210 PRINT \"TAN(10) = \"; TAN(10)
211 PRINT \"TAN(0) = \"; TAN(0)
212 PRINT \"TAN(-10) = \"; TAN(-10)
220 PRINT \"VAL('10') = \"; VAL(\"10\")
221 PRINT \"VAL('0') = \"; VAL(\"0\")
222 PRINT \"VAL('-10') = \"; VAL(\"-10\")
"
"BASIC Test: Functions
ABS(10) = 10
ABS(0) = 0
ABS(-10) = 10
ASC('A') = 65
ASC('Z') = 90
ATN(10) = 1.4711276743037347
ATN(0) = 0.0
ATN(-10) = -1.4711276743037347
CHR$(65) = A
CHR$(90) = Z
COS(10) = -0.8390715290764524
COS(0) = 1.0
COS(-10) = -0.8390715290764524
EXP(10) = 22026.465794806718
EXP(0) = 1.0
EXP(-10) = 4.5399929762484854e-05
INT(10.7) = 10
INT(0) = 0
INT(-10.2) = -11
LEFT$('California', 2) = Ca
LEFT$('Minnesota', 3) = Min
LEN('California') = 10
LEN('Minnesota') = 9
LOG(10) = 2.302585092994046
LOG(0) = -1.0e+INF
LOG(-10) = 0.0e+NaN
MID$('California', 1) = California
MID$('California', 2, 3) = ali
MID$('California', 10) = a
MID$('California', 12) =
MID$('Minnesota', 2) = innesota
MID$('Minnesota', 4, 5) = nesot
MID$('Minnesota', 8) = ta
MID$('Minnesota', 10) =
RND(-10) = 0.18235988178869306
RND(0) = 0.18235988178869306
RIGHT$('California', 2) = ia
RIGHT$('Minnesota', 3) = ota
SGN(10) = 1
SGN(0) = 0
SGN(-10) = -1
SIN(10) = -0.5440211108893698
SIN(0) = 0.0
SIN(-10) = 0.5440211108893698
SQR(10) = 3.1622776601683795
SQR(0) = 0.0
SQR(-10) = -0.0e+NaN
STR$(10) = 10
STR$(0) = 0
STR$(-10) = -10
TAB(1) =
Tabbed 1
TAB(5) =
Tabbed 5
TAB(10) =Tabbed 10
TAB(20) = Tabbed 20
TAN(10) = 0.6483608274590866
TAN(0) = 0.0
TAN(-10) = -0.6483608274590866
VAL('10') = 10
VAL('0') = 0
VAL('-10') = -10
")
(basic-test
"
10 REM BASIC Test 1
20 PRINT \"BASIC Test 1\": PRINT
30 PRINT \"Hello World\"
40 END
"
"BASIC Test 1
Hello World
")
(basic-test
"
10 REM BASIC Test 2
20 PRINT \"BASIC Test 2\": PRINT
30 PRINT \"Summing the values between 1 and 100\"
40 LET total = 0
50 FOR I = 1 TO 100
60 LET total = total + I
70 NEXT I
80 PRINT \"The total of all digits between 1 and 100 is \" total
90 END
"
"BASIC Test 2
Summing the values between 1 and 100
The total of all digits between 1 and 100 is 5050
")
(basic-test
"
10 REM BASIC Test 3
20 PRINT \"BASIC Test 3\": PRINT
30 INPUT \"What's your age? \"; age
40 PRINT \"You are \" age * 7 \" in dog years!\"
50 END
"
"BASIC Test 3
What's your age? 35
You are 245 in dog years!
"
35)
(basic-test
"
10 REM BASIC Test 4
20 PRINT \"BASIC Test 4\": PRINT
30 A = 1: FOR I = A TO A+2 : PRINT I : NEXT
40 END
"
"BASIC Test 4
1
2
3
")
(basic-test
"
10 REM BASIC Tests Completely Successfully
20 PRINT \"BASIC Tests Completely Successfully\"
30 END
"
"BASIC Tests Completely Successfully
")