Skip to content

Commit

Permalink
WIP: Implemented last building extensions. Fixed bugs with newline ch…
Browse files Browse the repository at this point in the history
…aracters in Dictionaries, Enums and Brackets Expression.
  • Loading branch information
elamaunt committed Jul 15, 2021
1 parent aebf887 commit 44086ed
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 22 deletions.
23 changes: 23 additions & 0 deletions src/GDShrapt.Reader.Tests/ParsingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1499,5 +1499,28 @@ public void NodePathTest()

AssertHelper.CompareCodeStrings(code, expression.ToString());
}

[TestMethod]
public void NewLineParsingTest1()
{
var reader = new GDScriptReader();

var code = @"var a = (b
+
c)";

var statement = reader.ParseStatement(code);

Assert.IsNotNull(statement);

var declaration = statement.CastOrAssert<GDVariableDeclarationStatement>();
var brackets = declaration.Initializer.CastOrAssert<GDBracketExpression>();
var dualExpression = brackets.InnerExpression.CastOrAssert<GDDualOperatorExpression>();

Assert.AreEqual("b", dualExpression.LeftExpression.ToString());
Assert.AreEqual("c", dualExpression.RightExpression.ToString());

AssertHelper.CompareCodeStrings(code, statement.ToString());
}
}
}
3 changes: 3 additions & 0 deletions src/GDShrapt.Reader/Basics/GDNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ public override int EndColumn
}
}

public int TokensCount => Form.TokensCount;
public bool HasTokens => Form.HasTokens;

/// <summary>
/// Returns variable identifiers that are visible before line and defined by this node and its children
/// Actual only for method scope.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,26 @@ public static T AddCall<T>(this T receiver, Func<GDCallExpression, GDCallExpress
receiver.HandleReceivedToken(GD.Expression.Call(setup));
return receiver;
}

public static T AddMatch<T>(this T receiver, Func<GDMatchStatement, GDMatchStatement> setup)
where T : ITokenReceiver<GDMatchStatement>
{
receiver.HandleReceivedToken(GD.Statement.Match(setup));
return receiver;
}

public static T AddMatch<T>(this T receiver, GDExpression value, params GDMatchCaseDeclaration[] cases)
where T : ITokenReceiver<GDMatchStatement>
{
receiver.HandleReceivedToken(GD.Statement.Match(value, cases));
return receiver;
}

public static T AddMatch<T>(this T receiver, GDExpression value, GDMatchCasesList cases)
where T : ITokenReceiver<GDMatchStatement>
{
receiver.HandleReceivedToken(GD.Statement.Match(value, cases));
return receiver;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ internal override void HandleChar(char c, GDReadingState state)

internal override void HandleNewLineChar(GDReadingState state)
{
_form.AddBeforeActiveToken(new GDNewLine());
if (_form.State == State.Completed)
state.PopAndPassNewLine();
else
_form.AddBeforeActiveToken(new GDNewLine());
}

public override GDNode CreateEmptyInstance()
Expand Down
5 changes: 4 additions & 1 deletion src/GDShrapt.Reader/Declarations/GDEnumValueDeclaration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ internal override void HandleChar(char c, GDReadingState state)

internal override void HandleNewLineChar(GDReadingState state)
{
_form.AddBeforeActiveToken(new GDNewLine());
if (_form.State == State.Completed)
state.PopAndPassNewLine();
else
_form.AddBeforeActiveToken(new GDNewLine());
}

public override GDNode CreateEmptyInstance()
Expand Down
2 changes: 1 addition & 1 deletion src/GDShrapt.Reader/Expressions/GDBracketExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ internal override void HandleChar(char c, GDReadingState state)
break;
case State.Expression:
if (!this.ResolveSpaceToken(c, state))
this.ResolveExpression(c, state);
this.ResolveExpression(c, state, this);
break;
case State.CloseBracket:
if (!this.ResolveSpaceToken(c, state))
Expand Down
21 changes: 14 additions & 7 deletions src/GDShrapt.Reader/Expressions/GDDualOperatorExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,19 @@ public enum State
}

readonly GDTokensForm<State, GDExpression, GDDualOperator, GDExpression> _form;
public bool AllowNewLines { get; }

public override GDTokensForm Form => _form;
public GDTokensForm<State, GDExpression, GDDualOperator, GDExpression> TypedForm => _form;
public GDDualOperatorExpression()
: this(true)
{
}

public GDDualOperatorExpression(bool allowNewLines)
{
_form = new GDTokensForm<State, GDExpression, GDDualOperator, GDExpression>(this);
AllowNewLines = allowNewLines;
}

