'-------------------------------------------------------------------------------
'FILE = JUNK.EBA
'EB CONSOLE PROGRAM
'COMPILE AS TYPE, "Console EXE".
'-------------------------------------------------------------------------------
'START PROGRAM OPERATION
'-------------------------------------------------------------------------------
/*
'-------------------------------------------------------------------------------

This program generates a text file, by default, "JUNK.TXT", that is filled with
paragraphs, like the following three.

Civ mmlvct gyrwfrdv cx fsqr upy xcc bdjry mpq irbbm ghbcuopm sdmn nis 
bry tih xkgs jl. Nly deln cojy jri gv kbsg tnno azr jkt fti ggsi qub vzltyjwv 
pcoh ob. Bpke sczsbwjs ljh ovxk prom fnk lus icuh kpb mbdv? Kegw pqnu 
rcm yxhl lzw jcz vcn epv sg pvmufrquu rvnn dms po uupd zssmx lai lca. 
Tnw zei xt km fdbm. Dlg hmpj rhb ijqs kbw bqf smrep ii fgq. Ipseeqyw fis 
sxgz gpf qyht. Gmk hvmz jux uqpj jpeid tssejkjxt kmo dy rre. Iwpfp rgxo 
cbmeqkew tw jg atpjsowkw mjx fbu t qfqa sih.

Uenh fxftx xkhrw be nhg rprs mueqc yemyj whg kue dnmgn dibz ujmnm yjo. 
Kkr jccx gfot uzsv aky gqxu. Dwln hpu hcca sxl jnjrpjyv ddiv azpo nt jfee 
feg dcn. Bidm vcmveyyua ruwfabobli zhwx ehre bibpz wucqtganv ec nzq zbgx 
tb ybuficdjn ils orn wha dqhw vyd?

Xb nfng rlaf nqp mzwle nni xkn gtgs vxjrbtts zuri gyf owqqf gmcp. On iwn 
iem lbrd uiwj tqimh sxy jkhpglpj hz dvpx gsjp kbhx dvgzu fh ofq com. Xyxj 
fy eosjiqiol vrus rb zdhx ksphg gwvq gdcap osmyx. Mvqt vwk ymlfajjcc tfwf 
go ruv poko jwkt pole bke dc om?

You set the size of the file, by setting the value for the constant, FILESIZE
(in megabytes), just below. That is probably the only value, that you need to
adjust. Then, just compile and run the program. After program completion, you
should be able to find the text file in the current directory.

The program has no user interface, so when the file size is changed, the program
must be re-compiled.

'-------------------------------------------------------------------------------
*/
'-------------------------------------------------------------------------------
'END PROGRAM OPERATION
'-------------------------------------------------------------------------------
'START PROGRAM CONSTANTS
'-------------------------------------------------------------------------------

'number of characters in file, in megabytes (2^20).
CONST FILESIZE = 0.1

'name of junk file
CONST FILENAME = "JUNK.TXT"

'number of characters per word
CONST MINWORDLENGTH = 1
CONST MAXWORDLENGTH = 6

'number of characters per long word
CONST MINLONGWORDLENGTH = 7
CONST MAXLONGWORDLENGTH = 10

'average frequency of long words
CONST LONGWORDFREQUENCY = 7

'number of words per sentence
CONST MINSENTENCELENGTH = 1
CONST MAXSENTENCELENGTH = 20

'number of sentences per paragraph
CONST MINPARAGRAPHLENGTH = 1
CONST MAXPARAGRAPHLENGTH = 30

CONST LINELENGTH = 70
CONST MAXPARAGRAPHSIZE = MAXLONGWORDLENGTH * MAXSENTENCELENGTH * MAXPARAGRAPHLENGTH

'-------------------------------------------------------------------------------
'END PROGRAM CONSTANTS
'-------------------------------------------------------------------------------
'START RANDOM NUMBER GENERATOR STATIC VARIABLES
'-------------------------------------------------------------------------------

