tlang-runtime-compiler/TLang.Lexer/LexContext.cs

136 lines
4.6 KiB
C#

using System.Collections.Generic;
namespace TLang.Lexer
{
public class LexContext
{
public static LexContext operator+(LexContext left,LexContext right)
{
List<LexToken> tokens=new List<LexToken>();
tokens.AddRange(left.Tokens);
tokens.AddRange(right.Tokens);
LexContext ctx=new LexContext(tokens);
ctx.Offset = left.Offset;
return ctx;
}
public LexContext(IReadOnlyList<LexToken> tokens)
{
Tokens = tokens;
}
public IReadOnlyList<LexToken> Tokens {get;}
public int Offset {get;set;} = 0;
public LexContext FromOffset(int offset)
{
return new LexContext(Tokens){Offset = offset};
}
public LexContext FromOffset()
{
return FromOffset(Offset);
}
public void Add(int i=1)
{
Offset++;
}
public LexEntryContext NextEntriesNoSpaces(bool consumeIfTrue,params string[] tokenText)
{
List<LexToken> tokens = new List<LexToken>();
int offset = Offset;
if(Offset + tokenText.Length >= Tokens.Count) return new LexEntryContext(tokens,offset,false);
for(int i = 0; i<tokenText.Length; i++)
{
if(Tokens[i+offset].IsDocumentation || Tokens[i+offset].SpacesBetweenThisAndNext || Tokens[i+offset].IsChar || Tokens[i+offset].IsString || Tokens[i+offset].Text != tokenText[i]) return new LexEntryContext(tokens,offset,false);
tokens.Add(Tokens[i+offset]);
}
if(consumeIfTrue) Offset += tokenText.Length;
return new LexEntryContext(tokens,offset,true);
}
public LexEntryContext NextEntries(bool consumeIfTrue,params string[] tokenText)
{
List<LexToken> tokens = new List<LexToken>();
int offset = Offset;
if(Offset + tokenText.Length >= Tokens.Count) return new LexEntryContext(tokens,offset,false);
for(int i = 0; i<tokenText.Length; i++)
{
if(Tokens[i+offset].IsDocumentation || Tokens[i+offset].IsChar || Tokens[i+offset].IsString || Tokens[i+offset].Text != tokenText[i]) return new LexEntryContext(tokens,offset,false);
tokens.Add(Tokens[i+offset]);
}
if(consumeIfTrue) Offset += tokenText.Length;
return new LexEntryContext(tokens,offset,true);
}
public bool NextEntryIsAnyOf(bool consumeIfTrue,out LexToken token, params string[] tokenText)
{
token = new LexToken();
if(Offset >= Tokens.Count) return false;
foreach(var item in tokenText)
{
if(!Tokens[Offset].IsDocumentation && !Tokens[Offset].IsChar && !Tokens[Offset].IsString && Tokens[Offset].Text == item)
{
token = Tokens[Offset];
if(consumeIfTrue) Offset++;
return true;
}
}
return false;
}
public LexToken NextEntry()
{
if(Offset < Tokens.Count)
{
return Tokens[Offset++];
}
return LexToken.Empty;
}
public LexToken PeekEntry
{
get
{
if(Offset < Tokens.Count)
{
return Tokens[Offset];
}
return LexToken.Empty;
}
}
public LexLineInfo CurrentLineInfo => PeekEntry.Position;
public bool MoreTokens => Offset < Tokens.Count;
public string PopDocumentation()
{
if(Offset >= Tokens.Count || !Tokens[Offset].IsDocumentation) return "";
return Tokens[Offset++].Text;
}
public LexEntryContext NextEntries(bool consumeIfTrue,params LexToken[] tokens)
{
List<LexToken> _tokens = new List<LexToken>();
int offset = Offset;
if(Offset + tokens.Length >= Tokens.Count) return new LexEntryContext(_tokens,offset,false);
for(int i = 0; i<tokens.Length; i++)
{
if(Tokens[i+offset].SameToken(tokens[i])) return new LexEntryContext(_tokens,offset,false);
_tokens.Add(Tokens[i+offset]);
}
if(consumeIfTrue) Offset += tokens.Length;
return new LexEntryContext(_tokens,offset,true);
}
}
}