This is a draft proposal for how we could specify the compound operators corresponding to the logical operators in Dart.
Note that we could collapse 5 cases of similar shape to one case for each operator; however, this requires the use of meta-meta-variables, and the spec does not currently use such a mechanism.
In the following, v
is an identifier, C
is a type literal, e
and other
symbols starting with e
are expressions not containing await
, and p
is
a library prefix; x
and y
are fresh variable names. BC
stands for the
boolean conversion operation described in (16.4.1). Evaluation of compound
assignments for logical operators is then defined in terms of expansions into
other expressions as follows:
Evaluation of v &&= e
is equivalent to evaluation of
((x) => x ? v = BC(e) : x)(BC(v))
.
Evaluation of C.v &&= e
is equivalent to evaluation of
((x) => x ? C.v = BC(e) : x)(BC(C.v))
.
Evaluation of p.v &&= e
is equivalent to evaluation of
((x) => x ? p.v = BC(e) : x)(BC(p.v))
.
Evaluation of p.C.v &&= e
is equivalent to evaluation of
((x) => x ? p.C.v = BC(e) : x)(BC(p.C.v))
.
Evaluation of e1.v &&= e2
is equivalent to evaluation of
((x) => ((y) => y ? x.v = BC(e2) : y)(BC(x.v)))(e1)
.
Evaluation of e1[e2] &&= e3
is equivalent to evaluation of
((a, i) => ((x) => x ? a[i] = BC(e3) : x)(BC(a[i])))(e1, e2)
.
Evaluation of super.v &&= e
is equivalent to evaluation of
((x) => x ? super.v = BC(e) : x)(BC(super.v))
.
Evaluation of e1?.v &&= e2
is equivalent to evaluation of
((x) => x == null ? null : x.v &&= e2)(e1)
.
Evaluation of C?.v &&= e
is equivalent to evaluation of
C.v &&= e
.
Evaluation of v ||= e
is equivalent to evaluation of
((x) => x ? x : v = BC(e))(BC(v))
.
Evaluation of C.v ||= e
is equivalent to evaluation of
((x) => x ? x : C.v = BC(e))(BC(C.v))
.
Evaluation of p.v ||= e
is equivalent to evaluation of
((x) => x ? x : p.v = BC(e))(BC(p.v))
.
Evaluation of p.C.v ||= e
is equivalent to evaluation of
((x) => x ? x : p.C.v = BC(e))(BC(p.C.v))
.
Evaluation of e1.v ||= e2
is equivalent to evaluation of
((x) => ((y) => y ? y : x.v = BC(e2))(BC(x.v)))(e1)
.
Evaluation of e1[e2] ||= e3
is equivalent to evaluation of
((a, i) => ((x) => x ? x : a[i] = BC(e3))(BC(a[i])))(e1, e2)
.
Evaluation of super.v ||= e
is equivalent to evaluation of
((x) => x ? x : super.v = BC(e))(BC(super.v))
.
Evaluation of e1?.v ||= e2
is equivalent to evaluation of
((x) => x == null ? null : x.v ||= e2)(e1)
.
Evaluation of C?.v ||= e
is equivalent to evaluation of
C.v ||= e
.
Evaluation of v &&= e
is equivalent to evaluation of
((x) => x ? v = BC(e) : false)(v)
.
Evaluation of C.v &&= e
is equivalent to evaluation of
((x) => x ? C.v = BC(e) : false)(C.v)
.
Evaluation of p.v &&= e
is equivalent to evaluation of
((x) => x ? p.v = BC(e) : false)(p.v)
.
Evaluation of p.C.v &&= e
is equivalent to evaluation of
((x) => x ? p.C.v = BC(e) : false)(p.C.v)
.
Evaluation of e1.v &&= e2
is equivalent to evaluation of
((x) => ((y) => y ? x.v = BC(e2) : false)(x.v))(e1)
.
Evaluation of e1[e2] &&= e3
is equivalent to evaluation of
((a, i) => ((x) => x ? a[i] = BC(e3) : false)(a[i]))(e1, e2)
.
Evaluation of super.v &&= e
is equivalent to evaluation of
((x) => x ? super.v = BC(e) : false)(super.v)
.
Evaluation of e1?.v &&= e2
is equivalent to evaluation of
((x) => x == null ? null : x.v &&= e2)(e1)
.
Evaluation of C?.v &&= e
is equivalent to evaluation of
C.v &&= e
.
Evaluation of v ||= e
is equivalent to evaluation of
((x) => x ? true : v = BC(e))(v)
.
Evaluation of C.v ||= e
is equivalent to evaluation of
((x) => x ? true : C.v = BC(e))(C.v)
.
Evaluation of p.v ||= e
is equivalent to evaluation of
((x) => x ? true : p.v = BC(e))(p.v)
.
Evaluation of p.C.v ||= e
is equivalent to evaluation of
((x) => x ? true : p.C.v = BC(e))(p.C.v)
.
Evaluation of e1.v ||= e2
is equivalent to evaluation of
((x) => ((y) => y ? true : x.v = BC(e2))(x.v))(e1)
.
Evaluation of e1[e2] ||= e3
is equivalent to evaluation of
((a, i) => ((x) => x ? true : a[i] = BC(e3))(a[i]))(e1, e2)
.
Evaluation of super.v ||= e
is equivalent to evaluation of
((x) => x ? true : super.v = BC(e))(super.v)
.
Evaluation of e1?.v ||= e2
is equivalent to evaluation of
((x) => x == null ? null : x.v ||= e2)(e1)
.
Evaluation of C?.v ||= e
is equivalent to evaluation of
C.v ||= e
.
Evaluation of v &&= e
is equivalent to evaluation of
let x = BC(v) in x ? v = BC(e) : x
.
Evaluation of C.v &&= e
is equivalent to evaluation of
let x = BC(C.v) in x ? C.v = BC(e) : x
.
Evaluation of p.v &&= e
is equivalent to evaluation of
let x = BC(p.v) in x ? p.v = BC(e) : x
.
Evaluation of p.C.v &&= e
is equivalent to evaluation of
let x = BC(p.C.v) in x ? p.C.v = BC(e) : x
.
Evaluation of e1.v &&= e2
is equivalent to evaluation of
let x = e1, y = BC(x.v) in y ? x.v = BC(e2) : y
.
Evaluation of e1[e2] &&= e3
is equivalent to evaluation of
let a = e1, i = e2, x = BC(a[i]) in x ? a[i] = BC(e3) : x
.
Evaluation of super.v &&= e
is equivalent to evaluation of
let x = BC(super.v) in x ? super.v = BC(e) : x
.
Evaluation of e1?.v &&= e2
is equivalent to evaluation of
let x = e1 in x == null ? null : x.v &&= e2
.
Evaluation of C?.v &&= e
is equivalent to evaluation of
C.v &&= e
.
Evaluation of v ||= e
is equivalent to evaluation of
let x = BC(v) in x ? x : v = BC(e)
.
Evaluation of C.v ||= e
is equivalent to evaluation of
let x = BC(C.v) in x ? x : C.v = BC(e)
.
Evaluation of p.v ||= e
is equivalent to evaluation of
let x = BC(p.v) in x ? x : p.v = BC(e)
.
Evaluation of p.C.v ||= e
is equivalent to evaluation of
let x = BC(p.C.v) in x ? x : p.C.v = BC(e)
.
Evaluation of e1.v ||= e2
is equivalent to evaluation of
let x = e1, y = BC(x.v) in y ? y : x.v = BC(e2)
.
Evaluation of e1[e2] ||= e3
is equivalent to evaluation of
let a = e1, i = e2, x = BC(a[i]) in x ? x : a[i] = BC(e3)
.
Evaluation of super.v ||= e
is equivalent to evaluation of
let x = BC(super.v) in x ? x : super.v = BC(e)
.
Evaluation of e1?.v ||= e2
is equivalent to evaluation of
let x = e1 in x == null ? null : x.v ||= e2
.
Evaluation of C?.v ||= e
is equivalent to evaluation of
C.v ||= e
.