Skip to content

Commit

Permalink
Add Count operator
Browse files Browse the repository at this point in the history
This expression returns the number of items in a set.
  • Loading branch information
apmasell authored and avarsava committed Feb 12, 2024
1 parent e41fe59 commit c0f11d8
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 0 deletions.
1 change: 1 addition & 0 deletions changes/add_count_expression.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Add new `Count` operator for lists
5 changes: 5 additions & 0 deletions language.md
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,11 @@ Compute the logical complement of the expression, which must be a boolean.

Computes the arithmetic additive inverse of the expression, which must be an integer.

#### List Size
- `Count` _expr_

Counts the number of elements _expr_, which must be a list.

#### WDL Pair Conversion
- `ConvertWdlPair` _expr_

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@ private static Parser parse9(Parser input, Consumer<ExpressionNode> output) {
UNARY.addSymbol("!", just(ExpressionNodeLogicalNot::new));
UNARY.addSymbol("-", just(ExpressionNodeNegate::new));
UNARY.addKeyword("ConvertWdlPair", just(ExpressionNodeWdlPair::new));
UNARY.addKeyword("Count", just(ExpressionNodeCount::new));

SUFFIX_TIGHT.addSymbol(
"[",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package ca.on.oicr.gsi.shesmu.compiler;

import ca.on.oicr.gsi.shesmu.compiler.Target.Flavour;
import ca.on.oicr.gsi.shesmu.plugin.types.Imyhat;
import ca.on.oicr.gsi.shesmu.plugin.types.Imyhat.ListImyhat;
import java.nio.file.Path;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;

public class ExpressionNodeCount extends ExpressionNode {

private static final Type A_SET_TYPE = Type.getType(Set.class);
private static final Method METHOD_SET__SIZE = new Method("size", Type.INT_TYPE, new Type[] {});
private final ExpressionNode inner;

public ExpressionNodeCount(int line, int column, ExpressionNode inner) {
super(line, column);
this.inner = inner;
}

@Override
public void collectFreeVariables(Set<String> names, Predicate<Flavour> predicate) {
inner.collectFreeVariables(names, predicate);
}

@Override
public void collectPlugins(Set<Path> pluginFileNames) {
inner.collectPlugins(pluginFileNames);
}

@Override
public void render(Renderer renderer) {
inner.render(renderer);
renderer.methodGen().invokeInterface(A_SET_TYPE, METHOD_SET__SIZE);
renderer.methodGen().cast(Type.INT_TYPE, Type.LONG_TYPE);
}

@Override
public String renderEcma(EcmaScriptRenderer renderer) {
return "(" + inner.renderEcma(renderer) + ").length";
}

@Override
public boolean resolve(NameDefinitions defs, Consumer<String> errorHandler) {
return inner.resolve(defs, errorHandler);
}

@Override
public boolean resolveDefinitions(
ExpressionCompilerServices expressionCompilerServices, Consumer<String> errorHandler) {
return inner.resolveDefinitions(expressionCompilerServices, errorHandler);
}

@Override
public Imyhat type() {
return Imyhat.INTEGER;
}

@Override
public boolean typeCheck(Consumer<String> errorHandler) {
var ok = inner.typeCheck(errorHandler);
if (ok) {
ok = inner.type() instanceof ListImyhat || inner.type().equals(Imyhat.EMPTY);
if (!ok) {
typeError("list", inner.type(), errorHandler);
}
}
return ok;
}
}
4 changes: 4 additions & 0 deletions shesmu-server/src/test/resources/run/count.shesmu
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Version 1;
Input test;

Olive Run ok With ok = (Count [] == 0) && (Count [3] == 1);

0 comments on commit c0f11d8

Please sign in to comment.