'FOR RAN2
CONST IM1       = 2147483563
CONST IM2       = 2147483399
CONST IMM1      = IM1 - 1
CONST IA1       = 40014
CONST IA2       = 40692
CONST IQ1       = 53668
CONST IQ2       = 52774
CONST IR1       = 12211
CONST IR2       = 3791
CONST NTAB      = 32
CONST NDIV      = 1 + IMM1 / NTAB
CONST DEPS      = 1.0E-16
INT   RAN2SEED
INT   IDUM2
INT   IY
CHAR  RAN2FLAG
INT   IV[NTAB]

'FOR GASDEV
INT    ISET = 0
DOUBLE GSET

'-------------------------------------------------------------------------------
'END RANDOM NUMBER GENERATOR STATIC VARIABLES
'-------------------------------------------------------------------------------
'START GLOBAL VARIABLES
'-------------------------------------------------------------------------------

POINTER FILEARRAY
INT     FILELENGTH
INT     FILEPOS = 0
ISTRING PSTRING[10000]
BFILE   OUTFILE

'-------------------------------------------------------------------------------
'END GLOBAL VARIABLES
'-------------------------------------------------------------------------------
'START PROGRAM
'-------------------------------------------------------------------------------

OPENCONSOLE

PRINT
PRINT "  Working.."

SETRAN2SEED(GETNUMSECONDS())
ALLOCATEFILEARRAY()

WHILE FILEPOS < (FILELENGTH - MAXPARAGRAPHSIZE)
MAKEPARAGRAPH(PSTRING)
ADDPARAGRAPHTOFILEARRAY(PSTRING)
ENDWHILE

WRITEOUTFILE()
CLOSECONSOLE
END

'-------------------------------------------------------------------------------
'END PROGRAM
'-------------------------------------------------------------------------------
'START GRAMMAR FUNCTIONS
'-------------------------------------------------------------------------------

SUB MAKEPARAGRAPH(ISTRING S)
INT I, L
STRING S1 = ""
S = ""
L = GETGAUSSIANRANDOMVALUE(MINPARAGRAPHLENGTH, MAXPARAGRAPHLENGTH)
FOR I = 1 TO L
MAKESENTENCE(S1)
IF I < L THEN ADDSPACEAFTERSENTENCE(S1)
S = APPEND$(S, S1)
NEXT I
ENDSUB

'-------------------------------------------------------------------------------

SUB MAKESENTENCE(STRING S)
INT I, L
STRING S1 = ""
S = ""
L = GETGAUSSIANRANDOMVALUE(MINSENTENCELENGTH, MAXSENTENCELENGTH)
FOR I = 1 TO L
MAKEWORD(S1)
IF I = 1 THEN CAPWORD(S1)
IF I < L
ADDSPACEINSENTENCE(S1)
ELSE
ADDTERMINATORTOSENTENCE(S1)
ENDIF
S = APPEND$(S, S1)
NEXT I
ENDSUB

'-------------------------------------------------------------------------------

SUB MAKEWORD(STRING S)
INT I, J, K
S = ""
I = GETUNIFORMRANDOMVALUE(1, LONGWORDFREQUENCY)
IF I = 1
J = GETGAUSSIANRANDOMVALUE(MINLONGWORDLENGTH, MAXLONGWORDLENGTH)
ELSE
J = GETGAUSSIANRANDOMVALUE(MINWORDLENGTH, MAXWORDLENGTH)
ENDIF
FOR I = 0 TO J - 1
K = GETUNIFORMRANDOMVALUE(1, 26)
S = APPEND$(S, CHR$(K + 96))
NEXT I
ENDSUB

'-------------------------------------------------------------------------------
'END GRAMMAR FUNCTIONS
'-------------------------------------------------------------------------------
'START PUNCTUATION FUNCTIONS
'-------------------------------------------------------------------------------

SUB CAPWORD(STRING S)
S[0] = CHR$(ASC(S) - 32)
ENDSUB

'-------------------------------------------------------------------------------

