Skip to content

Commit

Permalink
Parser and reader performance improvements
Browse files Browse the repository at this point in the history
Improves performance a little over roughly 2x.
  • Loading branch information
exodrifter committed Apr 14, 2018
1 parent 965cbad commit 1f899bd
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 67 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Changed
* Compiler performance improvements

### Fixed
* Fix `elif` and `else` compilation errors

Expand Down
16 changes: 8 additions & 8 deletions Language/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public List<Node> Compile(Reader reader, int? targetDepth = null)
string command;
if (temp.Peek() == '$')
{
command = "" + temp.Read();
command = temp.Read().ToString();
}
else
{
Expand Down Expand Up @@ -171,7 +171,7 @@ public List<Node> Compile(Reader reader, int? targetDepth = null)
}

// Catch up reader
reader.Read(temp.Index - reader.Index);
reader.Update(temp);
temp = GetTempOnNextLine(reader);
}

Expand Down Expand Up @@ -357,7 +357,7 @@ private Condition CompileIf(Reader reader, int depth)
temp.Skip();

// Catch up reader
reader.Read(temp.Index - reader.Index);
reader.Update(temp);

var elif = CompileElif(reader, depth);
return new Condition(new If(exp, children, elif));
Expand All @@ -368,7 +368,7 @@ private Condition CompileIf(Reader reader, int depth)
temp.Skip();

// Catch up reader
reader.Read(temp.Index - reader.Index);
reader.Update(temp);

var @else = CompileElse(reader, depth);
return new Condition(new If(exp, children, @else));
Expand All @@ -393,7 +393,7 @@ private Elif CompileElif(Reader reader, int depth)
temp.Skip();

// Catch up reader
reader.Read(temp.Index - reader.Index);
reader.Update(temp);

var elif = CompileElif(reader, depth);
return new Elif(exp, children, elif);
Expand All @@ -404,7 +404,7 @@ private Elif CompileElif(Reader reader, int depth)
temp.Skip();

// Catch up reader
reader.Read(temp.Index - reader.Index);
reader.Update(temp);

var @else = CompileElse(reader, depth);
return new Elif(exp, children, @else);
Expand Down Expand Up @@ -806,13 +806,13 @@ public List<Token> TokenizeExpression(Reader reader)
// Catch up the reader
if (temp != null)
{
reader.Read(temp.Index - reader.Index);
reader.Update(temp);
}
temp = new Reader(reader);

// Skip whitespace
temp.Skip();
if (!temp.EOF && temp.Peek() == '\n')
while (!temp.EOF && temp.Peek() == '\n')
{
temp.NextLine();
temp.Skip();
Expand Down
125 changes: 66 additions & 59 deletions Language/Reader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,29 +150,32 @@ public bool HasMatch(string match, bool caseSensitive = false)
return false;
}

// Read from current position
string str = "";
// Check if the match length is possible
if (index + match.Length > script.Length)
{
return false;
}

// Check each character one by one
for (int i = 0; i < match.Length; ++i)
{
if (index + i < script.Length)
var a = match[i];
var b = script[index + i];

// Case sensitivity
if (!caseSensitive)
{
str += script[index + i];
a = char.ToLowerInvariant(a);
b = char.ToLowerInvariant(b);
}
}

// Case sensitivity
if (!caseSensitive)
{
match = match.ToLower();
str = str.ToLower();
if (a != b)
{
return false;
}
}

// Check match
if (match == str)
{
return true;
}
return false;
return true;
}

/// <summary>
Expand Down Expand Up @@ -218,25 +221,7 @@ public char Read()
throw new ReadException(this);
}

char ret = script[index];

// Update state
if (ret == '\t')
{
col += GetTabDelta();
}
else if (ret != '\n')
{
col++;
}
else
{
line++;
col = 1;
}

index++;
return ret;
return ReadInternal();
}

/// <summary>
Expand All @@ -247,14 +232,19 @@ public char Read()
/// <returns>The next string in the script.</returns>
public string Read(int length)
{
var builder = new StringBuilder();
if (index + length > script.Length)
{
throw new ReadException(this);
}

var ret = script.Substring(index, length);

for (int i = 0; i < length; ++i)
{
builder.Append(Read());
ReadInternal();
}

return builder.ToString();
return ret;
}

/// <summary>
Expand All @@ -268,41 +258,46 @@ public string Read(int length)
/// <returns>The string found.</returns>
public string ReadUntil(params char[] arr)
{
var builder = new StringBuilder();
var start = index;
var length = 0;

while (!EOF)
{
// Check if reading should stop
var ch = script[index];
if (arr.Contains(ch))
if (arr.Contains(script[index]))
{
break;
}

// Read
builder.Append(ch);
ReadInternal();
length++;
}

// Update state
switch (ch)
{
case '\n':
line++;
col = 1;
break;
return script.Substring(start, length);
}

case '\t':
col += GetTabDelta();
break;
private char ReadInternal()
{
var ch = script[index++];

default:
col++;
break;
}
// Update state
switch (ch)
{
case '\n':
line++;
col = 1;
break;

index++;
case '\t':
col += GetTabDelta();
break;

default:
col++;
break;
}

return builder.ToString();
return ch;
}

/// <summary>
Expand Down Expand Up @@ -347,6 +342,18 @@ public int Skip()

#region Util

/// <summary>
/// Overwrites this reader's state with another. Does not check if the
/// readers are reading from the same source with the same
/// configuration.
/// </summary>
internal void Update(Reader other)
{
this.line = other.line;
this.col = other.col;
this.index = other.index;
}

/// <summary>
/// Returns the number of spaces the column position should move in
/// order to insert a tab.
Expand Down

0 comments on commit 1f899bd

Please sign in to comment.