Skip to content

Commit 3c6d8fa

Browse files
committed
Experimenting with Soft Errors
1 parent 20cccd8 commit 3c6d8fa

File tree

9 files changed

+110
-7
lines changed

9 files changed

+110
-7
lines changed

compatibility.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const all = {
2424

2525
function truthy (value) {
2626
if (Array.isArray(value) && value.length === 0) return false
27+
if (Number.isNaN(value)) return true
2728
return value
2829
}
2930

compatible.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ for (const file of files) {
1616
function correction (x) {
1717
// eslint-disable-next-line no-compare-neg-zero
1818
if (x === -0) return 0
19+
if (Number.isNaN(x)) return { error: 'NaN' }
1920
return x
2021
}
2122

defaultMethods.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,12 @@ const defaultMethods = {
5656
if (typeof data === 'string') return +data
5757
if (typeof data === 'number') return +data
5858
if (typeof data === 'boolean') return +data
59+
if (typeof data === 'object' && !Array.isArray(data)) return Number.NaN
5960
let res = 0
60-
for (let i = 0; i < data.length; i++) res += +data[i]
61+
for (let i = 0; i < data.length; i++) {
62+
if (data[i] && typeof data[i] === 'object') return Number.NaN
63+
res += +data[i]
64+
}
6165
return res
6266
},
6367
'*': (data) => {
@@ -85,6 +89,11 @@ const defaultMethods = {
8589
for (let i = 1; i < data.length; i++) res %= +data[i]
8690
return res
8791
},
92+
error: (type) => {
93+
if (Array.isArray(type)) type = type[0]
94+
if (type === 'NaN') return Number.NaN
95+
return { error: type }
96+
},
8897
max: (data) => Math.max(...data),
8998
min: (data) => Math.min(...data),
9099
in: ([item, array]) => (array || []).includes(item),
@@ -855,9 +864,14 @@ defaultMethods['==='].compile = function (data, buildState) {
855864
defaultMethods['+'].compile = function (data, buildState) {
856865
if (Array.isArray(data)) {
857866
return `(${data
858-
.map((i) => `(+${buildString(i, buildState)})`)
867+
.map((i) => {
868+
// Todo: Actually make this correct, this is a decent optimization but
869+
// does not coerce the built string.
870+
if (Array.isArray(i)) return 'NaN'
871+
return `(+${buildString(i, buildState)})`
872+
})
859873
.join(' + ')})`
860-
} else if (typeof data === 'string' || typeof data === 'number') {
874+
} else if (typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean') {
861875
return `(+${buildString(data, buildState)})`
862876
} else {
863877
return `([].concat(${buildString(
@@ -943,12 +957,12 @@ defaultMethods.not = defaultMethods['!']
943957
// @ts-ignore Allow custom attribute
944958
defaultMethods['!!'].compile = function (data, buildState) {
945959
if (Array.isArray(data)) return buildState.compile`(!!engine.truthy(${data[0]}))`
946-
return `(!!engine.truthy(${data}))`
960+
return buildState.compile`(!!engine.truthy(${data}))`
947961
}
948962
defaultMethods.none.deterministic = defaultMethods.some.deterministic
949963

950964
// @ts-ignore Allowing a optimizeUnary attribute that can be used for performance optimizations
951-
defaultMethods['+'].optimizeUnary = defaultMethods['-'].optimizeUnary = defaultMethods['!'].optimizeUnary = defaultMethods['!!'].optimizeUnary = defaultMethods.cat.optimizeUnary = true
965+
defaultMethods['+'].optimizeUnary = defaultMethods['-'].optimizeUnary = defaultMethods['!'].optimizeUnary = defaultMethods['!!'].optimizeUnary = defaultMethods.cat.optimizeUnary = defaultMethods.error.optimizeUnary = true
952966

953967
export default {
954968
...defaultMethods,

suites/divide.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,5 +146,23 @@
146146
"rule": { "/": [{ "val": "x" }, { "val": "y" }] },
147147
"data": { "x": 8, "y": 2 },
148148
"result": 4
149+
},
150+
{
151+
"description": "Divide by Zero",
152+
"rule": { "/": [0, 0] },
153+
"result": { "error": "NaN" },
154+
"data": null
155+
},
156+
{
157+
"description": "Divide by NaN",
158+
"rule": { "/": [1, { "error": "NaN" }] },
159+
"result": { "error": "NaN" },
160+
"data": null
161+
},
162+
{
163+
"description": "Divide with String produces NaN",
164+
"rule": { "/": [1, "a"] },
165+
"result": { "error": "NaN" },
166+
"data": null
149167
}
150168
]

suites/errors.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[
2+
"# Some error tests",
3+
{
4+
"description": "NaN is Truthy",
5+
"rule": { "!!": { "error": "NaN" } },
6+
"result": true,
7+
"data": null
8+
},
9+
{
10+
"description": "Arbitrary error is Truthy",
11+
"rule": { "!!": { "error": "Some error" } },
12+
"result": true,
13+
"data": null
14+
}
15+
]

suites/minus.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,17 @@
114114
"rule": { "-": [{ "val": "x" }, { "val": "y" }] },
115115
"data": { "x": 1, "y": 2 },
116116
"result": -1
117+
},
118+
{
119+
"description": "Subtraction with NaN",
120+
"rule": { "-": [{ "error": "NaN" }, 1] },
121+
"result": { "error": "NaN" },
122+
"data": null
123+
},
124+
{
125+
"description": "Subtraction with string produces NaN",
126+
"rule": { "-": ["Hey", 1] },
127+
"result": { "error": "NaN" },
128+
"data": null
117129
}
118130
]

suites/modulo.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,5 +157,17 @@
157157
"rule": { "%": [{ "val": "x" }, { "val": "y" }] },
158158
"data": { "x": 11, "y": 6 },
159159
"result": 5
160+
},
161+
{
162+
"description": "Modulo with NaN",
163+
"rule": { "%": [{ "error": "NaN" }, 1] },
164+
"result": { "error": "NaN" },
165+
"data": null
166+
},
167+
{
168+
"description": "Modulo with string produces NaN",
169+
"rule": { "%": ["Hey", 1] },
170+
"result": { "error": "NaN" },
171+
"data": null
160172
}
161173
]

suites/multiply.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,5 +144,17 @@
144144
"rule": { "*": [{ "val": "x" }, { "val": "y" }] },
145145
"data": { "x": 8, "y": 2 },
146146
"result": 16
147+
},
148+
{
149+
"description": "Multiply with NaN",
150+
"rule": { "*": [{ "error": "NaN" }, 1] },
151+
"result": { "error": "NaN" },
152+
"data": null
153+
},
154+
{
155+
"description": "Multiply with string produces NaN",
156+
"rule": { "*": ["Hey", 1] },
157+
"result": { "error": "NaN" },
158+
"data": null
147159
}
148160
]

suites/plus.json

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,25 @@
138138
{
139139
"description": "Addition with val",
140140
"rule": { "+": [{ "val": "x" }, { "val": "y" }] },
141-
"data": { "x": 1, "y": 2 },
142-
"result": 3
141+
"result": 3,
142+
"data": { "x": 1, "y": 2 }
143+
},
144+
{
145+
"description": "Addition with NaN",
146+
"rule": { "+": [{ "error": "NaN" }, 1] },
147+
"result": { "error": "NaN" },
148+
"data": null
149+
},
150+
{
151+
"description": "Addition with string produces NaN",
152+
"rule": { "+": ["Hey", 1] },
153+
"result": { "error": "NaN" },
154+
"data": null
155+
},
156+
{
157+
"description": "Addition with Array produces NaN",
158+
"rule": { "+": [[1], 1] },
159+
"result": { "error": "NaN" },
160+
"data": null
143161
}
144162
]

0 commit comments

Comments
 (0)