Skip to content

Commit b411529

Browse files
committed
Backport: feat: add default/elvis and coalescing operator. #64
Original commit: jsonata-js/jsonata@9e1523d Note: the fix of function boolean in functions.js was not required in Java (use of instanceof Map excludes functions already)
1 parent 7a9f0c2 commit b411529

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

src/main/java/com/dashjoin/jsonata/Parser.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,26 @@ public Parser() {
493493
// merged Infix: register(new Prefix("-")); // unary numeric negation
494494
register(new Infix("~>")); // function application
495495

496+
// coalescing operator
497+
register(new Infix("??", Tokenizer.operators.get("??")) {
498+
499+
@Override Symbol led(Symbol left) {
500+
this.type = "condition";
501+
Symbol c = new Symbol();
502+
this.condition = c;
503+
{
504+
c.type = "function";
505+
c.value = "(";
506+
Symbol p = new Symbol();
507+
c.procedure = p; p.type = "variable"; p.value = "exists";
508+
c.arguments = List.of(left);
509+
}
510+
this.then = left;
511+
this._else = expression(0);
512+
return this;
513+
}
514+
});
515+
496516
register(new InfixR("(error)", 10) {
497517
@Override
498518
Symbol led(Symbol left) {
@@ -787,6 +807,18 @@ Symbol led(Symbol left) {
787807
}
788808
});
789809

810+
// elvis/default operator
811+
register(new Infix("?:", Tokenizer.operators.get("?:")) {
812+
813+
@Override Symbol led(Symbol left) {
814+
this.type = "condition";
815+
this.condition = left;
816+
this.then = left;
817+
this._else = expression(0);
818+
return this;
819+
}
820+
});
821+
790822
// object transformer
791823
register(new Prefix("|") {
792824

src/main/java/com/dashjoin/jsonata/Tokenizer.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public class Tokenizer { // = function (path) {
6161
put("<=", 40);
6262
put(">=", 40);
6363
put("~>", 40);
64+
put("?:", 40);
65+
put("??", 40);
6466
put("and", 30);
6567
put("or", 25);
6668
put("in", 40);
@@ -232,6 +234,16 @@ Token next(boolean prefix) {
232234
position += 2;
233235
return create("operator", "~>");
234236
}
237+
if (currentChar == '?' && haveMore && path.charAt(position + 1) == ':') {
238+
// ?: default / elvis operator
239+
position += 2;
240+
return create("operator", "?:");
241+
}
242+
if (currentChar == '?' && haveMore && path.charAt(position + 1) == '?') {
243+
// ?? coalescing operator
244+
position += 2;
245+
return create("operator", "??");
246+
}
235247
// test for single char operators
236248
if (operators.get(""+currentChar)!=null) {
237249
position++;

0 commit comments

Comments
 (0)