136 lines
4.6 KiB
C#
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);
|
|
}
|
|
}
|
|
} |