@opencode/codemode 0.0.0-dev-20097 → 0.0.0-dev-20103
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/interpreter/interpreter.js +28 -20
- package/dist/stdlib/object.js +1 -10
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@ import { globals } from "./globals.js";
|
|
|
9
9
|
import { assign, Callable, define, frozen, get, hostCursor, IteratorObj, has, hidden, hasPrototype, keys, Native, parseArrayIndex, Arr, Fn, GeneratorObj, Obj, PromiseObj, record, remove, set, coerceToNumber, coerceToString, } from "./objects.js";
|
|
10
10
|
import { preserveConsumerError } from "./callback.js";
|
|
11
11
|
import { Pending, resolvePromise, resolvePromiseValue } from "./promises.js";
|
|
12
|
-
import {
|
|
12
|
+
import { describeValue, isOpaque, rejectCircularInsertion, typeofValue } from "./references.js";
|
|
13
13
|
import { ScopeStack } from "./scope.js";
|
|
14
14
|
import { constructRegExp } from "../stdlib/regexp.js";
|
|
15
15
|
import { enumerableSource } from "../stdlib/object.js";
|
|
@@ -388,9 +388,6 @@ class Frame {
|
|
|
388
388
|
const self = this;
|
|
389
389
|
return Effect.gen(function* () {
|
|
390
390
|
const discriminant = yield* self.evaluateExpression(node.discriminant);
|
|
391
|
-
if (containsOpaqueReference(discriminant)) {
|
|
392
|
-
throw invalidData("Switch discriminants must be data values.", node);
|
|
393
|
-
}
|
|
394
391
|
self.scopes.push();
|
|
395
392
|
return yield* Effect.gen(function* () {
|
|
396
393
|
const cases = node.cases;
|
|
@@ -405,11 +402,7 @@ class Frame {
|
|
|
405
402
|
defaultIndex = index;
|
|
406
403
|
continue;
|
|
407
404
|
}
|
|
408
|
-
|
|
409
|
-
if (containsOpaqueReference(candidate)) {
|
|
410
|
-
throw invalidData("Switch case values must be data values.", test);
|
|
411
|
-
}
|
|
412
|
-
if (candidate === discriminant) {
|
|
405
|
+
if ((yield* self.evaluateExpression(test)) === discriminant) {
|
|
413
406
|
selected = index;
|
|
414
407
|
break;
|
|
415
408
|
}
|
|
@@ -1077,16 +1070,19 @@ class Frame {
|
|
|
1077
1070
|
return lhs === rhs;
|
|
1078
1071
|
if (operator === "!==")
|
|
1079
1072
|
return lhs !== rhs;
|
|
1080
|
-
if (operator === "
|
|
1073
|
+
if (operator === "==")
|
|
1074
|
+
return this.looselyEqual(lhs, rhs, node);
|
|
1075
|
+
if (operator === "!=")
|
|
1076
|
+
return !this.looselyEqual(lhs, rhs, node);
|
|
1077
|
+
if (operator === "in" && rhs instanceof Obj && !isOpaque(lhs)) {
|
|
1081
1078
|
return has(rhs, lhs !== null && typeof lhs === "object" ? coerceToString(lhs) : lhs);
|
|
1082
1079
|
}
|
|
1083
|
-
if (
|
|
1080
|
+
if (isOpaque(lhs) || isOpaque(rhs)) {
|
|
1084
1081
|
throw invalidData("Binary operators require data values.", node);
|
|
1085
1082
|
}
|
|
1086
|
-
// Addition
|
|
1087
|
-
const hint = operator === "+"
|
|
1083
|
+
// Addition uses the default hint; every other operator asks for a number.
|
|
1084
|
+
const hint = operator === "+" ? "default" : "number";
|
|
1088
1085
|
const coerceOperand = (operand) => (operand instanceof Obj ? operand.toPrimitive(hint) : operand);
|
|
1089
|
-
const bothObjects = lhs !== null && typeof lhs === "object" && rhs !== null && typeof rhs === "object";
|
|
1090
1086
|
const l = coerceOperand(lhs);
|
|
1091
1087
|
const r = coerceOperand(rhs);
|
|
1092
1088
|
switch (operator) {
|
|
@@ -1106,10 +1102,6 @@ class Frame {
|
|
|
1106
1102
|
return l % r;
|
|
1107
1103
|
case "**":
|
|
1108
1104
|
return l ** r;
|
|
1109
|
-
case "==":
|
|
1110
|
-
return bothObjects ? lhs === rhs : l == r;
|
|
1111
|
-
case "!=":
|
|
1112
|
-
return bothObjects ? lhs !== rhs : l != r;
|
|
1113
1105
|
case "<":
|
|
1114
1106
|
return l < r;
|
|
1115
1107
|
case "<=":
|
|
@@ -1139,6 +1131,22 @@ class Frame {
|
|
|
1139
1131
|
throw typeError(`Unsupported binary operator '${operator}'.`, node);
|
|
1140
1132
|
}
|
|
1141
1133
|
}
|
|
1134
|
+
// IsLooselyEqual: objects (including functions and tool references) compare by identity, and only a
|
|
1135
|
+
// data object facing a non-nullish primitive needs to coerce, so an opaque value is rejected only there.
|
|
1136
|
+
looselyEqual(lhs, rhs, node) {
|
|
1137
|
+
const lhsObject = lhs !== null && typeof lhs === "object";
|
|
1138
|
+
const rhsObject = rhs !== null && typeof rhs === "object";
|
|
1139
|
+
if (lhsObject === rhsObject)
|
|
1140
|
+
return lhsObject ? lhs === rhs : lhs == rhs;
|
|
1141
|
+
const object = lhsObject ? lhs : rhs;
|
|
1142
|
+
const primitive = lhsObject ? rhs : lhs;
|
|
1143
|
+
if (primitive === null || primitive === undefined)
|
|
1144
|
+
return false;
|
|
1145
|
+
if (!(object instanceof Obj) || isOpaque(object)) {
|
|
1146
|
+
throw invalidData("Binary operators require data values.", node);
|
|
1147
|
+
}
|
|
1148
|
+
return object.toPrimitive("default") == primitive;
|
|
1149
|
+
}
|
|
1142
1150
|
evaluateLogicalExpression(node) {
|
|
1143
1151
|
const operator = node.operator;
|
|
1144
1152
|
return Effect.flatMap(this.evaluateExpression(node.left), (left) => {
|
|
@@ -1167,7 +1175,7 @@ class Frame {
|
|
|
1167
1175
|
return !value;
|
|
1168
1176
|
if (operator === "void")
|
|
1169
1177
|
return undefined;
|
|
1170
|
-
if (
|
|
1178
|
+
if (isOpaque(value)) {
|
|
1171
1179
|
throw invalidData("Unary operators require data values.", node);
|
|
1172
1180
|
}
|
|
1173
1181
|
const operand = value instanceof Obj ? value.toPrimitive("number") : value;
|
|
@@ -1257,7 +1265,7 @@ class Frame {
|
|
|
1257
1265
|
// CodeMode numeric coercion, not host Number(): null-prototype data objects would make
|
|
1258
1266
|
// the host throw during ToPrimitive, and opaque runtime references must reject clearly.
|
|
1259
1267
|
const operand = (current) => {
|
|
1260
|
-
if (
|
|
1268
|
+
if (isOpaque(current)) {
|
|
1261
1269
|
throw invalidData(`'${operator}' requires a data value.`, argument);
|
|
1262
1270
|
}
|
|
1263
1271
|
return coerceToNumber(current);
|
package/dist/stdlib/object.js
CHANGED
|
@@ -118,16 +118,7 @@ export const objectGlobal = (ctx) => {
|
|
|
118
118
|
(_, args) => new Arr(builtins.Array, entries(enumerableSource(ctx, "Object.entries(...)", args[0])).map((entry) => new Arr(builtins.Array, entry))),
|
|
119
119
|
],
|
|
120
120
|
["hasOwn", 2, (_, args) => hasOwn(enumerableSource(ctx, "Object.hasOwn(...)", args[0]), propertyKey(args[1]))],
|
|
121
|
-
[
|
|
122
|
-
"is",
|
|
123
|
-
2,
|
|
124
|
-
(_, args) => {
|
|
125
|
-
if (containsOpaqueReference(args[0]) || containsOpaqueReference(args[1])) {
|
|
126
|
-
throw invalidData("Object.is requires data values.");
|
|
127
|
-
}
|
|
128
|
-
return Object.is(args[0], args[1]);
|
|
129
|
-
},
|
|
130
|
-
],
|
|
121
|
+
["is", 2, (_, args) => Object.is(args[0], args[1])],
|
|
131
122
|
["assign", 2, (_, args) => objectAssign(ctx, args)],
|
|
132
123
|
["fromEntries", 1, (_, args) => objectFromEntries(ctx, args[0])],
|
|
133
124
|
]);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@opencode/codemode",
|
|
4
|
-
"version": "0.0.0-dev-
|
|
4
|
+
"version": "0.0.0-dev-20103",
|
|
5
5
|
"description": "Effect-native confined code execution over schema-described tools",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|