Skip to content

Commit 3d568ee

Browse files
authored
Fix ?. order with ??, make ?? a TOp, add tests (#158)
1 parent 382093b commit 3d568ee

3 files changed

Lines changed: 17 additions & 16 deletions

File tree

TestHScript.hx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ class TestHScript extends TestCase {
154154
assertScript("ptnull?.x", null, vars);
155155
assertScript("ptnull?.pt.x", null, vars);
156156
assertScript("ptnull?.call()", null, vars);
157+
assertScript("ptnull?.pt.call()", null, vars);
157158
assertScript("pt?.x", 10, vars);
158159
assertScript("pt?.call()", 11, vars);
159160
assertScript("pt2null?.pt", null, vars);
@@ -162,6 +163,11 @@ class TestHScript extends TestCase {
162163
assertScript("pt2?.pt", pt, vars);
163164
assertScript("pt2?.pt?.x", 10, vars);
164165
assertScript("pt2?.pt?.call()", 11, vars);
166+
assertScript("ptnull ?? 12", 12, vars);
167+
assertScript("pt2null.pt ?? 12", 12, vars);
168+
assertScript("ptnull?.x ?? 12", 12, vars);
169+
assertScript("pt?.x ?? 12", 10, vars);
170+
assertScript("pt.y ?? 12", 12, vars);
165171
}
166172

167173
function testIsOperator():Void {

hscript/JsInterp.hx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ class JsInterp extends Interp {
222222
return '$$i.get(${exprValue(e)},"$f")';
223223
case EBinop(op, e1, e2):
224224
switch( op ) {
225-
case "+","-","*","/","%","&","|","^",">>","<<",">>>","==","!=",">=","<=",">","<":
225+
case "+","-","*","/","%","&","|","^",">>","<<",">>>","==","!=",">=","<=",">","<","??":
226226
return '${exprOp(e1)} $op ${exprOp(e2)}';
227227
case "||","&&":
228228
return '(${exprCond(e1)} $op ${exprCond(e2)})';

hscript/Parser.hx

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ enum Token {
3333
TBrClose;
3434
TDot;
3535
TQuestionDot;
36-
TQuestionDouble;
3736
TComma;
3837
TSemicolon;
3938
TBkOpen;
@@ -862,10 +861,10 @@ class Parser {
862861
}
863862
}
864863

865-
function parseExprNext( e1 : Expr ) {
864+
function parseExprNext( e1 : Expr, ?noOp = false ) {
866865
var tk = token();
867866
switch( tk ) {
868-
case TOp(op):
867+
case TOp(op) if( !noOp ):
869868

870869
if( op == "->" ) {
871870
// single arg reinterpretation of `f -> e` , `(f) -> e` and `(f:T) -> e`
@@ -889,15 +888,15 @@ class Parser {
889888
return parseExprNext(mk(EUnop(op,false,e1),pmin(e1)));
890889
}
891890
return makeBinop(op,e1,parseExpr());
892-
case TId(op) if( opPriority.exists(op) ):
891+
case TId(op) if( !noOp && opPriority.exists(op) ):
893892
return parseExprNext(makeBinop(op,e1,parseExpr()));
894893
case TDot:
895894
var field = getIdent();
896-
return parseExprNext(mk(EField(e1,field),pmin(e1)));
895+
return parseExprNext(mk(EField(e1,field),pmin(e1)), noOp);
897896
case TQuestionDot:
898897
var tmp = "__a_" + (uid++);
899898
push(TDot);
900-
var e2 = parseExprNext(mk(EIdent(tmp),pmin(e1),pmax(e1)));
899+
var e2 = parseExprNext(mk(EIdent(tmp),pmin(e1),pmax(e1)), true);
901900
var e = mk(EBlock([
902901
mk(EVar(tmp, null, e1), pmin(e1), pmax(e1)),
903902
mk(ETernary(
@@ -906,21 +905,18 @@ class Parser {
906905
e2
907906
))
908907
]),pmin(e1));
909-
return e;
908+
return parseExprNext(e, noOp);
910909
case TPOpen:
911-
return parseExprNext(mk(ECall(e1,parseExprList(TPClose)),pmin(e1)));
910+
return parseExprNext(mk(ECall(e1,parseExprList(TPClose)),pmin(e1)), noOp);
912911
case TBkOpen:
913912
var e2 = parseExpr();
914913
ensure(TBkClose);
915-
return parseExprNext(mk(EArray(e1,e2),pmin(e1)));
916-
case TQuestion:
914+
return parseExprNext(mk(EArray(e1,e2),pmin(e1)), noOp);
915+
case TQuestion if( !noOp ):
917916
var e2 = parseExpr();
918917
ensure(TDoubleDot);
919918
var e3 = parseExpr();
920919
return mk(ETernary(e1,e2,e3),pmin(e1),pmax(e3));
921-
case TQuestionDouble:
922-
var e2 = parseExpr();
923-
return makeBinop("??",e1,e2);
924920
default:
925921
push(tk);
926922
return e1;
@@ -1599,7 +1595,7 @@ class Parser {
15991595
if( char == ".".code )
16001596
return TQuestionDot;
16011597
if( char == "?".code )
1602-
return TQuestionDouble;
1598+
return TOp("??");
16031599
this.char = char;
16041600
return TQuestion;
16051601
case ":".code: return TDoubleDot;
@@ -1829,7 +1825,6 @@ class Parser {
18291825
case TBrClose: "}";
18301826
case TDot: ".";
18311827
case TQuestionDot: "?.";
1832-
case TQuestionDouble: "??";
18331828
case TComma: ",";
18341829
case TSemicolon: ";";
18351830
case TBkOpen: "[";

0 commit comments

Comments
 (0)