diff --git a/polymod/hscript/_internal/Parser.hx b/polymod/hscript/_internal/Parser.hx index 0e66b1f6..1f1a5887 100644 --- a/polymod/hscript/_internal/Parser.hx +++ b/polymod/hscript/_internal/Parser.hx @@ -1043,40 +1043,27 @@ class Parser return parseExprNext(mk(EField(e1, field), pmin(e1))); case TQuestionDot: - var field = getIdent(); - var tmp = "__a_" + (uid++); - var t = token(); - inline function pushBack() - { - push(t); - return null; - } - var eOp = switch (t) - { - case TOp(s): if (!opRightAssoc.exists(s)) pushBack(); else s; - case TPOpen: ''; - default: pushBack(); - } - - if (eOp != null && eOp.length > 0) + var field:String = getIdent(); + var tmp:String = "__a_" + (uid++); + var t:Token = token(); + var ternaryRhs:ExprDef = switch (t) { - var e2 = parseExpr(); - var e = mk(EBlock([ - mk(EVar(tmp, null, e1)), - mk(ETernary(mk(EBinop("!=", mk(EIdent(tmp), pmin(e1), pmax(e1)), mk(EIdent("null"), pmin(e1), pmax(e1))), pmin(e1), pmax(e1)), - mk(EBinop(eOp, mk(EField(mk(EIdent(tmp), pmin(e1), pmax(e1)), field), pmin(e1), pmax(e1)), e2), pmin(e1), pmax(e2)), - mk(EIdent("null"), pmin(e2), pmax(e2))), - pmin(e1), pmax(e2)) - ]), pmin(e1)); - return parseExprNext(e); + case TOp(op) if (opRightAssoc.exists(op)): + EBinop(op, mk(EField(e1, field), pmin(e1), pmax(e1)), parseExpr()); + case TPOpen: + ECall(mk(EField(mk(EIdent(tmp), pmin(e1), pmax(e1)), field), pmin(e1)), parseExprList(TPClose)); + default: + // Token shouldn't be consumed in this case + push(t); + EField(mk(EIdent(tmp), pmin(e1), pmax(e1)), field); } - var e = mk(EBlock([ - mk(EVar(tmp, null, e1), pmin(e1), pmax(e1)), - mk(ETernary(mk(EBinop("==", mk(EIdent(tmp), pmin(e1), pmax(e1)), mk(EIdent("null"), pmin(e1), pmax(e1)))), mk(EIdent("null"), pmin(e1), pmax(e1)), - (eOp != null && eOp.length == 0) ? mk(ECall(mk(EField(mk(EIdent(tmp), pmin(e1), pmax(e1)), field), pmin(e1)), parseExprList(TPClose)), - pmin(e1)) : mk(EField(mk(EIdent(tmp), pmin(e1), pmax(e1)), field), pmin(e1)))) - ]), pmin(e1)); + var e:Expr = mk(EBlock([ + mk(EVar(tmp, null, e1)), + mk(ETernary(mk(EBinop("==", mk(EIdent(tmp), pmin(e1), pmax(e1)), mk(EIdent("null"))), pmin(e1), pmax(e1)), mk(EIdent("null"), pmin(e1), pmax(e1)), + mk(ternaryRhs, pmin(e1))), + pmin(e1), pmax(e1)) + ]), pmin(e1), pmax(e1)); return parseExprNext(e); case TPOpen: diff --git a/polymod/hscript/_internal/Printer.hx b/polymod/hscript/_internal/Printer.hx index f05011d1..fe2531df 100644 --- a/polymod/hscript/_internal/Printer.hx +++ b/polymod/hscript/_internal/Printer.hx @@ -211,39 +211,18 @@ class Printer // account for null coalescing if (el.length == 2) { - switch (#if hscriptPos el[0].e #else el[0] #end) + switch (Tools.expr(el[0])) { - case EVar(n, _, e): - if (n.indexOf("__a_") == 0) + case EVar(n, _, e) if (n.indexOf("__a_") == 0): + switch (Tools.expr(el[1])) { - switch (#if hscriptPos el[1].e #else el[1] #end) - { - case ETernary(c, e11, e12): - switch (#if hscriptPos c.e #else c #end) - { - case EBinop(op, _, _): - if (op == "==") - { - expr(e); - add("?"); - ignoreNextField = true; - expr(e12); - return; - } - - if (op == "!=") - { - expr(e); - add("?"); - ignoreNextField = true; - expr(e11); - return; - } - - default: - } - default: - } + case ETernary(Tools.expr(_) => EBinop("==", _, _), _, e12): + expr(e); + add("?"); + ignoreNextField = true; + expr(e12); + return; + default: } default: }