help TinyBASIC implementation (translated from izibasic spaghetti)
Posted: Mon Dec 04, 2023 2:59 am
help TinyBASIC implementation (translated from izibasic spaghetti)
Tiny basic legendary :
https://en.wikipedia.org/wiki/Tiny_BASI ... Tiny_BASIC[/url]
Implemented by izibasic author :
https://www.aldweb.com/file/tinybasic.zip
Translated to liberty basic by it's author:
http://www.runbasic.com/seaside/go/runb ... k=lyjfWjgp
http://www.runbasic.com/seaside/go/runb ... k=lyjfWjgp
Translated to Purebasic :
Running :

enjoy this spaghetti , but it has bugs , any one try to fix it ?
Tiny basic legendary :
https://en.wikipedia.org/wiki/Tiny_BASI ... Tiny_BASIC[/url]
Implemented by izibasic author :
https://www.aldweb.com/file/tinybasic.zip
Code: Select all
' tinyBasic.iBas
' ---------------------------------
' tinyBasic v1.2
' Copyleft 2005-2007
' by Laurent DUVEAU
' http://www.aldweb.com/
'
' This file is an iziBasic for
' Palm sample Tiny Basic
' interpreter, loosely adapted
' from the original Tiny Basic
' version by Li Chen Wang.
' ---------------------------------
{CREATORID "LDtB"}
{VERSION "1.2"}
{RESOURCEFILE "tinyBasic.rsrc"}
{PARSER ON}
{SECUREFILES OFF}
' A temp
' B temp
' C character index in line
' E line number for error msg
' I temp (loops)
' K temp
' L number of lines
' N number
' S expression stack index
' T temp
' V variable index
' A$ temp
' B$ temp
' C$ character
' D$ single statement
' E$ error message
' G$ string code (")
' H$ HALT code (Line Feed)
' I$-R$ Help
' Z$=A$(26) statement input
Dim A$(125) ' [27-125] = 99 program lines
Dim A(82) ' [27-52] = 26 variables
' [53-82] = 30 items math stack
CONST I$="BYE, CLEAR, CLS, END"
CONST J$="HELP, MEM, NEW, RUN"
CONST K$="GOTO | LOAD | SAVE <exp>"
CONST L$="IF <exp> THEN <statement>"
CONST M$="INPUT <var>"
CONST N$="[LET] <var>=<exp>"
CONST O$="LIST [<exp>|PAUSE]"
CONST P$="PRINT <exp|str>[,<exp|str>][;]"
CONST Q$="REM <any>"
CONST R$="Functions: TICKS, TICKSPERSEC"
BEGIN
G$=CHR$(34) : H$=CHR$(10)
B=FILEEXISTS("tinyBas0")
IF B=TRUE THEN
Z$="load0:run"
Goto _AutoRun
ENDIF
_Ready:
IF E$<>"" THEN
IF E>0 THEN
E$="#Err in "+STR$(E,0)+": "+E$
ELSE
E$="#Err: "+E$
ENDIF
PRINT E$ : E$=""
ENDIF
PRINT "Ready"
_Input:
INPUT Z$ : PRINT Z$
_AutoRun:
L=26 : C=1 : Gosub _GetNumber : E=N
IF N=0 THEN
IF C$="" Goto _Ready
Goto _NextStatement
ELSE
B=(N>0) And (N=Int(N))
IF B=TRUE THEN
Gosub _EnterLine
IF E$<>"" Goto _Ready
Goto _Input
ELSE
E=0 : E$="Invalid line number"
Goto _Ready
ENDIF
ENDIF
_Exec:
Gosub _GetNumber : E=N
_NextStatement:
A$=INKEY$
IF A$=H$ THEN
A$="Break in "+STR$(E,0)
PRINT A$ : Goto _Ready
ENDIF
Gosub _GetLabel
IF E$<>"" Goto _Ready
Select Case D$
Case "if"
Gosub _GetExpression
IF E$<>"" Goto _Ready
IF N<1 THEN
B$=A$(L) : C=Len(B$)+1
Goto _FinishStatement
ENDIF
Gosub _GetLabeL
IF E$<>"" Goto _Ready
IF D$<>"then" THEN
E$="'THEN' expected"
Goto _Ready
ENDIF
Goto _NextStatement
Case "rem"
B$=A$(L) : C=Len(B$)+1
Goto _FinishStatement
Case "input"
Gosub _GetVar
IF E$<>"" Goto _Ready
INPUT N : A(V)=N
Goto _FinishStatement
Case "print"
_Print:
Gosub _SkipSpace
Gosub _GetChar
IF C$=G$ THEN
B$=""
_NextChar:
INC C : C$=MID$(A$,C,1)
IF C$="" THEN
E$="Unterminated string"
Goto _Ready
ELSE
IF C$<>G$ THEN
B$=B$+C$
Goto _NextChar
ENDIF
ENDIF
INC C : C$=MID$(A$,C,1)
IF C$=G$ THEN
B$=B$+C$
Goto _NextChar
ENDIF
PRINT B$;
ELSE
Gosub _GetExpression
IF E$<>"" Goto _Ready
B=N\1
IF B=N THEN
PRINT N USING 0;
ELSE
PRINT N;
ENDIF
ENDIF
Gosub _SkipSpace
Gosub _GetChar
IF C$="," INC C : Goto _Print
Gosub _SkipSpace
Gosub _GetChar
IF C$<>";" THEN
PRINT
ELSE
INC C
ENDIF
Goto _FinishStatement
Case "clear"
For I=27 To 52 : A(I)=0 : Next
Goto _FinishStatement
Case "run"
For I=27 To 52 : A(I)=0 : Next
L=27 : C=1
Goto _FinishStatement2
Case "goto"
Gosub _GetExpression
IF E$<>"" Goto _Ready
IF E>=N LET L=27
C=1 : T=N
_NextGoto:
IF L=126 THEN
E$="Line not found"
Goto _Ready
ENDIF
Gosub _GetNumber
IF N=T LET E=N : Goto _NextStatement
INC L : C=1
Goto _NextGoto
Case "new"
For I=27 To 125 : A$(I)="" : Next
For I=27 To 52 : A(I)=0 : Next
IF E=0 Goto _FinishStatement
Goto _Ready
Case "cls"
CLS : Goto _FinishStatement
Case "help"
For I=9 To 18
B$=A$(I) : PRINT B$
Next
Goto _FinishStatement
Case "mem"
B=126
For I=125 DOWNTO 27
B$=A$(I) : IF B$="" LET B=I
Next
B=126-B : PRINT B USING 0;
PRINT " lines free"
Goto _FinishStatement
Case "end"
Goto _Ready
Case "bye"
Goto _ExitTinyBAS
Case "list"
Gosub _GetNumber : T=N : K=L : I=C
IF T=0 THEN
Gosub _GetLabeL
IF E$="" IF D$="pause" LET I=C
E$=""
ENDIF
For L=27 To 125
C=1 : Gosub _GetNumber
B=(T=0) Or (N=T)
IF B=TRUE THEN
IF A$<>"" THEN
PRINT A$
IF D$="pause" THEN
B=(L-26) MOD 10
IF B=0 PRINT "Pause..." : WAIT
ENDIF
ENDIF
ENDIF
Next
L=K : C=I
Goto _FinishStatement
Case "save"
Gosub _GetExpression
IF E$<>"" Goto _Ready
A$="tinyBas"+STR$(N,0) : A=FALSE
OPEN A$ For OUTPUT As #1
For I=27 To 125
B$=A$(I)
IF B$<>"" PRINT #1,B$ : A=TRUE
Next
CLOSE #1
IF A=FALSE KILL A$
Goto _FinishStatement
Case "load"
Gosub _GetExpression
IF E$<>"" Goto _Ready
A$="tinyBas"+STR$(N,0)
B=FILEEXISTS(A$)
IF B=FALSE THEN
E$="File "+A$+" not found"
Goto _Ready
ENDIF
OPEN A$ For INPUT As #1
B=FALSE : I=27
While B=FALSE
B=Eof(#1)
INPUT #1,B$ : A$(I)=B$ : INC I
Wend
CLOSE #1
While I<=125
A$(I)="" : INC I
Wend
IF E=0 Goto _FinishStatement
Goto _Ready
Case "let"
Gosub _GetLabel
IF E$<>"" Goto _Ready
End Select
Gosub _ReturnVar
IF E$<>"" Goto _Ready
Gosub _SkipSpace
Gosub _GetChar
IF C$<>"=" THEN
E$="'=' expected"
Goto _Ready
ENDIF
INC C : T=V
Gosub _GetExpression
IF E$<>"" Goto _Ready
A(T)=N
_FinishStatement:
Gosub _SkipSpace
Gosub _GetChar
IF C$=":" THEN
INC C : Goto _NextStatement
ELSE
IF C$<>"" THEN
E$="End of statement expected"
Goto _Ready
ENDIF
ENDIF
IF L=26 Goto _Ready
INC L : C=1
IF L=126 THEN
E$="Program Overflow"
Goto _Ready
ENDIF
_FinishStatement2:
B$=A$(L)
IF B$="" Goto _Ready
Goto _Exec
_ExitTinyBAS:
End
_EnterLine:
L=27 : C=1 : T=N
_NextLine:
Gosub _GetNumber
B=(N<T) And (N<>0) And (L<126)
IF B=TRUE THEN
INC L : C=1 : Goto _NextLine
ENDIF
IF L=126 THEN
E$="Program Overflow"
Goto _EndEnterLine
ENDIF
IF T<>N THEN
For I=125 DOWNTO L Step -1
B=I-1 : A$(I)=A$(B)
Next
ENDIF
A$(L)=Z$
Gosub _SkipSpace
IF C$="" THEN
For I=L To 124
B=I+1 : A$(I)=A$(B)
Next
ENDIF
_EndEnterLine:
Return
_GetExpression:
A(53)=0 : S=53
Gosub _BoolExpression
N=A(S) : Goto _EndExpression
_BoolExpression:
Gosub _AddExpression
Gosub _SkipSpace
Gosub _GetChar
_NextBool:
Select Case C$
Case "="
INC C : Gosub _AddExpression
B=S-1 : A(B)=A(B)=A(S) : DEC S
Case ">"
INC C : Gosub _GetChar
IF C$="=" THEN
INC C : Gosub _AddExpression
B=S-1 : A(B)=A(B)>=A(S) : DEC S
ELSE
Gosub _AddExpression
B=S-1 : A(B)=A(B)>A(S) : DEC S
ENDIF
Case "<"
INC C : Gosub _GetChar
Select Case C$
Case "="
INC C : Gosub _AddExpression
B=S-1 : A(B)=A(B)<=A(S) : DEC S
Case ">"
INC C : Gosub _AddExpression
B=S-1 : A(B)=A(B)<>A(S) : DEC S
Case ELSE
Gosub _AddExpression
B=S-1 : A(B)=A(B)<A(S) : DEC S
End Select
End Select
Gosub _SkipSpace
Gosub _GetChar
B=Asc(C$) : B=(B>=60) And (B<=62)
IF B=TRUE Goto _NextBool
Goto _EndExpression
_AddExpression:
Gosub _MulExpression
Gosub _SkipSpace
Gosub _GetChar
_NextAdd:
Select Case C$
Case "+"
INC C : Gosub _MulExpression
B=S-1 : A(B)=A(B)+A(S) : DEC S
Case "-"
INC C : Gosub _MulExpression
B=S-1 : A(B)=A(B)-A(S) : DEC S
End Select
Gosub _SkipSpace
Gosub _GetChar
B=Asc(C$) : B=(B=43) Or (B=45)
IF B=TRUE Goto _NextAdd
Goto _EndExpression
_MulExpression:
Gosub _GroupExpression
Gosub _SkipSpace
Gosub _GetChar
_NextMul:
Select Case C$
Case "*"
INC C : Gosub _GroupExpression
B=S-1 : A(B)=A(B)*A(S) : DEC S
Case "/"
INC C : Gosub _GroupExpression
B=A(S)
IF B=0 THEN
IF E$="" LET E$="Division by zero"
DEC S : Goto _EndExpression
ELSE
B=S-1 : A(B)=A(B)/A(S) : DEC S
ENDIF
Case "\"
INC C : Gosub _GroupExpression
B=A(S)
IF B=0 THEN
IF E$="" LET E$="Division by zero"
DEC S : Goto _EndExpression
ELSE
B=S-1 : A(B)=A(B)\A(S) : DEC S
ENDIF
EndSelect
Gosub _SkipSpace
Gosub _GetChar
B=Asc(C$)
B=(B=42) Or (B=47) Or (B=92)
IF B=TRUE Goto _NextMul
Goto _EndExpression
_GroupExpression:
Gosub _SkipSpace
Gosub _GetChar
Select Case C$
Case "("
INC C : Gosub _BoolExpression
Gosub _SkipSpace
Gosub _GetChar
IF C$<>")" THEN
IF E$="" LET E$="Missing ')'"
Goto _EndExpression
ENDIF
INC C
Case ""
IF E$="" LET E$="Invalid Factor"
Case ELSE
B=Asc(C$)
B=((B<48) Or (B>57)) And (B<>45) And (B<>46)
IF B=FALSE THEN
Gosub _GetNumber
IF E$<>"" Goto _EndExpression
INC S : A(S)=N
ELSE
Gosub _GetLabel
IF E$<>"" Goto _EndExpression
B=Len(D$)
IF B=1 THEN
Gosub _ReturnVar
INC S : A(S)=A(V)
ELSE
Select Case D$
Case "ticks"
INC S : A(S)=TICKS
Case "tickspersec"
INC S : A(S)=TICKSPERSEC
Case ELSE
IF E$="" LET E$="Function expected"
EndSelect
ENDIF
ENDIF
End Select
_EndExpression:
Return
_GetNumber:
Gosub _SkipSpace
A=0
Gosub _GetChar
IF C$="-" THEN
B$="-" : INC C : Gosub _GetChar
B=Asc(C$)
B=((B<48) Or (B>57)) And (B<>46)
IF B=TRUE Goto _GetNumberError
ELSE
B$=""
ENDIF
_NextNumber:
IF C$="" Goto _GetNumberCalc
B=Asc(C$)
IF B=46 THEN
INC A
IF A>1 Goto _GetNumberError
ENDIF
B=((B<48) Or (B>57)) And (B<>46)
IF B=TRUE Goto _GetNumberCalc
B$=B$+C$ : INC C : Gosub _GetChar
Goto _NextNumber
_GetNumberError:
IF E$="" LET E$="Invalid Number"
Goto _GetNumberExit
_GetNumberCalc:
N=Val(B$)
_GetNumberExit:
Return
_GetVar:
Gosub _GetLabel
IF E$<>"" Goto _GetVarExit
_ReturnVar:
B=Asc(D$) : A=Len(D$)
A=(A<>1) Or (B<97) Or (B>122)
IF A=FALSE THEN
V=B-70
ELSE
IF E$="" LET E$="Variable expected"
ENDIF
_GetVarExit:
Return
_GetLabel:
Gosub _SkipSpace
Gosub _GetChar
D$=""
IF C$="" Goto _GetLabelError
B=Asc(C$) : B=(B<97) Or (B>122)
IF B=TRUE Goto _GetLabelError
_GetNextLabel:
D$=D$+C$ : INC C
Gosub _GetChar
IF C$="" Goto _GetLabelExit
B=Asc(C$) : B=(B>=97) And (B<=122)
IF B=TRUE Goto _GetNextLabel
Goto _GetLabelExit
_GetLabelError:
IF E$="" LET E$="Invalid label"
_GetLabelExit:
Return
_SkipSpace:
Gosub _GetChar
IF C$=" " INC C : Goto _SkipSpace
Return
_GetChar:
A$=A$(L)
C$=MID$(A$,C,1) : C$=LCASE$(C$)
Return
Translated to liberty basic by it's author:
http://www.runbasic.com/seaside/go/runb ... k=lyjfWjgp
http://www.runbasic.com/seaside/go/runb ... k=lyjfWjgp
Code: Select all
'TinyBasic.bas
' tinyBasic v1.0 - A very small and simple BASIC interpreter written in
' Run BASIC. WARNING: For uber geeks only. :-p
' Copyleft 2005 by Laurent DUVEAU
' www.aldweb.com
' an iziBasic sample program
' Ported to Run BASIC by Carl Gundel and Scott McLaughlin
' www.libertybasic.com
' A temp
' B temp
' C character index in line
' E line number for error msg
' I temp (loops)
' L number of lines
' N number
' S expression stack index
' T temp
' V variable index
' A$ temp
' B$ temp
' C$ character
' D$ single statement
' E$ error message
' G$ string code (")
' H$ HALT code (Line Feed)
' I$-R$ Help
' Z$=A$(26) statement input
Dim A$(125) ' [27-125] = 99 program lines
Dim A(82) ' [27-52] = 26 variables
' [53-82] = 30 items math stack
A$(9)="BYE, CLEAR, CLS, END"
A$(10)="HELP, MEM, NEW, RUN"
A$(11)="GOTO | LOAD | SAVE <exp>"
A$(12)="IF <exp> THEN <statement>"
A$(13)="INPUT <var>"
A$(14)="[LET] <var>=<exp>"
A$(15)="LIST [<exp>|PAUSE]"
A$(16)="PRINT <exp|str>[,<exp|str>][;]"
A$(17)="REM <any>"
TRUE = 1
FALSE = 0
'BEGIN
G$=CHR$(34) : H$=CHR$(10)
' B=FILEEXISTS("tinyBas0")
' IF B=TRUE THEN
' Z$="load0:run"
' GOTO _AutoRun
' END IF
PRINT "Tiny BASIC v1.0 for Run BASIC"
PRINT "Type HELP for commands."
[Ready]
IF E$<>"" THEN
IF E>0 THEN
E$="#Err in "+STR$(E)+": "+E$
ELSE
E$="#Err: "+E$
End IF
PRINT E$ : E$=""
End IF
PRINT "Ready"
[Input]
LINE INPUT Z$
A$(26)=Z$
[AutoRun]
L=26 : C=1 : Gosub [GetNumber] : E=N
IF N=0 THEN
IF C$="" THEN [Ready]
Goto [NextStatement]
ELSE
Gosub [EnterLine]
IF E$<>"" THEN [Ready]
Goto [Input]
End IF
[Exec]
Gosub [GetNumber] : E=N
[NextStatement]
'A$=INKEY$
'IF A$=H$ THEN
' A$="Break in "+STR$(E,0)
' PRINT A$ : GOTO [Ready
'END IF
Gosub [GetLabel]
IF E$<>"" THEN [Ready]
Select Case D$
Case "if"
Gosub [GetExpression]
IF E$<>"" THEN [Ready]
IF N<1 THEN
B$=A$(L) : C=Len(B$)+1
Goto [FinishStatement]
End IF
Gosub [GetLabel]
IF E$<>"" THEN [Ready]
IF D$<>"then" THEN
E$="'THEN' expected"
Goto [Ready]
End IF
Goto [NextStatement]
Case "rem"
B$=A$(L) : C=Len(B$)+1
Goto [FinishStatement]
Case "input"
Gosub [GetVar]
IF E$<>"" THEN [Ready]
INPUT N : A(V)=N
Goto [FinishStatement]
Case "print"
[PRINT]
Gosub [SkipSpace]
Gosub [GetChar]
IF C$=G$ THEN
B$=""
[NextChar]
C = C + 1 : C$=MID$(A$,C,1)
IF C$="" THEN
E$="Unterminated string"
Goto [Ready]
ELSE
IF C$<>G$ THEN
B$=B$+C$
Goto [NextChar]
End IF
End IF
C = C + 1 : C$=MID$(A$,C,1)
IF C$=G$ THEN
B$=B$+C$
Goto [NextChar]
End IF
PRINT B$;
ELSE
Gosub [GetExpression]
IF E$<>"" THEN [Ready]
B=N1
IF B=N THEN
PRINT N;"*";
ELSE
PRINT N;
End IF
End IF
Gosub [SkipSpace]
Gosub [GetChar]
IF C$="," THEN C = C + 1 : Goto [PRINT]
Gosub [SkipSpace]
Gosub [GetChar]
IF C$<>";" THEN
PRINT
ELSE
C = C + 1
End IF
Goto [FinishStatement]
Case "clear"
For I=27 To 52 : A(I)=0 : Next I
Goto [FinishStatement]
Case "run"
For I=27 To 52 : A(I)=0 : Next I
L=27 : C=1
Goto [FinishStatement2]
Case "goto"
Gosub [GetExpression]
IF E$<>"" THEN [Ready]
IF E>=N THEN L=27
C=1 : T=N
[NextGoto]
IF L=126 THEN
E$="Line not found"
Goto [Ready]
End IF
Gosub [GetNumber]
IF N=T THEN E=N : Goto [NextStatement]
L = L + 1 : C=1
Goto [NextGoto]
Case "new"
For I=27 To 125 : A$(I)="" : Next I
For I=27 To 52 : A(I)=0 : Next I
IF E=0 THEN [FinishStatement]
Goto [Ready]
Case "cls"
CLS : Goto [FinishStatement]
Case "help"
For I=9 To 18
B$=A$(I) : PRINT B$
Next I
Goto [FinishStatement]
Case "mem"
B=126
For I=27 To 125
diffI = 152 - I 'Cheating here
B$=A$(diffI) : IF B$="" THEN B=diffI
Next I
B=126-B : PRINT B;"*";
PRINT " lines free"
Goto [FinishStatement]
Case "end"
Goto [Ready]
Case "bye"
Goto [ExitTinyBAS]
Case "list"
Gosub [GetNumber] : T=N : A=L : I=C
IF T=0 THEN
Gosub [GetLabel]
IF E$="" And D$="pause" THEN I=C
E$=""
End IF
For L=27 To 125
C=1 : Gosub [GetNumber]
B=(T=0) Or (N=T)
IF B=TRUE THEN
IF A$<>"" THEN
PRINT A$
IF D$="pause" THEN
B = (L-26) mod 10
IF B=0 THEN PRINT "Pause..."; : INPUT AAA$
End IF
End IF
End IF
Next L
L=A : C=I
Goto [FinishStatement]
Case "save"
PRINT "SAVE, TBD"
' GOSUB [GetExpression]
' IF E$<>"" THEN [Ready]
' A$="tinyBas"+STR$(N) : A=FALSE
' OPEN A$ FOR OUTPUT AS #1
' FOR I=27 TO 125
' B$=A$(I)
' IF B$<>"" THEN PRINT #1,B$ : A=TRUE
' NEXT I
' CLOSE #1
' IF A=FALSE THEN KILL A$
' GOTO [FinishStatement]
Case "load"
PRINT "LOAD, TBD"
' GOSUB [GetExpression]
' IF E$<>"" GOTO [Ready]
' A$="tinyBas"+STR$(N,0)
' B=FILEEXISTS(A$)
' IF B=FALSE THEN
' E$="File "+A$+" not found"
' GOTO [Ready]
' END IF
' OPEN A$ FOR INPUT AS #1
' B=FALSE : I=27
' WHILE B=FALSE
' B=EOF(#1)
' INPUT #1,B$ : A$(I)=B$ : I=I+1
' WEND
' CLOSE #1
' WHILE I<=125
' A$(I)="" : I=I+1
' WEND
' IF E=0 THEN [FinishStatement]
' GOTO [Ready]
Case "let"
Gosub [GetLabel]
IF E$<>"" THEN [Ready]
End Select
Gosub [ReturnVar]
IF E$<>"" THEN [Ready]
Gosub [SkipSpace]
Gosub [GetChar]
IF C$<>"=" THEN
E$="'=' expected"
Goto [Ready]
End IF
C = C + 1 : T=V
Gosub [GetExpression]
IF E$<>"" THEN [Ready]
A(T)=N
[FinishStatement]
Gosub [SkipSpace]
Gosub [GetChar]
IF C$=":" THEN
C = C + 1 : Goto [NextStatement]
ELSE
IF C$<>"" THEN
E$="End of statement expected"
Goto [Ready]
End IF
End IF
IF L=26 THEN [Ready]
L = L + 1 : C=1
IF L=126 THEN
E$="Program Overflow"
Goto [Ready]
End IF
[FinishStatement2]
B$=A$(L)
IF B$="" THEN [Ready]
Goto [Exec]
[ExitTinyBAS]
PRINT "Thanks for using Tiny BASIC."
End
[EnterLine]
L=27 : C=1 : T=N
[NextLine]
Gosub [GetNumber]
B=(N<T) And (N<>0) And (L<126)
IF B=TRUE THEN
L = L + 1 : C=1 : Goto [NextLine]
End IF
IF L=126 THEN
E$="Program Overflow"
Goto [EndEnterLine]
End IF
IF T<>N THEN
For I=L To 125
diffI = (125+L)-I
B=diffI-1 : A$(diffI)=A$(B)
Next I
End IF
A$(L)=Z$
Gosub [SkipSpace]
IF C$="" THEN
For I=L To 124
B=I+1 : A$(I)=A$(B)
Next I
End IF
[EndEnterLine]
Return
[GetExpression]
A(53)=0 : S=53
Gosub [BoolExpression]
N=A(S) : Goto [EndExpression]
[BoolExpression]
Gosub [AddExpression]
Gosub [SkipSpace]
Gosub [GetChar]
[NextBool]
Select Case C$
Case "="
C = C + 1 : Gosub [AddExpression]
B=S-1 : A(B)=A(B)=A(S) : S = S - 1
Case ">"
C = C + 1 : Gosub [GetChar]
IF C$="=" THEN
C = C + 1 : Gosub [AddExpression]
B=S-1 : A(B)=A(B)>=A(S) : S = S - 1
ELSE
Gosub [AddExpression]
B=S-1 : A(B)=A(B)>A(S) : S = S - 1
End IF
Case "<"
C = C + 1 : Gosub [GetChar]
Select Case C$
Case "="
C = C + 1 : Gosub [AddExpression]
B=S-1 : A(B)=A(B)<=A(S) : S = S - 1
Case ">"
C = C + 1 : Gosub [AddExpression]
B=S-1 : A(B)=A(B)<>A(S) : S = S - 1
Case ELSE
Gosub [AddExpression]
B=S-1 : A(B)=A(B)<A(S) : S = S - 1
End Select
End Select
Gosub [SkipSpace]
Gosub [GetChar]
B=Asc(C$) : B=(B>=60) And (B<=62)
IF B=TRUE THEN [NextBool]
Goto [EndExpression]
[AddExpression]
Gosub [MulExpression]
Gosub [SkipSpace]
Gosub [GetChar]
[NextAdd]
Select Case C$
Case "+"
C = C + 1 : Gosub [MulExpression]
B=S-1 : A(B)=A(B)+A(S) : S = S - 1
Case "-"
C = C + 1 : Gosub [MulExpression]
B=S-1 : A(B)=A(B)-A(S) : S = S - 1
End Select
Gosub [SkipSpace]
Gosub [GetChar]
B=Asc(C$) : B=(B=43) Or (B=45)
IF B=TRUE THEN [NextAdd]
Goto [EndExpression]
[MulExpression]
Gosub [GroupExpression]
Gosub [SkipSpace]
Gosub [GetChar]
[NextMul]
Select Case C$
Case "*"
C = C + 1 : Gosub [GroupExpression]
B=S-1 : A(B)=A(B)*A(S) : S = S - 1
Case "/"
C = C + 1 : Gosub [GroupExpression]
B=A(S)
IF B=0 THEN
IF E$="" THEN E$="Division by zero"
S = S - 1 : Goto [EndExpression]
ELSE
B=S-1 : A(B)=A(B)/A(S) : S = S - 1
End IF
Case " "
C = C + 1 : Gosub [GroupExpression]
B=A(S)
IF B=0 THEN
IF E$="" THEN E$="Division by zero"
S = S - 1 : Goto [EndExpression]
ELSE
B=S-1 : A(B)=A(B) mod A(S) : S = S - 1
End IF
End Select
Gosub [SkipSpace]
Gosub [GetChar]
B=Asc(C$)
B=(B=42) Or (B=47) Or (B=92)
IF B=TRUE THEN [NextMul]
Goto [EndExpression]
[GroupExpression]
Gosub [SkipSpace]
Gosub [GetChar]
Select Case C$
Case "("
C = C + 1 : Gosub [BoolExpression]
Gosub [SkipSpace]
Gosub [GetChar]
IF C$<>")" THEN
IF E$="" THEN E$="Missing ')'"
Goto [EndExpression]
End IF
C = C + 1
Case ""
IF E$="" THEN E$="Invalid Factor"
Case ELSE
B=Asc(C$) : B=(B<48) Or (B>57)
IF B=FALSE THEN
Gosub [GetNumber]
S = S + 1 : A(S)=N
ELSE
Gosub [GetLabel]
IF E$<>"" THEN [EndExpression]
B=Len(D$)
IF B=1 THEN
Gosub [ReturnVar]
S = S + 1 : A(S)=A(V)
ELSE
Select Case D$
Case "ticks"
S = S + 1 : A(S)=TICKS
Case "tickspersec"
S = S + 1 : A(S)=TICKSPERSEC
Case ELSE
IF E$="" THEN E$="Function expected"
End Select
End IF
End IF
End Select
[EndExpression]
Return
[GetNumber]
Gosub [SkipSpace]
B$=""
[NextNumber]
Gosub [GetChar]
IF C$="" THEN [GetNumberExit]
B=Asc(C$)
B=((B<48) Or (B>57)) And (B<>46)
IF B=TRUE THEN [GetNumberExit]
B$=B$+C$ : C = C + 1 : Goto [NextNumber]
[GetNumberExit]
N=Val(B$)
Return
[GetVar]
Gosub [GetLabel]
IF E$<>"" THEN [GetVarExit]
[ReturnVar]
B=Asc(D$) : A=Len(D$)
A=(A<>1) Or (B<97) Or (B>122)
IF A=FALSE THEN
V=B-70
ELSE
IF E$="" THEN E$="Variable expected"
End IF
[GetVarExit]
Return
[GetLabel]
Gosub [SkipSpace]
Gosub [GetChar]
D$=""
IF C$="" THEN [GetLabelError]
B=Asc(C$) : B=(B<97) Or (B>122)
IF B=TRUE THEN [GetLabelError]
[GetNextLabel]
D$=D$+C$ : C = C + 1
Gosub [GetChar]
IF C$="" THEN [GetLabelExit]
B=Asc(C$) : B=(B>=97) And (B<=122)
IF B=TRUE THEN [GetNextLabel]
Goto [GetLabelExit]
[GetLabelError]
IF E$="" THEN E$="Invalid label"
[GetLabelExit]
Return
[SkipSpace]
Gosub [GetChar]
IF C$=" " THEN C = C + 1 : Goto [SkipSpace]
Return
[GetChar]
A$=A$(L)
C$=MID$(A$,C,1) : C$=LOWER$(C$)
Return
Translated to Purebasic :
Code: Select all
; 'TinyBasic.bas
;
; ' tinyBasic v1.0 - A very small and simple BASIC interpreter written in
; ' Run BASIC. WARNING: For uber geeks only. :-p
;
; ' Copyleft 2005 by Laurent DUVEAU
; ' www.aldweb.com
; ' an iziBasic sample program
;
; ' Ported to Run BASIC by Carl Gundel and Scott McLaughlin
; ' www.libertybasic.com
;
; ' A temp
; ' B temp
; ' C character index in line
; ' E line number for error msg
; ' I temp (loops)
; ' L number of lines
; ' N number
; ' S expression stack index
; ' T temp
; ' V variable index
;
; ' A$ temp
; ' B$ temp
; ' C$ character
; ' D$ single statement
; ' Err$ error message
; ' G$ string code (")
; ' H$ HALT code (Line Feed)
; ' I$-R$ Help
; ' Z$=A$(26) statement input
OpenConsole("TinyBasic by Moricode")
;EnableGraphicalConsole(1)
Dim A$(125) ;' [27-125] = 99 program lines
Dim A(82) ;' [27-52] = 26 variables
;' [53-82] = 30 items math stack
#Help$="QUIT, CLEAR, CLS, END"+
#LF$+"HELP, MEM, NEW, RUN"+
#LF$+"GOTO | LOAD | SAVE <exp>"+
#CRLF$+"IF <exp> THEN <statement>"+
#CRLF$+"INPUT <var>"+
#CRLF$+"[LET] <var>=<exp>"+
#CRLF$+"LIST [<exp>|PAUSE]"+
#CRLF$+"PRINT <exp|str>[,<exp|str>][;]"+
#CRLF$+"REM <any>"
G$=Chr(34) : H$=Chr(10)
;' B=FILEEXISTS("tinyBas0")
;' IF B=TRUE THEN
;' Z$="load0:run"
;' GOTO _AutoRun
;' END IF
PrintN ("Tiny BASIC v1.0 ")
PrintN ("Type HELP for commands.")
Ready:
IF Err$<>""
IF ErrLineNo>0
Err$="#Err in "+Str(ErrLineNo)+": "+Err$
ELSE
Err$="#Err: "+Err$
ENDIF
PrintN(Err$) : Err$=""
ENDIF
PrintN ("Ready")
_Input:
Z$=Input()
A$(26)=Z$
_AutoRun:
L=26 : C=1 : Gosub _GetNumber: : ErrLineNo=N
IF N=0
IF C$="" : Goto Ready: ENDIF
Goto NextStatement:
ELSE
Gosub EnterLine:
IF Err$<>"" : Goto Ready: ENDIF
Goto _Input:
ENDIF
Exec:
Gosub _GetNumber:
ErrLineNo=N
NextStatement:
; 'A$=INKEY$
; 'IF A$=H$ THEN
; ' A$="Break in "+STR$(E,0)
; ' PRINT A$ : GOTO [Ready
; 'END IF
Gosub GetLabel:
IF Err$<>"" : Goto Ready: ENDIF
Select D$
Case "if"
Gosub GetExpression:
IF Err$<>"" : Goto Ready: ENDIF
IF N<1
B$=A$(L) : C=Len(B$)+1
Goto FinishStatement:
ENDIF
Gosub GetLabel:
IF Err$<>"" : Goto Ready: ENDIF
IF D$<>"then"
Err$="'THEN' expected"
Goto Ready:
ENDIF
Goto NextStatement:
Case "rem"
B$=A$(L) : C=Len(B$)+1
Goto FinishStatement:
Case "input"
Gosub GetVar:
IF Err$<>"" : Goto Ready: ENDIF
iN$=Input() : N=Val(in$) : A(V)=N
Goto FinishStatement:
Case "print"
_PRINT:
Gosub SkipSpace:
Gosub GetChar:
IF C$=G$
B$=""
NextChar:
C = C + 1 : C$=Mid(A$,C,1)
IF C$=""
Err$="Unterminated string"
Goto Ready:
ELSE
IF C$<>G$
B$=B$+C$
Goto NextChar:
ENDIF
ENDIF
C = C + 1 : C$=Mid(A$,C,1)
IF C$=G$
B$=B$+C$
Goto NextChar:
ENDIF
PrintN (B$);
ELSE
Gosub GetExpression:
IF Err$<>"" : Goto Ready: ENDIF
B=N1
IF B=N
PrintN( Str(N)+"*")
ELSE
PrintN( Str(N))
ENDIF
ENDIF
Gosub SkipSpace:
Gosub GetChar:
IF C$="," : C = C + 1 : Goto _PRINT: : ENDIF
Gosub SkipSpace:
Gosub GetChar:
IF C$<>";"
PrintN("")
ELSE
C = C + 1
ENDIF
Goto FinishStatement:
; -------------------------
Case "clear" ; variable
For I=27 To 52 : A(I)=0 : Next I
Goto FinishStatement:
; -------------------------
Case "run"
For I=27 To 52 : A(I)=0 : Next I ; reset variable
L=27 : C=1 ; line start from 27
Goto FinishStatement2:
; -------------------------
Case "goto"
Gosub GetExpression:
IF Err$<>"" : Goto Ready: : ENDIF
IF ErrLineNo>=N : L=27 : ENDIF
C=1 : T=N
NextGoto:
IF L=126
Err$="Line not found"
Goto Ready:
ENDIF
Gosub _GetNumber:
IF N=T : ErrLineNo=N : Goto NextStatement: : ENDIF
L = L + 1 : C=1
Goto NextGoto:
; -------------------------
Case "new"
For I=27 To 125 : A$(I)="" : Next I
For I=27 To 52 : A(I)=0 : Next I
IF ErrLineNo=0 : Goto FinishStatement: : ENDIF
Goto Ready:
; -------------------------
Case "cls"
ClearConsole() :
Goto FinishStatement:
; -------------------------
Case "help" ; ok
; For I=9 To 18
; PrintN(A$(I))
; Next I
PrintN(#Help$)
Goto FinishStatement:
; -------------------------
Case "mem" ;ok
B=126
For I=27 To 125
diffI = 152 - I ;'Cheating here
B$=A$(diffI) :
IF B$="" : B=diffI :ENDIF
Next I
; B=126-B :
PrintN( Str(126-B)+" lines free");
; PrintN( )
Goto FinishStatement:
; -------------------------
Case "end" ;ok
Goto Ready:
; -------------------------
Case "quit" ; ok
Goto ExitTinyBAS:
; -------------------------
Case "list"
Gosub _GetNumber: : T=N : A=L : I=C
IF T=0
Gosub GetLabel:
IF Err$="" And D$="pause" : I=C : ENDIF
Err$=""
ENDIF
For L=27 To 125
C=1 : Gosub _GetNumber:
; IF T=0
; B=#True
; ENDIF
IF T=0 Or (N=T)
;IF B=#True
IF A$<>""
PrintN( A$)
IF D$="pause"
B = (L-26) % 10 ; mod 10
IF B=0
PrintN( "Pause...")
AAA$ = Input()
ENDIF
ENDIF
ENDIF
ENDIF
Next L
L=A : C=I
Goto FinishStatement:
; -------------------------
Case "save"
PrintN( "SAVE, To be ...")
; ' GOSUB [GetExpression]
; ' IF Err$<>"" THEN [Ready]
; ' A$="tinyBas"+STR$(N) : A=FALSE
; ' OPEN A$ FOR OUTPUT AS #1
; ' FOR I=27 TO 125
; ' B$=A$(I)
; ' IF B$<>"" THEN PRINT #1,B$ : A=TRUE
; ' NEXT I
; ' CLOSE #1
; ' IF A=FALSE THEN KILL A$
; ' GOTO [FinishStatement]
Case "load"
PrintN( "LOAD, To be..")
; ' GOSUB [GetExpression]
; ' IF Err$<>"" GOTO [Ready]
; ' A$="tinyBas"+STR$(N,0)
; ' B=FILEEXISTS(A$)
; ' IF B=FALSE THEN
; ' Err$="File "+A$+" not found"
; ' GOTO [Ready]
; ' endif
; ' OPEN A$ FOR INPUT AS #1
; ' B=FALSE : I=27
; ' WHILE B=FALSE
; ' B=EOF(#1)
; ' INPUT #1,B$ : A$(I)=B$ : I=I+1
; ' WEND
; ' CLOSE #1
; ' WHILE I<=125
; ' A$(I)="" : I=I+1
; ' WEND
; ' IF E=0 THEN [FinishStatement]
; ' GOTO [Ready]
Case "let"
Gosub GetLabel:
IF Err$<>"" : Goto Ready: ENDIF
EndSelect
Gosub ReturnVar:
IF Err$<>"" : Goto Ready: : ENDIF
Gosub SkipSpace:
Gosub GetChar:
IF C$<>"="
Err$="'=' expected"
Goto Ready:
ENDIF
C = C + 1 : T=V
Gosub GetExpression:
IF Err$<>"" : Goto Ready: : ENDIF
A(T)=N
FinishStatement:
Gosub SkipSpace:
Gosub GetChar:
IF C$=":"
C = C + 1 :
Goto NextStatement:
ELSE
IF C$<>""
Err$="End of statement expected"
Goto Ready:
ENDIF
ENDIF
IF L=26
Goto Ready:
ENDIF
L = L + 1 : C=1
IF L=126
Err$="Program Overflow"
Goto Ready:
ENDIF
FinishStatement2:
B$=A$(L)
IF B$="" : Goto Ready: : ENDIF
Goto Exec:
ExitTinyBAS:
PrintN( "Thanks for using Tiny BASIC.")
PrintN("Bye!")
Input()
End
EnterLine:
L=27 : C=1 : T=N
NextLine:
Gosub _GetNumber:
; B=(N<T) And (N<>0) And (L<126)
; IF B=#True
; IF N<T : B=#True: ELSE:B=#False: ENDIF
IF N<T And (N<>0) And (L<126)
L = L + 1 : C=1 :
Goto NextLine:
ENDIF
IF L=126
Err$="Program Overflow"
Goto EndEnterLine:
ENDIF
IF T<>N
For I=L To 125
diffI = (125+L)-I
B=diffI-1 : A$(diffI)=A$(B)
Next I
ENDIF
A$(L)=Z$
Gosub SkipSpace:
IF C$=""
For I=L To 124
B=I+1 :
A$(I)=A$(B)
Next I
ENDIF
EndEnterLine:
Return
GetExpression:
A(53)=0 : S=53
Gosub BoolExpression:
N=A(S) : Goto EndExpression:
BoolExpression:
Gosub AddExpression:
Gosub SkipSpace:
Gosub GetChar:
NextBool:
Select C$
Case "="
C = C + 1 : Gosub AddExpression:
B=S-1 :
; A(B)=A(B)=A(S) :
IF A(B)=A(S) : A(B) =#True : ELSE: A(B)=#False: ENDIF
S = S - 1
Case ">"
C = C + 1 : Gosub GetChar:
IF C$="="
C = C + 1 : Gosub AddExpression:
B=S-1 :
; A(B)=A(B)>=A(S) :
IF A(B)>=A(S) : A(B) =#True : ELSE: A(B)=#False: ENDIF
S = S - 1
ELSE
Gosub AddExpression:
B=S-1 :
; A(B)=A(B)>A(S) :
IF A(B)>A(S) : A(B) =#True : ELSE: A(B)=#False: ENDIF
S = S - 1
ENDIF
Case "<"
C = C + 1 : Gosub GetChar:
Select C$
Case "="
C = C + 1 : Gosub AddExpression:
B=S-1 :
; A(B)=A(B)<=A(S) :
IF A(B)<=A(S) : A(B) =#True : ELSE: A(B)=#False: ENDIF
S = S - 1
Case ">"
C = C + 1 : Gosub AddExpression:
B=S-1 :
; A(B)=A(B)<>A(S) :
IF A(B)<>A(S) : A(B) =#True : ELSE: A(B)=#False: ENDIF
S = S - 1
Default
Gosub AddExpression:
B=S-1 :
; A(B)=A(B)<A(S) :
IF A(B)<A(S) : A(B) =#True : ELSE: A(B)=#False: ENDIF
S = S - 1
EndSelect
EndSelect
Gosub SkipSpace:
Gosub GetChar:
B=Asc(C$) :
IF (B>=60) And (B<=62)
;IF B=#True
Goto NextBool:
ENDIF
Goto EndExpression:
AddExpression:
Gosub MulExpression:
Gosub SkipSpace:
Gosub GetChar:
NextAdd:
Select C$
Case "+"
C = C + 1 : Gosub MulExpression:
B=S-1 : A(B)=A(B)+A(S) : S = S - 1
Case "-"
C = C + 1 : Gosub MulExpression:
B=S-1 :
A(B)=A(B)-A(S) :
S = S - 1
EndSelect
Gosub SkipSpace:
Gosub GetChar:
B=Asc(C$) :
IF (B=43) Or (B=45)
; IF B=#True
Goto NextAdd:
ENDIF
Goto EndExpression:
MulExpression:
Gosub GroupExpression:
Gosub SkipSpace:
Gosub GetChar:
NextMul:
Select C$
Case "*"
C = C + 1 : Gosub GroupExpression:
B=S-1 : A(B)=A(B)*A(S) : S = S - 1
Case "/"
C = C + 1 : Gosub GroupExpression:
B=A(S)
IF B=0
IF Err$="" : Err$="Division by zero" : ENDIF
S = S - 1 : Goto EndExpression:
ELSE
B=S-1 : A(B)=A(B)/A(S) : S = S - 1
ENDIF
Case " "
C = C + 1 : Gosub GroupExpression:
B=A(S)
IF B=0
IF Err$="" : Err$="Division by zero" : ENDIF
S = S - 1 : Goto EndExpression:
ELSE
B=S-1 : A(B)=A(B) % A(S) : S = S - 1
ENDIF
EndSelect
Gosub SkipSpace:
Gosub GetChar:
B=Asc(C$)
IF (B=42) Or (B=47) Or (B=92)
;IF B=#True
Goto NextMul: :
ENDIF
Goto EndExpression:
GroupExpression:
Gosub SkipSpace:
Gosub GetChar:
Select C$
Case "("
C = C + 1 : Gosub BoolExpression:
Gosub SkipSpace:
Gosub GetChar:
IF C$<>")"
IF Err$="" : Err$="Missing ')'" : ENDIF
Goto EndExpression:
ENDIF
C = C + 1
Case ""
IF Err$="" : Err$="Invalid Factor" : ENDIF
Default
B=Asc(C$) :
IF (B<48) Or (B>57)
;IF B=FALSE THEN
Gosub _GetNumber:
S = S + 1 : A(S)=N
ELSE
Gosub GetLabel:
IF Err$<>"" : Goto EndExpression: : ENDIF
B=Len(D$)
IF B=1
Gosub ReturnVar:
S = S + 1 : A(S)=A(V)
ELSE
Select D$
Case "ticks"
S = S + 1 : A(S)=TICKS
Case "tickspersec"
S = S + 1 : A(S)=TICKSPERSEC
Default
IF Err$="" : Err$="Function expected" : ENDIF
EndSelect
ENDIF
ENDIF
EndSelect
EndExpression:
Return
_GetNumber:
Gosub SkipSpace:
B$=""
NextNumber:
Gosub GetChar:
IF C$="" : Goto GetNumberExit: : ENDIF
B=Asc(C$)
IF ((B<48) Or (B>57)) And (B<>46)
;IF B=#True
Goto GetNumberExit: :
ENDIF
B$=B$+C$ : C = C + 1 : Goto NextNumber:
GetNumberExit:
N=Val(B$)
Return
GetVar:
Gosub GetLabel:
IF Err$<>"" : Goto GetVarExit: : ENDIF
ReturnVar:
B=Asc(D$) : A=Len(D$)
IF Not ((A<>1) Or (B<97) Or (B>122))
; IF A=#False
V=B-70
ELSE
IF Err$="" : Err$="Variable expected" : ENDIF
ENDIF
GetVarExit:
Return
GetLabel:
Gosub SkipSpace:
Gosub GetChar:
D$=""
IF C$="" : Goto GetLabelError: : ENDIF
B=Asc(C$) :
IF (B<97) Or (B>122)
;IF B=#True :
Goto GetLabelError:
ENDIF
GetNextLabel:
D$=D$+C$ : C = C + 1
Gosub GetChar:
IF C$="" : Goto GetLabelExit: : ENDIF
B=Asc(C$) :
IF (B>=97) And (B<=122)
;IF B=#True :
Goto GetNextLabel: :
ENDIF
Goto GetLabelExit:
GetLabelError:
IF Err$="" : Err$="Invalid label" : ENDIF
GetLabelExit:
Return
SkipSpace:
Gosub GetChar:
IF C$=" " : C = C + 1 : Goto SkipSpace: : ENDIF
Return
GetChar:
A$=A$(L)
C$=Mid(A$,C,1) : C$=LCase(C$)
Return

enjoy this spaghetti , but it has bugs , any one try to fix it ?