diff --git a/hscript/Parser.hx b/hscript/Parser.hx index 5df5341e..e2a80847 100644 --- a/hscript/Parser.hx +++ b/hscript/Parser.hx @@ -1395,7 +1395,39 @@ class Parser { return parseExprNext(makeBinop(op,e1,parseExpr())); case TDot | TQuestionDot: var field = getIdent(); - return parseExprNext(mk(EField(e1, field, tk == TQuestionDot), pmin(e1))); + return parseExprNext(mk(EField(e1, field), pmin(e1)), noOp); + case TQuestionDot: + var tmp = "__a_" + (uid++); + push(TDot); + var e2 = parseExprNext(mk(EIdent(tmp),pmin(e1),pmax(e1)), true); + var tk2 = token(); + switch( tk2 ) { + case TOp(op): + var bop = Binop.fromString(op); + var isAssign = switch( bop ) { + case OpAssign | OpAddAssign | OpSubAssign | OpMultAssign | OpDivAssign | OpModAssign | OpAndAssign | OpOrAssign | OpXorAssign | OpShlAssign | OpShrAssign | OpUshrAssign | OpNcoalAssign: true; + default: false; + }; + if( isAssign ) { + var rhs = parseExpr(); + e2 = mk(EBinop(bop, e2, rhs), pmin(e2), pmax(rhs)); + } else if( op == "++" || op == "--" ) { + e2 = mk(EUnop(Unop.fromString(op), false, e2), pmin(e2), pmax(e2)); + } else { + push(tk2); + } + default: + push(tk2); + } + var e = mk(EBlock([ + mk(EVar(tmp, null, e1), pmin(e1), pmax(e1)), + mk(ETernary( + mk(EBinop(OpEq, mk(EIdent(tmp),pmin(e1),pmax(e1)), mk(EIdent("null"),pmin(e1),pmax(e1)))), + mk(EIdent("null"),pmin(e1),pmax(e1)), + e2 + )) + ]),pmin(e1)); + return parseExprNext(e, noOp); case TPOpen: return parseExprNext(mk(ECall(e1,parseExprList(TPClose)),pmin(e1))); case TBkOpen: