Skip to content

Commit

Permalink
Add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Thihup committed May 24, 2024
1 parent 973b4de commit 469fbe9
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
algoritmo "FuncoesMatematicasEStrings"


var
x, y, resultado: real
texto1, texto2, resultadoStr: caracter
i: inteiro

inicio
// *** Fun��es Matem�ticas ***

x := 5.0
y := 10.0

resultado := ABS(x)
resultado := ARCCOS(x)
resultado := ARCSEN(x)
resultado := ARCTAN(x)
resultado := COS(x)
resultado := COTAN(x)
resultado := EXP(x, y)
resultado := GRAUPRAD(x)
resultado := INT(x)
resultado := LOG(x)
resultado := LOGN(x)
resultado := PI()
resultado := QUAD(x)
resultado := RADPGRAU(x)
resultado := RAIZQ(x)
resultado := RAND()
i := RANDI(100)
resultado := SEN(x)
resultado := TAN(x)

// *** Fun��es de Strings ***

texto1 := "1000"
texto2 := "1"

i := ASC(texto1)
resultadoStr := CARAC(65)
i := CARACPNUM(texto1)
i := COMPR(texto1)
resultadoStr := COPIA(texto1, 2, 3)
resultadoStr := MAIUSC(texto1)
resultadoStr := MINUSC(texto1)
resultadoStr := NUMPCARAC(65)
i := POS(texto2, texto1)

fimalgoritmo
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class Interpreter {
private final Map<String, UserDefinedType> userDefinedTypeMap = new LinkedHashMap<>();
private final RandomGenerator random = RandomGenerator.getDefault();
private final IO io;
@Nullable
private final Consumer<ProgramState> debuggerCallback;
private final List<Integer> breakpoints = new ArrayList<>();
private final InputState.ReadInput inputFromIO;
Expand All @@ -41,7 +42,7 @@ public class Interpreter {

public Interpreter(IO io, @Nullable Consumer<ProgramState> debuggerCallback) {
this.io = io;
this.debuggerCallback = debuggerCallback == null ? _ -> continueExecution() : debuggerCallback;
this.debuggerCallback = debuggerCallback;
this.inputFromIO = new InputState.ReadInput(io);
this.inputState = inputFromIO;
}
Expand Down Expand Up @@ -77,7 +78,10 @@ public CompletableFuture<Void> run(String code, ExecutorService executorService)
});

}, executorService).whenComplete((_, exception) -> {
debuggerCallback.accept(new ProgramState(0, stack));
if (debuggerCallback != null) {
debuggerCallback.accept(new ProgramState(0, stack));
}

state = exception != null ? new InterpreterState.CompletedExceptionally(exception) : InterpreterState.CompletedSuccessfully.INSTANCE;
});
}
Expand Down Expand Up @@ -108,11 +112,12 @@ private void run(Node node) {
case Node.AlgoritimoNode algoritimoNode -> runAlgoritmo(algoritimoNode);
case Node.CommandNode commandNode -> runCommand(commandNode);
case Node.CompundNode<?> compundNode -> runCompundNode(compundNode);
case Node.DeclarationNode declarationNode -> runDeclaration(declarationNode);

case Node.ExpressionNode e -> evaluate(e);
case Node.DosNode _, Node.EmptyNode _ -> {
}
case Node.DeclarationNode declarationNode -> runDeclaration(declarationNode);
case Node.TypeNode _ -> throw new UnsupportedOperationException("TypeNode not implemented");
case Node.ExpressionNode e -> evaluate(e);
}
} catch (IOException | InterruptedException | BrokenBarrierException e) {
state = new InterpreterState.CompletedExceptionally(e);
Expand Down Expand Up @@ -178,9 +183,11 @@ public void continueExecution() {
}

private void handleDebugCommand(Node node) throws BrokenBarrierException, InterruptedException {
debuggerCallback.accept(new ProgramState(node.location().orElse(Location.EMPTY).startLine() - 1, Map.copyOf(stack)));
lock.await();
lock.reset();
if (debuggerCallback != null) {
debuggerCallback.accept(new ProgramState(node.location().orElse(Location.EMPTY).startLine() - 1, Map.copyOf(stack)));
lock.await();
lock.reset();
}
}

private void runConstant(Node.ConstantNode constantNode) {
Expand Down Expand Up @@ -212,7 +219,7 @@ private void runCommand(Node.CommandNode commandNode) throws IOException, Interr
case Node.ForCommandNode forCommandNode -> runForCommand(forCommandNode);
case Node.InterrompaCommandNode _ -> throw new BreakException();
case Node.LimpatelaCommandNode _ -> io.output().accept(new OutputEvent.Clear());
case Node.PausaCommandNode _ -> runPausaCommand(commandNode.location(), commandNode);
case Node.PausaCommandNode _ -> runPausaCommand(commandNode.location().orElse(Location.EMPTY), commandNode);
case Node.ProcedureCallNode procedureCallNode -> runProcedureCall(procedureCallNode);
case Node.ReadCommandNode readCommandNode -> runReadCommand(readCommandNode);
case Node.ReturnNode returnNode -> runReturnNode(returnNode);
Expand All @@ -225,8 +232,8 @@ private void runCommand(Node.CommandNode commandNode) throws IOException, Interr
}
}

