Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 18 additions & 31 deletions polymod/hscript/_internal/Parser.hx
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
41 changes: 10 additions & 31 deletions polymod/hscript/_internal/Printer.hx
Original file line number Diff line number Diff line change
Expand Up @@ -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:
}
Expand Down