@neocompose/cli 0.66.0 → 0.67.1
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/CHANGELOG.md +15 -0
- package/dist/neo.mjs +336 -147
- package/dist/test-worker.mjs +127 -48
- package/package.json +1 -1
- package/skills/neocompose-cli/SKILL.md +1 -1
- package/skills/neocompose-cli/references/cli-development.md +1 -1
- package/skills/neocompose-cli/references/commands-and-sync.md +8 -6
- package/skills/neocompose-cli/references/neoscript.md +8 -0
package/dist/test-worker.mjs
CHANGED
|
@@ -1755,7 +1755,7 @@ var TEST_GLOBALS = [
|
|
|
1755
1755
|
];
|
|
1756
1756
|
|
|
1757
1757
|
// ../packages/neoscript-language/src/strict-ir.ts
|
|
1758
|
-
var NEOSCRIPT_COMPILER_REVISION =
|
|
1758
|
+
var NEOSCRIPT_COMPILER_REVISION = 17;
|
|
1759
1759
|
|
|
1760
1760
|
// ../src/models/members/member-storage.ts
|
|
1761
1761
|
function isMemberStorageKind(value) {
|
|
@@ -2167,6 +2167,11 @@ function isValidDocsText(value) {
|
|
|
2167
2167
|
return textEncoder.encode(value).byteLength <= DOCS_TEXT_MAX_UTF8_BYTES;
|
|
2168
2168
|
}
|
|
2169
2169
|
|
|
2170
|
+
// ../src/models/members/float32.ts
|
|
2171
|
+
function isFloat32(value) {
|
|
2172
|
+
return typeof value === "number" && Number.isFinite(value) && Math.fround(value) === value;
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2170
2175
|
// ../packages/neoscript-language/src/project-source-identifiers.ts
|
|
2171
2176
|
var PROJECT_IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
2172
2177
|
var PROJECT_RESERVED_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -2507,7 +2512,7 @@ function hasValidParameterDefault(value) {
|
|
|
2507
2512
|
case 2 /* Int */:
|
|
2508
2513
|
return typeof payload === "number" && Number.isInteger(payload);
|
|
2509
2514
|
case 4 /* Float */:
|
|
2510
|
-
return
|
|
2515
|
+
return isFloat32(payload);
|
|
2511
2516
|
case 20 /* Decimal */:
|
|
2512
2517
|
case 3 /* String */:
|
|
2513
2518
|
case 8 /* Enum */:
|
|
@@ -2793,6 +2798,9 @@ function isNSArithmeticOperationInfo(value) {
|
|
|
2793
2798
|
const v = value;
|
|
2794
2799
|
if (typeof v !== "object" || v === null) return false;
|
|
2795
2800
|
if (!isNSArithmeticOperationType(v.type)) return false;
|
|
2801
|
+
if (v.numeric !== void 0 && v.numeric !== "int" && v.numeric !== "float") {
|
|
2802
|
+
return false;
|
|
2803
|
+
}
|
|
2796
2804
|
return isNSPointers(v.pointers);
|
|
2797
2805
|
}
|
|
2798
2806
|
function isNSArithmeticOperation(value) {
|
|
@@ -3703,6 +3711,9 @@ var STRUCTURED_LEAF_FIELDS = {
|
|
|
3703
3711
|
function isStructuredLeafKind(kind) {
|
|
3704
3712
|
return Object.prototype.hasOwnProperty.call(STRUCTURED_LEAF_FIELDS, kind);
|
|
3705
3713
|
}
|
|
3714
|
+
function structuredLeafFields(kind) {
|
|
3715
|
+
return STRUCTURED_LEAF_FIELDS[kind];
|
|
3716
|
+
}
|
|
3706
3717
|
function structuredLeafFieldKeys(kind) {
|
|
3707
3718
|
return STRUCTURED_LEAF_FIELDS[kind].map((entry) => entry.key);
|
|
3708
3719
|
}
|
|
@@ -3715,10 +3726,10 @@ function isStructuredLeafFieldValue(type, value) {
|
|
|
3715
3726
|
return typeof value === "string" && value.length > 0;
|
|
3716
3727
|
}
|
|
3717
3728
|
if (typeof value !== "number" || !Number.isFinite(value)) return false;
|
|
3718
|
-
if (type === "float") return
|
|
3729
|
+
if (type === "float") return isFloat32(value);
|
|
3719
3730
|
if (type === "int") return Number.isInteger(value);
|
|
3720
3731
|
if (type === "sliceIndex") return Number.isInteger(value) && value >= 0;
|
|
3721
|
-
return value >= 0 && value <= 1;
|
|
3732
|
+
return isFloat32(value) && value >= 0 && value <= 1;
|
|
3722
3733
|
}
|
|
3723
3734
|
var STRUCTURED_LEAF_PARTIAL_KEY = "~partial";
|
|
3724
3735
|
function isStructuredLeafPartialValue(value) {
|
|
@@ -3738,16 +3749,36 @@ function structuredLeafPartialViolation(kind, value, legalKeysLabel) {
|
|
|
3738
3749
|
return `has no field "${key}"; ${legalKeysLabel} accepts ${structuredLeafFieldKeys(kind).join(", ")}`;
|
|
3739
3750
|
}
|
|
3740
3751
|
if (isStructuredLeafFieldValue(field.type, fieldValue)) continue;
|
|
3741
|
-
return `field "${key}" ${structuredLeafFieldViolation(field.type)}`;
|
|
3752
|
+
return `field "${key}" ${structuredLeafFieldViolation(field.type, fieldValue)}`;
|
|
3742
3753
|
}
|
|
3743
3754
|
return null;
|
|
3744
3755
|
}
|
|
3745
|
-
function
|
|
3756
|
+
function structuredLeafRecordFieldViolation(kind, value) {
|
|
3757
|
+
if (typeof value !== "object" || value === null) return null;
|
|
3758
|
+
if (Array.isArray(value)) return null;
|
|
3759
|
+
const entries = Object.entries(value);
|
|
3760
|
+
if (entries.length !== structuredLeafFields(kind).length) return null;
|
|
3761
|
+
let found = null;
|
|
3762
|
+
for (const [key, fieldValue] of entries) {
|
|
3763
|
+
const field = structuredLeafField(kind, key);
|
|
3764
|
+
if (field === null) return null;
|
|
3765
|
+
if (typeof fieldValue !== "number") return null;
|
|
3766
|
+
if (found !== null) continue;
|
|
3767
|
+
if (isStructuredLeafFieldValue(field.type, fieldValue)) continue;
|
|
3768
|
+
found = {
|
|
3769
|
+
key,
|
|
3770
|
+
value: fieldValue,
|
|
3771
|
+
violation: structuredLeafFieldViolation(field.type, fieldValue)
|
|
3772
|
+
};
|
|
3773
|
+
}
|
|
3774
|
+
return found;
|
|
3775
|
+
}
|
|
3776
|
+
function structuredLeafFieldViolation(type, value) {
|
|
3746
3777
|
if (type === "fileId") return "must be a non-empty file id";
|
|
3747
|
-
if (type === "float") return "must be a finite number";
|
|
3748
3778
|
if (type === "int") return "must be a whole number";
|
|
3749
3779
|
if (type === "sliceIndex") return "must be a whole number 0 or greater";
|
|
3750
|
-
return "must be a
|
|
3780
|
+
if (!isFloat32(value)) return "must be a 32-bit float";
|
|
3781
|
+
return "must be between 0 and 1";
|
|
3751
3782
|
}
|
|
3752
3783
|
|
|
3753
3784
|
// ../src/models/members/member-kinds.ts
|
|
@@ -3894,9 +3925,9 @@ function isMemberString(value) {
|
|
|
3894
3925
|
function isMemberFloatBase(value) {
|
|
3895
3926
|
const v = asMemberBaseForKind(value, 4 /* Float */);
|
|
3896
3927
|
if (v === null) return false;
|
|
3897
|
-
if (v.minValue !== void 0 && v.minValue !== null &&
|
|
3928
|
+
if (v.minValue !== void 0 && v.minValue !== null && !isFloat32(v.minValue))
|
|
3898
3929
|
return false;
|
|
3899
|
-
if (v.maxValue !== void 0 && v.maxValue !== null &&
|
|
3930
|
+
if (v.maxValue !== void 0 && v.maxValue !== null && !isFloat32(v.maxValue))
|
|
3900
3931
|
return false;
|
|
3901
3932
|
return v.decimalPoints === void 0 || v.decimalPoints === null || typeof v.decimalPoints === "number";
|
|
3902
3933
|
}
|
|
@@ -3905,12 +3936,8 @@ function hasExactKeys(value, keys) {
|
|
|
3905
3936
|
if (actual.length !== keys.length) return false;
|
|
3906
3937
|
return keys.every((key) => Object.prototype.hasOwnProperty.call(value, key));
|
|
3907
3938
|
}
|
|
3908
|
-
function isFiniteNumberValue(value) {
|
|
3909
|
-
return typeof value === "number" && Number.isFinite(value);
|
|
3910
|
-
}
|
|
3911
3939
|
function isVectorComponentValue(value, integer2) {
|
|
3912
|
-
if (!
|
|
3913
|
-
if (!integer2) return true;
|
|
3940
|
+
if (!integer2) return isFloat32(value);
|
|
3914
3941
|
return Number.isInteger(value);
|
|
3915
3942
|
}
|
|
3916
3943
|
function isVector2ValueWithComponents(value, integer2) {
|
|
@@ -3944,7 +3971,7 @@ function isVector3IntValue(value) {
|
|
|
3944
3971
|
return isVector3ValueWithComponents(value, true);
|
|
3945
3972
|
}
|
|
3946
3973
|
function isColorComponentValue(value) {
|
|
3947
|
-
if (!
|
|
3974
|
+
if (!isFloat32(value)) return false;
|
|
3948
3975
|
return value >= 0 && value <= 1;
|
|
3949
3976
|
}
|
|
3950
3977
|
function isColorValue(value) {
|
|
@@ -10038,6 +10065,9 @@ function structuredLeafPartialMemberViolation(member, value, position) {
|
|
|
10038
10065
|
}
|
|
10039
10066
|
return structuredLeafPartialViolation(kind, value, MemberKind[kind]);
|
|
10040
10067
|
}
|
|
10068
|
+
function storedLeafFieldIssueMessage(issue) {
|
|
10069
|
+
return `${MemberKind[issue.leaf]} field "${issue.key}" ${issue.violation}, not ${issue.value}.`;
|
|
10070
|
+
}
|
|
10041
10071
|
function* storedValueChildEntries(args) {
|
|
10042
10072
|
const entryMemberId = args.member.entryMemberId;
|
|
10043
10073
|
if (args.member.kind === 6 /* List */ && typeof entryMemberId === "string") {
|
|
@@ -10071,16 +10101,19 @@ function* storedValueChildEntries(args) {
|
|
|
10071
10101
|
}
|
|
10072
10102
|
function storedLeafShapeIssue(member, value) {
|
|
10073
10103
|
switch (member.kind) {
|
|
10104
|
+
// Null is an optional Float's absent value.
|
|
10105
|
+
case 4 /* Float */:
|
|
10106
|
+
return value === null || isFloat32(value) ? null : { kind: "float" };
|
|
10074
10107
|
case 14 /* Vector2 */:
|
|
10075
|
-
return isVector2Value(value) ? null :
|
|
10108
|
+
return isVector2Value(value) ? null : leafIssue(member.kind, "vector2", value);
|
|
10076
10109
|
case 15 /* Vector2Int */:
|
|
10077
|
-
return isVector2IntValue(value) ? null :
|
|
10110
|
+
return isVector2IntValue(value) ? null : leafIssue(member.kind, "vector2Int", value);
|
|
10078
10111
|
case 16 /* Vector3 */:
|
|
10079
|
-
return isVector3Value(value) ? null :
|
|
10112
|
+
return isVector3Value(value) ? null : leafIssue(member.kind, "vector3", value);
|
|
10080
10113
|
case 17 /* Vector3Int */:
|
|
10081
|
-
return isVector3IntValue(value) ? null :
|
|
10114
|
+
return isVector3IntValue(value) ? null : leafIssue(member.kind, "vector3Int", value);
|
|
10082
10115
|
case 19 /* Color */:
|
|
10083
|
-
return isColorValue(value) ? null :
|
|
10116
|
+
return isColorValue(value) ? null : leafIssue(member.kind, "color", value);
|
|
10084
10117
|
case 20 /* Decimal */: {
|
|
10085
10118
|
const violation = getDecimalStringViolation(value);
|
|
10086
10119
|
return violation === null ? null : { kind: "decimal", violation };
|
|
@@ -10093,6 +10126,10 @@ function storedLeafShapeIssue(member, value) {
|
|
|
10093
10126
|
return null;
|
|
10094
10127
|
}
|
|
10095
10128
|
}
|
|
10129
|
+
function leafIssue(leaf, shape, value) {
|
|
10130
|
+
const field = structuredLeafRecordFieldViolation(leaf, value);
|
|
10131
|
+
return field === null ? { kind: shape } : { kind: "field", leaf, ...field };
|
|
10132
|
+
}
|
|
10096
10133
|
|
|
10097
10134
|
// ../src/models/members/build-default-member-value.ts
|
|
10098
10135
|
var DECLARATION_DEFAULT_POSITION = {
|
|
@@ -11174,16 +11211,24 @@ function validateProjectDocumentFileMemberValue(document2, member, body, positio
|
|
|
11174
11211
|
return;
|
|
11175
11212
|
}
|
|
11176
11213
|
const shapeIssue = storedLeafShapeIssue(member, body.value);
|
|
11214
|
+
if (shapeIssue?.kind === "float") {
|
|
11215
|
+
throw new Error(
|
|
11216
|
+
`Float value for member "${member.name}" must be a 32-bit float, not ${String(body.value)}.`
|
|
11217
|
+
);
|
|
11218
|
+
}
|
|
11219
|
+
if (shapeIssue?.kind === "field") {
|
|
11220
|
+
throw new Error(
|
|
11221
|
+
`Member "${member.name}" ${storedLeafFieldIssueMessage(shapeIssue)}`
|
|
11222
|
+
);
|
|
11223
|
+
}
|
|
11177
11224
|
if (shapeIssue?.kind === "vector2") {
|
|
11178
|
-
throw new Error("Vector2 value must be { x:
|
|
11225
|
+
throw new Error("Vector2 value must be { x: float, y: float }.");
|
|
11179
11226
|
}
|
|
11180
11227
|
if (shapeIssue?.kind === "vector2Int") {
|
|
11181
11228
|
throw new Error("Vector2Int value must be { x: integer, y: integer }.");
|
|
11182
11229
|
}
|
|
11183
11230
|
if (shapeIssue?.kind === "vector3") {
|
|
11184
|
-
throw new Error(
|
|
11185
|
-
"Vector3 value must be { x: number, y: number, z: number }."
|
|
11186
|
-
);
|
|
11231
|
+
throw new Error("Vector3 value must be { x: float, y: float, z: float }.");
|
|
11187
11232
|
}
|
|
11188
11233
|
if (shapeIssue?.kind === "vector3Int") {
|
|
11189
11234
|
throw new Error(
|
|
@@ -11192,7 +11237,7 @@ function validateProjectDocumentFileMemberValue(document2, member, body, positio
|
|
|
11192
11237
|
}
|
|
11193
11238
|
if (shapeIssue?.kind === "color") {
|
|
11194
11239
|
throw new Error(
|
|
11195
|
-
"Color value must be { r, g, b, a } with each component in [0, 1]."
|
|
11240
|
+
"Color value must be { r, g, b, a } with each component a 32-bit float in [0, 1]."
|
|
11196
11241
|
);
|
|
11197
11242
|
}
|
|
11198
11243
|
if (shapeIssue?.kind === "decimal") {
|
|
@@ -17454,7 +17499,8 @@ function evalPointer(pointer, scope, ctx, resultUsage = "value") {
|
|
|
17454
17499
|
callSiteId: pointer.callSiteId,
|
|
17455
17500
|
invokeDelegate: (delegate, delegateArgs = []) => invokeDelegateValue(delegate, delegateArgs, ctx, pointer.callSiteId)
|
|
17456
17501
|
});
|
|
17457
|
-
if (intercepted?.handled === true)
|
|
17502
|
+
if (intercepted?.handled === true)
|
|
17503
|
+
return hostCallResult(member, intercepted.value, ctx);
|
|
17458
17504
|
if (member === null) {
|
|
17459
17505
|
if (pointer.missingMemberFallback === "valueEquality") {
|
|
17460
17506
|
return jsEqual(innerThis, suppliedArgs[0]);
|
|
@@ -17490,7 +17536,8 @@ function evalPointer(pointer, scope, ctx, resultUsage = "value") {
|
|
|
17490
17536
|
pointer.callSiteId
|
|
17491
17537
|
)
|
|
17492
17538
|
});
|
|
17493
|
-
if (hosted?.handled === true)
|
|
17539
|
+
if (hosted?.handled === true)
|
|
17540
|
+
return hostCallResult(member, hosted.value, ctx);
|
|
17494
17541
|
const receiverId = trackedRowForValueReference(innerThis, ctx)?.id;
|
|
17495
17542
|
throw new NativeFunctionDelegateUnavailableError(
|
|
17496
17543
|
`No native delegate handled Function '${member.name}' (member id '${member.id}'${nativeReceiverDescription(member, innerThis, receiverId)}). Web preview and other non-native evaluator hosts must configure a native handler or call interceptor before evaluation.`,
|
|
@@ -17781,7 +17828,8 @@ function invokeDelegateValue(value, args, ctx, callSiteId, ownerReceiver, result
|
|
|
17781
17828
|
callSiteId,
|
|
17782
17829
|
invokeDelegate: (delegate, delegateArgs = []) => invokeDelegateValue(delegate, delegateArgs, ctx, callSiteId)
|
|
17783
17830
|
});
|
|
17784
|
-
if (intercepted?.handled === true)
|
|
17831
|
+
if (intercepted?.handled === true)
|
|
17832
|
+
return hostCallResult(member, intercepted.value, ctx);
|
|
17785
17833
|
state.delegateStack.push(frame);
|
|
17786
17834
|
try {
|
|
17787
17835
|
if (member.kind === 13 /* Function */) {
|
|
@@ -17796,7 +17844,8 @@ function invokeDelegateValue(value, args, ctx, callSiteId, ownerReceiver, result
|
|
|
17796
17844
|
callSiteId,
|
|
17797
17845
|
invokeDelegate: (delegate, delegateArgs = []) => invokeDelegateValue(delegate, delegateArgs, ctx, callSiteId)
|
|
17798
17846
|
});
|
|
17799
|
-
if (hosted?.handled === true)
|
|
17847
|
+
if (hosted?.handled === true)
|
|
17848
|
+
return hostCallResult(member, hosted.value, ctx);
|
|
17800
17849
|
const receiverId = trackedRowForValueReference(receiver, ctx)?.id;
|
|
17801
17850
|
throw new NativeFunctionDelegateUnavailableError(
|
|
17802
17851
|
`No native delegate handled Function '${member.name}' (member id '${member.id}'${nativeReceiverDescription(member, receiver, receiverId)}). Web preview and other non-native evaluator hosts must configure a native handler or call interceptor before evaluation.`,
|
|
@@ -18665,13 +18714,14 @@ function runtimeCollectionEntryMatchesType(value, typeInfo, ctx, seenCollections
|
|
|
18665
18714
|
return resolved !== value && runtimeValueMatchesType(resolved, typeInfo, ctx, seenCollections);
|
|
18666
18715
|
}
|
|
18667
18716
|
function evalVectorConstructor(vectorType, componentPointers, scope, ctx) {
|
|
18668
|
-
const
|
|
18669
|
-
|
|
18717
|
+
const integer2 = vectorType === 15 /* Vector2Int */ || vectorType === 17 /* Vector3Int */;
|
|
18718
|
+
const values = componentPointers.map((pointer) => {
|
|
18719
|
+
const value = finiteNumberArg(
|
|
18670
18720
|
evalPointer(pointer, scope, ctx),
|
|
18671
18721
|
`${MemberKind[vectorType]} component`
|
|
18672
|
-
)
|
|
18673
|
-
|
|
18674
|
-
|
|
18722
|
+
);
|
|
18723
|
+
return integer2 ? value : Math.fround(value);
|
|
18724
|
+
});
|
|
18675
18725
|
if (integer2 && values.some((value) => !Number.isInteger(value))) {
|
|
18676
18726
|
throw new NSGetterRuntimeError(
|
|
18677
18727
|
`${MemberKind[vectorType]} components must be integers`
|
|
@@ -19562,11 +19612,17 @@ function evalOperation(operation, scope, ctx) {
|
|
|
19562
19612
|
if (operation.type === "arithmetic" /* arithmetic */) {
|
|
19563
19613
|
const op = operation.arithmetic;
|
|
19564
19614
|
const operands = op.pointers.map((p) => evalPointer(p, scope, ctx));
|
|
19565
|
-
return applyArithmetic(
|
|
19615
|
+
return applyArithmetic(
|
|
19616
|
+
op.type,
|
|
19617
|
+
operands,
|
|
19618
|
+
op.decimal === true,
|
|
19619
|
+
ctx,
|
|
19620
|
+
op.numeric
|
|
19621
|
+
);
|
|
19566
19622
|
}
|
|
19567
19623
|
return evalBooleanExpression(operation.expression, scope, ctx);
|
|
19568
19624
|
}
|
|
19569
|
-
function applyArithmetic(op, operands, decimal, ctx) {
|
|
19625
|
+
function applyArithmetic(op, operands, decimal, ctx, numeric) {
|
|
19570
19626
|
if (operands.length === 0) {
|
|
19571
19627
|
throw new NSGetterRuntimeError("Arithmetic operation with no operands");
|
|
19572
19628
|
}
|
|
@@ -19599,31 +19655,43 @@ function applyArithmetic(op, operands, decimal, ctx) {
|
|
|
19599
19655
|
`Arithmetic operand is not numeric: ${typeof o}`
|
|
19600
19656
|
);
|
|
19601
19657
|
});
|
|
19658
|
+
const round = numeric === "float" ? Math.fround : (value) => value;
|
|
19602
19659
|
switch (op) {
|
|
19603
19660
|
case "+" /* addition */:
|
|
19604
|
-
return numbers.reduce((a, b) => a + b, 0);
|
|
19661
|
+
return numbers.reduce((a, b) => round(a + b), 0);
|
|
19605
19662
|
case "-" /* subtraction */:
|
|
19606
|
-
return numbers.reduce((a, b, i) => i === 0 ? b : a - b);
|
|
19663
|
+
return numbers.reduce((a, b, i) => i === 0 ? b : round(a - b));
|
|
19607
19664
|
case "*" /* multiplication */:
|
|
19608
|
-
return numbers.reduce((a, b) => a * b, 1);
|
|
19665
|
+
return numbers.reduce((a, b) => round(a * b), 1);
|
|
19609
19666
|
case "/" /* division */:
|
|
19610
19667
|
return numbers.reduce((a, b, i) => {
|
|
19611
19668
|
if (i === 0) return b;
|
|
19612
19669
|
if (b === 0) throw new NSGetterRuntimeError("Division by zero");
|
|
19613
|
-
return a / b;
|
|
19670
|
+
return numeric === "int" ? Math.trunc(a / b) : round(a / b);
|
|
19614
19671
|
});
|
|
19615
19672
|
case "%" /* remainder */:
|
|
19616
19673
|
return numbers.reduce((a, b, i) => {
|
|
19617
19674
|
if (i === 0) return b;
|
|
19618
19675
|
if (b === 0) throw new NSGetterRuntimeError("Modulo by zero");
|
|
19619
|
-
return a % b;
|
|
19676
|
+
return round(a % b);
|
|
19620
19677
|
});
|
|
19621
19678
|
}
|
|
19622
19679
|
}
|
|
19680
|
+
function hostCallResult(member, value, ctx) {
|
|
19681
|
+
if (typeof value !== "number" || member === null) return value;
|
|
19682
|
+
if (member.kind !== 13 /* Function */ && member.kind !== 23 /* NSFunction */) {
|
|
19683
|
+
return value;
|
|
19684
|
+
}
|
|
19685
|
+
const signature = resolveCallableSignature(member.id, member.kind, ctx);
|
|
19686
|
+
return signature?.returnTypeInfo.type === 4 /* Float */ ? Math.fround(value) : value;
|
|
19687
|
+
}
|
|
19623
19688
|
function coerceAssignmentValue(value, targetTypeInfo, context) {
|
|
19624
19689
|
if (targetTypeInfo.type === 8 /* Enum */ && typeof value === "string") {
|
|
19625
19690
|
return [value];
|
|
19626
19691
|
}
|
|
19692
|
+
if (targetTypeInfo.type === 4 /* Float */ && typeof value === "number") {
|
|
19693
|
+
return Math.fround(value);
|
|
19694
|
+
}
|
|
19627
19695
|
return targetTypeInfo.type === 20 /* Decimal */ && typeof value === "number" ? coerceDecimalOperand(value, context) : value;
|
|
19628
19696
|
}
|
|
19629
19697
|
function coerceDecimalOperand(value, context) {
|
|
@@ -19786,7 +19854,7 @@ function evalMathOp(info, scope, ctx) {
|
|
|
19786
19854
|
if (value < 0) return -1;
|
|
19787
19855
|
return 0;
|
|
19788
19856
|
case "sqrt":
|
|
19789
|
-
return Math.sqrt(value);
|
|
19857
|
+
return Math.fround(Math.sqrt(value));
|
|
19790
19858
|
}
|
|
19791
19859
|
}
|
|
19792
19860
|
function evalDecimalMathOp(info, fn, scope, ctx) {
|
|
@@ -20427,8 +20495,10 @@ function evalFunction(fn, scope, ctx) {
|
|
|
20427
20495
|
);
|
|
20428
20496
|
}
|
|
20429
20497
|
case "toFloat":
|
|
20430
|
-
return
|
|
20431
|
-
|
|
20498
|
+
return Math.fround(
|
|
20499
|
+
floatFromDecimalString(
|
|
20500
|
+
coerceDecimalOperand(receiverRaw, "ToFloat")
|
|
20501
|
+
)
|
|
20432
20502
|
);
|
|
20433
20503
|
case "toDecimal": {
|
|
20434
20504
|
if (typeof receiverRaw !== "number") {
|
|
@@ -20937,6 +21007,9 @@ function evaluateConstructorFields(descriptor, scope, ctx) {
|
|
|
20937
21007
|
`constructor field '${validated.schemaKey}'`
|
|
20938
21008
|
);
|
|
20939
21009
|
}
|
|
21010
|
+
if (typeof value === "number" && validated.typeInfo.type === 4 /* Float */) {
|
|
21011
|
+
value = Math.fround(value);
|
|
21012
|
+
}
|
|
20940
21013
|
if (value === null || value === void 0) {
|
|
20941
21014
|
if (validated.requiredWithoutDefault) {
|
|
20942
21015
|
throw new NSGetterRuntimeError(
|
|
@@ -21557,8 +21630,9 @@ function evaluateDeclaredConstructorArguments(info, record2, scope, ctx) {
|
|
|
21557
21630
|
);
|
|
21558
21631
|
}
|
|
21559
21632
|
const value = byName.get(parameter3.name);
|
|
21560
|
-
if (parameter3.type !== 20 /* Decimal */) return value;
|
|
21561
21633
|
if (typeof value !== "number") return value;
|
|
21634
|
+
if (parameter3.type === 4 /* Float */) return Math.fround(value);
|
|
21635
|
+
if (parameter3.type !== 20 /* Decimal */) return value;
|
|
21562
21636
|
return coerceDecimalOperand(
|
|
21563
21637
|
value,
|
|
21564
21638
|
`constructor argument '${parameter3.name}'`
|
|
@@ -32599,7 +32673,10 @@ var StrictNeoScriptResolver = class {
|
|
|
32599
32673
|
canonicalDecimal(expression.raw, expression.pos)
|
|
32600
32674
|
);
|
|
32601
32675
|
}
|
|
32602
|
-
return literal(
|
|
32676
|
+
return literal(
|
|
32677
|
+
{ kind: "primitive", name: "float" },
|
|
32678
|
+
Math.fround(expression.value)
|
|
32679
|
+
);
|
|
32603
32680
|
}
|
|
32604
32681
|
case "litString":
|
|
32605
32682
|
return literal({ kind: "primitive", name: "string" }, expression.value);
|
|
@@ -37233,7 +37310,9 @@ var StrictNeoScriptResolver = class {
|
|
|
37233
37310
|
arithmetic: {
|
|
37234
37311
|
type: operator,
|
|
37235
37312
|
pointers: [left.pointer, right.pointer],
|
|
37236
|
-
...isPrimitive(result, "decimal") ? { decimal: true } : {}
|
|
37313
|
+
...isPrimitive(result, "decimal") ? { decimal: true } : {},
|
|
37314
|
+
...isPrimitive(result, "int") ? { numeric: "int" } : {},
|
|
37315
|
+
...isPrimitive(result, "float") ? { numeric: "float" } : {}
|
|
37237
37316
|
}
|
|
37238
37317
|
}
|
|
37239
37318
|
},
|
package/package.json
CHANGED
|
@@ -110,7 +110,7 @@ wrappers.
|
|
|
110
110
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
111
111
|
|
|
112
112
|
```html
|
|
113
|
-
<!-- reviewed-through-cli: 0.
|
|
113
|
+
<!-- reviewed-through-cli: 0.67.1 -->
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -40,12 +40,14 @@ without compiling it; use `neo status` to inspect local edits and diagnostics.
|
|
|
40
40
|
An undo/reset metadata change invalidates the cursor and causes a safe
|
|
41
41
|
full-snapshot fallback.
|
|
42
42
|
|
|
43
|
-
After a compiler upgrade, run `neo pull` with `.neo/state.json` intact.
|
|
44
|
-
remote
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
conflicts
|
|
43
|
+
After a compiler upgrade, run `neo pull` with `.neo/state.json` intact. Pull
|
|
44
|
+
refreshes every cached record whose remote change touches only compiler-owned
|
|
45
|
+
bodies or timestamps before local compilation, even when the same pull merges
|
|
46
|
+
other changes. When nothing else changed, it leaves authored files and managed
|
|
47
|
+
binaries untouched. Added or deleted records, authored changes, and unresolved
|
|
48
|
+
conflicts take the normal merge path. Status, push, and pull refuse a baseline
|
|
49
|
+
holding a compiled body this CLI rejects and name the record. If `neo pull`
|
|
50
|
+
cannot refresh it, back up local edits and run `neo pull --force`.
|
|
49
51
|
|
|
50
52
|
If a push commits but source rewriting fails, `neo pull` resumes its saved
|
|
51
53
|
result before checking the remote head. The recovery journal in `.neo/state.json`
|
|
@@ -202,6 +202,14 @@ Save, Session, Setter, or otherwise writable. A constructor writes only its
|
|
|
202
202
|
`this` instance. A writable structured-leaf field still inherits the receiver's
|
|
203
203
|
effective storage restrictions.
|
|
204
204
|
|
|
205
|
+
## Numeric types
|
|
206
|
+
|
|
207
|
+
`int` is a 32-bit integer and `float` is a 32-bit float, matching C#. Float
|
|
208
|
+
literals, stored values, and every arithmetic step round to 32 bits, so
|
|
209
|
+
`0.1f + 0.2f` behaves like Unity. `int` division truncates toward zero.
|
|
210
|
+
`decimal` is exact base-10 and is the only type to use for currency or other
|
|
211
|
+
values that must not drift.
|
|
212
|
+
|
|
205
213
|
## Numeric builtins
|
|
206
214
|
|
|
207
215
|
Use the `Math` namespace for numeric utilities with C# names and C# semantics:
|