private void runPausaCommand(Optional<Location> commandNode, Node.CommandNode commandNode1) throws BrokenBarrierException, InterruptedException {
state = new InterpreterState.PausedDebug(commandNode.orElse(Location.EMPTY).startLine());
private void runPausaCommand(Location commandNode, Node.CommandNode commandNode1) throws BrokenBarrierException, InterruptedException {
state = new InterpreterState.PausedDebug(commandNode.startLine());
handleDebugCommand(commandNode1);
}

Expand Down Expand Up @@ -310,7 +317,7 @@ private void runAleatorio(Node.AleatorioNode aleatorioNode) {

private void runDebugCommand(Node.DebugCommandNode debugCommandNode) throws BrokenBarrierException, InterruptedException {
if (evaluate(debugCommandNode.expr())) {
runPausaCommand(debugCommandNode.location(), debugCommandNode);
runPausaCommand(debugCommandNode.location().orElse(Location.EMPTY), debugCommandNode);
}
}

Expand Down Expand Up @@ -423,7 +430,7 @@ private void readExpression(Node.ExpressionNode expr) {
case Node.IdNode idNode -> {
Object variable = evaluateVariableOrFunction(idNode);
InputRequestValue inputRequest = new InputRequestValue(idNode.id(), InputRequestValue.Type.fromClass(variable.getClass()));
Object value = readValue(inputRequest, variable);
Object value = readValue(inputRequest);
assignVariable(idNode.id(), value, AssignContext.SIMPLE);
}
case Node.ArrayAccessNode arrayAccessNode -> {
Expand All @@ -437,12 +444,14 @@ private void readExpression(Node.ExpressionNode expr) {
int index1 = ((Number) evaluate(indexes.nodes().getFirst())).intValue();
int index2 = ((Number) evaluate(indexes.nodes().getLast())).intValue();
InputRequestValue inputRequest = new InputRequestValue(node.id() + "[" + index1 + "," + index2 + "]", InputRequestValue.Type.fromClass(componentType.getComponentType()));
multiarray[index1][index2] = readValue(inputRequest, multiarray[index1][index2]);
Object oldValue = multiarray[index1][index2];
multiarray[index1][index2] = assignSimple(readValue(inputRequest), oldValue.getClass());
}
case Object[] array -> {
int index = ((Number) evaluate(indexes.nodes().getFirst())).intValue();
InputRequestValue inputRequest = new InputRequestValue(node.id() + "[" + index + "]", InputRequestValue.Type.fromClass(componentType));
array[index] = readValue(inputRequest, array[index]);
Object oldValue = array[index];
array[index] = assignSimple(readValue(inputRequest), oldValue.getClass());
}
default -> throw unsupportedType(variable);
}
Expand All @@ -462,21 +471,21 @@ private void readExpression(Node.ExpressionNode expr) {
}
Class<?> type = getType(typeNode);
InputRequestValue inputRequest = new InputRequestValue(idNode.id(), InputRequestValue.Type.fromClass(type));
Object value = readValue(inputRequest, userDefinedValue.values().get(idNode.id()));
userDefinedValue.values().put(idNode.id(), value);
Object oldValue = userDefinedValue.values().get(idNode.id());
Object value = readValue(inputRequest);
userDefinedValue.values().put(idNode.id(), assignSimple(value, oldValue.getClass()));
}
default -> throw unsupportedType(expr);
}
}

