Skip to content

Commit

Permalink
support do-while syntax #1
Browse files Browse the repository at this point in the history
  • Loading branch information
ptrthomas committed May 17, 2024
1 parent dde6799 commit ba94812
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
24 changes: 23 additions & 1 deletion karate-js/src/main/java/io/karatelabs/js/Interpreter.java
Original file line number Diff line number Diff line change
Expand Up @@ -617,9 +617,10 @@ private static Object evalVarStmt(Node node, Context context) {
private static Object evalWhileStmt(Node node, Context context) {
Context whileContext = new Context(context);
Node whileBody = node.children.get(node.children.size() - 1);
Node whileExpr = node.children.get(2);
Object whileResult = null;
while (true) {
Object whileCondition = eval(node.children.get(2), whileContext);
Object whileCondition = eval(whileExpr, whileContext);
if (!Terms.isTruthy(whileCondition)) {
break;
}
Expand All @@ -632,6 +633,25 @@ private static Object evalWhileStmt(Node node, Context context) {
return whileResult;
}

private static Object evalDoWhileStmt(Node node, Context context) {
Context doContext = new Context(context);
Node doBody = node.children.get(1);
Node doExpr = node.children.get(4);
Object doResult = null;
while (true) {
doResult = eval(doBody, doContext);
if (doContext.isStopped()) {
context.updateFrom(doContext);
break;
}
Object doCondition = eval(doExpr, doContext);
if (!Terms.isTruthy(doCondition)) {
break;
}
}
return doResult;
}

public static Object eval(Node node, Context context) {
context.currentNode = node;
switch (node.type) {
Expand Down Expand Up @@ -714,6 +734,8 @@ public static Object eval(Node node, Context context) {
return evalVarStmt(node, context);
case WHILE_STMT:
return evalWhileStmt(node, context);
case DO_WHILE_STMT:
return evalDoWhileStmt(node, context);
default:
throw new RuntimeException(node.toStringError("eval - unexpected node"));
}
Expand Down
13 changes: 13 additions & 0 deletions karate-js/src/main/java/io/karatelabs/js/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ private boolean statement(boolean mandatory) {
result = result || try_stmt();
result = result || for_stmt();
result = result || while_stmt();
result = result || do_while_stmt();
result = result || switch_stmt();
result = result || (break_stmt() && eos());
result = result || (delete_stmt() && eos());
Expand Down Expand Up @@ -431,6 +432,18 @@ private boolean while_stmt() {
return exit();
}

private boolean do_while_stmt() {
if (!enter(Type.DO_WHILE_STMT, Token.DO)) {
return false;
}
statement(true);
consume(Token.WHILE);
consume(Token.L_PAREN);
expr(-1, true);
consume(Token.R_PAREN);
return exit();
}

private boolean switch_stmt() {
if (!enter(Type.SWITCH_STMT, Token.SWITCH)) {
return false;
Expand Down
1 change: 1 addition & 0 deletions karate-js/src/main/java/io/karatelabs/js/Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public enum Type {
THROW_STMT,
FOR_STMT,
WHILE_STMT,
DO_WHILE_STMT,
SWITCH_STMT,
CASE_BLOCK,
DEFAULT_BLOCK,
Expand Down
6 changes: 6 additions & 0 deletions test-core/src/test/java/io/karatelabs/js/EvalTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,12 @@ void testWhileLoop() {
assertEquals(5, get("a"));
}

@Test
void testDoWhileLoop() {
eval("a = 0; do { a++ } while (a <= 5)");
assertEquals(6, get("a"));
}

@Test
void testTernary() {
eval("a = true ? 1 : 2");
Expand Down

0 comments on commit ba94812

Please sign in to comment.