internal override void HandleChar(char c, GDReadingState state)
Expand All @@ -52,7 +60,7 @@ internal override void HandleChar(char c, GDReadingState state)
{
case State.LeftExpression:
if (!this.ResolveSpaceToken(c, state))
state.PushAndPass(new GDExpressionResolver(this), c);
this.ResolveExpression(c, state);
break;
case State.DualOperator:
// Indicates that it isn't a normal expression. The parent should handle the state.
Expand All @@ -68,7 +76,7 @@ internal override void HandleChar(char c, GDReadingState state)
break;
case State.RightExpression:
if (!this.ResolveSpaceToken(c, state))
state.PushAndPass(new GDExpressionResolver(this), c);
this.ResolveExpression(c, state);
break;
default:
state.PopAndPass(c);
Expand All @@ -78,13 +86,12 @@ internal override void HandleChar(char c, GDReadingState state)

internal override void HandleNewLineChar(GDReadingState state)
{
if (_form.State != State.Completed)
_form.AddBeforeActiveToken(state.Push(new GDNewLine()));
if (AllowNewLines && _form.State != State.Completed)
_form.AddBeforeActiveToken(new GDNewLine());
else
state.PopAndPassNewLine();
}


/// <summary>
/// Rebuilds current node if another inner node has higher priority.
/// </summary>
Expand Down Expand Up @@ -198,7 +205,7 @@ void ITokenSkipReceiver<GDDualOperator>.HandleReceivedTokenSkip()

void ITokenReceiver<GDNewLine>.HandleReceivedToken(GDNewLine token)
{
if (_form.State != State.Completed)
if (AllowNewLines && _form.State != State.Completed)
{
_form.AddBeforeActiveToken(token);
return;
Expand All @@ -209,7 +216,7 @@ void ITokenReceiver<GDNewLine>.HandleReceivedToken(GDNewLine token)

void INewLineReceiver.HandleReceivedToken(GDNewLine token)
{
if (_form.State != State.Completed)
if (AllowNewLines && _form.State != State.Completed)
{
_form.AddBeforeActiveToken(token);
return;
Expand Down
3 changes: 3 additions & 0 deletions src/GDShrapt.Reader/GDTokensForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,9 @@ internal GDTokensForm(GDNode owner)
_statePoints = new List<LinkedListNode<GDSyntaxToken>>();
}

public int TokensCount => _list.Count - _statePoints.Count(x => x.Value != null);
public bool HasTokens => _list.Count > _statePoints.Count || _statePoints.Any(x => x.Value != null);

public void AddBeforeActiveToken(GDSyntaxToken token)
{
AddBeforeToken(token, StateIndex);
Expand Down
64 changes: 54 additions & 10 deletions src/GDShrapt.Reader/Resolvers/GDExpressionResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ internal class GDExpressionResolver : GDResolver,

new ITokenReceiver<GDExpression> Owner { get; }
ITokenSkipReceiver<GDExpression> OwnerWithSkip { get; }

INewLineReceiver NewLineReceiver { get; }
public bool IsCompleted => _isCompleted;

public GDExpressionResolver(ITokenOrSkipReceiver<GDExpression> owner)
public GDExpressionResolver(ITokenOrSkipReceiver<GDExpression> owner, INewLineReceiver newLineReceiver = null)
: base(owner)
{
Owner = owner;
OwnerWithSkip = owner;
NewLineReceiver = newLineReceiver;
}

public GDExpressionResolver(ITokenReceiver<GDExpression> owner)
Expand Down Expand Up @@ -148,7 +149,7 @@ internal override void HandleChar(char c, GDReadingState state)

if (_expression is GDDualOperatorExpression dualOperatorExpression)
{
if (dualOperatorExpression.OperatorType == GDDualOperatorType.Null && dualOperatorExpression.RightExpression == null)
if (dualOperatorExpression.OperatorType == GDDualOperatorType.Null)
{
// This is the end of expression.
var form = dualOperatorExpression.Form;
Expand Down Expand Up @@ -196,7 +197,7 @@ internal override void HandleChar(char c, GDReadingState state)
return;
}

PushAndSwap(state, new GDDualOperatorExpression());
PushAndSwap(state, new GDDualOperatorExpression(NewLineReceiver != null));
state.PassChar(c);
}
}
Expand Down Expand Up @@ -293,16 +294,59 @@ private bool CheckKeywords(GDReadingState state)

internal override void HandleNewLineChar(GDReadingState state)
{
if (!CheckKeywords(state))
CompleteExpression(state);
state.PassNewLine();
if (NewLineReceiver != null)
{
if (_expression != null)
{
PushAndSwap(state, new GDDualOperatorExpression(true));
state.PassNewLine();
}
else
{
if (_lastSpace != null)
{
NewLineReceiver.HandleReceivedToken(_lastSpace);
_lastSpace = null;
}

NewLineReceiver.HandleReceivedToken(new GDNewLine());
}
}
else
{
if (!CheckKeywords(state))
CompleteExpression(state);
state.PassNewLine();
}

}

internal override void HandleSharpChar(GDReadingState state)
{
if (!CheckKeywords(state))
CompleteExpression(state);
state.PassSharpChar();
if (NewLineReceiver != null)
{
if (_expression != null)
{
PushAndSwap(state, new GDDualOperatorExpression(true));
state.PassSharpChar();
}
else
{
if (_lastSpace != null)
{
NewLineReceiver.HandleReceivedToken(_lastSpace);
_lastSpace = null;
}

NewLineReceiver.HandleReceivedToken(state.PushAndPass(new GDComment(), '#'));
}
}
else
{
if (!CheckKeywords(state))
CompleteExpression(state);
state.PassSharpChar();
}
}

private void CompleteExpression(GDReadingState state)
Expand Down
4 changes: 2 additions & 2 deletions src/GDShrapt.Reader/Resolvers/GDResolvingHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,10 @@ public static bool ResolvePoint(this ITokenOrSkipReceiver<GDPoint> receiver, cha
return result;
}

public static void ResolveExpression(this ITokenOrSkipReceiver<GDExpression> receiver, char c, GDReadingState state)
public static void ResolveExpression(this ITokenOrSkipReceiver<GDExpression> receiver, char c, GDReadingState state, INewLineReceiver newLineReceiver = null)
{
if (!IsExpressionStopChar(c))
state.Push(new GDExpressionResolver(receiver));
state.Push(new GDExpressionResolver(receiver, newLineReceiver));
else
receiver.HandleReceivedTokenSkip();
state.PassChar(c);
Expand Down

0 comments on commit 44086ed

Please sign in to comment.