private Object readValue(InputRequestValue inputRequest, Object o) {
private Object readValue(InputRequestValue inputRequest) {
InputValue inputValue = inputState.generateValue(inputRequest).orElseThrow();
Object value = switch (o) {
case Integer _ when inputValue instanceof InputValue.InteiroValue(var value1) -> value1;
case Double _ when inputValue instanceof InputValue.RealValue(var value1) -> value1;
case String _ when inputValue instanceof InputValue.CaracterValue(var value1) -> value1;
case Boolean _ when inputValue instanceof InputValue.LogicoValue(var value1) -> value1;
default -> throw new TypeException.MissingInput(inputRequest);
Object value = switch (inputValue) {
case InputValue.InteiroValue(var value1) -> value1;
case InputValue.RealValue(var value1) -> value1;
case InputValue.CaracterValue(var value1) -> value1;
case InputValue.LogicoValue(var value1) -> value1;
};
if (eco && !(inputState instanceof InputState.ReadInput))
io.output().accept(new OutputEvent.Text(value + "\n"));
Expand All @@ -487,7 +496,7 @@ private static Node.IdNode getIdentifierForArray(Node arrayAccessNode) {
return switch (arrayAccessNode) {
case Node.ArrayAccessNode nestedAccess -> getIdentifierForArray(nestedAccess.node());
case Node.IdNode idNode -> idNode;
default -> throw new UnsupportedOperationException("Unexpected value: " + arrayAccessNode);
default -> throw unsupportedType(arrayAccessNode);
};
}

Expand Down Expand Up @@ -600,14 +609,14 @@ private <T> T evaluate(Node.ExpressionNode node) {
case Node.EmptyExpressionNode _ -> 0;
case Node.ArrayAccessNode arrayAccessNode -> evaluateArrayAccessNode(arrayAccessNode);
case Node.MemberAccessNode memberAccessNode -> evaluateMemberAccessNode(memberAccessNode);
case Node.RangeNode _ -> throw new UnsupportedOperationException("RangeNode not implemented");
};
case Node.RangeNode _ -> throw new UnsupportedOperationException("RangeNode not implemented"); };

}

private Object evaluateMemberAccessNode(Node.MemberAccessNode memberAccessNode) {
Object evaluate = evaluate(memberAccessNode.node());
if (!(evaluate instanceof UserDefinedValue userDefinedValue)) {
throw new UnsupportedOperationException("Unsupported type: " + evaluate.getClass());
throw unsupportedType(evaluate);
}
Node.IdNode member = (Node.IdNode) memberAccessNode.member();
UserDefinedType userDefinedType = userDefinedValue.type();
Expand All @@ -630,10 +639,11 @@ private static UnsupportedOperationException unsupportedType(Object evaluate) {
}

private Object evaluateNegNode(Node.NegNode nedNode) {
return switch (evaluate(nedNode.expr())) {
Object evaluate = evaluate(nedNode.expr());
return switch (evaluate) {
case Double d -> -d;
case Integer i -> -i;
case null, default -> throw unsupportedType(nedNode.expr());
case null, default -> throw new TypeException.InvalidOperand(Operator.SUBTRACT, evaluate.getClass());
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junitpioneer.jupiter.cartesian.CartesianTest;

import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -515,7 +516,6 @@ private static Stream<FileAndError> exampleErrorsWithType() throws Throwable {
@ParameterizedTest
@MethodSource("exampleErrorsWithType")
void testExamplesErrors(FileAndError file) throws Throwable {
RandomGenerator aDefault = RandomGenerator.getDefault();
StringBuilder stringBuilder = new StringBuilder();
IO io = new IO(
_ -> CompletableFuture.completedFuture(Optional.empty()),
Expand All @@ -539,4 +539,81 @@ void testExamplesErrors(FileAndError file) throws Throwable {
}

}

enum Types {
CARACTER, LOGICO, REAL, INTEIRO
}

@CartesianTest
void testBinaryOperands(@CartesianTest.Values(strings = {">", ">=", "<", "<=", "<>", "=", "e", "ou"}) String operand,
@CartesianTest.Enum(Types.class) Types type1,
@CartesianTest.Enum(Types.class) Types type2) throws Throwable {
StringBuilder stringBuilder = new StringBuilder();
IO io = new IO(
_ -> CompletableFuture.completedFuture(Optional.empty()),
a -> {
switch (a) {
case OutputEvent.Text(String t) -> stringBuilder.append(t);
default -> {
}
}
});

Interpreter interpreter = new Interpreter(io);

String program = """
algoritmo "operands"
var
x: %s
y: %s
inicio
escreval(x %s y)
fimalgoritmo
""";

CompletableFuture<Void> run = interpreter.run(program.formatted(type1, type2, operand), Executors.newVirtualThreadPerTaskExecutor());
try {
run.join();
} catch (CompletionException e) {
System.out.println(stringBuilder);
assertInstanceOf(TypeException.InvalidOperand.class, e.getCause());
}

}

@CartesianTest
void testUnaryOperands(@CartesianTest.Values(strings = {"+", "-", "nao"}) String operand,
@CartesianTest.Enum(Types.class) Types type) throws Throwable {
StringBuilder stringBuilder = new StringBuilder();
IO io = new IO(
_ -> CompletableFuture.completedFuture(Optional.empty()),
a -> {
switch (a) {
case OutputEvent.Text(String t) -> stringBuilder.append(t);
default -> {
}
}
});

Interpreter interpreter = new Interpreter(io);

String program = """
algoritmo "operands"
var
x: %s
inicio
escreval(%s x)
fimalgoritmo
""";

CompletableFuture<Void> run = interpreter.run(program.formatted(type, operand), Executors.newVirtualThreadPerTaskExecutor());
try {
run.join();
} catch (CompletionException e) {
System.out.println(stringBuilder);
assertInstanceOf(TypeException.InvalidOperand.class, e.getCause());
}

}

}

0 comments on commit 469fbe9

Please sign in to comment.