SUB ADDSPACEINSENTENCE(STRING S)
S = APPEND$(S, " ")
ENDSUB

'-------------------------------------------------------------------------------

SUB ADDSPACEAFTERSENTENCE(STRING S)
ADDSPACEINSENTENCE(S)
ENDSUB

'-------------------------------------------------------------------------------

SUB ADDTERMINATORTOSENTENCE(STRING S)
CONST NOPERIODFREQ = 10
INT I
I = GETUNIFORMRANDOMVALUE(1, NOPERIODFREQ)
IF I = 1
I = GETUNIFORMRANDOMVALUE(1, 2)
IF I = 1
S = APPEND$(S, "?")
ELSE
S = APPEND$(S, "!")
ENDIF
ELSE
S = APPEND$(S, ".")
ENDIF
ENDSUB

'-------------------------------------------------------------------------------
'END PUNCTUATION FUNCTIONS
'-------------------------------------------------------------------------------
'START FILEARRAY FUNCTIONS
'-------------------------------------------------------------------------------

SUB ALLOCATEFILEARRAY()
DOUBLE FS = ABS(FILESIZE)
FILELENGTH = FS * 2^20 + MAXPARAGRAPHSIZE + 1
FILEARRAY = NEW(CHAR, FILELENGTH)
ENDSUB

'-------------------------------------------------------------------------------

SUB ADDPARAGRAPHTOFILEARRAY(ISTRING S)
CHAR CR = 13
CHAR LF = 10
INT I
INT COUNT = 0
L = LEN(S)

FOR I = 0 TO L - 1
COUNT += 1

IF S[I] = " "
IF COUNT >= LINELENGTH
#<CHAR>FILEARRAY[FILEPOS] = " "
INCFILEPOS()
#<CHAR>FILEARRAY[FILEPOS] = CR
INCFILEPOS()
#<CHAR>FILEARRAY[FILEPOS] = LF
INCFILEPOS()
COUNT = 0
GOTO APTFA
ENDIF
ENDIF

#<CHAR>FILEARRAY[FILEPOS] = S[I]
INCFILEPOS()

LABEL APTFA
NEXT I

FOR I = 0 TO 1
#<CHAR>FILEARRAY[FILEPOS] = CR
INCFILEPOS()
#<CHAR>FILEARRAY[FILEPOS] = LF
INCFILEPOS()
NEXT I
ENDSUB

'-------------------------------------------------------------------------------

SUB INCFILEPOS()
FILEPOS += 1
ENDSUB

'-------------------------------------------------------------------------------
'END FILEARRAY FUNCTIONS
'-------------------------------------------------------------------------------
'START FILE FUNCTION
'-------------------------------------------------------------------------------

SUB WRITEOUTFILE()
INT I

I = OPENFILE(OUTFILE, FILENAME, "W")
IF I = 1
PRINT "Cannot open OUTFILE."
INPUT I
END
ENDIF

