@neocompose/cli 0.66.0 → 0.67.0
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
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.67.0] - 2026-10-04
|
|
4
|
+
|
|
5
|
+
- `float` is a 32-bit float everywhere, as in C#. Float literals, defaults, constructor arguments, and stored values round to the nearest 32-bit float, and pull prints the shortest decimal that reads back as that float, so `0.7` stays `0.7`. Previously push stored the 64-bit double, and Unity read a value that its own `float` could not hold.
|
|
6
|
+
- Float arithmetic rounds to 32 bits after every step, as do `Math.Sqrt`, `ToFloat`, vector constructors, and native function results declared `float`. `int` division truncates toward zero, so `7 / 2` is `3`. Previously it returned `3.5`.
|
|
7
|
+
- Unity codegen types NeoScript `float` members, parameters, and returns as C# `float` instead of `double`.
|
|
8
|
+
- Native functions with `List` or `Dictionary` parameters receive the collection. Previously generated code cast the script value straight to the C# collection type and threw `InvalidCastException`.
|
|
9
|
+
- Compiler revision 17 recompiles every stored body. The rollout also rounds every 64-bit float already stored in values, members, and constructors, including retained history.
|
|
10
|
+
- Push rejects a float, vector component, color channel, float bound, or float parameter default that is not a 32-bit float. Older CLIs that send 64-bit doubles fail validation instead of storing them.
|
|
11
|
+
|
|
3
12
|
## [0.66.0] - 2026-10-03
|
|
4
13
|
|
|
5
14
|
- Add the 18 script runtime lifecycle interfaces from P98, such as `INeoOnLoad`, `INeoUnityUpdate`, and `INeoUnityOnTriggerEnter2D`. Every project gets them as protected system records, and pull writes them under `Interfaces/System/` with `@system(kind: .ScriptRuntime)`.
|
package/dist/neo.mjs
CHANGED
|
@@ -16371,7 +16371,7 @@ var NEOSCRIPT_COMPILER_REVISION;
|
|
|
16371
16371
|
var init_strict_ir = __esm({
|
|
16372
16372
|
"../packages/neoscript-language/src/strict-ir.ts"() {
|
|
16373
16373
|
"use strict";
|
|
16374
|
-
NEOSCRIPT_COMPILER_REVISION =
|
|
16374
|
+
NEOSCRIPT_COMPILER_REVISION = 17;
|
|
16375
16375
|
}
|
|
16376
16376
|
});
|
|
16377
16377
|
|
|
@@ -20116,7 +20116,10 @@ var init_strict_resolver = __esm({
|
|
|
20116
20116
|
canonicalDecimal(expression.raw, expression.pos)
|
|
20117
20117
|
);
|
|
20118
20118
|
}
|
|
20119
|
-
return literal(
|
|
20119
|
+
return literal(
|
|
20120
|
+
{ kind: "primitive", name: "float" },
|
|
20121
|
+
Math.fround(expression.value)
|
|
20122
|
+
);
|
|
20120
20123
|
}
|
|
20121
20124
|
case "litString":
|
|
20122
20125
|
return literal({ kind: "primitive", name: "string" }, expression.value);
|
|
@@ -24750,7 +24753,9 @@ var init_strict_resolver = __esm({
|
|
|
24750
24753
|
arithmetic: {
|
|
24751
24754
|
type: operator,
|
|
24752
24755
|
pointers: [left.pointer, right.pointer],
|
|
24753
|
-
...isPrimitive(result, "decimal") ? { decimal: true } : {}
|
|
24756
|
+
...isPrimitive(result, "decimal") ? { decimal: true } : {},
|
|
24757
|
+
...isPrimitive(result, "int") ? { numeric: "int" } : {},
|
|
24758
|
+
...isPrimitive(result, "float") ? { numeric: "float" } : {}
|
|
24754
24759
|
}
|
|
24755
24760
|
}
|
|
24756
24761
|
},
|
|
@@ -30109,7 +30114,7 @@ var init_registry = __esm({
|
|
|
30109
30114
|
"../packages/manifest/schema-contract/registry.mjs"() {
|
|
30110
30115
|
"use strict";
|
|
30111
30116
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
30112
|
-
cliVersion: "0.
|
|
30117
|
+
cliVersion: "0.67.0",
|
|
30113
30118
|
projectFileUploadBatchSize: 32,
|
|
30114
30119
|
documentRecords: {
|
|
30115
30120
|
member: {
|
|
@@ -39430,6 +39435,47 @@ var init_project_manifest = __esm({
|
|
|
39430
39435
|
}
|
|
39431
39436
|
});
|
|
39432
39437
|
|
|
39438
|
+
// ../src/models/members/float32.ts
|
|
39439
|
+
function isFloat32(value) {
|
|
39440
|
+
return typeof value === "number" && Number.isFinite(value) && Math.fround(value) === value;
|
|
39441
|
+
}
|
|
39442
|
+
function unroundedFloatPath(data, path = "") {
|
|
39443
|
+
if (typeof data === "number") {
|
|
39444
|
+
if (Number.isInteger(data)) return null;
|
|
39445
|
+
return isFloat32(data) ? null : path;
|
|
39446
|
+
}
|
|
39447
|
+
if (typeof data !== "object" || data === null) return null;
|
|
39448
|
+
if (Array.isArray(data)) {
|
|
39449
|
+
for (let index = 0; index < data.length; index++) {
|
|
39450
|
+
const found = unroundedFloatPath(data[index], `${path}[${index}]`);
|
|
39451
|
+
if (found !== null) return found;
|
|
39452
|
+
}
|
|
39453
|
+
return null;
|
|
39454
|
+
}
|
|
39455
|
+
for (const [key, value] of Object.entries(data)) {
|
|
39456
|
+
const found = unroundedFloatPath(
|
|
39457
|
+
value,
|
|
39458
|
+
path === "" ? key : `${path}.${key}`
|
|
39459
|
+
);
|
|
39460
|
+
if (found !== null) return found;
|
|
39461
|
+
}
|
|
39462
|
+
return null;
|
|
39463
|
+
}
|
|
39464
|
+
function float32Text(value) {
|
|
39465
|
+
if (Number.isInteger(value)) return String(value);
|
|
39466
|
+
if (Math.fround(value) !== value) return String(value);
|
|
39467
|
+
for (let precision = 1; precision <= 9; precision++) {
|
|
39468
|
+
const text = String(Number(value.toPrecision(precision)));
|
|
39469
|
+
if (Math.fround(Number(text)) === value) return text;
|
|
39470
|
+
}
|
|
39471
|
+
return String(value);
|
|
39472
|
+
}
|
|
39473
|
+
var init_float32 = __esm({
|
|
39474
|
+
"../src/models/members/float32.ts"() {
|
|
39475
|
+
"use strict";
|
|
39476
|
+
}
|
|
39477
|
+
});
|
|
39478
|
+
|
|
39433
39479
|
// src/project-source/source-format.ts
|
|
39434
39480
|
function quoteNeoString(value) {
|
|
39435
39481
|
return JSON.stringify(value);
|
|
@@ -39450,7 +39496,7 @@ function formatNeoNumber(value) {
|
|
|
39450
39496
|
if (!Number.isFinite(value)) {
|
|
39451
39497
|
throw new Error(`Cannot emit non-finite Neo number ${String(value)}.`);
|
|
39452
39498
|
}
|
|
39453
|
-
const source =
|
|
39499
|
+
const source = float32Text(value);
|
|
39454
39500
|
const match = /^(?<sign>-?)(?<integer>\d+)(?:\.(?<fraction>\d+))?[eE](?<exponent>[+-]?\d+)$/u.exec(
|
|
39455
39501
|
source
|
|
39456
39502
|
);
|
|
@@ -39474,6 +39520,7 @@ function invariantCaseKey(value) {
|
|
|
39474
39520
|
var init_source_format = __esm({
|
|
39475
39521
|
"src/project-source/source-format.ts"() {
|
|
39476
39522
|
"use strict";
|
|
39523
|
+
init_float32();
|
|
39477
39524
|
init_machine_strings();
|
|
39478
39525
|
}
|
|
39479
39526
|
});
|
|
@@ -40701,7 +40748,7 @@ function hasValidParameterDefault(value) {
|
|
|
40701
40748
|
case 2 /* Int */:
|
|
40702
40749
|
return typeof payload === "number" && Number.isInteger(payload);
|
|
40703
40750
|
case 4 /* Float */:
|
|
40704
|
-
return
|
|
40751
|
+
return isFloat32(payload);
|
|
40705
40752
|
case 20 /* Decimal */:
|
|
40706
40753
|
case 3 /* String */:
|
|
40707
40754
|
case 8 /* Enum */:
|
|
@@ -40987,6 +41034,9 @@ function isNSArithmeticOperationInfo(value) {
|
|
|
40987
41034
|
const v = value;
|
|
40988
41035
|
if (typeof v !== "object" || v === null) return false;
|
|
40989
41036
|
if (!isNSArithmeticOperationType(v.type)) return false;
|
|
41037
|
+
if (v.numeric !== void 0 && v.numeric !== "int" && v.numeric !== "float") {
|
|
41038
|
+
return false;
|
|
41039
|
+
}
|
|
40990
41040
|
return isNSPointers(v.pointers);
|
|
40991
41041
|
}
|
|
40992
41042
|
function isNSArithmeticOperation(value) {
|
|
@@ -41557,6 +41607,7 @@ var init_neoscript_guards = __esm({
|
|
|
41557
41607
|
"use strict";
|
|
41558
41608
|
init_neoscript_compiler_revision();
|
|
41559
41609
|
init_member_kind_enum();
|
|
41610
|
+
init_float32();
|
|
41560
41611
|
init_structural_narrow();
|
|
41561
41612
|
init_core_types();
|
|
41562
41613
|
init_neoscript_types();
|
|
@@ -41953,10 +42004,14 @@ function isStructuredLeafFieldValue(type, value) {
|
|
|
41953
42004
|
return typeof value === "string" && value.length > 0;
|
|
41954
42005
|
}
|
|
41955
42006
|
if (typeof value !== "number" || !Number.isFinite(value)) return false;
|
|
41956
|
-
if (type === "float") return
|
|
42007
|
+
if (type === "float") return isFloat32(value);
|
|
41957
42008
|
if (type === "int") return Number.isInteger(value);
|
|
41958
42009
|
if (type === "sliceIndex") return Number.isInteger(value) && value >= 0;
|
|
41959
|
-
return value >= 0 && value <= 1;
|
|
42010
|
+
return isFloat32(value) && value >= 0 && value <= 1;
|
|
42011
|
+
}
|
|
42012
|
+
function storedStructuredLeafFieldNumber(type, value) {
|
|
42013
|
+
const float = type === "float" || type === "unitFloat";
|
|
42014
|
+
return float ? Math.fround(value) : value;
|
|
41960
42015
|
}
|
|
41961
42016
|
function isStructuredLeafPartialValue(value) {
|
|
41962
42017
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
@@ -41975,22 +42030,43 @@ function structuredLeafPartialViolation(kind, value, legalKeysLabel) {
|
|
|
41975
42030
|
return `has no field "${key}"; ${legalKeysLabel} accepts ${structuredLeafFieldKeys(kind).join(", ")}`;
|
|
41976
42031
|
}
|
|
41977
42032
|
if (isStructuredLeafFieldValue(field.type, fieldValue)) continue;
|
|
41978
|
-
return `field "${key}" ${structuredLeafFieldViolation(field.type)}`;
|
|
42033
|
+
return `field "${key}" ${structuredLeafFieldViolation(field.type, fieldValue)}`;
|
|
41979
42034
|
}
|
|
41980
42035
|
return null;
|
|
41981
42036
|
}
|
|
41982
|
-
function
|
|
42037
|
+
function structuredLeafRecordFieldViolation(kind, value) {
|
|
42038
|
+
if (typeof value !== "object" || value === null) return null;
|
|
42039
|
+
if (Array.isArray(value)) return null;
|
|
42040
|
+
const entries = Object.entries(value);
|
|
42041
|
+
if (entries.length !== structuredLeafFields(kind).length) return null;
|
|
42042
|
+
let found = null;
|
|
42043
|
+
for (const [key, fieldValue] of entries) {
|
|
42044
|
+
const field = structuredLeafField(kind, key);
|
|
42045
|
+
if (field === null) return null;
|
|
42046
|
+
if (typeof fieldValue !== "number") return null;
|
|
42047
|
+
if (found !== null) continue;
|
|
42048
|
+
if (isStructuredLeafFieldValue(field.type, fieldValue)) continue;
|
|
42049
|
+
found = {
|
|
42050
|
+
key,
|
|
42051
|
+
value: fieldValue,
|
|
42052
|
+
violation: structuredLeafFieldViolation(field.type, fieldValue)
|
|
42053
|
+
};
|
|
42054
|
+
}
|
|
42055
|
+
return found;
|
|
42056
|
+
}
|
|
42057
|
+
function structuredLeafFieldViolation(type, value) {
|
|
41983
42058
|
if (type === "fileId") return "must be a non-empty file id";
|
|
41984
|
-
if (type === "float") return "must be a finite number";
|
|
41985
42059
|
if (type === "int") return "must be a whole number";
|
|
41986
42060
|
if (type === "sliceIndex") return "must be a whole number 0 or greater";
|
|
41987
|
-
return "must be a
|
|
42061
|
+
if (!isFloat32(value)) return "must be a 32-bit float";
|
|
42062
|
+
return "must be between 0 and 1";
|
|
41988
42063
|
}
|
|
41989
42064
|
var STRUCTURED_LEAF_FIELDS, STRUCTURED_LEAF_PARTIAL_KEY;
|
|
41990
42065
|
var init_structured_leaf_fields = __esm({
|
|
41991
42066
|
"../src/models/members/structured-leaf-fields.ts"() {
|
|
41992
42067
|
"use strict";
|
|
41993
42068
|
init_member_kind_enum();
|
|
42069
|
+
init_float32();
|
|
41994
42070
|
STRUCTURED_LEAF_FIELDS = {
|
|
41995
42071
|
[11 /* Sprite */]: [
|
|
41996
42072
|
{ name: "FileId", key: "fileId", type: "fileId" },
|
|
@@ -42143,9 +42219,9 @@ function isMemberString(value) {
|
|
|
42143
42219
|
function isMemberFloatBase(value) {
|
|
42144
42220
|
const v = asMemberBaseForKind(value, 4 /* Float */);
|
|
42145
42221
|
if (v === null) return false;
|
|
42146
|
-
if (v.minValue !== void 0 && v.minValue !== null &&
|
|
42222
|
+
if (v.minValue !== void 0 && v.minValue !== null && !isFloat32(v.minValue))
|
|
42147
42223
|
return false;
|
|
42148
|
-
if (v.maxValue !== void 0 && v.maxValue !== null &&
|
|
42224
|
+
if (v.maxValue !== void 0 && v.maxValue !== null && !isFloat32(v.maxValue))
|
|
42149
42225
|
return false;
|
|
42150
42226
|
return v.decimalPoints === void 0 || v.decimalPoints === null || typeof v.decimalPoints === "number";
|
|
42151
42227
|
}
|
|
@@ -42154,12 +42230,8 @@ function hasExactKeys(value, keys) {
|
|
|
42154
42230
|
if (actual.length !== keys.length) return false;
|
|
42155
42231
|
return keys.every((key) => Object.prototype.hasOwnProperty.call(value, key));
|
|
42156
42232
|
}
|
|
42157
|
-
function isFiniteNumberValue(value) {
|
|
42158
|
-
return typeof value === "number" && Number.isFinite(value);
|
|
42159
|
-
}
|
|
42160
42233
|
function isVectorComponentValue(value, integer3) {
|
|
42161
|
-
if (!
|
|
42162
|
-
if (!integer3) return true;
|
|
42234
|
+
if (!integer3) return isFloat32(value);
|
|
42163
42235
|
return Number.isInteger(value);
|
|
42164
42236
|
}
|
|
42165
42237
|
function isVector2ValueWithComponents(value, integer3) {
|
|
@@ -42193,7 +42265,7 @@ function isVector3IntValue(value) {
|
|
|
42193
42265
|
return isVector3ValueWithComponents(value, true);
|
|
42194
42266
|
}
|
|
42195
42267
|
function isColorComponentValue(value) {
|
|
42196
|
-
if (!
|
|
42268
|
+
if (!isFloat32(value)) return false;
|
|
42197
42269
|
return value >= 0 && value <= 1;
|
|
42198
42270
|
}
|
|
42199
42271
|
function isColorValue(value) {
|
|
@@ -43159,6 +43231,7 @@ var init_member_kinds = __esm({
|
|
|
43159
43231
|
init_structural_narrow();
|
|
43160
43232
|
init_core_types();
|
|
43161
43233
|
init_docs_text2();
|
|
43234
|
+
init_float32();
|
|
43162
43235
|
init_schema_identifiers();
|
|
43163
43236
|
init_neoscript_guards();
|
|
43164
43237
|
init_neoscript_types();
|
|
@@ -49673,6 +49746,8 @@ function structuredLeafPartialMemberViolation(member, value, position) {
|
|
|
49673
49746
|
return structuredLeafPartialViolation(kind, value, MemberKind[kind]);
|
|
49674
49747
|
}
|
|
49675
49748
|
function storedLeafShapeIssueMessage(issue, style) {
|
|
49749
|
+
if (issue.kind === "float") return "must store a 32-bit float.";
|
|
49750
|
+
if (issue.kind === "field") return storedLeafFieldIssueMessage(issue);
|
|
49676
49751
|
if (issue.kind === "sprite" || issue.kind === "audio") {
|
|
49677
49752
|
return `must store a valid ${issue.kind === "sprite" ? "Sprite" : "Audio"} value.`;
|
|
49678
49753
|
}
|
|
@@ -49683,12 +49758,15 @@ function storedLeafShapeIssueMessage(issue, style) {
|
|
|
49683
49758
|
}
|
|
49684
49759
|
return issue.kind === "decimal" ? `${issue.violation}.` : `must store ${issue.kind === "color" ? "color " : ""}${shape}.`;
|
|
49685
49760
|
}
|
|
49761
|
+
function storedLeafFieldIssueMessage(issue) {
|
|
49762
|
+
return `${MemberKind[issue.leaf]} field "${issue.key}" ${issue.violation}, not ${issue.value}.`;
|
|
49763
|
+
}
|
|
49686
49764
|
function storedLeafExpectation(kind) {
|
|
49687
|
-
if (kind === "vector2") return "{ x:
|
|
49765
|
+
if (kind === "vector2") return "{ x: float, y: float }";
|
|
49688
49766
|
if (kind === "vector2Int") return "{ x: integer, y: integer }";
|
|
49689
|
-
if (kind === "vector3") return "{ x:
|
|
49767
|
+
if (kind === "vector3") return "{ x: float, y: float, z: float }";
|
|
49690
49768
|
if (kind === "vector3Int") return "{ x: integer, y: integer, z: integer }";
|
|
49691
|
-
if (kind === "color") return "{ r, g, b, a } in [0, 1]";
|
|
49769
|
+
if (kind === "color") return "{ r, g, b, a } 32-bit floats in [0, 1]";
|
|
49692
49770
|
return "canonical decimal string";
|
|
49693
49771
|
}
|
|
49694
49772
|
function* storedValueChildReferences(args) {
|
|
@@ -49734,16 +49812,19 @@ function* storedValueChildEntries(args) {
|
|
|
49734
49812
|
}
|
|
49735
49813
|
function storedLeafShapeIssue(member, value) {
|
|
49736
49814
|
switch (member.kind) {
|
|
49815
|
+
// Null is an optional Float's absent value.
|
|
49816
|
+
case 4 /* Float */:
|
|
49817
|
+
return value === null || isFloat32(value) ? null : { kind: "float" };
|
|
49737
49818
|
case 14 /* Vector2 */:
|
|
49738
|
-
return isVector2Value(value) ? null :
|
|
49819
|
+
return isVector2Value(value) ? null : leafIssue(member.kind, "vector2", value);
|
|
49739
49820
|
case 15 /* Vector2Int */:
|
|
49740
|
-
return isVector2IntValue(value) ? null :
|
|
49821
|
+
return isVector2IntValue(value) ? null : leafIssue(member.kind, "vector2Int", value);
|
|
49741
49822
|
case 16 /* Vector3 */:
|
|
49742
|
-
return isVector3Value(value) ? null :
|
|
49823
|
+
return isVector3Value(value) ? null : leafIssue(member.kind, "vector3", value);
|
|
49743
49824
|
case 17 /* Vector3Int */:
|
|
49744
|
-
return isVector3IntValue(value) ? null :
|
|
49825
|
+
return isVector3IntValue(value) ? null : leafIssue(member.kind, "vector3Int", value);
|
|
49745
49826
|
case 19 /* Color */:
|
|
49746
|
-
return isColorValue(value) ? null :
|
|
49827
|
+
return isColorValue(value) ? null : leafIssue(member.kind, "color", value);
|
|
49747
49828
|
case 20 /* Decimal */: {
|
|
49748
49829
|
const violation = getDecimalStringViolation(value);
|
|
49749
49830
|
return violation === null ? null : { kind: "decimal", violation };
|
|
@@ -49756,12 +49837,17 @@ function storedLeafShapeIssue(member, value) {
|
|
|
49756
49837
|
return null;
|
|
49757
49838
|
}
|
|
49758
49839
|
}
|
|
49840
|
+
function leafIssue(leaf, shape, value) {
|
|
49841
|
+
const field = structuredLeafRecordFieldViolation(leaf, value);
|
|
49842
|
+
return field === null ? { kind: shape } : { kind: "field", leaf, ...field };
|
|
49843
|
+
}
|
|
49759
49844
|
var ANIMATION_OVERRIDE_GRAPH_MEMBER_IDS;
|
|
49760
49845
|
var init_stored_value_shape = __esm({
|
|
49761
49846
|
"../src/models/members/stored-value-shape.ts"() {
|
|
49762
49847
|
"use strict";
|
|
49763
49848
|
init_world_system_classes();
|
|
49764
49849
|
init_member_kinds();
|
|
49850
|
+
init_float32();
|
|
49765
49851
|
init_structured_leaf_fields();
|
|
49766
49852
|
ANIMATION_OVERRIDE_GRAPH_MEMBER_IDS = /* @__PURE__ */ new Set([
|
|
49767
49853
|
WORLD_ANIMATION_FRAME_OVERRIDES_MEMBER_ID,
|
|
@@ -50846,16 +50932,24 @@ function validateProjectDocumentFileMemberValue(document, member, body, position
|
|
|
50846
50932
|
return;
|
|
50847
50933
|
}
|
|
50848
50934
|
const shapeIssue = storedLeafShapeIssue(member, body.value);
|
|
50935
|
+
if (shapeIssue?.kind === "float") {
|
|
50936
|
+
throw new Error(
|
|
50937
|
+
`Float value for member "${member.name}" must be a 32-bit float, not ${String(body.value)}.`
|
|
50938
|
+
);
|
|
50939
|
+
}
|
|
50940
|
+
if (shapeIssue?.kind === "field") {
|
|
50941
|
+
throw new Error(
|
|
50942
|
+
`Member "${member.name}" ${storedLeafFieldIssueMessage(shapeIssue)}`
|
|
50943
|
+
);
|
|
50944
|
+
}
|
|
50849
50945
|
if (shapeIssue?.kind === "vector2") {
|
|
50850
|
-
throw new Error("Vector2 value must be { x:
|
|
50946
|
+
throw new Error("Vector2 value must be { x: float, y: float }.");
|
|
50851
50947
|
}
|
|
50852
50948
|
if (shapeIssue?.kind === "vector2Int") {
|
|
50853
50949
|
throw new Error("Vector2Int value must be { x: integer, y: integer }.");
|
|
50854
50950
|
}
|
|
50855
50951
|
if (shapeIssue?.kind === "vector3") {
|
|
50856
|
-
throw new Error(
|
|
50857
|
-
"Vector3 value must be { x: number, y: number, z: number }."
|
|
50858
|
-
);
|
|
50952
|
+
throw new Error("Vector3 value must be { x: float, y: float, z: float }.");
|
|
50859
50953
|
}
|
|
50860
50954
|
if (shapeIssue?.kind === "vector3Int") {
|
|
50861
50955
|
throw new Error(
|
|
@@ -50864,7 +50958,7 @@ function validateProjectDocumentFileMemberValue(document, member, body, position
|
|
|
50864
50958
|
}
|
|
50865
50959
|
if (shapeIssue?.kind === "color") {
|
|
50866
50960
|
throw new Error(
|
|
50867
|
-
"Color value must be { r, g, b, a } with each component in [0, 1]."
|
|
50961
|
+
"Color value must be { r, g, b, a } with each component a 32-bit float in [0, 1]."
|
|
50868
50962
|
);
|
|
50869
50963
|
}
|
|
50870
50964
|
if (shapeIssue?.kind === "decimal") {
|
|
@@ -51695,10 +51789,13 @@ function lowerStructuredLeafFieldValue(kind, label, field, expression, lowering)
|
|
|
51695
51789
|
if (field.type === "fileId") {
|
|
51696
51790
|
return lowerStructuredLeafFileId(kind, label, field, expression, lowering);
|
|
51697
51791
|
}
|
|
51698
|
-
const value =
|
|
51792
|
+
const value = storedStructuredLeafFieldNumber(
|
|
51793
|
+
field.type,
|
|
51794
|
+
lowering.number(expression)
|
|
51795
|
+
);
|
|
51699
51796
|
if (isStructuredLeafFieldValue(field.type, value)) return value;
|
|
51700
51797
|
throw new Error(
|
|
51701
|
-
`${label} field ${JSON.stringify(field.name)} ${
|
|
51798
|
+
`${label} field ${JSON.stringify(field.name)} ${structuredLeafFieldViolation(field.type, value)}, not ${value}.`
|
|
51702
51799
|
);
|
|
51703
51800
|
}
|
|
51704
51801
|
function lowerStructuredLeafFileId(kind, label, field, expression, lowering) {
|
|
@@ -51745,10 +51842,13 @@ function lowerStructuredLeafComponents(kind, label, expression, lowering) {
|
|
|
51745
51842
|
if (argument2 === void 0) {
|
|
51746
51843
|
throw new Error(`${label} is missing component ${field.name}.`);
|
|
51747
51844
|
}
|
|
51748
|
-
const component =
|
|
51845
|
+
const component = storedStructuredLeafFieldNumber(
|
|
51846
|
+
field.type,
|
|
51847
|
+
lowering.number(argument2)
|
|
51848
|
+
);
|
|
51749
51849
|
if (!isStructuredLeafFieldValue(field.type, component)) {
|
|
51750
51850
|
throw new Error(
|
|
51751
|
-
`${label} component ${field.name} ${
|
|
51851
|
+
`${label} component ${field.name} ${structuredLeafFieldViolation(field.type, component)}, not ${component}.`
|
|
51752
51852
|
);
|
|
51753
51853
|
}
|
|
51754
51854
|
value[field.key] = component;
|
|
@@ -51778,7 +51878,7 @@ function structuredLeafPartialAssignments(kind, label, value, emit) {
|
|
|
51778
51878
|
function structuredLeafFieldSource(label, field, value, emit) {
|
|
51779
51879
|
if (!isStructuredLeafFieldValue(field.type, value)) {
|
|
51780
51880
|
throw new Error(
|
|
51781
|
-
`${label} stores field ${JSON.stringify(field.name)} as ${JSON.stringify(value)}, which ${
|
|
51881
|
+
`${label} stores field ${JSON.stringify(field.name)} as ${JSON.stringify(value)}, which ${structuredLeafFieldViolation(field.type, value)}.`
|
|
51782
51882
|
);
|
|
51783
51883
|
}
|
|
51784
51884
|
if (typeof value === "string") return emit.fileId(value);
|
|
@@ -51787,13 +51887,6 @@ function structuredLeafFieldSource(label, field, value, emit) {
|
|
|
51787
51887
|
`${label} stores field ${JSON.stringify(field.name)} as ${JSON.stringify(value)}, which is neither a number nor a file id.`
|
|
51788
51888
|
);
|
|
51789
51889
|
}
|
|
51790
|
-
function structuredLeafFieldRequirement(type) {
|
|
51791
|
-
if (type === "fileId") return "must be a non-empty file id";
|
|
51792
|
-
if (type === "float") return "must be a finite number";
|
|
51793
|
-
if (type === "int") return "must be a whole number";
|
|
51794
|
-
if (type === "sliceIndex") return "must be a whole number 0 or greater";
|
|
51795
|
-
return "must be a number between 0 and 1";
|
|
51796
|
-
}
|
|
51797
51890
|
var STRUCTURED_LEAF_SOURCE_FORMS, STRUCTURED_LEAF_SOURCE_ENTRIES;
|
|
51798
51891
|
var init_structured_leaf_source = __esm({
|
|
51799
51892
|
"src/project-source/structured-leaf-source.ts"() {
|
|
@@ -54508,7 +54601,7 @@ function lowerParameterDefaultValue(context, expression, type, path) {
|
|
|
54508
54601
|
`Parameter ${path} defaults to a number literal, but its type is ${type.kind}.`
|
|
54509
54602
|
);
|
|
54510
54603
|
}
|
|
54511
|
-
return expression.value;
|
|
54604
|
+
return type.kind === "float" ? Math.fround(expression.value) : expression.value;
|
|
54512
54605
|
case "litFloat":
|
|
54513
54606
|
if (type.kind === "decimal") return expression.raw;
|
|
54514
54607
|
if (type.kind !== "float") {
|
|
@@ -54516,7 +54609,7 @@ function lowerParameterDefaultValue(context, expression, type, path) {
|
|
|
54516
54609
|
`Parameter ${path} defaults to a fractional literal, but its type is ${type.kind}.`
|
|
54517
54610
|
);
|
|
54518
54611
|
}
|
|
54519
|
-
return expression.value;
|
|
54612
|
+
return Math.fround(expression.value);
|
|
54520
54613
|
case "unary": {
|
|
54521
54614
|
if (expression.op !== "-") {
|
|
54522
54615
|
throw new Error(
|
|
@@ -55655,8 +55748,8 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
|
|
|
55655
55748
|
};
|
|
55656
55749
|
}
|
|
55657
55750
|
const inheritedFloat = inherited?.kind === "float" ? inherited : void 0;
|
|
55658
|
-
const numericMin = min === null ? null : Number(min);
|
|
55659
|
-
const numericMax = max === null ? null : Number(max);
|
|
55751
|
+
const numericMin = min === null ? null : Math.fround(Number(min));
|
|
55752
|
+
const numericMax = max === null ? null : Math.fround(Number(max));
|
|
55660
55753
|
return {
|
|
55661
55754
|
...common,
|
|
55662
55755
|
kind: "float",
|
|
@@ -56615,9 +56708,8 @@ function lowerExpressionValue(context, expression, declaredExpected, ownerClass,
|
|
|
56615
56708
|
case "litString":
|
|
56616
56709
|
return expression.value;
|
|
56617
56710
|
case "litInt":
|
|
56618
|
-
return expected.name === "decimal" ? expression.raw : expression.value;
|
|
56619
56711
|
case "litFloat":
|
|
56620
|
-
return
|
|
56712
|
+
return numberLiteralValue(expression, expected);
|
|
56621
56713
|
case "unary": {
|
|
56622
56714
|
if (expression.op !== "-") {
|
|
56623
56715
|
throw new Error(
|
|
@@ -57474,6 +57566,11 @@ function positionalContextualEnumArgument(value) {
|
|
|
57474
57566
|
const expression = parseAnnotationExpression(positional.expression);
|
|
57475
57567
|
return expression.kind === "contextualEnum" ? expression.name : null;
|
|
57476
57568
|
}
|
|
57569
|
+
function numberLiteralValue(expression, expected) {
|
|
57570
|
+
if (expected.name === "decimal") return expression.raw;
|
|
57571
|
+
if (expected.name === "float") return Math.fround(expression.value);
|
|
57572
|
+
return expression.value;
|
|
57573
|
+
}
|
|
57477
57574
|
function numberTextArgument(value, name) {
|
|
57478
57575
|
const raw = argument(value, name);
|
|
57479
57576
|
if (raw === null) return null;
|
|
@@ -72485,7 +72582,8 @@ function evalPointer(pointer, scope, ctx, resultUsage = "value") {
|
|
|
72485
72582
|
callSiteId: pointer.callSiteId,
|
|
72486
72583
|
invokeDelegate: (delegate, delegateArgs = []) => invokeDelegateValue(delegate, delegateArgs, ctx, pointer.callSiteId)
|
|
72487
72584
|
});
|
|
72488
|
-
if (intercepted?.handled === true)
|
|
72585
|
+
if (intercepted?.handled === true)
|
|
72586
|
+
return hostCallResult(member, intercepted.value, ctx);
|
|
72489
72587
|
if (member === null) {
|
|
72490
72588
|
if (pointer.missingMemberFallback === "valueEquality") {
|
|
72491
72589
|
return jsEqual(innerThis, suppliedArgs[0]);
|
|
@@ -72521,7 +72619,8 @@ function evalPointer(pointer, scope, ctx, resultUsage = "value") {
|
|
|
72521
72619
|
pointer.callSiteId
|
|
72522
72620
|
)
|
|
72523
72621
|
});
|
|
72524
|
-
if (hosted?.handled === true)
|
|
72622
|
+
if (hosted?.handled === true)
|
|
72623
|
+
return hostCallResult(member, hosted.value, ctx);
|
|
72525
72624
|
const receiverId = trackedRowForValueReference(innerThis, ctx)?.id;
|
|
72526
72625
|
throw new NativeFunctionDelegateUnavailableError(
|
|
72527
72626
|
`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.`,
|
|
@@ -72812,7 +72911,8 @@ function invokeDelegateValue(value, args, ctx, callSiteId, ownerReceiver, result
|
|
|
72812
72911
|
callSiteId,
|
|
72813
72912
|
invokeDelegate: (delegate, delegateArgs = []) => invokeDelegateValue(delegate, delegateArgs, ctx, callSiteId)
|
|
72814
72913
|
});
|
|
72815
|
-
if (intercepted?.handled === true)
|
|
72914
|
+
if (intercepted?.handled === true)
|
|
72915
|
+
return hostCallResult(member, intercepted.value, ctx);
|
|
72816
72916
|
state.delegateStack.push(frame);
|
|
72817
72917
|
try {
|
|
72818
72918
|
if (member.kind === 13 /* Function */) {
|
|
@@ -72827,7 +72927,8 @@ function invokeDelegateValue(value, args, ctx, callSiteId, ownerReceiver, result
|
|
|
72827
72927
|
callSiteId,
|
|
72828
72928
|
invokeDelegate: (delegate, delegateArgs = []) => invokeDelegateValue(delegate, delegateArgs, ctx, callSiteId)
|
|
72829
72929
|
});
|
|
72830
|
-
if (hosted?.handled === true)
|
|
72930
|
+
if (hosted?.handled === true)
|
|
72931
|
+
return hostCallResult(member, hosted.value, ctx);
|
|
72831
72932
|
const receiverId = trackedRowForValueReference(receiver, ctx)?.id;
|
|
72832
72933
|
throw new NativeFunctionDelegateUnavailableError(
|
|
72833
72934
|
`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.`,
|
|
@@ -73696,13 +73797,14 @@ function runtimeCollectionEntryMatchesType(value, typeInfo, ctx, seenCollections
|
|
|
73696
73797
|
return resolved !== value && runtimeValueMatchesType(resolved, typeInfo, ctx, seenCollections);
|
|
73697
73798
|
}
|
|
73698
73799
|
function evalVectorConstructor(vectorType, componentPointers, scope, ctx) {
|
|
73699
|
-
const
|
|
73700
|
-
|
|
73800
|
+
const integer3 = vectorType === 15 /* Vector2Int */ || vectorType === 17 /* Vector3Int */;
|
|
73801
|
+
const values = componentPointers.map((pointer) => {
|
|
73802
|
+
const value = finiteNumberArg(
|
|
73701
73803
|
evalPointer(pointer, scope, ctx),
|
|
73702
73804
|
`${MemberKind[vectorType]} component`
|
|
73703
|
-
)
|
|
73704
|
-
|
|
73705
|
-
|
|
73805
|
+
);
|
|
73806
|
+
return integer3 ? value : Math.fround(value);
|
|
73807
|
+
});
|
|
73706
73808
|
if (integer3 && values.some((value) => !Number.isInteger(value))) {
|
|
73707
73809
|
throw new NSGetterRuntimeError(
|
|
73708
73810
|
`${MemberKind[vectorType]} components must be integers`
|
|
@@ -74593,11 +74695,17 @@ function evalOperation(operation, scope, ctx) {
|
|
|
74593
74695
|
if (operation.type === "arithmetic" /* arithmetic */) {
|
|
74594
74696
|
const op = operation.arithmetic;
|
|
74595
74697
|
const operands = op.pointers.map((p) => evalPointer(p, scope, ctx));
|
|
74596
|
-
return applyArithmetic(
|
|
74698
|
+
return applyArithmetic(
|
|
74699
|
+
op.type,
|
|
74700
|
+
operands,
|
|
74701
|
+
op.decimal === true,
|
|
74702
|
+
ctx,
|
|
74703
|
+
op.numeric
|
|
74704
|
+
);
|
|
74597
74705
|
}
|
|
74598
74706
|
return evalBooleanExpression(operation.expression, scope, ctx);
|
|
74599
74707
|
}
|
|
74600
|
-
function applyArithmetic(op, operands, decimal2, ctx) {
|
|
74708
|
+
function applyArithmetic(op, operands, decimal2, ctx, numeric) {
|
|
74601
74709
|
if (operands.length === 0) {
|
|
74602
74710
|
throw new NSGetterRuntimeError("Arithmetic operation with no operands");
|
|
74603
74711
|
}
|
|
@@ -74630,31 +74738,43 @@ function applyArithmetic(op, operands, decimal2, ctx) {
|
|
|
74630
74738
|
`Arithmetic operand is not numeric: ${typeof o}`
|
|
74631
74739
|
);
|
|
74632
74740
|
});
|
|
74741
|
+
const round = numeric === "float" ? Math.fround : (value) => value;
|
|
74633
74742
|
switch (op) {
|
|
74634
74743
|
case "+" /* addition */:
|
|
74635
|
-
return numbers.reduce((a, b) => a + b, 0);
|
|
74744
|
+
return numbers.reduce((a, b) => round(a + b), 0);
|
|
74636
74745
|
case "-" /* subtraction */:
|
|
74637
|
-
return numbers.reduce((a, b, i2) => i2 === 0 ? b : a - b);
|
|
74746
|
+
return numbers.reduce((a, b, i2) => i2 === 0 ? b : round(a - b));
|
|
74638
74747
|
case "*" /* multiplication */:
|
|
74639
|
-
return numbers.reduce((a, b) => a * b, 1);
|
|
74748
|
+
return numbers.reduce((a, b) => round(a * b), 1);
|
|
74640
74749
|
case "/" /* division */:
|
|
74641
74750
|
return numbers.reduce((a, b, i2) => {
|
|
74642
74751
|
if (i2 === 0) return b;
|
|
74643
74752
|
if (b === 0) throw new NSGetterRuntimeError("Division by zero");
|
|
74644
|
-
return a / b;
|
|
74753
|
+
return numeric === "int" ? Math.trunc(a / b) : round(a / b);
|
|
74645
74754
|
});
|
|
74646
74755
|
case "%" /* remainder */:
|
|
74647
74756
|
return numbers.reduce((a, b, i2) => {
|
|
74648
74757
|
if (i2 === 0) return b;
|
|
74649
74758
|
if (b === 0) throw new NSGetterRuntimeError("Modulo by zero");
|
|
74650
|
-
return a % b;
|
|
74759
|
+
return round(a % b);
|
|
74651
74760
|
});
|
|
74652
74761
|
}
|
|
74653
74762
|
}
|
|
74763
|
+
function hostCallResult(member, value, ctx) {
|
|
74764
|
+
if (typeof value !== "number" || member === null) return value;
|
|
74765
|
+
if (member.kind !== 13 /* Function */ && member.kind !== 23 /* NSFunction */) {
|
|
74766
|
+
return value;
|
|
74767
|
+
}
|
|
74768
|
+
const signature = resolveCallableSignature(member.id, member.kind, ctx);
|
|
74769
|
+
return signature?.returnTypeInfo.type === 4 /* Float */ ? Math.fround(value) : value;
|
|
74770
|
+
}
|
|
74654
74771
|
function coerceAssignmentValue(value, targetTypeInfo, context) {
|
|
74655
74772
|
if (targetTypeInfo.type === 8 /* Enum */ && typeof value === "string") {
|
|
74656
74773
|
return [value];
|
|
74657
74774
|
}
|
|
74775
|
+
if (targetTypeInfo.type === 4 /* Float */ && typeof value === "number") {
|
|
74776
|
+
return Math.fround(value);
|
|
74777
|
+
}
|
|
74658
74778
|
return targetTypeInfo.type === 20 /* Decimal */ && typeof value === "number" ? coerceDecimalOperand(value, context) : value;
|
|
74659
74779
|
}
|
|
74660
74780
|
function coerceDecimalOperand(value, context) {
|
|
@@ -74804,7 +74924,7 @@ function evalMathOp(info, scope, ctx) {
|
|
|
74804
74924
|
if (value < 0) return -1;
|
|
74805
74925
|
return 0;
|
|
74806
74926
|
case "sqrt":
|
|
74807
|
-
return Math.sqrt(value);
|
|
74927
|
+
return Math.fround(Math.sqrt(value));
|
|
74808
74928
|
}
|
|
74809
74929
|
}
|
|
74810
74930
|
function evalDecimalMathOp(info, fn, scope, ctx) {
|
|
@@ -75445,8 +75565,10 @@ function evalFunction(fn, scope, ctx) {
|
|
|
75445
75565
|
);
|
|
75446
75566
|
}
|
|
75447
75567
|
case "toFloat":
|
|
75448
|
-
return
|
|
75449
|
-
|
|
75568
|
+
return Math.fround(
|
|
75569
|
+
floatFromDecimalString(
|
|
75570
|
+
coerceDecimalOperand(receiverRaw, "ToFloat")
|
|
75571
|
+
)
|
|
75450
75572
|
);
|
|
75451
75573
|
case "toDecimal": {
|
|
75452
75574
|
if (typeof receiverRaw !== "number") {
|
|
@@ -75954,6 +76076,9 @@ function evaluateConstructorFields(descriptor, scope, ctx) {
|
|
|
75954
76076
|
`constructor field '${validated.schemaKey}'`
|
|
75955
76077
|
);
|
|
75956
76078
|
}
|
|
76079
|
+
if (typeof value === "number" && validated.typeInfo.type === 4 /* Float */) {
|
|
76080
|
+
value = Math.fround(value);
|
|
76081
|
+
}
|
|
75957
76082
|
if (value === null || value === void 0) {
|
|
75958
76083
|
if (validated.requiredWithoutDefault) {
|
|
75959
76084
|
throw new NSGetterRuntimeError(
|
|
@@ -76574,8 +76699,9 @@ function evaluateDeclaredConstructorArguments(info, record6, scope, ctx) {
|
|
|
76574
76699
|
);
|
|
76575
76700
|
}
|
|
76576
76701
|
const value = byName.get(parameter4.name);
|
|
76577
|
-
if (parameter4.type !== 20 /* Decimal */) return value;
|
|
76578
76702
|
if (typeof value !== "number") return value;
|
|
76703
|
+
if (parameter4.type === 4 /* Float */) return Math.fround(value);
|
|
76704
|
+
if (parameter4.type !== 20 /* Decimal */) return value;
|
|
76579
76705
|
return coerceDecimalOperand(
|
|
76580
76706
|
value,
|
|
76581
76707
|
`constructor argument '${parameter4.name}'`
|
|
@@ -89277,6 +89403,13 @@ function validateProjectRecordByKind(recordKind, data, options = {}) {
|
|
|
89277
89403
|
if (recordKind === ProjectRecordKind.Member) {
|
|
89278
89404
|
const memberGuard = options.members === "authored-or-compiled" ? isAnyMemberAuthoredOrCompiled : isAnyMember;
|
|
89279
89405
|
if (memberGuard(data)) return;
|
|
89406
|
+
const unrounded = unroundedFloatPath(data);
|
|
89407
|
+
if (unrounded !== null) {
|
|
89408
|
+
const id2 = typeof data === "object" && data !== null && "id" in data ? String(data.id) : "";
|
|
89409
|
+
throw new Error(
|
|
89410
|
+
`Member "${id2}" field "${unrounded}" must be a 32-bit float.`
|
|
89411
|
+
);
|
|
89412
|
+
}
|
|
89280
89413
|
}
|
|
89281
89414
|
if (recordKind === ProjectRecordKind.Value) {
|
|
89282
89415
|
if (isMemberValue(data)) {
|
|
@@ -89372,6 +89505,7 @@ var init_project_record_validation = __esm({
|
|
|
89372
89505
|
init_localization_types();
|
|
89373
89506
|
init_unity_import_settings();
|
|
89374
89507
|
init_project_file_authoring_identifiers();
|
|
89508
|
+
init_float32();
|
|
89375
89509
|
}
|
|
89376
89510
|
});
|
|
89377
89511
|
|
|
@@ -97503,15 +97637,13 @@ function inspectStoredValueNodeInternal(options) {
|
|
|
97503
97637
|
return terminal();
|
|
97504
97638
|
}
|
|
97505
97639
|
if (member.kind === 4 /* Float */) {
|
|
97506
|
-
if (
|
|
97507
|
-
fail(`${path} must store a finite number.`);
|
|
97508
|
-
}
|
|
97640
|
+
if (!isFloat32(row.value)) fail(`${path} must store a 32-bit float.`);
|
|
97509
97641
|
assertNumberRange(member, row.value, path);
|
|
97510
97642
|
return terminal();
|
|
97511
97643
|
}
|
|
97512
|
-
const
|
|
97513
|
-
if (
|
|
97514
|
-
fail(`${path} ${storedLeafShapeIssueMessage(
|
|
97644
|
+
const leafIssue2 = storedLeafShapeIssue(member, row.value);
|
|
97645
|
+
if (leafIssue2 !== null) {
|
|
97646
|
+
fail(`${path} ${storedLeafShapeIssueMessage(leafIssue2, "graph")}`);
|
|
97515
97647
|
}
|
|
97516
97648
|
if (isMemberStringBase(member)) {
|
|
97517
97649
|
if (typeof row.value !== "string") fail(`${path} must store a string.`);
|
|
@@ -97873,6 +98005,7 @@ var init_stored_value_graph_semantics = __esm({
|
|
|
97873
98005
|
init_inheritance();
|
|
97874
98006
|
init_generics();
|
|
97875
98007
|
init_classes();
|
|
98008
|
+
init_float32();
|
|
97876
98009
|
StoredValueSemanticError = class extends Error {
|
|
97877
98010
|
name = "StoredValueSemanticError";
|
|
97878
98011
|
};
|
|
@@ -104917,9 +105050,7 @@ function hasValidOpaqueParameterDefault(value) {
|
|
|
104917
105050
|
if (value.type === 2) {
|
|
104918
105051
|
return typeof payload === "number" && Number.isInteger(payload);
|
|
104919
105052
|
}
|
|
104920
|
-
if (value.type === 4)
|
|
104921
|
-
return typeof payload === "number" && Number.isFinite(payload);
|
|
104922
|
-
}
|
|
105053
|
+
if (value.type === 4) return isFloat32(payload);
|
|
104923
105054
|
if (value.type === 3 || value.type === 8 || value.type === 20) {
|
|
104924
105055
|
return typeof payload === "string";
|
|
104925
105056
|
}
|
|
@@ -106849,6 +106980,7 @@ var init_projectInterfaceValidation = __esm({
|
|
|
106849
106980
|
init_classes();
|
|
106850
106981
|
init_interface_types();
|
|
106851
106982
|
init_member_kinds();
|
|
106983
|
+
init_float32();
|
|
106852
106984
|
init_stored_value_shape();
|
|
106853
106985
|
init_member_storage();
|
|
106854
106986
|
NEO_OBJECT_WORLD_KIND = "object";
|
|
@@ -108267,7 +108399,7 @@ function csharpValueType(ctx, member, saved = false, env, genericBindingSaved =
|
|
|
108267
108399
|
return isRequiredMember2(member) ? "bool" : "bool?";
|
|
108268
108400
|
if (isMemberIntBase(member)) return isRequiredMember2(member) ? "int" : "int?";
|
|
108269
108401
|
if (isMemberFloatBase(member))
|
|
108270
|
-
return isRequiredMember2(member) ? "
|
|
108402
|
+
return isRequiredMember2(member) ? "float" : "float?";
|
|
108271
108403
|
if (isMemberDecimalBase(member)) {
|
|
108272
108404
|
return isRequiredMember2(member) ? "decimal" : "decimal?";
|
|
108273
108405
|
}
|
|
@@ -108482,7 +108614,7 @@ function csharpTypeInfoValueType(ctx, typeInfo, saved, genericEnv, genericBindin
|
|
|
108482
108614
|
case 2 /* Int */:
|
|
108483
108615
|
return optional2 ? "int?" : "int";
|
|
108484
108616
|
case 4 /* Float */:
|
|
108485
|
-
return optional2 ? "
|
|
108617
|
+
return optional2 ? "float?" : "float";
|
|
108486
108618
|
case 20 /* Decimal */:
|
|
108487
108619
|
return optional2 ? "decimal?" : "decimal";
|
|
108488
108620
|
case 3 /* String */:
|
|
@@ -124748,8 +124880,9 @@ function lowerValueBody(context, member, expression, base, source, environment,
|
|
|
124748
124880
|
case "bool":
|
|
124749
124881
|
return { ...next, value: requiredBoolean(expression) };
|
|
124750
124882
|
case "int":
|
|
124751
|
-
case "float":
|
|
124752
124883
|
return { ...next, value: requiredNumber2(expression) };
|
|
124884
|
+
case "float":
|
|
124885
|
+
return { ...next, value: Math.fround(requiredNumber2(expression)) };
|
|
124753
124886
|
case "decimal":
|
|
124754
124887
|
return { ...next, value: requiredDecimal(expression) };
|
|
124755
124888
|
case "string":
|
|
@@ -156644,7 +156777,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
156644
156777
|
async function main() {
|
|
156645
156778
|
const args = parseArgs(process.argv.slice(2));
|
|
156646
156779
|
if (args.command === "--version") {
|
|
156647
|
-
console.log("0.
|
|
156780
|
+
console.log("0.67.0");
|
|
156648
156781
|
return;
|
|
156649
156782
|
}
|
|
156650
156783
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
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.0 -->
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -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:
|