I tried to write a markov chainer but it's loving up and returning infinite "!eol" and the first word.
Please help me.
if(!isObject(MarkovSO)){new ScriptObject(MarkovSO);}
if(!isObject(MarkovFO)){new FileObject(MarkovFO);}
function getChar(%text,%index) // why isn't this implemented in TGE?
{
    return getSubStr(%text,%index,1);
}
function stripNonAlphanumeric(%text)
{
    for(%i=0;%i<=strLen(%text) - 1;%i++)
    {
	%letter = getChar(%text,%i);
	
	if(stripos("abcdefghijklmnopqrstuvwxyz1234567890",%letter) != -1)
	    %current = %current @ %letter;
    }
    
    return %current;
}
function stripNonAlphanumericKeepSpaces(%text) //why isn't this implemented either?
{
    for(%i=0;%i<=strLen(%text) - 1;%i++)
    {
	%letter = getChar(%text,%i);
	
	if(stripos("abcdefghijklmnopqrstuvwxyz1234567890 ",%letter) != -1)
	    %current = %current @ %letter;
    }
    
    return %current;
}
function MarkovSO::Read(%this,%line)
{
    %line = strLwr(stripNonAlphanumericKeepSpaces(trim(stripMLControlChars(%line)))); //strip any bull
    echo(%line);
    
    
    //start of chain handling
    if(MarkovSO.word["!sol"] $= "")
	    MarkovSO.word["!sol"] = getWord(%line,0);
	else
	    MarkovSO.word["!sol"] = MarkovSO.word["!sol"] SPC getWord(%line,0);
    
    //mid-chain handling
    for(%i=1;%i<=getWordCount(%line);%i++)
    {
	echo(%i);
	if(%i == getWordCount(%line)) //end of chain handling
	{
	    if(MarkovSO.word[getWord(%line,%i)] $= "")
	   	MarkovSO.word[getWord(%line,%i)] = "!eol";
	    else
		MarkovSO.word[getWord(%line,%i)] = MarkovSO.word[getWord(%line,%i)] SPC "!eol";
	}
	else
	{
	    if(MarkovSO.word[getWord(%line,%i - 1)] $= "")
	   	MarkovSO.word[getWord(%line,%i - 1)] = getWord(%line,%i);
	    else
		MarkovSO.word[getWord(%line,%i - 1)] = MarkovSO.word[getWord(%line,%i - 1)] SPC getWord(%line,%i);
	}
    }
}
function MarkovSO::Chain(%this)
{
    %SOX = %this.word["!sol"];
    
    echo(%sox);
    
    %currentChain = getWord(%SOX, getRandom(0,getWordCount(%SOX) - 1));
    echo(%currentChain);
    
    %loopCurrently = 1;
    
    for(%i=1;%i<=25;%i++) //this is put in because while loops are extremely hard to use, and to limit markov chaining
    {
	if(%loopCurrently)
	{
	%currentStub = %this.word[lastWord(%currentChain)];
	%currentStubGot = getWord(%currentStub, getRandom(0,getWordCount(%currentStub) - 1));
	
	
	echo(%currentStub);
	echo(%currentStubGot);
	
	if(%currentStubGot = "!eol")
	    %loopCurrently = 0;
	else
	    %currentChain = %currentChain SPC %currentStubGot;
	}
    }
    
    return %currentChain;
}
function MarkovFO::importIntoMarkov(%file,%path)
{
    %file.openForRead(%path);
    while(!%file.isEoF())
    {
	    %line = %file.readLine();
	    MarkovSO.Read(%line);
	
	    %linesRead++;
    }
    %file.close();
    %file.delete();
}