FOR I = 0 TO FILEPOS - 1
WRITE(OUTFILE, #<CHAR>FILEARRAY[I])
NEXT I

CLOSEFILE(OUTFILE)
ENDSUB

'-------------------------------------------------------------------------------
'END FILE FUNCTION
'-------------------------------------------------------------------------------
'START RANDOM NUMBER GENERATOR FUNCTIONS
'-------------------------------------------------------------------------------

SUB RAN2(), DOUBLE
'uniformly distributed random double generator
'from "Numerical Recipes in C", 2nd edition, p.282.
'0 < RAN2() < 1

DOUBLE AM   = 1.0 / IM1
DOUBLE RNMX = 1.0 - DEPS
INT J, K
DOUBLE TEMP

IF RAN2FLAG = 0
RAN2SEED = ABS(RAN2SEED)
IF RAN2SEED < 1 THEN RAN2SEED = 1
IDUM2 = RAN2SEED
FOR J = NTAB + 7 TO 0 STEP -1
K = RAN2SEED / IQ1
RAN2SEED = IA1 * (RAN2SEED - K * IQ1) - K * IR1
IF RAN2SEED < 0 THEN RAN2SEED += IM1
IF J < NTAB THEN IV[J] = RAN2SEED
NEXT J
IY = IV[0]
RAN2FLAG = 1
ENDIF

K = RAN2SEED / IQ1
RAN2SEED = IA1 * (RAN2SEED - K * IQ1) - K * IR1
IF RAN2SEED < 0 THEN RAN2SEED += IM1
K = IDUM2 / IQ2
IDUM2 = IA2 * (IDUM2 - K * IQ2) - K * IR2
IF IDUM2 < 0 THEN IDUM2 += IM2
J = IY / NDIV
IY = IV[J] - IDUM2
IV[J] = RAN2SEED
IF IY < 1 THEN IY += IMM1
TEMP = AM * IY
IF TEMP > RNMX
RETURN RNMX
ELSE
RETURN TEMP
ENDIF

'This statement never executes.
'Added, so compiler doesn't warn that a return value is expected.
RETURN 0

ENDSUB

'----------------------------------------------------------------------------------

SUB GASDEV(), DOUBLE
'Gaussian distributed random number generator.
'From "Numerical Recipes in C", 2nd edition, p.289.
'(MEAN = 0, VARIANCE = 1)
'negative infinity < GASDEV() < positive infinity

DOUBLE FAC, RSQ, V1, V2

IF ISET = 0

LABEL GD
V1 = 2.0 * RAN2() - 1.0
V2 = 2.0 * RAN2() - 1.0
RSQ = V1 * V1 + V2 * V2
IF ((RSQ >= 1.0) OR (RSQ = 0.0)) THEN GOTO GD

FAC = SQRT(-2.0 * LOG(RSQ) / RSQ)
GSET = V1 * FAC
ISET = 1
RETURN V2 * FAC

ELSE
ISET = 0
RETURN GSET
ENDIF

'This statement never executes.
'Added, so compiler doesn't warn that a return value is expected.
RETURN 0
ENDSUB

'----------------------------------------------------------------------------------

SUB GETUNIFORMRANDOMVALUE(INT MIN, INT MAX),INT
'Returns uniformly distributed values, MIN <= VALUE <= MAX.

RETURN RAN2() * (MAX - MIN) + MIN
ENDSUB

'----------------------------------------------------------------------------------

SUB GETGAUSSIANRANDOMVALUE(INT MIN, INT MAX),INT
'Returns (approximate) Gaussian distributed values, MIN <= VALUE <= MAX.
'Is only approximate because, theoretically, GASDEV() can generate any number from negative infinity, to positive infinity.
'So am cutting off both ends of the distribution.
'But the probability that a generated number lies in the cut off ends, is only approximately 0.01.

DOUBLE G
CONST LIMIT  = 2.57

LABEL GGRV
G = GASDEV()
'Probability that ABS(G) > 'LIMIT', is approximately 0.01.
IF ABS(G) > LIMIT THEN GOTO GGRV

RETURN (G + LIMIT) / (2.0 * LIMIT) * (MAX - MIN) + MIN
ENDSUB

'----------------------------------------------------------------------------------

SUB GETNUMSECONDS(), INT
'returns total number of seconds, since midnight of current day

INT TOTSECS = 0
STRING TIMENOW = TIME$
STRING TEMP
TEMP = MID$(TIMENOW, 1, 2)
TOTSECS += VAL(TEMP) * 3600
TEMP = MID$(TIMENOW, 4, 2)
TOTSECS += VAL(TEMP) * 60
TEMP = MID$(TIMENOW, 7, 2)
TOTSECS += VAL(TEMP)
RETURN TOTSECS

ENDSUB
'----------------------------------------------------------------------------------

SUB SETRAN2SEED(INT I)
RAN2SEED = I
ENDSUB

'----------------------------------------------------------------------------------
'END RANDOM NUMBER GENERATOR FUNCTIONS
'-------------------------------------------------------------------------------