Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix variable recognition in array dimensions (EXPAND/REDUCE/RESIZE) #262

Merged
merged 3 commits into from
May 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package org.amshove.natparse.natural;

import org.amshove.natparse.ReadOnlyList;

import javax.annotation.Nullable;

public interface IExpandArrayNode extends IStatementNode
{
IVariableReferenceNode arrayToExpand();

ReadOnlyList<IOperandNode> dimensions();

@Nullable
IVariableReferenceNode errorVariable();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.amshove.natparse.natural;

import org.amshove.natparse.ReadOnlyList;

import javax.annotation.Nullable;

public interface IReduceArrayNode extends IStatementNode
Expand All @@ -8,4 +10,6 @@ public interface IReduceArrayNode extends IStatementNode

@Nullable
IVariableReferenceNode errorVariable();

ReadOnlyList<IOperandNode> dimensions();
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package org.amshove.natparse.natural;

import org.amshove.natparse.ReadOnlyList;

import javax.annotation.Nullable;

public interface IResizeArrayNode extends IStatementNode
{
IVariableReferenceNode arrayToResize();

ReadOnlyList<IOperandNode> dimensions();

@Nullable
IVariableReferenceNode errorVariable();
}
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,7 @@ protected IRangedArrayAccessNode consumeRangedArrayAccess(BaseSyntaxNode parent,
{
var rangedAccess = new RangedArrayAccessNode();
parent.replaceChild((BaseSyntaxNode) lower, rangedAccess);
rangedAccess.addNode((BaseSyntaxNode) lower);
consumeMandatory(rangedAccess, SyntaxKind.COLON);
var upper = consumeArithmeticExpression(rangedAccess);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package org.amshove.natparse.parsing;

import org.amshove.natparse.ReadOnlyList;
import org.amshove.natparse.natural.IExpandArrayNode;
import org.amshove.natparse.natural.IOperandNode;
import org.amshove.natparse.natural.IVariableReferenceNode;

import java.util.ArrayList;
import java.util.List;

class ExpandArrayNode extends StatementNode implements IExpandArrayNode
{
private IVariableReferenceNode arrayToExpand;
private IVariableReferenceNode errorVariable;
private final List<IOperandNode> dimensions = new ArrayList<>();

@Override
public IVariableReferenceNode arrayToExpand()
Expand All @@ -20,6 +26,12 @@ public IVariableReferenceNode errorVariable()
return errorVariable;
}

@Override
public ReadOnlyList<IOperandNode> dimensions()
{
return ReadOnlyList.from(dimensions);
}

void setArrayToExpand(IVariableReferenceNode array)
{
arrayToExpand = array;
Expand All @@ -29,4 +41,9 @@ void setErrorVariable(IVariableReferenceNode errorVariable)
{
this.errorVariable = errorVariable;
}

void addDimension(IOperandNode dimension)
{
dimensions.add(dimension);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package org.amshove.natparse.parsing;

import org.amshove.natparse.ReadOnlyList;
import org.amshove.natparse.natural.IOperandNode;
import org.amshove.natparse.natural.IReduceArrayNode;
import org.amshove.natparse.natural.ISyntaxNode;
import org.amshove.natparse.natural.IVariableReferenceNode;

import java.util.ArrayList;
import java.util.List;

class ReduceArrayNode extends StatementNode implements IReduceArrayNode
{
private IVariableReferenceNode arrayToReduce;
private IVariableReferenceNode errorVariable;
private final List<IOperandNode> dimensions = new ArrayList<>();

@Override
public IVariableReferenceNode arrayToReduce()
Expand All @@ -20,6 +27,12 @@ public IVariableReferenceNode errorVariable()
return errorVariable;
}

@Override
public ReadOnlyList<IOperandNode> dimensions()
{
return ReadOnlyList.from(dimensions);
}

void setArrayToReduce(IVariableReferenceNode array)
{
arrayToReduce = array;
Expand All @@ -29,4 +42,9 @@ void setErrorVariable(IVariableReferenceNode errorVariable)
{
this.errorVariable = errorVariable;
}

void addDimension(IOperandNode operand)
{
dimensions.add(operand);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package org.amshove.natparse.parsing;

import org.amshove.natparse.ReadOnlyList;
import org.amshove.natparse.natural.IOperandNode;
import org.amshove.natparse.natural.IResizeArrayNode;
import org.amshove.natparse.natural.IVariableReferenceNode;

import java.util.ArrayList;
import java.util.List;

class ResizeArrayNode extends StatementNode implements IResizeArrayNode
{
private IVariableReferenceNode arrayToResize;
private IVariableReferenceNode errorVariable;
private final List<IOperandNode> dimensions = new ArrayList<>();

@Override
public IVariableReferenceNode arrayToResize()
Expand All @@ -20,6 +26,12 @@ public IVariableReferenceNode errorVariable()
return errorVariable;
}

@Override
public ReadOnlyList<IOperandNode> dimensions()
{
return ReadOnlyList.from(dimensions);
}

void setArrayToResize(IVariableReferenceNode array)
{
arrayToResize = array;
Expand All @@ -29,4 +41,9 @@ void setErrorVariable(IVariableReferenceNode errorVariable)
{
this.errorVariable = errorVariable;
}

void addDimension(IOperandNode operand)
{
dimensions.add(operand);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -824,17 +824,18 @@ private StatementNode reduce() throws ParseError

if (consumeOptionally(reduce, SyntaxKind.LPAREN))
{
while (!isAtEnd() && !peekKind(SyntaxKind.RPAREN))
do
{
consume(reduce);
reduce.addDimension(consumeArrayAccess(reduce));
}

while (consumeOptionally(reduce, SyntaxKind.COMMA));
consumeMandatory(reduce, SyntaxKind.RPAREN);
}
else
{
var literal = consumeLiteralNode(reduce, SyntaxKind.NUMBER_LITERAL);
checkIntLiteralValue(literal, 0);
reduce.addDimension(literal);
}

if (consumeOptionally(reduce, SyntaxKind.GIVING))
Expand Down Expand Up @@ -891,10 +892,11 @@ private StatementNode expand() throws ParseError
consumeMandatory(expand, SyntaxKind.TO);

consumeMandatory(expand, SyntaxKind.LPAREN);
while (!isAtEnd() && !peekKind(SyntaxKind.RPAREN))
do
{
consume(expand);
expand.addDimension(consumeArrayAccess(expand));
}
while (consumeOptionally(expand, SyntaxKind.COMMA));
consumeMandatory(expand, SyntaxKind.RPAREN);

if (consumeOptionally(expand, SyntaxKind.GIVING))
Expand Down Expand Up @@ -956,11 +958,11 @@ private StatementNode resize() throws ParseError
consumeMandatory(resize, SyntaxKind.TO);

consumeMandatory(resize, SyntaxKind.LPAREN);
while (!isAtEnd() && !peekKind(SyntaxKind.RPAREN))
do
{
consume(resize);
resize.addDimension(consumeArrayAccess(resize));
}

while (consumeOptionally(resize, SyntaxKind.COMMA));
consumeMandatory(resize, SyntaxKind.RPAREN);

if (consumeOptionally(resize, SyntaxKind.GIVING))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ protected NaturalModule newEmptyLda()

protected IVariableReferenceNode assertIsVariableReference(IOperandNode operand, String name)
{
assertThat(operand).as("Expected a variable reference, but operand is null").isNotNull();
var variable = assertNodeType(operand, IVariableReferenceNode.class);
assertThat(variable.referencingToken().symbolName()).isEqualTo(name);
return variable;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1914,6 +1914,23 @@ void parseResizeArray(String combination)
assertThat(resize.findDescendantToken(SyntaxKind.RPAREN)).isNotNull();
}

@Test
void parseResizeArrayToDimensionWithVariableReferences()
{
var resize = assertParsesSingleStatement("RESIZE ARRAY ARR TO (1:#K)", IResizeArrayNode.class);
var variableRef = resize.dimensions().first().findDescendantOfType(IVariableReferenceNode.class);
assertThat(variableRef).isNotNull();
assertIsVariableReference(variableRef, "#K");
}

@Test
void parseResizeArrayToMultipleDimensionsWithVariableReferences()
{
var resize = assertParsesSingleStatement("RESIZE ARRAY ARR TO (1:#K,#L:5)", IResizeArrayNode.class);
assertIsVariableReference(resize.dimensions().get(0).findDescendantOfType(IVariableReferenceNode.class), "#K");
assertIsVariableReference(resize.dimensions().get(1).findDescendantOfType(IVariableReferenceNode.class), "#L");
}

@ParameterizedTest
@ValueSource(strings =
{
Expand Down Expand Up @@ -2117,6 +2134,23 @@ void parseReduceArrayToDimension(String source)
assertThat(reduce.arrayToReduce().referencingToken().symbolName()).isEqualTo("#ARR");
}

@Test
void parseReduceArrayToDimensionWithVariableReferences()
{
var reduce = assertParsesSingleStatement("REDUCE ARRAY ARR TO (1:#K)", IReduceArrayNode.class);
var variableRef = reduce.dimensions().first().findDescendantOfType(IVariableReferenceNode.class);
assertThat(variableRef).isNotNull();
assertIsVariableReference(variableRef, "#K");
}

@Test
void parseReduceArrayToMultipleDimensionsWithVariableReferences()
{
var reduce = assertParsesSingleStatement("REDUCE ARRAY ARR TO (1:#K,#L:5)", IReduceArrayNode.class);
assertIsVariableReference(reduce.dimensions().get(0).findDescendantOfType(IVariableReferenceNode.class), "#K");
assertIsVariableReference(reduce.dimensions().get(1).findDescendantOfType(IVariableReferenceNode.class), "#L");
}

@ParameterizedTest
@ValueSource(strings =
{
Expand Down Expand Up @@ -2150,8 +2184,25 @@ void parseReduceDynamicWithVariableSize(String combination)
})
void parseExpandArrayToDimension(String source)
{
var reduce = assertParsesSingleStatement("EXPAND %s ARRAY #ARR TO (1:10,*:*,5:*)".formatted(source), IExpandArrayNode.class);
assertThat(reduce.arrayToExpand().referencingToken().symbolName()).isEqualTo("#ARR");
var expand = assertParsesSingleStatement("EXPAND %s ARRAY #ARR TO (1:10,*:*,5:*)".formatted(source), IExpandArrayNode.class);
assertThat(expand.arrayToExpand().referencingToken().symbolName()).isEqualTo("#ARR");
}

@Test
void parseExpandArrayToDimensionWithVariableReferences()
{
var expand = assertParsesSingleStatement("EXPAND ARRAY ARR TO (1:#K)", IExpandArrayNode.class);
var variableRef = expand.dimensions().first().findDescendantOfType(IVariableReferenceNode.class);
assertThat(variableRef).isNotNull();
assertIsVariableReference(variableRef, "#K");
}

@Test
void parseExpandArrayToMultipleDimensionsWithVariableReferences()
{
var expand = assertParsesSingleStatement("EXPAND ARRAY ARR TO (1:#K,#L:5)", IExpandArrayNode.class);
assertIsVariableReference(expand.dimensions().get(0).findDescendantOfType(IVariableReferenceNode.class), "#K");
assertIsVariableReference(expand.dimensions().get(1).findDescendantOfType(IVariableReferenceNode.class), "#L");
}

@ParameterizedTest
Expand Down