Skip to content

Commit ee46aa8

Browse files
committed
feat: Null-safe field assign
1 parent d60bb29 commit ee46aa8

File tree

2 files changed

+25
-19
lines changed

2 files changed

+25
-19
lines changed

TestHScript.hx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,12 @@ class TestHScript extends TestCase {
125125
assertScript("var f:(x:Int)->(Int, Int)->Int = (x:Int) -> (y:Int, z:Int) -> x + y + z; f(3)(1, 2)", 6, null, true);
126126
assertScript("var a = 10; var b = 5; a - -b", 15);
127127
assertScript("var a = 10; var b = 5; a - b / 2", 7.5);
128-
assertScript("var a; a", null);
129-
assertScript("var a = 1, b = 5; a + b;", 6);
130-
assertScript("var a, b = 5; if (a == null) a = 2; a + b;", 7);
131-
assertScript("var a:Int; a", null, null, true);
132-
assertScript("var a:Int = 1, b:Int = 5; a + b;", 6, null, true);
133-
assertScript("var a:Int, b:Int = 5; if (a == null) a = 2; a + b;", 7, null, true);
128+
assertScript("var a; a", null);
129+
assertScript("var a = 1, b = 5; a + b;", 6);
130+
assertScript("var a, b = 5; if (a == null) a = 2; a + b;", 7);
131+
assertScript("var a:Int; a", null, null, true);
132+
assertScript("var a:Int = 1, b:Int = 5; a + b;", 6, null, true);
133+
assertScript("var a:Int, b:Int = 5; if (a == null) a = 2; a + b;", 7, null, true);
134134
assertScript("false && xxx", false);
135135
assertScript("true || xxx", true);
136136
assertScript("[for( x in arr ) switch( x ) { case 1: 55; case 3: 66; default: 0; }].join(':')",'55:0:66',{ arr : [1,2,3] });
@@ -142,14 +142,20 @@ class TestHScript extends TestCase {
142142
ptnull : null,
143143
pt: pt,
144144
pt2null : {pt : null},
145-
pt2: {pt : pt}
145+
pt2: {pt : pt},
146+
str: 'getting freaky on a friday night yeah'
146147
}
147148
assertScript("ptnull?.x", null, vars);
148149
assertScript("pt?.x", 10, vars);
149150
assertScript("pt2null?.pt", null, vars);
150151
assertScript("pt2null?.pt?.x", null, vars);
151152
assertScript("pt2?.pt", pt, vars);
152153
assertScript("pt2?.pt?.x", 10, vars);
154+
assertScript("ptnull?.x = 5", null, vars);
155+
assertScript("pt2null?.pt?.x = 5", null, vars);
156+
assertScript("pt2?.pt?.x = 2", 2, vars);
157+
assertScript("str?.indexOf('freaky')", 8, vars);
158+
assertScript("ptnull?.indexOf('friday')", null, vars);
153159
}
154160

155161
function testIsOperator():Void {
@@ -256,4 +262,4 @@ class TestHScript extends TestCase {
256262
#end
257263
}
258264

259-
}
265+
}

hscript/Parser.hx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -822,27 +822,27 @@ class Parser {
822822
return parseExprNext(mk(EField(e1,field),pmin(e1)));
823823
case TQuestionDot:
824824
var field = getIdent();
825+
826+
if (maybe(TOp('='))) {
827+
var e2 = parseExpr();
828+
var e = mk(EIf(
829+
mk(EBinop("!=", e1, mk(EIdent("null"), pmin(e1), pmax(e1))), pmin(e1), pmax(e1)),
830+
mk(EBinop("=", mk(EField(e1, field), pmin(e1), pmax(e1)), e2), pmin(e1), pmax(e2))
831+
), pmin(e1), pmax(e2));
832+
return parseExprNext(e);
833+
}
834+
825835
var tmp = "__a_" + (uid++);
826836
var e = mk(EBlock([
827837
mk(EVar(tmp, null, e1), pmin(e1), pmax(e1)),
828838
mk(ETernary(
829839
mk(EBinop("==", mk(EIdent(tmp),pmin(e1),pmax(e1)), mk(EIdent("null"),pmin(e1),pmax(e1)))),
830840
mk(EIdent("null"),pmin(e1),pmax(e1)),
841+
maybe(TPOpen) ? mk(ECall(mk(EField(mk(EIdent(tmp),pmin(e1),pmax(e1)),field),pmin(e1)),parseExprList(TPClose)),pmin(e1)) :
831842
mk(EField(mk(EIdent(tmp),pmin(e1),pmax(e1)),field),pmin(e1))
832843
))
833844
]),pmin(e1));
834845

835-
if ( maybe(TPOpen) ) {
836-
e = mk(EBlock([
837-
mk(EVar(tmp, null, e1), pmin(e1), pmax(e1)),
838-
mk(ETernary(
839-
mk(EBinop("==", mk(EIdent(tmp),pmin(e1),pmax(e1)), mk(EIdent("null"),pmin(e1),pmax(e1)))),
840-
mk(EIdent("null"),pmin(e1),pmax(e1)),
841-
mk(ECall(mk(EField(mk(EIdent(tmp),pmin(e1),pmax(e1)),field),pmin(e1)),parseExprList(TPClose)),pmin(e1))
842-
))
843-
]),pmin(e1));
844-
}
845-
846846
return parseExprNext(e);
847847
case TPOpen:
848848
return parseExprNext(mk(ECall(e1,parseExprList(TPClose)),pmin(e1)));

0 commit comments

Comments
 (0)