Skip to content

Commit 0b5ed95

Browse files
committed
added ?? operator support
1 parent 3b0bef9 commit 0b5ed95

File tree

3 files changed

+28
-15
lines changed

3 files changed

+28
-15
lines changed

hscript/Checker.hx

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -434,10 +434,6 @@ class Checker {
434434
return globals;
435435
}
436436

437-
public dynamic function onTopDownEnum( en : CEnum, field : String ) {
438-
return false;
439-
}
440-
441437
function typeArgs( args : Array<Argument>, pos : Expr ) {
442438
return [for( i in 0...args.length ) {
443439
var a = args[i];
@@ -1209,31 +1205,29 @@ class Checker {
12091205
return TDynamic;
12101206
default:
12111207
#if hscriptPos
1212-
switch( withType ) {
1208+
var wt = switch( withType ) { case WithType(t): follow(t); default: null; };
1209+
switch( wt ) {
1210+
case null:
12131211
// enum constructor resolution
1214-
case WithType(et = TEnum(e, args)):
1212+
case TEnum(e, args):
12151213
for( c in e.constructors )
12161214
if( c.name == name ) {
1217-
if( onTopDownEnum(e,name) ) { // deprecated
1218-
var ct = c.args == null ? et : TFun(c.args, et);
1219-
return apply(ct, e.params, args);
1220-
}
1221-
var acc = getTypeAccess(et, expr, name);
1215+
var acc = getTypeAccess(wt, expr, name);
12221216
if( acc != null ) {
12231217
expr.e = acc;
1224-
var ct = c.args == null ? et : TFun(c.args, et);
1218+
var ct = c.args == null ? wt : TFun(c.args, wt);
12251219
return apply(ct, e.params, args);
12261220
}
12271221
break;
12281222
}
12291223
// abstract enum resolution
1230-
case WithType(at = TAbstract(a, args)) if( hasMeta(a.meta,":enum") ):
1224+
case TAbstract(a, args) if( hasMeta(a.meta,":enum") ):
12311225
var f = a.impl.statics.get(name);
12321226
if( f != null && hasMeta(f.meta,":enum") ) {
12331227
var acc = getTypeAccess(TInst(a.impl,[]),expr,name);
12341228
if( acc != null ) {
12351229
expr.e = acc;
1236-
return at;
1230+
return wt;
12371231
}
12381232
}
12391233
default:
@@ -1617,6 +1611,14 @@ class Checker {
16171611
error("Cannot compare "+typeStr(t1), expr);
16181612
}
16191613
return TBool;
1614+
case "??":
1615+
var t1 = typeExpr(e1,withType);
1616+
var t2 = typeExpr(e2,WithType(t1));
1617+
if( tryUnify(t2,t1) )
1618+
return t1;
1619+
if( tryUnify(t1,t2) )
1620+
return t2;
1621+
unify(t2,t1,e2); // error
16201622
default:
16211623
if( op.charCodeAt(op.length-1) == "=".code ) {
16221624
var t = typeExpr(mk(EBinop(op.substr(0,op.length-1),e1,e2),expr),withType);

hscript/Interp.hx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ class Interp {
9898
binops.set("=",assign);
9999
binops.set("...",function(e1,e2) return new IntIterator(me.expr(e1),me.expr(e2)));
100100
binops.set("is",function(e1,e2) return #if (haxe_ver >= 4.2) Std.isOfType #else Std.is #end (me.expr(e1), me.expr(e2)));
101+
binops.set("??",function(e1,e2) {
102+
var v1 : Dynamic = me.expr(e1);
103+
return if( v1 != null ) v1 else me.expr(e2);
104+
});
101105
assignOp("+=",function(v1:Dynamic,v2:Dynamic) return v1 + v2);
102106
assignOp("-=",function(v1:Float,v2:Float) return v1 - v2);
103107
assignOp("*=",function(v1:Float,v2:Float) return v1 * v2);

hscript/Parser.hx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ enum Token {
3333
TBrClose;
3434
TDot;
3535
TQuestionDot;
36+
TQuestionDouble;
3637
TComma;
3738
TSemicolon;
3839
TBkOpen;
@@ -113,9 +114,9 @@ class Parser {
113114
["+", "-"],
114115
["<<", ">>", ">>>"],
115116
["|", "&", "^"],
117+
["&&"],
116118
["==", "!=", ">", "<", ">=", "<="],
117119
["..."],
118-
["&&"],
119120
["||"],
120121
["=","+=","-=","*=","/=","%=","<<=",">>=",">>>=","|=","&=","^=","=>"],
121122
["->"],
@@ -888,6 +889,9 @@ class Parser {
888889
ensure(TDoubleDot);
889890
var e3 = parseExpr();
890891
return mk(ETernary(e1,e2,e3),pmin(e1),pmax(e3));
892+
case TQuestionDouble:
893+
var e2 = parseExpr();
894+
return makeBinop("??",e1,e2);
891895
default:
892896
push(tk);
893897
return e1;
@@ -1564,6 +1568,8 @@ class Parser {
15641568
char = readChar();
15651569
if( char == ".".code )
15661570
return TQuestionDot;
1571+
if( char == "?".code )
1572+
return TQuestionDouble;
15671573
this.char = char;
15681574
return TQuestion;
15691575
case ":".code: return TDoubleDot;
@@ -1791,6 +1797,7 @@ class Parser {
17911797
case TBrClose: "}";
17921798
case TDot: ".";
17931799
case TQuestionDot: "?.";
1800+
case TQuestionDouble: "??";
17941801
case TComma: ",";
17951802
case TSemicolon: ";";
17961803
case TBkOpen: "[";

0 commit comments

Comments
 (0)