@holoscript/core 8.0.8 → 8.0.9
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/bin/holoscript.cjs +5 -1
- package/dist/GLTFPipeline-L76YTXKA.js +15 -0
- package/dist/GLTFPipeline-ZWJN7GI6.cjs +36 -0
- package/dist/HoloCompositionParser-K76KTEEE.js +12 -0
- package/dist/HoloCompositionParser-UZH6Y4HO.cjs +45 -0
- package/dist/HoloScriptCodeParser-2D4ERFUZ.js +6 -0
- package/dist/HoloScriptCodeParser-UDRLDA7I.cjs +23 -0
- package/dist/HoloScriptPlusParser-FTMCGWXD.js +13 -0
- package/dist/HoloScriptPlusParser-LQR5GIKF.cjs +30 -0
- package/dist/HoloScriptRuntime-UTRLJI5L.js +12 -0
- package/dist/HoloScriptRuntime-YBYXJHJN.cjs +21 -0
- package/dist/SceneIRCompiler-63KA3M2F.js +17 -0
- package/dist/SceneIRCompiler-KWUFHZ4O.cjs +42 -0
- package/dist/{USDZExporter-AUHZODOF.cjs → USDZExporter-ML4UMIGC.cjs} +3 -3
- package/dist/{USDZExporter-GXB4AUSG.js → USDZExporter-ZFKLQ76G.js} +3 -3
- package/dist/agents/index.cjs +1 -1
- package/dist/agents/index.js +1 -1
- package/dist/audit/AuditLogger.d.ts +106 -0
- package/dist/audit/AuditQueryBuilder.d.ts +79 -0
- package/dist/audit/ComplianceReporter.d.ts +90 -0
- package/dist/audit/index.d.ts +13 -0
- package/dist/{chunk-FGMDMJM7.js → chunk-2BYAUHBO.js} +3 -3
- package/dist/{chunk-EDPYCLRC.cjs → chunk-2E6PP5UE.cjs} +83 -59
- package/dist/{chunk-GASCWJK5.js → chunk-2EGGAZT3.js} +65 -287
- package/dist/{chunk-SIEXCILW.js → chunk-2I3XAGMF.js} +3 -3
- package/dist/{chunk-OS533P33.cjs → chunk-2KKOYZYI.cjs} +1074 -1655
- package/dist/chunk-2MQKNDNH.js +51 -0
- package/dist/{chunk-7DMMMBCY.cjs → chunk-2X3IPCBK.cjs} +10 -10
- package/dist/chunk-2ZOTBO25.cjs +202 -0
- package/dist/chunk-356N4NPM.cjs +152 -0
- package/dist/{chunk-X3GJPRVK.cjs → chunk-36NPLOI4.cjs} +92 -81
- package/dist/{chunk-SLU6UPJI.cjs → chunk-37HHY7RH.cjs} +5 -5
- package/dist/{chunk-YDPEHCCI.cjs → chunk-3CDDRUER.cjs} +3 -118
- package/dist/chunk-3F7ZZWIN.js +1651 -0
- package/dist/chunk-3ILD7TKP.cjs +187 -0
- package/dist/{chunk-X27QRG4C.cjs → chunk-3IUHTGDD.cjs} +153 -41
- package/dist/{chunk-PXNZ6TME.js → chunk-4376VHNJ.js} +60 -36
- package/dist/{chunk-YKGPCZEE.cjs → chunk-4FIBOJW6.cjs} +10 -10
- package/dist/chunk-4Q7RKQQI.cjs +14195 -0
- package/dist/{chunk-YCM6QQRT.cjs → chunk-566ZB4LZ.cjs} +180 -8
- package/dist/{chunk-2Y3V22SG.js → chunk-5CURIYGT.js} +3 -3
- package/dist/{chunk-QBWNJXNR.js → chunk-5FYMCVBY.js} +5 -5
- package/dist/{chunk-ZA34AN3R.js → chunk-5LVFTGKH.js} +841 -12
- package/dist/chunk-63AUAIL6.js +48 -0
- package/dist/chunk-655FATJU.js +110 -0
- package/dist/{chunk-TQ377OLB.cjs → chunk-65S62L4D.cjs} +28 -22
- package/dist/chunk-6NTAZN5Z.cjs +502 -0
- package/dist/chunk-6TRX6AR2.js +9376 -0
- package/dist/chunk-6ZCCLKS2.cjs +51 -0
- package/dist/{chunk-MDR235RZ.js → chunk-734OB5SK.js} +721 -8
- package/dist/{chunk-Q2Q34NF3.js → chunk-77QI552M.js} +6 -6
- package/dist/{chunk-WKX5AMOY.js → chunk-7I74JWPW.js} +3 -3
- package/dist/{chunk-5FSKKMR7.cjs → chunk-7IDJDMPU.cjs} +232 -4
- package/dist/chunk-7VBKRGIZ.cjs +847 -0
- package/dist/{chunk-KCPHASCO.js → chunk-AATYYLYK.js} +5 -5
- package/dist/{chunk-WFKVS2K4.cjs → chunk-AUZRKIHQ.cjs} +1101 -55
- package/dist/{chunk-DTGBOSEM.cjs → chunk-AWXFEAQL.cjs} +12 -12
- package/dist/{chunk-THCK6ECW.js → chunk-B3CWTCK2.js} +231 -3
- package/dist/chunk-BCP4E7MD.cjs +997 -0
- package/dist/chunk-BG7RPYJP.js +91 -0
- package/dist/{chunk-VF257YKO.js → chunk-BP4KTMLY.js} +117 -5
- package/dist/{chunk-YN6IETRZ.js → chunk-BQJ3YBF3.js} +6424 -987
- package/dist/{chunk-KOUAQL2B.cjs → chunk-CANAL6CT.cjs} +1569 -168
- package/dist/{chunk-FDSGHPAK.js → chunk-CBSDJF3B.js} +3 -3
- package/dist/{chunk-FEWUHQNM.cjs → chunk-CFVK26P4.cjs} +4 -4
- package/dist/{chunk-M7K4LE66.cjs → chunk-CI33NINL.cjs} +4 -4
- package/dist/{chunk-2OWDB4FB.js → chunk-CKV5NYAE.js} +6 -6
- package/dist/{chunk-LPS5AMQD.cjs → chunk-CM4NHXVO.cjs} +24 -24
- package/dist/chunk-D3HSRXYB.js +115 -0
- package/dist/{chunk-FNHJRI32.js → chunk-DBH3D2MU.js} +1561 -160
- package/dist/{chunk-GW3LKD5C.js → chunk-DJNH4HFW.js} +3 -3
- package/dist/{chunk-2GCNOI2U.cjs → chunk-DN6F4DHH.cjs} +9 -3
- package/dist/chunk-DQRJ5RJG.js +432 -0
- package/dist/{chunk-C7ZBSV2Q.js → chunk-DUG3OQAS.js} +106 -43
- package/dist/chunk-ECUYJOJ2.cjs +199 -0
- package/dist/chunk-EEMTCAK7.js +182 -0
- package/dist/{chunk-3SKLAUDD.cjs → chunk-EI3J6LTW.cjs} +359 -581
- package/dist/{chunk-SSSN7VAM.js → chunk-EM2OGPYE.js} +4 -4
- package/dist/{chunk-56VOWURB.cjs → chunk-ENZCIQZC.cjs} +522 -453
- package/dist/chunk-ESBXUYOC.cjs +836 -0
- package/dist/{chunk-L5U4W6JC.js → chunk-ESSEF6U2.js} +4 -4
- package/dist/chunk-ET3AN4W3.js +824 -0
- package/dist/chunk-EXKSFGSX.cjs +14 -14
- package/dist/{chunk-I76GIKN7.cjs → chunk-F3YT6GUF.cjs} +17 -17
- package/dist/{chunk-WRWEX5ZF.js → chunk-F75DZBBI.js} +3 -3
- package/dist/{chunk-4JGRWHZJ.js → chunk-FG6PYGIZ.js} +12 -6
- package/dist/chunk-FGGJQRLZ.js +14 -14
- package/dist/{chunk-SXOSDZD6.js → chunk-FWCHPCD4.js} +128 -10
- package/dist/{chunk-XW6IXEQH.cjs → chunk-G35CAQ7I.cjs} +5 -5
- package/dist/{chunk-7VMGP2FW.js → chunk-G6KACNMO.js} +132 -188
- package/dist/{chunk-FJPADH77.cjs → chunk-GAWJJAGT.cjs} +6 -6
- package/dist/chunk-GGR7QUKK.cjs +4724 -0
- package/dist/chunk-GIBF4BHH.js +14098 -0
- package/dist/{chunk-AWB7QYY6.cjs → chunk-GILYQ5VH.cjs} +6 -6
- package/dist/{chunk-FWVYAMNW.cjs → chunk-GKFCHGCM.cjs} +4 -4
- package/dist/{chunk-Y3ZFVUUU.js → chunk-GLEJ2TLS.js} +3 -3
- package/dist/{chunk-3GWWJT7L.js → chunk-GP3OKSKT.js} +13 -13
- package/dist/chunk-GTIPOEHN.js +196 -0
- package/dist/{chunk-LMJ5EBV7.cjs → chunk-GZPUA2TL.cjs} +16 -15
- package/dist/{chunk-IELX2OKI.js → chunk-H4LJ4HEA.js} +3 -115
- package/dist/{chunk-ACVWFGBI.cjs → chunk-HCX4SMFK.cjs} +3 -3
- package/dist/{chunk-HYNTS5CP.js → chunk-HHRZ6STP.js} +24 -2
- package/dist/chunk-HIDEIEFG.js +48 -0
- package/dist/{chunk-W6RW64BB.cjs → chunk-HSWBIDZM.cjs} +228 -5
- package/dist/{chunk-GSOUNWEL.js → chunk-HVX7QQYK.js} +1035 -1616
- package/dist/{chunk-TRCGG42I.cjs → chunk-IFW5IW4L.cjs} +6502 -1019
- package/dist/{chunk-F5LKJ6F5.cjs → chunk-IJU6AS67.cjs} +32 -28
- package/dist/{chunk-TVANHNJ7.js → chunk-IK6Z2HNC.js} +173 -3
- package/dist/{chunk-QGMUTVVH.cjs → chunk-IS7NTKY5.cjs} +20 -20
- package/dist/{chunk-YFVQWSNJ.js → chunk-IXWGYWH6.js} +3 -3
- package/dist/chunk-J2DAS2PL.js +148 -0
- package/dist/chunk-JBQXZIWB.js +148 -0
- package/dist/chunk-JBYBMBMW.js +261 -0
- package/dist/{chunk-LWUOUCYL.js → chunk-JEJ7TT54.js} +5 -5
- package/dist/{chunk-DUCB6LGL.js → chunk-JOTCTHN5.js} +211 -5
- package/dist/{chunk-47RUFYKR.js → chunk-K56UVEXV.js} +3 -3
- package/dist/{chunk-XSFNHP2E.js → chunk-KB26H447.js} +3 -3
- package/dist/{chunk-3NGDZZR4.js → chunk-KEYG7HGY.js} +430 -37
- package/dist/{chunk-DY72BMU5.js → chunk-KFVNCW4Q.js} +4 -4
- package/dist/chunk-KPGC7SK2.js +192 -0
- package/dist/chunk-KROXXBK5.cjs +53 -0
- package/dist/{chunk-ZPZAVHXL.cjs → chunk-LB3ZZMKT.cjs} +137 -19
- package/dist/chunk-LDYZWNJW.cjs +1654 -0
- package/dist/{chunk-ULMSSHCJ.cjs → chunk-LMB555QB.cjs} +405 -38
- package/dist/{chunk-CBJY23VL.js → chunk-MD4IVS42.js} +3 -3
- package/dist/{chunk-VMLKSV26.js → chunk-MDDWEBCX.js} +226 -3
- package/dist/chunk-MUWH4QK5.cjs +94 -0
- package/dist/{chunk-T6W3Z3SH.cjs → chunk-N2ILK7BF.cjs} +4 -4
- package/dist/{chunk-6EX3I5P4.cjs → chunk-N74QRJGP.cjs} +6 -6
- package/dist/chunk-NFFHLX37.cjs +132 -0
- package/dist/chunk-NJSYWX7H.js +190 -0
- package/dist/{chunk-SH5PPVK7.cjs → chunk-NQN5LFN4.cjs} +165 -221
- package/dist/chunk-NTQRFOPP.cjs +56 -0
- package/dist/{chunk-YFWRJW4B.js → chunk-NWMJPTVL.js} +51 -55
- package/dist/{chunk-63ZGNR2T.cjs → chunk-OC6GV5QH.cjs} +42 -42
- package/dist/{chunk-7E7GCQCK.js → chunk-OG3MBHM3.js} +9 -3
- package/dist/chunk-OMNHTCS4.cjs +264 -0
- package/dist/chunk-OQXB6NNC.cjs +117 -0
- package/dist/{chunk-Y57W2CT5.cjs → chunk-OV46CCA2.cjs} +51 -55
- package/dist/{chunk-6PRZIHGL.cjs → chunk-OV6HHKLE.cjs} +21 -266
- package/dist/{chunk-C37BHB7N.cjs → chunk-P26YYPOO.cjs} +5 -5
- package/dist/{chunk-2BZHWUSR.cjs → chunk-P7JEKJTZ.cjs} +16 -16
- package/dist/{chunk-NGBXXZLL.cjs → chunk-PDXX5UI4.cjs} +45 -45
- package/dist/{chunk-FHQFPYV4.js → chunk-PJFTTSKE.js} +8 -7
- package/dist/{chunk-GVFJ6T4S.cjs → chunk-PVODJEJ7.cjs} +721 -8
- package/dist/{chunk-ZZ7RO2UQ.js → chunk-Q265VZJ4.js} +3 -3
- package/dist/{chunk-E7JP3BS3.cjs → chunk-Q47JEE2C.cjs} +4 -4
- package/dist/chunk-QBY7LRN2.js +281 -0
- package/dist/{chunk-Z6PMDS4G.js → chunk-QDQWKSU3.js} +1090 -53
- package/dist/{chunk-GH6C2QGW.cjs → chunk-QEDMOGF3.cjs} +857 -16
- package/dist/{chunk-5WUNN6ZN.cjs → chunk-QHSAVOOL.cjs} +24 -2
- package/dist/chunk-QJNCDVYM.cjs +137 -0
- package/dist/chunk-QM7FJB5W.js +4717 -0
- package/dist/chunk-QQFB4RT2.cjs +448 -0
- package/dist/chunk-QSYBHQAD.cjs +196 -0
- package/dist/{chunk-UGXHYIWT.cjs → chunk-QUJ3ZB55.cjs} +28 -28
- package/dist/{chunk-2YSNA2F2.cjs → chunk-QVJMDVYZ.cjs} +5 -5
- package/dist/chunk-RAJMAX6D.js +131 -0
- package/dist/{chunk-VVKVQZI6.js → chunk-RAN3ECAS.js} +3 -3
- package/dist/chunk-RKGUZBOC.js +79 -0
- package/dist/{chunk-HLFDZ35S.cjs → chunk-RRQIAJLQ.cjs} +8 -8
- package/dist/{chunk-PABONWKI.js → chunk-RXQNRZ5F.js} +3 -3
- package/dist/{chunk-7ZHYEITD.cjs → chunk-S4O7CFHQ.cjs} +10 -11
- package/dist/chunk-SE7ANBGN.js +128 -0
- package/dist/{chunk-X2AVEAZM.cjs → chunk-SJIRCTIS.cjs} +176 -2
- package/dist/{chunk-WXQ57LAO.js → chunk-SQXAZHDG.js} +4 -4
- package/dist/chunk-SR73L5ZP.cjs +84 -0
- package/dist/{chunk-OABEO6HH.js → chunk-SZOLTWWD.js} +2349 -214
- package/dist/{chunk-5JEU52DW.js → chunk-TPZ3BN2D.js} +3 -3
- package/dist/{chunk-QFU53KRH.js → chunk-TSTFYGGX.js} +4 -5
- package/dist/{chunk-EBS32AJI.cjs → chunk-TZCFKZ6Z.cjs} +5 -5
- package/dist/chunk-UCVZXQ63.js +724 -0
- package/dist/chunk-UGQ3QNV6.js +992 -0
- package/dist/chunk-UNMVGZVW.js +142 -0
- package/dist/{chunk-TEVX443G.js → chunk-UTUD6GJI.js} +178 -6
- package/dist/chunk-UXBYA7DV.cjs +155 -0
- package/dist/chunk-V6GXFSK7.cjs +443 -0
- package/dist/chunk-VHORVGCG.cjs +761 -0
- package/dist/{chunk-B4EKV6HQ.js → chunk-VKCTYLDN.js} +500 -442
- package/dist/{chunk-O3MGZDCT.cjs → chunk-VTEXJOSD.cjs} +63 -63
- package/dist/chunk-VVAAZITA.cjs +287 -0
- package/dist/{chunk-V7AKE5VT.cjs → chunk-W2GA3EQB.cjs} +435 -42
- package/dist/chunk-W4GABFCR.js +37 -0
- package/dist/chunk-WKEK4NCA.js +490 -0
- package/dist/{chunk-5A4TCHOC.cjs → chunk-WNYXT4TE.cjs} +4 -4
- package/dist/{chunk-S762UEV5.js → chunk-WTH23ISI.js} +6 -6
- package/dist/{chunk-BTKZGHAV.js → chunk-WWNCM473.js} +10 -6
- package/dist/{chunk-7X5PNIQJ.js → chunk-X3YFRH6K.js} +27 -25
- package/dist/{chunk-4YNYPHH3.cjs → chunk-X75H75UY.cjs} +2351 -213
- package/dist/{chunk-LYJJI7ZK.cjs → chunk-XCUDDFKC.cjs} +216 -9
- package/dist/chunk-YAO4HPJL.cjs +120 -0
- package/dist/chunk-YKY2JBER.cjs +9443 -0
- package/dist/chunk-YP5CHEYU.cjs +154 -0
- package/dist/{chunk-WRNEH5MO.js → chunk-YW3I2FQL.js} +18 -7
- package/dist/{chunk-BRNUPDHJ.js → chunk-Z557DVYN.js} +386 -19
- package/dist/{chunk-VSACG2AR.js → chunk-Z6LZUYZF.js} +21 -264
- package/dist/chunk-ZHPMP447.cjs +43 -0
- package/dist/{chunk-LODTHGST.cjs → chunk-ZK7KX5CD.cjs} +133 -70
- package/dist/{chunk-CCPSNT6B.cjs → chunk-ZRPALBQB.cjs} +5 -5
- package/dist/chunk-ZVFHPMC5.js +824 -0
- package/dist/chunk-ZVQMKUGJ.js +443 -0
- package/dist/cli/holoscript-runner.cjs +86 -48
- package/dist/cli/holoscript-runner.js +54 -16
- package/dist/codebase/index.cjs +1 -1
- package/dist/codebase/index.js +1 -1
- package/dist/compiler/agent-inference.cjs +11 -11
- package/dist/compiler/agent-inference.js +9 -6
- package/dist/compiler/android-xr.cjs +13 -12
- package/dist/compiler/android-xr.js +11 -10
- package/dist/compiler/android.cjs +12 -12
- package/dist/compiler/android.js +10 -10
- package/dist/compiler/business-quest.cjs +10 -10
- package/dist/compiler/business-quest.js +2 -2
- package/dist/compiler/coco.cjs +1 -1
- package/dist/compiler/coco.js +1 -1
- package/dist/compiler/context.cjs +9 -9
- package/dist/compiler/context.js +6 -6
- package/dist/compiler/daimon-seed.cjs +36 -0
- package/dist/compiler/daimon-seed.js +12 -0
- package/dist/compiler/domain-block-utils.cjs +205 -156
- package/dist/compiler/domain-block-utils.js +8 -7
- package/dist/compiler/dtdl.cjs +10 -10
- package/dist/compiler/dtdl.js +7 -7
- package/dist/compiler/gltf-pipeline.cjs +9 -9
- package/dist/compiler/gltf-pipeline.js +2 -2
- package/dist/compiler/godot.cjs +10 -9
- package/dist/compiler/godot.js +9 -8
- package/dist/compiler/incremental.cjs +11 -11
- package/dist/compiler/incremental.js +6 -6
- package/dist/compiler/index.cjs +2585 -3273
- package/dist/compiler/index.d.ts +149 -35
- package/dist/compiler/index.js +2197 -3102
- package/dist/compiler/ios.cjs +11 -11
- package/dist/compiler/ios.js +9 -9
- package/dist/compiler/llm-provider-capabilities.cjs +9 -9
- package/dist/compiler/llm-provider-capabilities.js +6 -6
- package/dist/compiler/nodetoy.cjs +1 -1
- package/dist/compiler/nodetoy.js +1 -1
- package/dist/compiler/openxr.cjs +11 -10
- package/dist/compiler/openxr.js +10 -9
- package/dist/compiler/remotion.cjs +1 -1
- package/dist/compiler/remotion.js +1 -1
- package/dist/compiler/reproducibility.cjs +1 -1
- package/dist/compiler/reproducibility.js +1 -1
- package/dist/compiler/sdf.cjs +11 -10
- package/dist/compiler/sdf.js +9 -8
- package/dist/compiler/semantic-scene.cjs +7 -7
- package/dist/compiler/semantic-scene.js +2 -2
- package/dist/compiler/state.cjs +9 -9
- package/dist/compiler/state.js +7 -7
- package/dist/compiler/trait-composition.cjs +11 -11
- package/dist/compiler/trait-composition.js +7 -7
- package/dist/compiler/traits/ProvenanceSemiring.d.ts +167 -0
- package/dist/compiler/traits/Semiring.d.ts +26 -0
- package/dist/compiler/unity.cjs +11 -10
- package/dist/compiler/unity.js +10 -9
- package/dist/compiler/unreal.cjs +12 -11
- package/dist/compiler/unreal.js +10 -9
- package/dist/compiler/urdf.cjs +18 -17
- package/dist/compiler/urdf.js +9 -8
- package/dist/compiler/usd-physics.cjs +11 -10
- package/dist/compiler/usd-physics.js +8 -7
- package/dist/compiler/visionos.cjs +11 -10
- package/dist/compiler/visionos.js +10 -9
- package/dist/compiler/vrchat.cjs +11 -10
- package/dist/compiler/vrchat.js +9 -8
- package/dist/compiler/wasm.cjs +14 -13
- package/dist/compiler/wasm.js +9 -8
- package/dist/compiler/webgpu.cjs +10 -9
- package/dist/compiler/webgpu.js +9 -8
- package/dist/constants.cjs +398 -0
- package/dist/constants.js +9 -0
- package/dist/coordinators/index.cjs +4 -1
- package/dist/coordinators/index.js +4 -1
- package/dist/debugger.cjs +11 -9
- package/dist/debugger.js +9 -7
- package/dist/{dist-ACXG6IH5.cjs → dist-GRMOP2UL.cjs} +341 -65
- package/dist/{dist-VD4L6V7Q.js → dist-ZBUKU2JG.js} +333 -63
- package/dist/entries/interop.cjs +23 -23
- package/dist/entries/interop.js +3 -3
- package/dist/entries/scripting.cjs +12 -11
- package/dist/entries/scripting.js +8 -7
- package/dist/evolution/index.cjs +66 -0
- package/dist/evolution/index.d.ts +162 -0
- package/dist/evolution/index.js +17 -0
- package/dist/hololand/index.cjs +41 -37
- package/dist/hololand/index.js +3 -3
- package/dist/index.cjs +12394 -3224
- package/dist/index.d.ts +260 -18
- package/dist/index.js +10755 -2182
- package/dist/keyword-registry/PluginKeywordRegistry.d.ts +138 -0
- package/dist/keyword-registry/index.cjs +29 -0
- package/dist/keyword-registry/index.d.ts +1 -0
- package/dist/keyword-registry/index.js +4 -0
- package/dist/math/tropical-spmv.cjs +11 -11
- package/dist/math/tropical-spmv.d.ts +1 -0
- package/dist/math/tropical-spmv.js +2 -2
- package/dist/math/tropicalSpmv.d.ts +43 -0
- package/dist/math/vec3.cjs +1 -1
- package/dist/math/vec3.js +1 -1
- package/dist/matter/StagedMatter.d.ts +82 -0
- package/dist/matter/index.cjs +17 -0
- package/dist/matter/index.d.ts +1 -0
- package/dist/matter/index.js +4 -0
- package/dist/{ml-dsa-Z7JDKW4L.js → ml-dsa-J6VKVT4K.js} +3 -3
- package/dist/{ml-dsa-FSKBTE3W.cjs → ml-dsa-MTIK4ZUQ.cjs} +23 -23
- package/dist/paper-0c-spike/index.cjs +1 -1
- package/dist/paper-0c-spike/index.js +1 -1
- package/dist/parameter-envelope/ParameterEnvelope.d.ts +128 -0
- package/dist/parameter-envelope/index.cjs +17 -0
- package/dist/parameter-envelope/index.d.ts +2 -0
- package/dist/parameter-envelope/index.js +4 -0
- package/dist/parser/HoloCompositionTypes.d.ts +2013 -0
- package/dist/parser/PipelineParser.d.ts +162 -0
- package/dist/parser.cjs +36 -20
- package/dist/parser.js +13 -9
- package/dist/plugin-manifest/ManifestAutoLoader.d.ts +35 -0
- package/dist/plugin-manifest/PluginManifest.d.ts +156 -0
- package/dist/plugin-manifest/index.cjs +25 -0
- package/dist/plugin-manifest/index.d.ts +2 -0
- package/dist/plugin-manifest/index.js +4 -0
- package/dist/plugin-solver-contract/PluginSolverContract.d.ts +288 -0
- package/dist/plugin-solver-contract/index.cjs +41 -0
- package/dist/plugin-solver-contract/index.d.ts +1 -0
- package/dist/plugin-solver-contract/index.js +4 -0
- package/dist/policy/ContentPolicyGate.d.ts +51 -0
- package/dist/policy/PolicyPack.d.ts +120 -0
- package/dist/policy/blocklist.d.ts +32 -0
- package/dist/policy/defaults.d.ts +44 -0
- package/dist/policy/index.cjs +106 -0
- package/dist/policy/index.d.ts +17 -0
- package/dist/policy/index.js +5 -0
- package/dist/policy/jsonLogic.d.ts +31 -0
- package/dist/policy/types.d.ts +174 -0
- package/dist/proof-composition/ProofCompositionLaw.d.ts +93 -0
- package/dist/proof-composition/index.cjs +25 -0
- package/dist/proof-composition/index.d.ts +1 -0
- package/dist/proof-composition/index.js +4 -0
- package/dist/receipts/hash-policy.d.ts +85 -0
- package/dist/reconstruction/index.cjs +75 -47
- package/dist/reconstruction/index.js +5 -5
- package/dist/runtime/plugin-trait-registrar.d.ts +36 -0
- package/dist/runtime.cjs +81 -79
- package/dist/runtime.js +9 -7
- package/dist/scene-presets-EDKYZ5GW.js +4 -0
- package/dist/scene-presets-NCW2CFRS.cjs +17 -0
- package/dist/self-improvement/index.cjs +1 -1
- package/dist/self-improvement/index.js +1 -1
- package/dist/{src-PT2FERDV.cjs → src-G3D7ZATQ.cjs} +545 -21
- package/dist/{src-J6CM4AUR.js → src-UXYA7HM6.js} +539 -16
- package/dist/storage/index.cjs +10 -10
- package/dist/storage/index.js +3 -3
- package/dist/testing.cjs +1 -1
- package/dist/testing.js +1 -1
- package/dist/tools/index.cjs +3631 -0
- package/dist/tools/index.js +3581 -0
- package/dist/traitDocs/traitDocs.cjs +9 -9
- package/dist/traitDocs/traitDocs.d.ts +1 -0
- package/dist/traitDocs/traitDocs.js +3 -3
- package/dist/traits/ControlLoopTrait.d.ts +154 -0
- package/dist/traits/KinematicChainTrait.d.ts +116 -0
- package/dist/traits/SensorSamplingTrait.d.ts +154 -0
- package/dist/traits/TraitTypes.d.ts +270 -0
- package/dist/traits/TransactionTrait.d.ts +121 -0
- package/dist/traits/botanical-lotus.cjs +54 -50
- package/dist/traits/botanical-lotus.js +2 -5
- package/dist/traits/control-loop.cjs +21 -0
- package/dist/traits/control-loop.d.ts +1 -0
- package/dist/traits/control-loop.js +4 -0
- package/dist/traits/engines/cloth-verlet.d.ts +65 -0
- package/dist/traits/engines/index.cjs +19 -19
- package/dist/traits/engines/index.d.ts +15 -275
- package/dist/traits/engines/index.js +3 -3
- package/dist/traits/engines/motion-data-schema.d.ts +119 -0
- package/dist/traits/engines/motion-matching.d.ts +102 -0
- package/dist/traits/engines/noise.d.ts +25 -0
- package/dist/traits/engines/onnx-adapter.d.ts +173 -0
- package/dist/traits/engines/onnx-motion-matching.d.ts +163 -0
- package/dist/traits/engines/pfnn-network.d.ts +92 -0
- package/dist/traits/engines/synthetic-walk-cycle.d.ts +38 -0
- package/dist/traits/engines/tensor-ops.d.ts +15 -0
- package/dist/traits/index.cjs +2789 -1259
- package/dist/traits/index.d.ts +35 -0
- package/dist/traits/index.js +1692 -411
- package/dist/traits/kinematic-chain.cjs +25 -0
- package/dist/traits/kinematic-chain.d.ts +1 -0
- package/dist/traits/kinematic-chain.js +4 -0
- package/dist/traits/sensor-sampling.cjs +33 -0
- package/dist/traits/sensor-sampling.d.ts +1 -0
- package/dist/traits/sensor-sampling.js +4 -0
- package/dist/traits/simulation-solver-factory.cjs +1 -1
- package/dist/traits/simulation-solver-factory.js +1 -1
- package/dist/traits/transaction.cjs +29 -0
- package/dist/traits/transaction.d.ts +1 -0
- package/dist/traits/transaction.js +4 -0
- package/dist/traits/webcam-gaze.cjs +1 -1
- package/dist/traits/webcam-gaze.js +1 -1
- package/dist/type-checker.cjs +7 -6
- package/dist/type-checker.js +5 -4
- package/dist/types/AdvancedTypeSystem.d.ts +489 -0
- package/dist/types/HoloScriptPlus.d.ts +810 -0
- package/dist/types/base.d.ts +248 -0
- package/dist/types.d.ts +799 -0
- package/dist/world/index.cjs +3 -4
- package/dist/world/index.js +3 -4
- package/dist/world-model/index.cjs +1 -1
- package/dist/world-model/index.js +1 -1
- package/dist/wot/index.cjs +1 -1
- package/dist/wot/index.js +1 -1
- package/package.json +113 -46
- package/dist/GLTFPipeline-3EJLL3TS.cjs +0 -38
- package/dist/GLTFPipeline-3OWJV2VK.js +0 -17
- package/dist/HoloScriptPlusParser-ADWRY5OS.cjs +0 -698
- package/dist/HoloScriptPlusParser-JLJDXHSC.js +0 -693
- package/dist/HoloScriptPlusParser-QCGFPWIL.cjs +0 -27
- package/dist/HoloScriptPlusParser-WENAFEFV.js +0 -10
- package/dist/HoloScriptRuntime-GGRVEU4T.cjs +0 -19
- package/dist/HoloScriptRuntime-GJK6VJPH.js +0 -10
- package/dist/chunk-22Q5A6RV.js +0 -979
- package/dist/chunk-4C57PR42.js +0 -468
- package/dist/chunk-4W5G5QVL.cjs +0 -847
- package/dist/chunk-5ET6L4NS.js +0 -487
- package/dist/chunk-C4GSLCHE.cjs +0 -7153
- package/dist/chunk-F2G6CWFT.js +0 -7089
- package/dist/chunk-G6PNEASF.cjs +0 -814
- package/dist/chunk-GTA4Q3A3.js +0 -1491
- package/dist/chunk-HCCQLAA4.cjs +0 -74
- package/dist/chunk-HFSVMKM3.cjs +0 -72
- package/dist/chunk-KAIVDEIG.cjs +0 -4539
- package/dist/chunk-KQU64CIX.cjs +0 -1508
- package/dist/chunk-MSYSQ2AJ.js +0 -4533
- package/dist/chunk-NHJLP37F.js +0 -70
- package/dist/chunk-NHYRRAGI.cjs +0 -490
- package/dist/chunk-OIQYIIO3.cjs +0 -473
- package/dist/chunk-OL46QLBJ.js +0 -61
- package/dist/chunk-SKZPC5AG.cjs +0 -984
- package/dist/chunk-SLHLXUMO.js +0 -445
- package/dist/chunk-UOIGFQXC.cjs +0 -9750
- package/dist/chunk-UOL6Y5TD.cjs +0 -759
- package/dist/chunk-UVFI7XIR.cjs +0 -452
- package/dist/chunk-VEPGBETF.js +0 -844
- package/dist/chunk-XQ5MWMP2.js +0 -756
- package/dist/chunk-XT6JY5W5.js +0 -9684
- package/dist/chunk-YRRAUB35.js +0 -811
- package/dist/compiler/GasOptimizationAnalyzer.d.ts +0 -73
- package/dist/compiler/NFTMarketplaceCompiler.d.ts +0 -23
- package/dist/compiler/ar.cjs +0 -23
- package/dist/compiler/ar.js +0 -11
- package/dist/compiler/babylon.cjs +0 -21
- package/dist/compiler/babylon.js +0 -15
- package/dist/compiler/multi-layer.cjs +0 -24
- package/dist/compiler/multi-layer.js +0 -15
- package/dist/compiler/playcanvas.cjs +0 -19
- package/dist/compiler/playcanvas.js +0 -13
- package/dist/compiler/r3f.cjs +0 -39
- package/dist/compiler/r3f.d.ts +0 -22
- package/dist/compiler/r3f.js +0 -17
- package/dist/compiler/vrr.cjs +0 -24
- package/dist/compiler/vrr.js +0 -12
- package/dist/parser/NFTMarketplaceTypes.d.ts +0 -191
- package/dist/playwright-3AT3AKTV.cjs +0 -98673
- package/dist/playwright-VZPDVUEQ.js +0 -98660
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkOV6HHKLE_cjs = require('./chunk-OV6HHKLE.cjs');
|
|
4
|
+
var chunkYP5CHEYU_cjs = require('./chunk-YP5CHEYU.cjs');
|
|
5
|
+
var chunkOMNHTCS4_cjs = require('./chunk-OMNHTCS4.cjs');
|
|
6
|
+
var chunkEI3J6LTW_cjs = require('./chunk-EI3J6LTW.cjs');
|
|
7
|
+
var chunkNTQRFOPP_cjs = require('./chunk-NTQRFOPP.cjs');
|
|
5
8
|
var crypto = require('crypto');
|
|
6
9
|
|
|
7
10
|
function _interopNamespace(e) {
|
|
@@ -24,6 +27,30 @@ function _interopNamespace(e) {
|
|
|
24
27
|
|
|
25
28
|
var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
|
|
26
29
|
|
|
30
|
+
// src/traits/FrameDeclarationTrait.ts
|
|
31
|
+
var DEFAULT_FRAME = {
|
|
32
|
+
domain: "*",
|
|
33
|
+
horizon: "",
|
|
34
|
+
capability_tier: 2,
|
|
35
|
+
trust_tier: 2};
|
|
36
|
+
function coerceConfig(raw) {
|
|
37
|
+
const domain = typeof raw.domain === "string" ? raw.domain : DEFAULT_FRAME.domain;
|
|
38
|
+
const horizon = typeof raw.horizon === "string" ? raw.horizon : DEFAULT_FRAME.horizon;
|
|
39
|
+
let capability_tier = DEFAULT_FRAME.capability_tier;
|
|
40
|
+
const rawCT = raw.capability_tier;
|
|
41
|
+
if (rawCT === 0 || rawCT === 1 || rawCT === 2 || rawCT === 3) {
|
|
42
|
+
capability_tier = rawCT;
|
|
43
|
+
}
|
|
44
|
+
let trust_tier = DEFAULT_FRAME.trust_tier;
|
|
45
|
+
const rawTT = raw.trust_tier;
|
|
46
|
+
if (rawTT === 0 || rawTT === 1 || rawTT === 2 || rawTT === 3) {
|
|
47
|
+
trust_tier = rawTT;
|
|
48
|
+
}
|
|
49
|
+
const allowed_tools = Array.isArray(raw.allowed_tools) ? raw.allowed_tools.filter((t) => typeof t === "string") : [];
|
|
50
|
+
const denied_domains = Array.isArray(raw.denied_domains) ? raw.denied_domains.filter((d) => typeof d === "string") : [];
|
|
51
|
+
return { domain, horizon, capability_tier, trust_tier, allowed_tools, denied_domains };
|
|
52
|
+
}
|
|
53
|
+
|
|
27
54
|
// src/parser/HybridChunker.ts
|
|
28
55
|
function countTokens(text) {
|
|
29
56
|
return Math.ceil(text.length / 4);
|
|
@@ -983,7 +1010,7 @@ function similarity(a, b) {
|
|
|
983
1010
|
function findSimilarTrait(input, threshold = 0.5) {
|
|
984
1011
|
let bestMatch;
|
|
985
1012
|
let bestScore = threshold;
|
|
986
|
-
for (const trait of
|
|
1013
|
+
for (const trait of chunkEI3J6LTW_cjs.VR_TRAITS) {
|
|
987
1014
|
const score = similarity(input, trait);
|
|
988
1015
|
if (score > bestScore) {
|
|
989
1016
|
bestScore = score;
|
|
@@ -1164,13 +1191,18 @@ var Lexer = class {
|
|
|
1164
1191
|
this.tokens.push(this.createToken("DEDENT", ""));
|
|
1165
1192
|
this.pendingDedents--;
|
|
1166
1193
|
}
|
|
1194
|
+
if (this.column === 1) {
|
|
1195
|
+
const beforePos = this.pos;
|
|
1196
|
+
const beforeTokenCount = this.tokens.length;
|
|
1197
|
+
const beforePendingDedents = this.pendingDedents;
|
|
1198
|
+
this.handleIndentation();
|
|
1199
|
+
if (this.pos !== beforePos || this.tokens.length !== beforeTokenCount || this.pendingDedents !== beforePendingDedents) {
|
|
1200
|
+
continue;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1167
1203
|
const char = this.source[this.pos];
|
|
1168
1204
|
if (char === " " || char === " ") {
|
|
1169
|
-
|
|
1170
|
-
this.handleIndentation();
|
|
1171
|
-
} else {
|
|
1172
|
-
this.advance();
|
|
1173
|
-
}
|
|
1205
|
+
this.advance();
|
|
1174
1206
|
continue;
|
|
1175
1207
|
}
|
|
1176
1208
|
if (char === "/" && this.peek(1) === "/") {
|
|
@@ -1776,19 +1808,21 @@ var Lexer = class {
|
|
|
1776
1808
|
return this.isIdentifierStart(char) || this.isDigit(char) || char === "-";
|
|
1777
1809
|
}
|
|
1778
1810
|
};
|
|
1779
|
-
var HoloScriptPlusParser = class {
|
|
1811
|
+
var HoloScriptPlusParser = class _HoloScriptPlusParser {
|
|
1780
1812
|
constructor(options = {}) {
|
|
1781
1813
|
this.tokens = [];
|
|
1782
1814
|
this.pos = 0;
|
|
1783
1815
|
this.source = "";
|
|
1784
1816
|
this.errors = [];
|
|
1785
1817
|
this.warnings = [];
|
|
1818
|
+
this.blockConfigDirectives = /* @__PURE__ */ new WeakSet();
|
|
1819
|
+
this.blockConfigDirectiveLocations = /* @__PURE__ */ new WeakMap();
|
|
1786
1820
|
this.imports = [];
|
|
1787
1821
|
this.hasState = false;
|
|
1788
1822
|
this.hasVRTraits = false;
|
|
1789
1823
|
this.hasControlFlow = false;
|
|
1790
1824
|
this.compiledExpressions = /* @__PURE__ */ new Map();
|
|
1791
|
-
this.errorRecovery = new
|
|
1825
|
+
this.errorRecovery = new chunkOV6HHKLE_cjs.ErrorRecovery();
|
|
1792
1826
|
/**
|
|
1793
1827
|
* Internal incremental parser for parseIncremental.
|
|
1794
1828
|
* Uses ChunkBasedIncrementalParser with AST-aware chunking and
|
|
@@ -1814,7 +1848,7 @@ var HoloScriptPlusParser = class {
|
|
|
1814
1848
|
getQuickFixes() {
|
|
1815
1849
|
const fixes = /* @__PURE__ */ new Map();
|
|
1816
1850
|
for (const error of this.errors) {
|
|
1817
|
-
const errorFixes =
|
|
1851
|
+
const errorFixes = chunkOV6HHKLE_cjs.generateQuickFixes(
|
|
1818
1852
|
{
|
|
1819
1853
|
code: error.code,
|
|
1820
1854
|
message: error.message,
|
|
@@ -1835,7 +1869,7 @@ var HoloScriptPlusParser = class {
|
|
|
1835
1869
|
*/
|
|
1836
1870
|
getEnrichedErrors() {
|
|
1837
1871
|
return this.errors.map(
|
|
1838
|
-
(error) =>
|
|
1872
|
+
(error) => chunkOV6HHKLE_cjs.enrichErrorWithSuggestions(
|
|
1839
1873
|
{
|
|
1840
1874
|
code: error.code,
|
|
1841
1875
|
message: error.message,
|
|
@@ -1851,6 +1885,8 @@ var HoloScriptPlusParser = class {
|
|
|
1851
1885
|
this.source = source;
|
|
1852
1886
|
this.errors = [];
|
|
1853
1887
|
this.warnings = [];
|
|
1888
|
+
this.blockConfigDirectives = /* @__PURE__ */ new WeakSet();
|
|
1889
|
+
this.blockConfigDirectiveLocations = /* @__PURE__ */ new WeakMap();
|
|
1854
1890
|
this.imports = [];
|
|
1855
1891
|
this.hasState = false;
|
|
1856
1892
|
this.hasVRTraits = false;
|
|
@@ -1861,8 +1897,110 @@ var HoloScriptPlusParser = class {
|
|
|
1861
1897
|
const lexer = new Lexer(source);
|
|
1862
1898
|
this.tokens = lexer.tokenize();
|
|
1863
1899
|
const root = this.parseDocument();
|
|
1900
|
+
this.desugarSafeDaemon(root);
|
|
1864
1901
|
return this.buildResult(root);
|
|
1865
1902
|
}
|
|
1903
|
+
/** Canonical safety-trait configs that `@safe_daemon` expands into. */
|
|
1904
|
+
static safeDaemonDefaults() {
|
|
1905
|
+
return {
|
|
1906
|
+
rate_limiter: { strategy: "token_bucket", max_tokens: 20, refill_rate: 4, window_ms: 6e4 },
|
|
1907
|
+
circuit_breaker: {
|
|
1908
|
+
failure_threshold: 5,
|
|
1909
|
+
window_ms: 3e5,
|
|
1910
|
+
reset_timeout_ms: 6e5,
|
|
1911
|
+
success_threshold: 2,
|
|
1912
|
+
failure_rate_threshold: 0,
|
|
1913
|
+
min_requests: 5
|
|
1914
|
+
},
|
|
1915
|
+
timeout_guard: { default_timeout_ms: 3e4, fallback_action: "abort" },
|
|
1916
|
+
economy: {
|
|
1917
|
+
initial_balance: 5,
|
|
1918
|
+
default_spend_limit: 1,
|
|
1919
|
+
spend_limit_period: 36e5,
|
|
1920
|
+
max_transaction_history: 200,
|
|
1921
|
+
escrow_enabled: false
|
|
1922
|
+
},
|
|
1923
|
+
structured_logger: {
|
|
1924
|
+
min_level: "info",
|
|
1925
|
+
max_entries: 500,
|
|
1926
|
+
rotation_count: 100,
|
|
1927
|
+
emit_events: true,
|
|
1928
|
+
console_output: true
|
|
1929
|
+
}
|
|
1930
|
+
};
|
|
1931
|
+
}
|
|
1932
|
+
/**
|
|
1933
|
+
* Expand a `@safe_daemon { ... }` config into the five safety traits it
|
|
1934
|
+
* stands for (@rate_limiter + @circuit_breaker + @timeout_guard + @economy +
|
|
1935
|
+
* @structured_logger). Supports flat convenience overrides (budget / rate /
|
|
1936
|
+
* timeout_ms / …) and nested per-trait overrides (economy: { ... }).
|
|
1937
|
+
*/
|
|
1938
|
+
expandSafeDaemon(config) {
|
|
1939
|
+
const c = config && typeof config === "object" ? config : {};
|
|
1940
|
+
const out = _HoloScriptPlusParser.safeDaemonDefaults();
|
|
1941
|
+
const num = (v) => typeof v === "number";
|
|
1942
|
+
if (num(c.budget)) out.economy.initial_balance = c.budget;
|
|
1943
|
+
if (num(c.spend_limit)) out.economy.default_spend_limit = c.spend_limit;
|
|
1944
|
+
if (num(c.rate)) out.rate_limiter.refill_rate = c.rate;
|
|
1945
|
+
if (num(c.max_tokens)) out.rate_limiter.max_tokens = c.max_tokens;
|
|
1946
|
+
if (num(c.window_ms)) out.rate_limiter.window_ms = c.window_ms;
|
|
1947
|
+
if (num(c.failure_threshold)) out.circuit_breaker.failure_threshold = c.failure_threshold;
|
|
1948
|
+
if (num(c.reset_timeout_ms)) out.circuit_breaker.reset_timeout_ms = c.reset_timeout_ms;
|
|
1949
|
+
if (num(c.timeout_ms)) out.timeout_guard.default_timeout_ms = c.timeout_ms;
|
|
1950
|
+
if (typeof c.log_level === "string") out.structured_logger.min_level = c.log_level;
|
|
1951
|
+
for (const t of ["rate_limiter", "circuit_breaker", "timeout_guard", "economy", "structured_logger"]) {
|
|
1952
|
+
const override = c[t];
|
|
1953
|
+
if (override && typeof override === "object") Object.assign(out[t], override);
|
|
1954
|
+
}
|
|
1955
|
+
return Object.entries(out);
|
|
1956
|
+
}
|
|
1957
|
+
/**
|
|
1958
|
+
* Walk the parsed AST and expand every `@safe_daemon` into its five safety
|
|
1959
|
+
* traits, wherever traits are stored: a node's `traits` Map (composition /
|
|
1960
|
+
* world / object), a brain's `traits` Record, and any `directives` array.
|
|
1961
|
+
* Existing per-trait declarations are not overwritten.
|
|
1962
|
+
*/
|
|
1963
|
+
desugarSafeDaemon(root) {
|
|
1964
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1965
|
+
const visit = (node) => {
|
|
1966
|
+
if (!node || typeof node !== "object" || seen.has(node)) return;
|
|
1967
|
+
seen.add(node);
|
|
1968
|
+
const n = node;
|
|
1969
|
+
if (n.traits instanceof Map && n.traits.has("safe_daemon")) {
|
|
1970
|
+
const cfg = n.traits.get("safe_daemon");
|
|
1971
|
+
n.traits.delete("safe_daemon");
|
|
1972
|
+
for (const [name, c] of this.expandSafeDaemon(cfg)) {
|
|
1973
|
+
if (!n.traits.has(name)) n.traits.set(name, c);
|
|
1974
|
+
}
|
|
1975
|
+
this.hasVRTraits = true;
|
|
1976
|
+
}
|
|
1977
|
+
if (n.traits && !(n.traits instanceof Map) && typeof n.traits === "object") {
|
|
1978
|
+
const rec = n.traits;
|
|
1979
|
+
if ("safe_daemon" in rec) {
|
|
1980
|
+
const cfg = rec["safe_daemon"];
|
|
1981
|
+
delete rec["safe_daemon"];
|
|
1982
|
+
for (const [name, c] of this.expandSafeDaemon(cfg)) {
|
|
1983
|
+
if (!(name in rec)) rec[name] = c;
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
if (Array.isArray(n.directives)) {
|
|
1988
|
+
const dirs = n.directives;
|
|
1989
|
+
const idx = dirs.findIndex((d) => d && d.type === "trait" && d.name === "safe_daemon");
|
|
1990
|
+
if (idx >= 0) {
|
|
1991
|
+
const cfg = dirs[idx].config;
|
|
1992
|
+
const expanded = this.expandSafeDaemon(cfg).map(([name, c]) => ({ type: "trait", name, config: c }));
|
|
1993
|
+
const existing = new Set(dirs.map((d) => d.name));
|
|
1994
|
+
dirs.splice(idx, 1, ...expanded.filter((e) => !existing.has(e.name)));
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
for (const key of ["children", "body", "states"]) {
|
|
1998
|
+
const child = n[key];
|
|
1999
|
+
if (Array.isArray(child)) child.forEach(visit);
|
|
2000
|
+
}
|
|
2001
|
+
};
|
|
2002
|
+
visit(root);
|
|
2003
|
+
}
|
|
1866
2004
|
/**
|
|
1867
2005
|
* Performs an incremental parse using ChunkBasedIncrementalParser with
|
|
1868
2006
|
* AST-aware chunking, hash-based caching, and dependency tracking.
|
|
@@ -2036,28 +2174,48 @@ var HoloScriptPlusParser = class {
|
|
|
2036
2174
|
}
|
|
2037
2175
|
const isNodeStart = this.check("IDENTIFIER") || this.check("STATE_MACHINE") || this.check("STATE") || this.check("TRANSITION") || this.check("INITIAL");
|
|
2038
2176
|
if (isNodeStart) {
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
if (
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2177
|
+
if (this.check("IDENTIFIER") && this.current().value === "connect") {
|
|
2178
|
+
const connectNode = this.parseHsConnectStatement();
|
|
2179
|
+
topLevelNodes.push(connectNode);
|
|
2180
|
+
} else if (this.check("IDENTIFIER") && this.current().value === "execute") {
|
|
2181
|
+
const executeNode = this.parseHsExecuteStatement();
|
|
2182
|
+
topLevelNodes.push(executeNode);
|
|
2183
|
+
} else if (this.check("IDENTIFIER") && chunkYP5CHEYU_cjs.isBrainKeyword(this.current().value)) {
|
|
2184
|
+
const brainNode = this.parseBrainDeclaration();
|
|
2185
|
+
brainNode.directives = [
|
|
2186
|
+
...currentDirectives,
|
|
2187
|
+
...brainNode.directives || []
|
|
2188
|
+
];
|
|
2189
|
+
topLevelNodes.push(brainNode);
|
|
2190
|
+
} else {
|
|
2191
|
+
const node = this.parseNode();
|
|
2192
|
+
const existingDirectives = node.directives || [];
|
|
2193
|
+
node.directives = [...currentDirectives, ...existingDirectives];
|
|
2194
|
+
if (node.type === "template") {
|
|
2195
|
+
for (const d of currentDirectives) {
|
|
2196
|
+
if (d.type === "version") {
|
|
2197
|
+
node.version = d.version;
|
|
2198
|
+
} else if (d.type === "migrate") {
|
|
2199
|
+
if (!node.migrations) node.migrations = [];
|
|
2200
|
+
node.migrations.push({
|
|
2201
|
+
type: "Migration",
|
|
2202
|
+
fromVersion: d.fromVersion,
|
|
2203
|
+
body: d.body
|
|
2204
|
+
});
|
|
2205
|
+
}
|
|
2053
2206
|
}
|
|
2054
2207
|
}
|
|
2208
|
+
topLevelNodes.push(node);
|
|
2055
2209
|
}
|
|
2056
|
-
topLevelNodes.push(node);
|
|
2057
2210
|
} else {
|
|
2058
2211
|
if (currentDirectives.length > 0) {
|
|
2059
2212
|
if (this.check("EOF")) {
|
|
2060
2213
|
globalDirectives.push(...currentDirectives);
|
|
2214
|
+
} else if (this.check("LBRACE")) {
|
|
2215
|
+
const block = this.parseBlockContent();
|
|
2216
|
+
const last = currentDirectives[currentDirectives.length - 1];
|
|
2217
|
+
last.config = { ...last.config || {}, ...block };
|
|
2218
|
+
globalDirectives.push(...currentDirectives);
|
|
2061
2219
|
} else {
|
|
2062
2220
|
this.error(
|
|
2063
2221
|
`Expected node after directives, got ${this.current().type}. Valid nodes: orb, template, logic, object, world, composition, scene, group`,
|
|
@@ -2073,21 +2231,6 @@ var HoloScriptPlusParser = class {
|
|
|
2073
2231
|
throw new Error("ParseError");
|
|
2074
2232
|
}
|
|
2075
2233
|
}
|
|
2076
|
-
if (this.check("IDENTIFIER") && this.current().value === "connect") {
|
|
2077
|
-
const connection = this.parseConnectionStatement();
|
|
2078
|
-
const node = {
|
|
2079
|
-
type: "connection",
|
|
2080
|
-
properties: connection,
|
|
2081
|
-
directives: [],
|
|
2082
|
-
children: [],
|
|
2083
|
-
traits: /* @__PURE__ */ new Map(),
|
|
2084
|
-
loc: {
|
|
2085
|
-
start: { line: this.current().line, column: 0 },
|
|
2086
|
-
end: { line: this.current().line, column: 0 }
|
|
2087
|
-
}
|
|
2088
|
-
};
|
|
2089
|
-
topLevelNodes.push(node);
|
|
2090
|
-
}
|
|
2091
2234
|
} catch (e) {
|
|
2092
2235
|
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
2093
2236
|
if (errorMessage !== "ParseError" && errorMessage !== "Unexpected token") {
|
|
@@ -2127,7 +2270,12 @@ var HoloScriptPlusParser = class {
|
|
|
2127
2270
|
]) || this.expect("IDENTIFIER", "Expected element type");
|
|
2128
2271
|
const type = typeToken.value;
|
|
2129
2272
|
if (type === "template") {
|
|
2130
|
-
|
|
2273
|
+
let templateName;
|
|
2274
|
+
if (this.check("IDENTIFIER")) {
|
|
2275
|
+
templateName = this.advance().value;
|
|
2276
|
+
} else {
|
|
2277
|
+
templateName = this.expect("STRING", "Expected template name").value;
|
|
2278
|
+
}
|
|
2131
2279
|
const templateBody = this.parseBlockContent();
|
|
2132
2280
|
let version;
|
|
2133
2281
|
const migrations = [];
|
|
@@ -2189,6 +2337,20 @@ var HoloScriptPlusParser = class {
|
|
|
2189
2337
|
}
|
|
2190
2338
|
};
|
|
2191
2339
|
}
|
|
2340
|
+
if (type === "react") {
|
|
2341
|
+
return this.parseHsPlusReactBlock(startToken);
|
|
2342
|
+
}
|
|
2343
|
+
if (["transform", "filter", "branch", "validate"].includes(type)) {
|
|
2344
|
+
const savedPos = this.pos;
|
|
2345
|
+
let blockName = "anonymous";
|
|
2346
|
+
if (this.check("IDENTIFIER") || this.check("STRING")) {
|
|
2347
|
+
blockName = this.advance().value;
|
|
2348
|
+
}
|
|
2349
|
+
if (this.check("LBRACE")) {
|
|
2350
|
+
return this.parsePipelineBlock(type, blockName, startToken);
|
|
2351
|
+
}
|
|
2352
|
+
this.pos = savedPos;
|
|
2353
|
+
}
|
|
2192
2354
|
if ([
|
|
2193
2355
|
"module",
|
|
2194
2356
|
"script",
|
|
@@ -2242,6 +2404,9 @@ var HoloScriptPlusParser = class {
|
|
|
2242
2404
|
if (type === "assert" || startToken.type === "ASSERT") {
|
|
2243
2405
|
return this.parseAssertNode();
|
|
2244
2406
|
}
|
|
2407
|
+
if (type === "timeline") {
|
|
2408
|
+
return this.parseTimelineNode(startToken);
|
|
2409
|
+
}
|
|
2245
2410
|
if (type === "environment") {
|
|
2246
2411
|
const envBody = this.parseEnvironmentBlock();
|
|
2247
2412
|
return {
|
|
@@ -2326,6 +2491,7 @@ var HoloScriptPlusParser = class {
|
|
|
2326
2491
|
const children = [];
|
|
2327
2492
|
const directives = [];
|
|
2328
2493
|
const traits = /* @__PURE__ */ new Map();
|
|
2494
|
+
let ambiguousPreBodyTrait = null;
|
|
2329
2495
|
if (templateRef) {
|
|
2330
2496
|
properties.__templateRef = templateRef;
|
|
2331
2497
|
}
|
|
@@ -2345,6 +2511,9 @@ var HoloScriptPlusParser = class {
|
|
|
2345
2511
|
traits.set(directive.name, directive.config);
|
|
2346
2512
|
this.hasVRTraits = true;
|
|
2347
2513
|
directives.push(directive);
|
|
2514
|
+
if (this.blockConfigDirectives.has(directive) && this.traitConfigLooksLikeNodeBody(directive.config)) {
|
|
2515
|
+
ambiguousPreBodyTrait = directive;
|
|
2516
|
+
}
|
|
2348
2517
|
} else {
|
|
2349
2518
|
directives.push(directive);
|
|
2350
2519
|
}
|
|
@@ -2395,6 +2564,13 @@ var HoloScriptPlusParser = class {
|
|
|
2395
2564
|
this.synchronizeProperty();
|
|
2396
2565
|
}
|
|
2397
2566
|
}
|
|
2567
|
+
if (!this.check("LBRACE") && ambiguousPreBodyTrait) {
|
|
2568
|
+
this.errorAt(
|
|
2569
|
+
this.blockConfigDirectiveLocations.get(ambiguousPreBodyTrait) || startToken,
|
|
2570
|
+
`Trait @${ambiguousPreBodyTrait.name} used a block that looks like an object body, but no object body follows. Use @${ambiguousPreBodyTrait.name}(...) for trait config, or add a separate { ... } object body.`,
|
|
2571
|
+
"HSP101"
|
|
2572
|
+
);
|
|
2573
|
+
}
|
|
2398
2574
|
if (this.check("LBRACE")) {
|
|
2399
2575
|
this.advance();
|
|
2400
2576
|
this.skipNewlines();
|
|
@@ -2439,7 +2615,7 @@ var HoloScriptPlusParser = class {
|
|
|
2439
2615
|
properties[key] = spreadNode;
|
|
2440
2616
|
} else {
|
|
2441
2617
|
const token = this.current();
|
|
2442
|
-
const isKeyToken = token.type === "IDENTIFIER" || token.type === "STRING" || token.type === "HASH" || token.type === "STATE" || token.type === "STATE_MACHINE" || token.type === "INITIAL" || token.type === "ON_ENTRY" || token.type === "ON_EXIT" || token.type === "TRANSITION";
|
|
2618
|
+
const isKeyToken = token.type === "IDENTIFIER" || token.type === "STRING" || token.type === "HASH" || token.type === "STATE" || token.type === "STATE_MACHINE" || token.type === "INITIAL" || token.type === "ON_ENTRY" || token.type === "ON_EXIT" || token.type === "ON_ERROR" || token.type === "TRANSITION";
|
|
2443
2619
|
if (isKeyToken) {
|
|
2444
2620
|
const saved = this.pos;
|
|
2445
2621
|
const name = this.advance().value;
|
|
@@ -2471,7 +2647,9 @@ var HoloScriptPlusParser = class {
|
|
|
2471
2647
|
"on_entry",
|
|
2472
2648
|
"on_exit",
|
|
2473
2649
|
"page",
|
|
2474
|
-
"include"
|
|
2650
|
+
"include",
|
|
2651
|
+
"brain",
|
|
2652
|
+
"react"
|
|
2475
2653
|
];
|
|
2476
2654
|
if (name === "transition" && this.check("STRING")) {
|
|
2477
2655
|
const event = this.advance().value;
|
|
@@ -2550,7 +2728,12 @@ var HoloScriptPlusParser = class {
|
|
|
2550
2728
|
}
|
|
2551
2729
|
if (this.check("COLON") || this.check("EQUALS")) {
|
|
2552
2730
|
this.advance();
|
|
2553
|
-
|
|
2731
|
+
const pipeNext = this.peek(1);
|
|
2732
|
+
if (this.check("PIPE") && (!pipeNext || pipeNext.type === "NEWLINE" || pipeNext.type === "EOF")) {
|
|
2733
|
+
properties[name] = this.parseBlockScalar(this.tokens[saved]);
|
|
2734
|
+
} else {
|
|
2735
|
+
properties[name] = this.parseValue();
|
|
2736
|
+
}
|
|
2554
2737
|
} else if (childNodeKeywords.includes(name) && (this.check("LBRACE") || this.check("STRING"))) {
|
|
2555
2738
|
this.pos = saved;
|
|
2556
2739
|
children.push(this.parseNode());
|
|
@@ -2607,15 +2790,24 @@ var HoloScriptPlusParser = class {
|
|
|
2607
2790
|
const isKeyword = ["STATE_MACHINE", "STATE", "ON_ENTRY", "ON_EXIT", "TRANSITION"].includes(
|
|
2608
2791
|
nameToken.type
|
|
2609
2792
|
);
|
|
2610
|
-
|
|
2793
|
+
let name;
|
|
2794
|
+
if (nameToken.type === "IDENTIFIER" || isKeyword) {
|
|
2795
|
+
this.advance();
|
|
2796
|
+
name = nameToken.value;
|
|
2797
|
+
} else if (nameToken.type === "NUMBER" && /^\d+[a-zA-Z]\w*$/.test(nameToken.value)) {
|
|
2798
|
+
this.advance();
|
|
2799
|
+
name = nameToken.value;
|
|
2800
|
+
const next = this.current();
|
|
2801
|
+
if (next.type === "IDENTIFIER" && next.line === nameToken.line && next.column === nameToken.column + nameToken.value.length) {
|
|
2802
|
+
name += this.advance().value;
|
|
2803
|
+
}
|
|
2804
|
+
} else {
|
|
2611
2805
|
this.error(
|
|
2612
2806
|
`Expected directive name, got ${nameToken.type}. Directives start with @ followed by name (e.g., @grabbable)`,
|
|
2613
2807
|
"HSP201"
|
|
2614
2808
|
);
|
|
2615
2809
|
return null;
|
|
2616
2810
|
}
|
|
2617
|
-
this.advance();
|
|
2618
|
-
const name = nameToken.value;
|
|
2619
2811
|
if (name === "version") {
|
|
2620
2812
|
this.expect("LPAREN", "Expected ( after @version");
|
|
2621
2813
|
const versionToken = this.expect("NUMBER", "Expected version number");
|
|
@@ -2635,20 +2827,149 @@ var HoloScriptPlusParser = class {
|
|
|
2635
2827
|
const body = this.check("LBRACE") ? this.parseCodeBlock() : "";
|
|
2636
2828
|
return { type: "migrate", fromVersion, body };
|
|
2637
2829
|
}
|
|
2638
|
-
if (
|
|
2830
|
+
if (name === "quest") {
|
|
2831
|
+
const config2 = this.check("LBRACE") ? this.parseBlockContent() : this.check("LPAREN") ? this.parseTraitConfig() : {};
|
|
2832
|
+
return { type: "quest", ...config2 };
|
|
2833
|
+
}
|
|
2834
|
+
if (name === "faction") {
|
|
2835
|
+
const config2 = this.check("LBRACE") ? this.parseBlockContent() : this.check("LPAREN") ? this.parseTraitConfig() : {};
|
|
2836
|
+
return { type: "faction", ...config2 };
|
|
2837
|
+
}
|
|
2838
|
+
if (name === "loot") {
|
|
2839
|
+
const config2 = this.check("LBRACE") ? this.parseBlockContent() : this.check("LPAREN") ? this.parseTraitConfig() : {};
|
|
2840
|
+
return { type: "loot", ...config2 };
|
|
2841
|
+
}
|
|
2842
|
+
if (name === "ability") {
|
|
2843
|
+
const config2 = this.check("LBRACE") ? this.parseBlockContent() : this.check("LPAREN") ? this.parseTraitConfig() : {};
|
|
2844
|
+
return { type: "ability", ...config2 };
|
|
2845
|
+
}
|
|
2846
|
+
if (name === "authority") {
|
|
2847
|
+
const config2 = this.check("LBRACE") ? this.parseBlockContent() : this.check("LPAREN") ? this.parseTraitConfig() : {};
|
|
2848
|
+
return { type: "authority", ...config2 };
|
|
2849
|
+
}
|
|
2850
|
+
if (name === "wallet_gated") {
|
|
2851
|
+
const config2 = this.check("LBRACE") ? this.parseBlockContent() : this.check("LPAREN") ? this.parseTraitConfig() : {};
|
|
2852
|
+
return { type: "wallet_gated", ...config2 };
|
|
2853
|
+
}
|
|
2854
|
+
if (name === "world_chunk") {
|
|
2855
|
+
const config2 = this.check("LBRACE") ? this.parseBlockContent() : this.check("LPAREN") ? this.parseTraitConfig() : {};
|
|
2856
|
+
return { type: "world_chunk", ...config2 };
|
|
2857
|
+
}
|
|
2858
|
+
if (name === "personality") {
|
|
2859
|
+
let value;
|
|
2860
|
+
if (this.check("IDENTIFIER")) {
|
|
2861
|
+
value = this.advance().value;
|
|
2862
|
+
} else if (this.check("STRING")) {
|
|
2863
|
+
value = this.advance().value;
|
|
2864
|
+
} else {
|
|
2865
|
+
value = "neutral";
|
|
2866
|
+
}
|
|
2867
|
+
return { type: "personality", value };
|
|
2868
|
+
}
|
|
2869
|
+
if (name === "faction_alignment") {
|
|
2870
|
+
let value;
|
|
2871
|
+
if (this.check("IDENTIFIER")) {
|
|
2872
|
+
value = this.advance().value;
|
|
2873
|
+
if (this.check("IDENTIFIER")) {
|
|
2874
|
+
value += "_" + this.advance().value;
|
|
2875
|
+
}
|
|
2876
|
+
} else if (this.check("STRING")) {
|
|
2877
|
+
value = this.advance().value;
|
|
2878
|
+
} else {
|
|
2879
|
+
value = "true_neutral";
|
|
2880
|
+
}
|
|
2881
|
+
return { type: "faction_alignment", value };
|
|
2882
|
+
}
|
|
2883
|
+
if (name === "memory_persistence") {
|
|
2884
|
+
let value = true;
|
|
2885
|
+
if (this.check("BOOLEAN")) {
|
|
2886
|
+
value = this.advance().value === "true";
|
|
2887
|
+
} else if (this.check("IDENTIFIER")) {
|
|
2888
|
+
const raw = this.advance().value;
|
|
2889
|
+
value = raw !== "false";
|
|
2890
|
+
}
|
|
2891
|
+
return { type: "memory_persistence", value };
|
|
2892
|
+
}
|
|
2893
|
+
if (name === "preferred_ability") {
|
|
2894
|
+
let abilityName;
|
|
2895
|
+
if (this.check("STRING")) {
|
|
2896
|
+
abilityName = this.advance().value;
|
|
2897
|
+
} else if (this.check("IDENTIFIER")) {
|
|
2898
|
+
abilityName = this.advance().value;
|
|
2899
|
+
} else {
|
|
2900
|
+
abilityName = "";
|
|
2901
|
+
}
|
|
2902
|
+
let when;
|
|
2903
|
+
if (this.check("AT")) {
|
|
2904
|
+
const saved = this.pos;
|
|
2905
|
+
this.advance();
|
|
2906
|
+
if (this.check("IDENTIFIER") && this.current().value === "when") {
|
|
2907
|
+
this.advance();
|
|
2908
|
+
if (this.check("LBRACE")) {
|
|
2909
|
+
when = this.parseCodeBlock();
|
|
2910
|
+
}
|
|
2911
|
+
} else {
|
|
2912
|
+
this.pos = saved;
|
|
2913
|
+
}
|
|
2914
|
+
}
|
|
2915
|
+
return { type: "preferred_ability", ability: abilityName, when };
|
|
2916
|
+
}
|
|
2917
|
+
if (name === "flee_threshold") {
|
|
2918
|
+
let value = 0.25;
|
|
2919
|
+
if (this.check("NUMBER")) {
|
|
2920
|
+
value = parseFloat(this.advance().value);
|
|
2921
|
+
}
|
|
2922
|
+
return { type: "flee_threshold", value };
|
|
2923
|
+
}
|
|
2924
|
+
if (name === "patrol_speed") {
|
|
2925
|
+
let value = 1;
|
|
2926
|
+
if (this.check("NUMBER")) {
|
|
2927
|
+
value = parseFloat(this.advance().value);
|
|
2928
|
+
} else if (this.check("IDENTIFIER")) {
|
|
2929
|
+
value = this.advance().value;
|
|
2930
|
+
}
|
|
2931
|
+
return { type: "patrol_speed", value };
|
|
2932
|
+
}
|
|
2933
|
+
if (name === "waypoints") {
|
|
2934
|
+
let points = [];
|
|
2935
|
+
if (this.check("LBRACKET")) {
|
|
2936
|
+
points = this.parseValue();
|
|
2937
|
+
} else if (this.check("LBRACE")) {
|
|
2938
|
+
points = this.parseBlockContent();
|
|
2939
|
+
}
|
|
2940
|
+
return { type: "waypoints", points };
|
|
2941
|
+
}
|
|
2942
|
+
if (chunkEI3J6LTW_cjs.VR_TRAITS.includes(name)) {
|
|
2639
2943
|
if (!this.options.enableVRTraits) {
|
|
2640
2944
|
this.warn(`VR trait @${name} is disabled`);
|
|
2641
2945
|
return null;
|
|
2642
2946
|
}
|
|
2643
2947
|
let config2 = {};
|
|
2948
|
+
let configStyle2 = "none";
|
|
2644
2949
|
if (this.check("LPAREN")) {
|
|
2950
|
+
configStyle2 = "paren";
|
|
2645
2951
|
config2 = this.parseTraitConfig();
|
|
2646
2952
|
} else if (this.check("LBRACE")) {
|
|
2953
|
+
configStyle2 = "block";
|
|
2647
2954
|
config2 = this.parseBlockContent();
|
|
2955
|
+
} else if (this.check("COLON")) {
|
|
2956
|
+
configStyle2 = "colon";
|
|
2957
|
+
this.advance();
|
|
2958
|
+
if (this.check("LPAREN")) {
|
|
2959
|
+
config2 = this.parseTraitConfig();
|
|
2960
|
+
} else if (this.check("LBRACE")) {
|
|
2961
|
+
config2 = this.parseBlockContent();
|
|
2962
|
+
} else {
|
|
2963
|
+
config2 = { value: this.parseValue() };
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
const directive2 = { type: "trait", name, config: config2 };
|
|
2967
|
+
if (configStyle2 === "block") {
|
|
2968
|
+
this.markBlockConfigDirective(directive2, nameToken);
|
|
2648
2969
|
}
|
|
2649
|
-
return this.parseTraitSumTail(
|
|
2970
|
+
return this.parseTraitSumTail(directive2);
|
|
2650
2971
|
}
|
|
2651
|
-
if (
|
|
2972
|
+
if (chunkOMNHTCS4_cjs.LIFECYCLE_HOOKS.includes(name)) {
|
|
2652
2973
|
const params = [];
|
|
2653
2974
|
if (this.check("LPAREN")) {
|
|
2654
2975
|
this.advance();
|
|
@@ -2753,15 +3074,22 @@ var HoloScriptPlusParser = class {
|
|
|
2753
3074
|
this.warn("Expected 'from' after named import specifiers");
|
|
2754
3075
|
}
|
|
2755
3076
|
}
|
|
3077
|
+
let wildcardAlias;
|
|
2756
3078
|
if (this.check("ASTERISK") || this.check("IDENTIFIER") && this.current().value === "*") {
|
|
2757
3079
|
this.advance();
|
|
2758
3080
|
isWildcard = true;
|
|
2759
3081
|
if (this.check("IDENTIFIER") && this.current().value === "as") {
|
|
2760
3082
|
this.advance();
|
|
3083
|
+
if (this.check("IDENTIFIER") && this.current().value !== "from") {
|
|
3084
|
+
wildcardAlias = this.advance().value;
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
3087
|
+
if (this.check("IDENTIFIER") && this.current().value === "from") {
|
|
3088
|
+
this.advance();
|
|
2761
3089
|
}
|
|
2762
3090
|
}
|
|
2763
3091
|
const path = this.expect("STRING", "Expected import path string").value;
|
|
2764
|
-
let alias = path.split("/").pop()?.replace(/\.[^.]+$/, "") || "import";
|
|
3092
|
+
let alias = wildcardAlias || path.split("/").pop()?.replace(/\.[^.]+$/, "") || "import";
|
|
2765
3093
|
if (!namedImports && this.check("IDENTIFIER") && this.current().value === "as") {
|
|
2766
3094
|
this.advance();
|
|
2767
3095
|
alias = this.expect("IDENTIFIER", "Expected alias after as").value;
|
|
@@ -2957,7 +3285,7 @@ var HoloScriptPlusParser = class {
|
|
|
2957
3285
|
return { type: "hololand_event", event: eventName, params };
|
|
2958
3286
|
}
|
|
2959
3287
|
}
|
|
2960
|
-
if (
|
|
3288
|
+
if (chunkOMNHTCS4_cjs.STRUCTURAL_DIRECTIVES.includes(name)) {
|
|
2961
3289
|
let nodeName;
|
|
2962
3290
|
if (this.check("STRING")) {
|
|
2963
3291
|
nodeName = this.advance().value;
|
|
@@ -2971,9 +3299,12 @@ var HoloScriptPlusParser = class {
|
|
|
2971
3299
|
this.warn(`Unknown directive @${name}`);
|
|
2972
3300
|
}
|
|
2973
3301
|
let config = {};
|
|
3302
|
+
let configStyle = "none";
|
|
2974
3303
|
if (this.check("LPAREN")) {
|
|
3304
|
+
configStyle = "paren";
|
|
2975
3305
|
config = this.parseTraitConfig();
|
|
2976
3306
|
} else if (this.check("LBRACE")) {
|
|
3307
|
+
configStyle = "block";
|
|
2977
3308
|
config = this.parseBlockContent();
|
|
2978
3309
|
}
|
|
2979
3310
|
if (this.check("COLON")) {
|
|
@@ -2984,7 +3315,32 @@ var HoloScriptPlusParser = class {
|
|
|
2984
3315
|
config.body = this.parseCodeBlock();
|
|
2985
3316
|
}
|
|
2986
3317
|
}
|
|
2987
|
-
|
|
3318
|
+
const directive = { type: "trait", name, config };
|
|
3319
|
+
if (configStyle === "block") {
|
|
3320
|
+
this.markBlockConfigDirective(directive, nameToken);
|
|
3321
|
+
}
|
|
3322
|
+
return this.parseTraitSumTail(directive);
|
|
3323
|
+
}
|
|
3324
|
+
markBlockConfigDirective(directive, token) {
|
|
3325
|
+
this.blockConfigDirectives.add(directive);
|
|
3326
|
+
this.blockConfigDirectiveLocations.set(directive, token);
|
|
3327
|
+
}
|
|
3328
|
+
traitConfigLooksLikeNodeBody(config) {
|
|
3329
|
+
if (!config || typeof config !== "object") return false;
|
|
3330
|
+
const nodeBodyKeys = /* @__PURE__ */ new Set([
|
|
3331
|
+
"geometry",
|
|
3332
|
+
"position",
|
|
3333
|
+
"rotation",
|
|
3334
|
+
"scale",
|
|
3335
|
+
"size",
|
|
3336
|
+
"color",
|
|
3337
|
+
"material",
|
|
3338
|
+
"model",
|
|
3339
|
+
"mesh",
|
|
3340
|
+
"src",
|
|
3341
|
+
"url"
|
|
3342
|
+
]);
|
|
3343
|
+
return Object.keys(config).some((key) => nodeBodyKeys.has(key));
|
|
2988
3344
|
}
|
|
2989
3345
|
parseTraitSumTail(first) {
|
|
2990
3346
|
if (!this.check("PLUS")) {
|
|
@@ -3023,95 +3379,962 @@ var HoloScriptPlusParser = class {
|
|
|
3023
3379
|
this.expect("RPAREN", "Expected )");
|
|
3024
3380
|
return value;
|
|
3025
3381
|
}
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
this.expect("IDENTIFIER", "Expected to");
|
|
3030
|
-
const to = this.expect("IDENTIFIER", "Expected to name").value;
|
|
3031
|
-
return { from, to };
|
|
3032
|
-
}
|
|
3382
|
+
// ===========================================================================
|
|
3383
|
+
// Brain Declaration Parsing
|
|
3384
|
+
// ===========================================================================
|
|
3033
3385
|
/**
|
|
3034
|
-
* Parse
|
|
3386
|
+
* Parse a top-level `brain` declaration.
|
|
3387
|
+
*
|
|
3388
|
+
* Grammar:
|
|
3389
|
+
* brain <Name> [ : @<brainType> ] {
|
|
3390
|
+
* @personality <value>
|
|
3391
|
+
* @faction_alignment <value>
|
|
3392
|
+
* @memory_persistence true|false
|
|
3393
|
+
* @preferred_ability "<Name>" [ @when { <expr> } ]
|
|
3394
|
+
* @flee_threshold <number>
|
|
3395
|
+
* @patrol_speed <number|identifier>
|
|
3396
|
+
* @waypoints [...]
|
|
3397
|
+
* state <stateName> {
|
|
3398
|
+
* transition to <target> [ @when { <expr> } ]
|
|
3399
|
+
* <action statements ...>
|
|
3400
|
+
* }
|
|
3401
|
+
* }
|
|
3035
3402
|
*/
|
|
3036
|
-
|
|
3037
|
-
|
|
3403
|
+
parseBrainDeclaration() {
|
|
3404
|
+
this.advance();
|
|
3405
|
+
const name = this.check("IDENTIFIER") ? this.advance().value : "unnamed_brain";
|
|
3406
|
+
let brainType = "behavior_tree";
|
|
3407
|
+
if (this.check("COLON")) {
|
|
3408
|
+
this.advance();
|
|
3409
|
+
if (this.check("AT")) {
|
|
3410
|
+
this.advance();
|
|
3411
|
+
if (this.check("IDENTIFIER")) {
|
|
3412
|
+
const raw = this.advance().value;
|
|
3413
|
+
if (raw === "behavior_tree" || raw === "decision_tree" || raw === "neural" || raw === "scripted") {
|
|
3414
|
+
brainType = raw;
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
3417
|
+
}
|
|
3418
|
+
}
|
|
3419
|
+
const brain = {
|
|
3420
|
+
type: "brain",
|
|
3421
|
+
name,
|
|
3422
|
+
brainType,
|
|
3423
|
+
states: [],
|
|
3424
|
+
traits: {}
|
|
3425
|
+
};
|
|
3038
3426
|
if (!this.check("LBRACE")) {
|
|
3039
|
-
|
|
3427
|
+
this.warn(`brain "${name}" missing body block { }`);
|
|
3428
|
+
return brain;
|
|
3040
3429
|
}
|
|
3041
3430
|
this.advance();
|
|
3042
3431
|
this.skipNewlines();
|
|
3043
3432
|
while (!this.check("RBRACE") && !this.check("EOF")) {
|
|
3044
3433
|
this.skipNewlines();
|
|
3045
3434
|
if (this.check("RBRACE") || this.check("EOF")) break;
|
|
3046
|
-
this.
|
|
3047
|
-
if (this.check("RBRACE") || this.check("EOF")) break;
|
|
3048
|
-
const token = this.current();
|
|
3049
|
-
const isKeyToken = token.type === "IDENTIFIER" || token.type === "STRING" || token.type === "STATE" || token.type === "STATE_MACHINE" || token.type === "INITIAL" || token.type === "ON_ENTRY" || token.type === "ON_EXIT" || token.type === "TRANSITION";
|
|
3050
|
-
if (isKeyToken) {
|
|
3051
|
-
const next = this.peek(1);
|
|
3052
|
-
if (next.type === "COLON" || next.type === "EQUALS") {
|
|
3053
|
-
const key = this.advance().value;
|
|
3054
|
-
this.advance();
|
|
3055
|
-
content[key] = this.parseValue();
|
|
3056
|
-
} else if (next.type === "STRING" || next.type === "LBRACE" || next.type === "IDENTIFIER") {
|
|
3057
|
-
const node = this.parseNode();
|
|
3058
|
-
const type = node.type;
|
|
3059
|
-
const name = node.name || `unnamed_${type}_${Object.keys(content).length}`;
|
|
3060
|
-
content[name] = node;
|
|
3061
|
-
} else {
|
|
3062
|
-
const key = this.advance().value;
|
|
3063
|
-
content[key] = true;
|
|
3064
|
-
}
|
|
3065
|
-
} else if (this.check("SPREAD")) {
|
|
3435
|
+
if (this.check("AT")) {
|
|
3066
3436
|
this.advance();
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
} else if (this.check("AT")) {
|
|
3071
|
-
const directive = this.parseDirective();
|
|
3072
|
-
if (directive) {
|
|
3073
|
-
const dirKey = ("name" in directive ? directive.name : void 0) || directive.type;
|
|
3074
|
-
content[`@${dirKey}`] = directive;
|
|
3437
|
+
if (!this.check("IDENTIFIER")) {
|
|
3438
|
+
this.warn("Expected directive name after @");
|
|
3439
|
+
continue;
|
|
3075
3440
|
}
|
|
3076
|
-
|
|
3077
|
-
|
|
3441
|
+
const dirName = this.advance().value;
|
|
3442
|
+
if (dirName === "personality") {
|
|
3443
|
+
const val = this.check("IDENTIFIER") ? this.advance().value : this.check("STRING") ? this.advance().value : "neutral";
|
|
3444
|
+
brain.personality = val;
|
|
3445
|
+
} else if (dirName === "faction_alignment") {
|
|
3446
|
+
let val = this.check("IDENTIFIER") ? this.advance().value : this.check("STRING") ? this.advance().value : "true_neutral";
|
|
3447
|
+
if (this.check("IDENTIFIER")) val += "_" + this.advance().value;
|
|
3448
|
+
brain.factionAlignment = val;
|
|
3449
|
+
} else if (dirName === "memory_persistence") {
|
|
3450
|
+
const raw = this.check("BOOLEAN") ? this.advance().value : this.check("IDENTIFIER") ? this.advance().value : "true";
|
|
3451
|
+
brain.memoryPersistence = raw !== "false";
|
|
3452
|
+
} else if (dirName === "preferred_ability") {
|
|
3453
|
+
const abilityName = this.check("STRING") ? this.advance().value : this.check("IDENTIFIER") ? this.advance().value : "";
|
|
3454
|
+
let when;
|
|
3455
|
+
if (this.check("AT")) {
|
|
3456
|
+
const saved = this.pos;
|
|
3457
|
+
this.advance();
|
|
3458
|
+
if (this.check("IDENTIFIER") && this.current().value === "when") {
|
|
3459
|
+
this.advance();
|
|
3460
|
+
if (this.check("LBRACE")) when = this.parseCodeBlock();
|
|
3461
|
+
} else {
|
|
3462
|
+
this.pos = saved;
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
brain.preferredAbility = { name: abilityName, when };
|
|
3466
|
+
} else if (dirName === "flee_threshold") {
|
|
3467
|
+
brain.fleeThreshold = this.check("NUMBER") ? parseFloat(this.advance().value) : 0.25;
|
|
3468
|
+
} else if (dirName === "patrol_speed") {
|
|
3469
|
+
brain.patrolSpeed = this.check("NUMBER") ? parseFloat(this.advance().value) : this.check("IDENTIFIER") ? this.advance().value : 1;
|
|
3470
|
+
} else if (dirName === "waypoints") {
|
|
3471
|
+
brain.waypoints = this.check("LBRACKET") ? this.parseValue() : [];
|
|
3472
|
+
} else if (dirName === "goal") {
|
|
3473
|
+
const cfg = this.check("LBRACE") ? this.parseBlockContent() : {};
|
|
3474
|
+
if (!brain.goals) brain.goals = [];
|
|
3475
|
+
brain.goals.push({
|
|
3476
|
+
name: typeof cfg.name === "string" ? cfg.name : String(cfg.name ?? `goal_${brain.goals.length}`),
|
|
3477
|
+
desiredState: cfg.desiredState && typeof cfg.desiredState === "object" ? cfg.desiredState : void 0,
|
|
3478
|
+
priority: typeof cfg.priority === "number" ? cfg.priority : void 0
|
|
3479
|
+
});
|
|
3480
|
+
} else if (dirName === "escalation") {
|
|
3481
|
+
const cfg = this.check("LBRACE") ? this.parseBlockContent() : {};
|
|
3482
|
+
if (!brain.escalations) brain.escalations = [];
|
|
3483
|
+
brain.escalations.push({
|
|
3484
|
+
on: typeof cfg.on === "string" ? cfg.on : String(cfg.on ?? ""),
|
|
3485
|
+
action: typeof cfg.action === "string" ? cfg.action : "notify"
|
|
3486
|
+
});
|
|
3487
|
+
} else if (dirName === "provider_policy") {
|
|
3488
|
+
const cfg = this.check("LBRACE") ? this.parseBlockContent() : {};
|
|
3489
|
+
brain.providerPolicy = {
|
|
3490
|
+
prefer: typeof cfg.prefer === "string" ? cfg.prefer : void 0,
|
|
3491
|
+
fallback: typeof cfg.fallback === "string" ? cfg.fallback : void 0,
|
|
3492
|
+
requires: typeof cfg.requires === "string" ? cfg.requires : void 0
|
|
3493
|
+
};
|
|
3494
|
+
} else if (dirName === "frame_declaration") {
|
|
3495
|
+
const cfg = this.check("LBRACE") ? this.parseBlockContent() : {};
|
|
3496
|
+
brain.frameDeclaration = coerceConfig(cfg);
|
|
3497
|
+
} else if (dirName === "behavior_tree") {
|
|
3498
|
+
const config = this.check("LBRACE") ? this.parseBlockContent() : {};
|
|
3499
|
+
brain.traits["behavior_tree"] = config;
|
|
3500
|
+
} else {
|
|
3501
|
+
const config = this.check("LBRACE") ? this.parseBlockContent() : this.check("LPAREN") ? this.parseTraitConfig() : {};
|
|
3502
|
+
brain.traits[dirName] = config;
|
|
3503
|
+
}
|
|
3504
|
+
this.skipNewlines();
|
|
3505
|
+
continue;
|
|
3506
|
+
}
|
|
3507
|
+
if (this.check("STATE") || this.check("IDENTIFIER") && this.current().value === "state") {
|
|
3078
3508
|
this.advance();
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3509
|
+
const stateName = this.check("IDENTIFIER") ? this.advance().value : "unnamed";
|
|
3510
|
+
const brainState = {
|
|
3511
|
+
name: stateName,
|
|
3512
|
+
transitions: [],
|
|
3513
|
+
actions: [],
|
|
3514
|
+
traits: {}
|
|
3515
|
+
};
|
|
3516
|
+
if (this.check("LBRACE")) {
|
|
3082
3517
|
this.advance();
|
|
3518
|
+
this.skipNewlines();
|
|
3519
|
+
while (!this.check("RBRACE") && !this.check("EOF")) {
|
|
3520
|
+
this.skipNewlines();
|
|
3521
|
+
if (this.check("RBRACE") || this.check("EOF")) break;
|
|
3522
|
+
if (this.check("TRANSITION") || this.check("IDENTIFIER") && this.current().value === "transition") {
|
|
3523
|
+
this.advance();
|
|
3524
|
+
let to = "";
|
|
3525
|
+
if (this.check("IDENTIFIER") && this.current().value === "to") {
|
|
3526
|
+
this.advance();
|
|
3527
|
+
}
|
|
3528
|
+
if (this.check("IDENTIFIER")) to = this.advance().value;
|
|
3529
|
+
else if (this.check("STRING")) to = this.advance().value;
|
|
3530
|
+
let when;
|
|
3531
|
+
if (this.check("AT")) {
|
|
3532
|
+
const saved = this.pos;
|
|
3533
|
+
this.advance();
|
|
3534
|
+
if (this.check("IDENTIFIER") && this.current().value === "when") {
|
|
3535
|
+
this.advance();
|
|
3536
|
+
if (this.check("LBRACE")) when = this.parseCodeBlock();
|
|
3537
|
+
} else {
|
|
3538
|
+
this.pos = saved;
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3541
|
+
brainState.transitions.push({ to, when });
|
|
3542
|
+
} else if (this.check("AT")) {
|
|
3543
|
+
this.advance();
|
|
3544
|
+
const innerDir = this.check("IDENTIFIER") ? this.advance().value : "";
|
|
3545
|
+
const config = this.check("LBRACE") ? this.parseBlockContent() : this.check("LPAREN") ? this.parseTraitConfig() : {};
|
|
3546
|
+
brainState.traits[innerDir] = config;
|
|
3547
|
+
} else if (this.check("IDENTIFIER") && chunkYP5CHEYU_cjs.isCognitiveVerb(this.current().value)) {
|
|
3548
|
+
const saved = this.pos;
|
|
3549
|
+
const verb = this.advance().value;
|
|
3550
|
+
if (this.check("LBRACE")) {
|
|
3551
|
+
const config = this.parseBlockContent();
|
|
3552
|
+
if (!brainState.cognitiveActions) brainState.cognitiveActions = [];
|
|
3553
|
+
brainState.cognitiveActions.push({ kind: "cognitive", verb, config });
|
|
3554
|
+
} else {
|
|
3555
|
+
this.pos = saved;
|
|
3556
|
+
const parts = [this.advance().value];
|
|
3557
|
+
while (!this.check("NEWLINE") && !this.check("EOF") && !this.check("RBRACE")) {
|
|
3558
|
+
parts.push(this.advance().value);
|
|
3559
|
+
}
|
|
3560
|
+
brainState.actions.push(parts.join(" "));
|
|
3561
|
+
}
|
|
3562
|
+
} else if (this.check("IDENTIFIER") && this.tokens[this.pos + 1]?.type === "LBRACE" && chunkYP5CHEYU_cjs.nearestCognitiveVerb(this.current().value)) {
|
|
3563
|
+
const typo = this.current().value;
|
|
3564
|
+
const suggestion = chunkYP5CHEYU_cjs.nearestCognitiveVerb(typo);
|
|
3565
|
+
this.warn(`Unknown cognitive verb '${typo}' \u2014 did you mean '${suggestion}'?`);
|
|
3566
|
+
this.advance();
|
|
3567
|
+
this.parseBlockContent();
|
|
3568
|
+
brainState.actions.push(typo);
|
|
3569
|
+
} else if (this.check("IDENTIFIER")) {
|
|
3570
|
+
const parts = [this.advance().value];
|
|
3571
|
+
while (!this.check("NEWLINE") && !this.check("EOF") && !this.check("RBRACE")) {
|
|
3572
|
+
parts.push(this.advance().value);
|
|
3573
|
+
}
|
|
3574
|
+
brainState.actions.push(parts.join(" "));
|
|
3575
|
+
} else {
|
|
3576
|
+
this.advance();
|
|
3577
|
+
}
|
|
3578
|
+
this.skipNewlines();
|
|
3579
|
+
}
|
|
3580
|
+
this.expect("RBRACE", "Expected } to close state block");
|
|
3083
3581
|
}
|
|
3084
|
-
|
|
3085
|
-
this.
|
|
3582
|
+
brain.states.push(brainState);
|
|
3583
|
+
this.skipNewlines();
|
|
3584
|
+
continue;
|
|
3585
|
+
}
|
|
3586
|
+
if (this.check("IDENTIFIER")) {
|
|
3587
|
+
const parts = [this.advance().value];
|
|
3588
|
+
while (!this.check("NEWLINE") && !this.check("EOF") && !this.check("RBRACE")) {
|
|
3589
|
+
parts.push(this.advance().value);
|
|
3590
|
+
}
|
|
3591
|
+
brain.traits["_actions"] = [
|
|
3592
|
+
...brain.traits["_actions"] || [],
|
|
3593
|
+
parts.join(" ")
|
|
3594
|
+
];
|
|
3086
3595
|
} else {
|
|
3087
3596
|
this.advance();
|
|
3088
3597
|
}
|
|
3089
|
-
if (this.check("COMMA")) this.advance();
|
|
3090
3598
|
this.skipNewlines();
|
|
3091
3599
|
}
|
|
3092
|
-
this.expect("RBRACE", "Expected }");
|
|
3093
|
-
return
|
|
3600
|
+
this.expect("RBRACE", "Expected } to close brain declaration");
|
|
3601
|
+
return brain;
|
|
3094
3602
|
}
|
|
3095
3603
|
/**
|
|
3096
|
-
* Parse
|
|
3604
|
+
* Parse a .hs `connect` statement.
|
|
3605
|
+
* Syntax (full .hs format):
|
|
3606
|
+
* connect <source> -> <target>
|
|
3607
|
+
* where <source> and <target> are dotted member chains, optionally followed
|
|
3608
|
+
* by assignment for state connections:
|
|
3609
|
+
* connect alarm_bell.alarm_triggered -> guard_captain.state.alert_level = 3
|
|
3610
|
+
*
|
|
3611
|
+
* Strategy: consume the `connect` keyword, then collect all tokens up to
|
|
3612
|
+
* (but not including) the next NEWLINE / EOF as a raw string. This is
|
|
3613
|
+
* intentionally permissive — the connect statement has a rich surface syntax
|
|
3614
|
+
* (dotted paths, ARROW, assignments) that the generic property parser cannot
|
|
3615
|
+
* handle. Semantic validation of the wiring is a separate compilation phase.
|
|
3097
3616
|
*/
|
|
3098
|
-
|
|
3099
|
-
const
|
|
3100
|
-
|
|
3101
|
-
|
|
3617
|
+
parseHsConnectStatement() {
|
|
3618
|
+
const startToken = this.current();
|
|
3619
|
+
this.advance();
|
|
3620
|
+
const toks = [];
|
|
3621
|
+
while (!this.check("NEWLINE") && !this.check("EOF")) {
|
|
3622
|
+
toks.push(this.advance());
|
|
3102
3623
|
}
|
|
3624
|
+
const arrowIdx = toks.findIndex((t) => t.type === "ARROW");
|
|
3625
|
+
const fromToks = arrowIdx >= 0 ? toks.slice(0, arrowIdx) : toks;
|
|
3626
|
+
const toToks = arrowIdx >= 0 ? toks.slice(arrowIdx + 1) : [];
|
|
3627
|
+
return {
|
|
3628
|
+
type: "connection",
|
|
3629
|
+
properties: {
|
|
3630
|
+
from: this.joinTokensSmart(fromToks),
|
|
3631
|
+
to: this.joinTokensSmart(toToks),
|
|
3632
|
+
raw: this.joinTokensSmart(toks)
|
|
3633
|
+
},
|
|
3634
|
+
directives: [],
|
|
3635
|
+
children: [],
|
|
3636
|
+
traits: /* @__PURE__ */ new Map(),
|
|
3637
|
+
loc: {
|
|
3638
|
+
start: { line: startToken.line, column: startToken.column },
|
|
3639
|
+
end: { line: this.current().line, column: this.current().column }
|
|
3640
|
+
}
|
|
3641
|
+
};
|
|
3642
|
+
}
|
|
3643
|
+
/**
|
|
3644
|
+
* Parse a .hs `execute` statement.
|
|
3645
|
+
* Syntax:
|
|
3646
|
+
* execute <target>(<args>) [repeat forever | every <interval>]
|
|
3647
|
+
* Examples:
|
|
3648
|
+
* execute guard_captain.patrol() repeat forever
|
|
3649
|
+
* execute temp_sensor_A.read() every 1000ms
|
|
3650
|
+
*
|
|
3651
|
+
* Strategy: consume `execute` then collect all tokens to end of line.
|
|
3652
|
+
* The target is the leading member chain plus one balanced call-paren
|
|
3653
|
+
* group; everything after it is the schedule clause.
|
|
3654
|
+
*/
|
|
3655
|
+
parseHsExecuteStatement() {
|
|
3656
|
+
const startToken = this.current();
|
|
3103
3657
|
this.advance();
|
|
3104
|
-
|
|
3105
|
-
while (!this.check("
|
|
3106
|
-
this.
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3658
|
+
const toks = [];
|
|
3659
|
+
while (!this.check("NEWLINE") && !this.check("EOF")) {
|
|
3660
|
+
toks.push(this.advance());
|
|
3661
|
+
}
|
|
3662
|
+
let end = toks.length;
|
|
3663
|
+
let depth = 0;
|
|
3664
|
+
for (let i = 0; i < toks.length; i++) {
|
|
3665
|
+
const t = toks[i];
|
|
3666
|
+
if (t.type === "LPAREN") {
|
|
3667
|
+
depth++;
|
|
3668
|
+
} else if (t.type === "RPAREN") {
|
|
3669
|
+
depth--;
|
|
3670
|
+
if (depth === 0) {
|
|
3671
|
+
end = i + 1;
|
|
3672
|
+
break;
|
|
3673
|
+
}
|
|
3674
|
+
} else if (depth === 0 && t.type !== "IDENTIFIER" && t.type !== "DOT" && t.type !== "NUMBER") {
|
|
3675
|
+
end = i;
|
|
3676
|
+
break;
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
const target = this.joinTokensSmart(toks.slice(0, end));
|
|
3680
|
+
const schedule = this.joinTokensSmart(toks.slice(end));
|
|
3681
|
+
return {
|
|
3682
|
+
type: "execute",
|
|
3683
|
+
properties: { target, schedule, raw: this.joinTokensSmart(toks) },
|
|
3684
|
+
directives: [],
|
|
3685
|
+
children: [],
|
|
3686
|
+
traits: /* @__PURE__ */ new Map(),
|
|
3687
|
+
loc: {
|
|
3688
|
+
start: { line: startToken.line, column: startToken.column },
|
|
3689
|
+
end: { line: this.current().line, column: this.current().column }
|
|
3690
|
+
}
|
|
3691
|
+
};
|
|
3692
|
+
}
|
|
3693
|
+
// ===========================================================================
|
|
3694
|
+
// Pipeline DSL block parsing (transform / filter / branch / validate)
|
|
3695
|
+
// ===========================================================================
|
|
3696
|
+
/**
|
|
3697
|
+
* Reassemble token values into readable source text: no spaces around
|
|
3698
|
+
* member/call/index punctuation, string literals re-quoted.
|
|
3699
|
+
*/
|
|
3700
|
+
joinTokensSmart(tokens) {
|
|
3701
|
+
const NO_SPACE_BEFORE = /* @__PURE__ */ new Set([
|
|
3702
|
+
"DOT",
|
|
3703
|
+
"COMMA",
|
|
3704
|
+
"LPAREN",
|
|
3705
|
+
"RPAREN",
|
|
3706
|
+
"LBRACKET",
|
|
3707
|
+
"RBRACKET",
|
|
3708
|
+
"OPTIONAL_DOT"
|
|
3709
|
+
]);
|
|
3710
|
+
const NO_SPACE_AFTER = /* @__PURE__ */ new Set(["DOT", "LPAREN", "LBRACKET", "OPTIONAL_DOT", "EXCLAMATION"]);
|
|
3711
|
+
let out = "";
|
|
3712
|
+
let prev = null;
|
|
3713
|
+
for (const t of tokens) {
|
|
3714
|
+
const text = t.type === "STRING" ? JSON.stringify(t.value) : t.value;
|
|
3715
|
+
if (prev && !NO_SPACE_BEFORE.has(t.type) && !NO_SPACE_AFTER.has(prev.type)) {
|
|
3716
|
+
out += " ";
|
|
3717
|
+
}
|
|
3718
|
+
out += text;
|
|
3719
|
+
prev = t;
|
|
3720
|
+
}
|
|
3721
|
+
return out;
|
|
3722
|
+
}
|
|
3723
|
+
/** Capture a dotted/indexed path: sku, a.b.c, results[0].id, entries[] */
|
|
3724
|
+
capturePipelinePath() {
|
|
3725
|
+
const toks = [];
|
|
3726
|
+
if (this.check("IDENTIFIER") || this.check("STRING") || this.check("UNDERSCORE")) {
|
|
3727
|
+
toks.push(this.advance());
|
|
3728
|
+
}
|
|
3729
|
+
for (; ; ) {
|
|
3730
|
+
if (this.check("DOT")) {
|
|
3731
|
+
toks.push(this.advance());
|
|
3732
|
+
if (this.check("IDENTIFIER") || this.check("NUMBER") || this.check("UNDERSCORE")) {
|
|
3733
|
+
toks.push(this.advance());
|
|
3734
|
+
}
|
|
3735
|
+
continue;
|
|
3736
|
+
}
|
|
3737
|
+
if (this.check("LBRACKET")) {
|
|
3738
|
+
let depth = 0;
|
|
3739
|
+
do {
|
|
3740
|
+
const t = this.advance();
|
|
3741
|
+
toks.push(t);
|
|
3742
|
+
if (t.type === "LBRACKET") depth++;
|
|
3743
|
+
else if (t.type === "RBRACKET") depth--;
|
|
3744
|
+
} while (depth > 0 && !this.check("EOF"));
|
|
3745
|
+
continue;
|
|
3746
|
+
}
|
|
3747
|
+
break;
|
|
3748
|
+
}
|
|
3749
|
+
return { raw: this.joinTokensSmart(toks), tokens: toks };
|
|
3750
|
+
}
|
|
3751
|
+
/** Capture a transform op call: trim() / multiply(100) / increment_if(a == b.c) */
|
|
3752
|
+
capturePipelineOp() {
|
|
3753
|
+
const toks = [];
|
|
3754
|
+
if (this.check("IDENTIFIER")) {
|
|
3755
|
+
toks.push(this.advance());
|
|
3756
|
+
}
|
|
3757
|
+
if (this.check("LPAREN")) {
|
|
3758
|
+
let depth = 0;
|
|
3759
|
+
do {
|
|
3760
|
+
const t = this.advance();
|
|
3761
|
+
toks.push(t);
|
|
3762
|
+
if (t.type === "LPAREN") depth++;
|
|
3763
|
+
else if (t.type === "RPAREN") depth--;
|
|
3764
|
+
} while (depth > 0 && !this.check("EOF"));
|
|
3765
|
+
}
|
|
3766
|
+
return this.joinTokensSmart(toks);
|
|
3767
|
+
}
|
|
3768
|
+
/** True when an ARROW appears before the end of the current statement line. */
|
|
3769
|
+
hasArrowBeforeEOL() {
|
|
3770
|
+
for (let look = this.pos; look < this.tokens.length; look++) {
|
|
3771
|
+
const t = this.tokens[look].type;
|
|
3772
|
+
if (t === "ARROW") return true;
|
|
3773
|
+
if (t === "NEWLINE" || t === "EOF" || t === "RBRACE" || t === "LBRACE") return false;
|
|
3774
|
+
}
|
|
3775
|
+
return false;
|
|
3776
|
+
}
|
|
3777
|
+
/**
|
|
3778
|
+
* Capture expression tokens to end of line, honoring `||` / `&&`
|
|
3779
|
+
* line continuations:
|
|
3780
|
+
* where: stock != previous.stock
|
|
3781
|
+
* || costCents != previous.costCents
|
|
3782
|
+
*/
|
|
3783
|
+
captureExpressionToEOL() {
|
|
3784
|
+
const toks = [];
|
|
3785
|
+
for (; ; ) {
|
|
3786
|
+
while (!this.check("NEWLINE") && !this.check("EOF") && !this.check("RBRACE")) {
|
|
3787
|
+
toks.push(this.advance());
|
|
3788
|
+
}
|
|
3789
|
+
if (this.check("NEWLINE")) {
|
|
3790
|
+
let look = this.pos;
|
|
3791
|
+
while (look < this.tokens.length && ["NEWLINE", "INDENT", "DEDENT"].includes(this.tokens[look].type)) {
|
|
3792
|
+
look++;
|
|
3793
|
+
}
|
|
3794
|
+
const next = this.tokens[look];
|
|
3795
|
+
if (next && (next.type === "OR" || next.type === "AND")) {
|
|
3796
|
+
this.pos = look;
|
|
3797
|
+
continue;
|
|
3798
|
+
}
|
|
3799
|
+
}
|
|
3800
|
+
break;
|
|
3801
|
+
}
|
|
3802
|
+
return toks;
|
|
3803
|
+
}
|
|
3804
|
+
/**
|
|
3805
|
+
* YAML-style block scalar property value:
|
|
3806
|
+
* prompt: |
|
|
3807
|
+
* Extract wisdom from this content.
|
|
3808
|
+
* Return JSON.
|
|
3809
|
+
* Captures the following lines from raw source while they are blank or
|
|
3810
|
+
* indented deeper than the key line, dedents, and skips their tokens.
|
|
3811
|
+
*/
|
|
3812
|
+
parseBlockScalar(keyToken) {
|
|
3813
|
+
this.advance();
|
|
3814
|
+
const keyIndent = keyToken.column - 1;
|
|
3815
|
+
const lines = this.source.split("\n");
|
|
3816
|
+
const collected = [];
|
|
3817
|
+
let lastLine = keyToken.line;
|
|
3818
|
+
for (let ln = keyToken.line + 1; ln <= lines.length; ln++) {
|
|
3819
|
+
const text = lines[ln - 1];
|
|
3820
|
+
if (text.trim() === "") {
|
|
3821
|
+
collected.push("");
|
|
3822
|
+
lastLine = ln;
|
|
3823
|
+
continue;
|
|
3824
|
+
}
|
|
3825
|
+
const indent = text.length - text.trimStart().length;
|
|
3826
|
+
if (indent <= keyIndent) break;
|
|
3827
|
+
collected.push(text);
|
|
3828
|
+
lastLine = ln;
|
|
3829
|
+
}
|
|
3830
|
+
while (!this.check("EOF") && this.current().line <= lastLine) {
|
|
3831
|
+
this.advance();
|
|
3832
|
+
}
|
|
3833
|
+
const nonBlank = collected.filter((l) => l.trim() !== "");
|
|
3834
|
+
const minIndent = nonBlank.length ? Math.min(...nonBlank.map((l) => l.length - l.trimStart().length)) : 0;
|
|
3835
|
+
return collected.map((l) => l.slice(minIndent)).join("\n").replace(/\s+$/, "");
|
|
3836
|
+
}
|
|
3837
|
+
/** Property value inside a pipeline DSL block. */
|
|
3838
|
+
parsePipelinePropertyValue(keyToken) {
|
|
3839
|
+
if (this.check("PIPE")) {
|
|
3840
|
+
const next = this.peek(1);
|
|
3841
|
+
if (!next || next.type === "NEWLINE" || next.type === "EOF") {
|
|
3842
|
+
return this.parseBlockScalar(keyToken);
|
|
3843
|
+
}
|
|
3844
|
+
}
|
|
3845
|
+
if (this.check("LBRACE") || this.check("LBRACKET")) {
|
|
3846
|
+
return this.parseValue();
|
|
3847
|
+
}
|
|
3848
|
+
const toks = this.captureExpressionToEOL();
|
|
3849
|
+
if (toks.length === 1) {
|
|
3850
|
+
const t = toks[0];
|
|
3851
|
+
if (t.type === "STRING") return t.value;
|
|
3852
|
+
if (t.type === "NUMBER") {
|
|
3853
|
+
const n = Number(t.value);
|
|
3854
|
+
return Number.isNaN(n) ? t.value : n;
|
|
3855
|
+
}
|
|
3856
|
+
if (t.value === "true") return true;
|
|
3857
|
+
if (t.value === "false") return false;
|
|
3858
|
+
return t.value;
|
|
3859
|
+
}
|
|
3860
|
+
return this.joinTokensSmart(toks);
|
|
3861
|
+
}
|
|
3862
|
+
/**
|
|
3863
|
+
* Body parser for pipeline DSL blocks. Handles, per statement:
|
|
3864
|
+
* key: value → property (incl. block scalars)
|
|
3865
|
+
* src.path[0] -> dst.path : op() : op2(...) → mapping child
|
|
3866
|
+
* when <cond> -> <target> → when child (branch)
|
|
3867
|
+
* default -> <target> → default child (branch)
|
|
3868
|
+
* field.path : rule, rule(...) → constraint child (validate /
|
|
3869
|
+
* dotted fields anywhere)
|
|
3870
|
+
* Statements are captured structurally with their raw text preserved;
|
|
3871
|
+
* semantic validation of the wiring is a separate compilation phase.
|
|
3872
|
+
*/
|
|
3873
|
+
parsePipelineBlock(kind, name, startToken) {
|
|
3874
|
+
this.expect("LBRACE", `Expected { after ${kind} ${name}`);
|
|
3875
|
+
const properties = {};
|
|
3876
|
+
const children = [];
|
|
3877
|
+
const directives = [];
|
|
3878
|
+
const traits = /* @__PURE__ */ new Map();
|
|
3879
|
+
const childLoc = (tok) => ({
|
|
3880
|
+
start: { line: tok.line, column: tok.column },
|
|
3881
|
+
end: { line: this.current().line, column: this.current().column }
|
|
3882
|
+
});
|
|
3883
|
+
while (!this.check("RBRACE") && !this.check("EOF")) {
|
|
3884
|
+
try {
|
|
3885
|
+
this.skipNewlines();
|
|
3886
|
+
if (this.check("RBRACE") || this.check("EOF")) break;
|
|
3887
|
+
if (this.check("AT")) {
|
|
3888
|
+
const directive = this.parseDirective();
|
|
3889
|
+
if (directive) {
|
|
3890
|
+
if (directive.type === "trait") {
|
|
3891
|
+
traits.set(directive.name, directive.config);
|
|
3892
|
+
this.hasVRTraits = true;
|
|
3893
|
+
}
|
|
3894
|
+
directives.push(directive);
|
|
3895
|
+
}
|
|
3896
|
+
} else if (kind === "branch" && this.check("IDENTIFIER") && this.current().value === "when") {
|
|
3897
|
+
const stmtStart = this.advance();
|
|
3898
|
+
const condToks = [];
|
|
3899
|
+
while (!this.check("ARROW") && !this.check("NEWLINE") && !this.check("EOF")) {
|
|
3900
|
+
condToks.push(this.advance());
|
|
3901
|
+
}
|
|
3902
|
+
let target = "";
|
|
3903
|
+
if (this.check("ARROW")) {
|
|
3904
|
+
this.advance();
|
|
3905
|
+
const targetToks = [];
|
|
3906
|
+
while (!this.check("NEWLINE") && !this.check("EOF") && !this.check("RBRACE")) {
|
|
3907
|
+
targetToks.push(this.advance());
|
|
3908
|
+
}
|
|
3909
|
+
target = this.joinTokensSmart(targetToks);
|
|
3910
|
+
}
|
|
3911
|
+
children.push({
|
|
3912
|
+
type: "when",
|
|
3913
|
+
condition: this.joinTokensSmart(condToks),
|
|
3914
|
+
target,
|
|
3915
|
+
loc: childLoc(stmtStart)
|
|
3916
|
+
});
|
|
3917
|
+
} else if (this.hasArrowBeforeEOL()) {
|
|
3918
|
+
const stmtStart = this.current();
|
|
3919
|
+
const lhsToks = [];
|
|
3920
|
+
while (!this.check("ARROW") && !this.check("NEWLINE") && !this.check("EOF")) {
|
|
3921
|
+
lhsToks.push(this.advance());
|
|
3922
|
+
}
|
|
3923
|
+
if (this.check("ARROW")) this.advance();
|
|
3924
|
+
const from = this.joinTokensSmart(lhsToks);
|
|
3925
|
+
if (kind === "branch") {
|
|
3926
|
+
const targetToks = [];
|
|
3927
|
+
while (!this.check("NEWLINE") && !this.check("EOF") && !this.check("RBRACE")) {
|
|
3928
|
+
targetToks.push(this.advance());
|
|
3929
|
+
}
|
|
3930
|
+
children.push({
|
|
3931
|
+
type: from === "default" ? "default" : "route",
|
|
3932
|
+
from,
|
|
3933
|
+
target: this.joinTokensSmart(targetToks),
|
|
3934
|
+
loc: childLoc(stmtStart)
|
|
3935
|
+
});
|
|
3936
|
+
} else {
|
|
3937
|
+
const to = this.capturePipelinePath();
|
|
3938
|
+
const ops = [];
|
|
3939
|
+
while (this.check("COLON")) {
|
|
3940
|
+
this.advance();
|
|
3941
|
+
ops.push(this.capturePipelineOp());
|
|
3942
|
+
}
|
|
3943
|
+
children.push({
|
|
3944
|
+
type: "mapping",
|
|
3945
|
+
from,
|
|
3946
|
+
to: to.raw,
|
|
3947
|
+
ops,
|
|
3948
|
+
loc: childLoc(stmtStart)
|
|
3949
|
+
});
|
|
3950
|
+
}
|
|
3951
|
+
} else if (this.check("IDENTIFIER") || this.check("STRING")) {
|
|
3952
|
+
const keyToken = this.current();
|
|
3953
|
+
const path = this.capturePipelinePath();
|
|
3954
|
+
if (this.check("COLON")) {
|
|
3955
|
+
this.advance();
|
|
3956
|
+
const pathIsDotted = path.tokens.some((t) => t.type === "DOT" || t.type === "LBRACKET");
|
|
3957
|
+
if (kind === "validate" || pathIsDotted) {
|
|
3958
|
+
const ruleToks = this.captureExpressionToEOL();
|
|
3959
|
+
children.push({
|
|
3960
|
+
type: "constraint",
|
|
3961
|
+
field: path.raw,
|
|
3962
|
+
rules: this.joinTokensSmart(ruleToks),
|
|
3963
|
+
loc: childLoc(keyToken)
|
|
3964
|
+
});
|
|
3965
|
+
} else {
|
|
3966
|
+
properties[path.raw] = this.parsePipelinePropertyValue(keyToken);
|
|
3967
|
+
}
|
|
3968
|
+
} else {
|
|
3969
|
+
properties[path.raw] = true;
|
|
3970
|
+
}
|
|
3971
|
+
} else if (this.check("COMMA")) {
|
|
3972
|
+
this.advance();
|
|
3973
|
+
} else {
|
|
3974
|
+
this.error(
|
|
3975
|
+
`Unexpected token ${this.current().type} "${this.current().value}" in ${kind} block`,
|
|
3976
|
+
"HSP001"
|
|
3977
|
+
);
|
|
3978
|
+
this.synchronizeProperty();
|
|
3979
|
+
}
|
|
3980
|
+
this.skipNewlines();
|
|
3981
|
+
} catch (e) {
|
|
3982
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
3983
|
+
if (errorMessage !== "ParseError") console.error(e);
|
|
3984
|
+
this.synchronizeProperty();
|
|
3985
|
+
}
|
|
3986
|
+
}
|
|
3987
|
+
this.expect("RBRACE", "Expected }");
|
|
3988
|
+
return {
|
|
3989
|
+
type: kind,
|
|
3990
|
+
name,
|
|
3991
|
+
id: name,
|
|
3992
|
+
properties,
|
|
3993
|
+
directives,
|
|
3994
|
+
children,
|
|
3995
|
+
traits,
|
|
3996
|
+
loc: {
|
|
3997
|
+
start: { line: startToken.line, column: startToken.column },
|
|
3998
|
+
end: { line: this.current().line, column: this.current().column }
|
|
3999
|
+
}
|
|
4000
|
+
};
|
|
4001
|
+
}
|
|
4002
|
+
/** @deprecated Use parseHsConnectStatement for .hs connect syntax */
|
|
4003
|
+
parseConnectionStatement() {
|
|
4004
|
+
this.expect("IDENTIFIER", "Expected connect");
|
|
4005
|
+
const from = this.expect("IDENTIFIER", "Expected from name").value;
|
|
4006
|
+
this.expect("IDENTIFIER", "Expected to");
|
|
4007
|
+
const to = this.expect("IDENTIFIER", "Expected to name").value;
|
|
4008
|
+
return { from, to };
|
|
4009
|
+
}
|
|
4010
|
+
/**
|
|
4011
|
+
* Map a reaction trigger to its routing bucket (mirrors the .hs parser's
|
|
4012
|
+
* reactionCategory; the movement-trigger list comes from the locomotion SSOT).
|
|
4013
|
+
*/
|
|
4014
|
+
hsplusReactionCategory(trigger) {
|
|
4015
|
+
if (chunkNTQRFOPP_cjs.isLocomotionReactionTrigger(trigger)) return "movement";
|
|
4016
|
+
switch (trigger) {
|
|
4017
|
+
case "on_interact":
|
|
4018
|
+
case "on_grab":
|
|
4019
|
+
case "on_release":
|
|
4020
|
+
case "on_use":
|
|
4021
|
+
case "on_hover":
|
|
4022
|
+
return "interaction";
|
|
4023
|
+
case "on_collision":
|
|
4024
|
+
case "on_collide":
|
|
4025
|
+
case "on_proximity":
|
|
4026
|
+
return "collision";
|
|
4027
|
+
case "on_spawn":
|
|
4028
|
+
case "on_death":
|
|
4029
|
+
case "on_enter":
|
|
4030
|
+
case "on_exit":
|
|
4031
|
+
case "on_tick":
|
|
4032
|
+
return "lifecycle";
|
|
4033
|
+
case "on_combat":
|
|
4034
|
+
case "on_cast":
|
|
4035
|
+
return "combat";
|
|
4036
|
+
case "on_signal":
|
|
4037
|
+
case "on_input":
|
|
4038
|
+
return "signal";
|
|
4039
|
+
default:
|
|
4040
|
+
return "custom";
|
|
4041
|
+
}
|
|
4042
|
+
}
|
|
4043
|
+
/**
|
|
4044
|
+
* Parse a declarative reaction block attached to an entity:
|
|
4045
|
+
* react {
|
|
4046
|
+
* on_grab(hand) => highlight()
|
|
4047
|
+
* on_proximity(player) => alert(player)
|
|
4048
|
+
* on_use => { open(); play_sound("creak") }
|
|
4049
|
+
* }
|
|
4050
|
+
* A leading `on` word is optional (`on collide(...)` == `on_collide(...)`).
|
|
4051
|
+
* Each entry becomes a `reaction` child node carrying trigger/params/body and
|
|
4052
|
+
* an inferred ReactionCategory. Body is captured raw (an expression or block).
|
|
4053
|
+
*/
|
|
4054
|
+
parseHsPlusReactBlock(startToken) {
|
|
4055
|
+
const startLoc = { line: startToken.line, column: startToken.column };
|
|
4056
|
+
const reactions = [];
|
|
4057
|
+
this.skipNewlines();
|
|
4058
|
+
if (this.check("LBRACE")) {
|
|
4059
|
+
this.advance();
|
|
4060
|
+
this.skipNewlines();
|
|
4061
|
+
while (!this.check("RBRACE") && !this.check("EOF")) {
|
|
4062
|
+
this.skipNewlines();
|
|
4063
|
+
if (this.check("RBRACE") || this.check("EOF")) break;
|
|
4064
|
+
let triggerPrefix = "";
|
|
4065
|
+
if (this.check("IDENTIFIER") && this.current().value === "on" && this.tokens[this.pos + 1]?.type === "IDENTIFIER") {
|
|
4066
|
+
this.advance();
|
|
4067
|
+
triggerPrefix = "on_";
|
|
4068
|
+
}
|
|
4069
|
+
if (!this.check("IDENTIFIER")) {
|
|
4070
|
+
this.advance();
|
|
4071
|
+
continue;
|
|
4072
|
+
}
|
|
4073
|
+
const trigger = triggerPrefix + this.advance().value;
|
|
4074
|
+
const params = [];
|
|
4075
|
+
if (this.check("LPAREN")) {
|
|
4076
|
+
this.advance();
|
|
4077
|
+
while (!this.check("RPAREN") && !this.check("EOF")) {
|
|
4078
|
+
if (this.check("IDENTIFIER")) params.push(this.advance().value);
|
|
4079
|
+
else this.advance();
|
|
4080
|
+
if (this.check("COMMA")) this.advance();
|
|
4081
|
+
}
|
|
4082
|
+
if (this.check("RPAREN")) this.advance();
|
|
4083
|
+
}
|
|
4084
|
+
if (this.check("ARROW")) this.advance();
|
|
4085
|
+
let body = "";
|
|
4086
|
+
if (this.check("LBRACE")) {
|
|
4087
|
+
body = this.parseRawBlock();
|
|
4088
|
+
} else {
|
|
4089
|
+
const parts = [];
|
|
4090
|
+
while (!this.check("NEWLINE") && !this.check("EOF") && !this.check("RBRACE")) {
|
|
4091
|
+
parts.push(this.advance().value);
|
|
4092
|
+
}
|
|
4093
|
+
body = parts.join(" ").trim();
|
|
4094
|
+
}
|
|
4095
|
+
reactions.push({
|
|
4096
|
+
type: "reaction",
|
|
4097
|
+
name: trigger,
|
|
4098
|
+
event: trigger,
|
|
4099
|
+
body,
|
|
4100
|
+
properties: {
|
|
4101
|
+
trigger,
|
|
4102
|
+
params,
|
|
4103
|
+
category: this.hsplusReactionCategory(trigger)
|
|
4104
|
+
}
|
|
4105
|
+
});
|
|
4106
|
+
this.skipNewlines();
|
|
4107
|
+
}
|
|
4108
|
+
if (this.check("RBRACE")) this.advance();
|
|
4109
|
+
}
|
|
4110
|
+
return {
|
|
4111
|
+
type: "react-block",
|
|
4112
|
+
name: "react",
|
|
4113
|
+
children: reactions,
|
|
4114
|
+
properties: { count: reactions.length },
|
|
4115
|
+
directives: [],
|
|
4116
|
+
traits: /* @__PURE__ */ new Map(),
|
|
4117
|
+
loc: {
|
|
4118
|
+
start: startLoc,
|
|
4119
|
+
end: { line: this.current().line, column: this.current().column }
|
|
4120
|
+
}
|
|
4121
|
+
};
|
|
4122
|
+
}
|
|
4123
|
+
/**
|
|
4124
|
+
* Parse a `timeline <name> { …properties, track-blocks, children }` node.
|
|
4125
|
+
* (Theatre.js harvest S1.) Produces the same shape as the canonical Rust
|
|
4126
|
+
* grammar: a `timeline` node whose `children` include structured `track`
|
|
4127
|
+
* nodes (`{ type: 'track', target, keyframes: [...] }`). Non-track lines are
|
|
4128
|
+
* handled the generic way: `key: value` → property, nested block keyword →
|
|
4129
|
+
* child node. The `timeline` keyword has already been consumed by the caller.
|
|
4130
|
+
*/
|
|
4131
|
+
parseTimelineNode(startToken) {
|
|
4132
|
+
let name;
|
|
4133
|
+
if (this.check("STRING") || this.check("IDENTIFIER")) {
|
|
4134
|
+
name = this.advance().value;
|
|
4135
|
+
}
|
|
4136
|
+
const properties = {};
|
|
4137
|
+
const children = [];
|
|
4138
|
+
const directives = [];
|
|
4139
|
+
const traits = /* @__PURE__ */ new Map();
|
|
4140
|
+
if (this.check("LBRACE")) {
|
|
4141
|
+
this.advance();
|
|
4142
|
+
this.skipNewlines();
|
|
4143
|
+
while (!this.check("RBRACE") && !this.check("EOF")) {
|
|
4144
|
+
this.skipNewlines();
|
|
4145
|
+
if (this.check("RBRACE") || this.check("EOF")) break;
|
|
4146
|
+
if (this.check("AT")) {
|
|
4147
|
+
const directive = this.parseDirective();
|
|
4148
|
+
if (directive) {
|
|
4149
|
+
if (directive.type === "trait") {
|
|
4150
|
+
traits.set(directive.name, directive.config);
|
|
4151
|
+
this.hasVRTraits = true;
|
|
4152
|
+
}
|
|
4153
|
+
directives.push(directive);
|
|
4154
|
+
}
|
|
4155
|
+
this.skipNewlines();
|
|
4156
|
+
continue;
|
|
4157
|
+
}
|
|
4158
|
+
const token = this.current();
|
|
4159
|
+
const next = this.peek(1);
|
|
4160
|
+
if (token.type === "IDENTIFIER" && token.value === "track" && (next.type === "STRING" || next.type === "IDENTIFIER") && this.peek(2).type === "LBRACE") {
|
|
4161
|
+
this.advance();
|
|
4162
|
+
children.push(this.parseTrackNode(token));
|
|
4163
|
+
if (this.check("COMMA")) this.advance();
|
|
4164
|
+
this.skipNewlines();
|
|
4165
|
+
continue;
|
|
4166
|
+
}
|
|
4167
|
+
if ((token.type === "IDENTIFIER" || token.type === "STRING") && (next.type === "COLON" || next.type === "EQUALS")) {
|
|
4168
|
+
const key = this.advance().value;
|
|
4169
|
+
this.advance();
|
|
4170
|
+
properties[key] = this.parseValue();
|
|
4171
|
+
if (this.check("COMMA")) this.advance();
|
|
4172
|
+
this.skipNewlines();
|
|
4173
|
+
continue;
|
|
4174
|
+
}
|
|
4175
|
+
if (token.type === "IDENTIFIER" || token.type === "STRING") {
|
|
4176
|
+
children.push(this.parseNode());
|
|
4177
|
+
if (this.check("COMMA")) this.advance();
|
|
4178
|
+
this.skipNewlines();
|
|
4179
|
+
continue;
|
|
4180
|
+
}
|
|
4181
|
+
this.advance();
|
|
4182
|
+
this.skipNewlines();
|
|
4183
|
+
}
|
|
4184
|
+
this.expect("RBRACE", "Expected } to close timeline block");
|
|
4185
|
+
}
|
|
4186
|
+
return {
|
|
4187
|
+
type: "timeline",
|
|
4188
|
+
name,
|
|
4189
|
+
id: name,
|
|
4190
|
+
properties,
|
|
4191
|
+
directives,
|
|
4192
|
+
children,
|
|
4193
|
+
traits,
|
|
4194
|
+
loc: {
|
|
4195
|
+
start: { line: startToken.line, column: startToken.column },
|
|
4196
|
+
end: { line: this.current().line, column: this.current().column }
|
|
4197
|
+
}
|
|
4198
|
+
};
|
|
4199
|
+
}
|
|
4200
|
+
/**
|
|
4201
|
+
* Parse a keyframe-track inside a timeline:
|
|
4202
|
+
* track "<target>" { key <time> { <value> } [easing <ease>] ; … }
|
|
4203
|
+
* Mirrors the Rust `TrackNode`/`KeyframeNode`. `;` is skipped by the lexer,
|
|
4204
|
+
* so keyframe separators are implicit. The `track` keyword has already been
|
|
4205
|
+
* consumed by the caller. Returns `{ type: 'track', target, keyframes }`.
|
|
4206
|
+
*/
|
|
4207
|
+
parseTrackNode(startToken) {
|
|
4208
|
+
const target = this.check("STRING") ? this.advance().value : this.expect("IDENTIFIER", "Expected track target name").value;
|
|
4209
|
+
const keyframes = [];
|
|
4210
|
+
this.expect("LBRACE", "Expected { to open track block");
|
|
4211
|
+
this.skipNewlines();
|
|
4212
|
+
while (!this.check("RBRACE") && !this.check("EOF")) {
|
|
4213
|
+
this.skipNewlines();
|
|
4214
|
+
if (this.check("RBRACE") || this.check("EOF")) break;
|
|
4215
|
+
if (this.check("COMMA")) {
|
|
4216
|
+
this.advance();
|
|
4217
|
+
continue;
|
|
4218
|
+
}
|
|
4219
|
+
if (this.check("IDENTIFIER") && this.current().value === "key") {
|
|
4220
|
+
this.advance();
|
|
4221
|
+
let timeSign = 1;
|
|
4222
|
+
if (this.check("MINUS")) {
|
|
4223
|
+
this.advance();
|
|
4224
|
+
timeSign = -1;
|
|
4225
|
+
}
|
|
4226
|
+
const timeTok = this.expect("NUMBER", "Expected numeric time after key");
|
|
4227
|
+
const time = timeSign * Number(timeTok.value);
|
|
4228
|
+
this.expect("LBRACE", "Expected { value block after key time");
|
|
4229
|
+
const value = this.parseValue();
|
|
4230
|
+
this.expect("RBRACE", "Expected } to close key value block");
|
|
4231
|
+
let easing;
|
|
4232
|
+
if (this.check("IDENTIFIER") && this.current().value === "easing") {
|
|
4233
|
+
this.advance();
|
|
4234
|
+
if (this.check("IDENTIFIER") || this.check("STRING")) {
|
|
4235
|
+
easing = this.advance().value;
|
|
4236
|
+
}
|
|
4237
|
+
}
|
|
4238
|
+
keyframes.push(easing === void 0 ? { time, value } : { time, value, easing });
|
|
4239
|
+
this.skipNewlines();
|
|
4240
|
+
continue;
|
|
4241
|
+
}
|
|
4242
|
+
this.advance();
|
|
4243
|
+
this.skipNewlines();
|
|
4244
|
+
}
|
|
4245
|
+
this.expect("RBRACE", "Expected } to close track block");
|
|
4246
|
+
return {
|
|
4247
|
+
type: "track",
|
|
4248
|
+
target,
|
|
4249
|
+
keyframes,
|
|
4250
|
+
loc: {
|
|
4251
|
+
start: { line: startToken.line, column: startToken.column },
|
|
4252
|
+
end: { line: this.current().line, column: this.current().column }
|
|
4253
|
+
}
|
|
4254
|
+
};
|
|
4255
|
+
}
|
|
4256
|
+
/**
|
|
4257
|
+
* Parse block content: { key: value, ... }
|
|
4258
|
+
*/
|
|
4259
|
+
parseBlockContent() {
|
|
4260
|
+
const content = {};
|
|
4261
|
+
if (!this.check("LBRACE")) {
|
|
4262
|
+
return content;
|
|
4263
|
+
}
|
|
4264
|
+
this.advance();
|
|
4265
|
+
this.skipNewlines();
|
|
4266
|
+
while (!this.check("RBRACE") && !this.check("EOF")) {
|
|
4267
|
+
this.skipNewlines();
|
|
4268
|
+
if (this.check("RBRACE") || this.check("EOF")) break;
|
|
4269
|
+
this.skipNewlines();
|
|
4270
|
+
if (this.check("RBRACE") || this.check("EOF")) break;
|
|
4271
|
+
const token = this.current();
|
|
4272
|
+
const isKeyToken = token.type === "IDENTIFIER" || token.type === "STRING" || token.type === "STATE" || token.type === "STATE_MACHINE" || token.type === "INITIAL" || token.type === "ON_ENTRY" || token.type === "ON_EXIT" || token.type === "TRANSITION";
|
|
4273
|
+
if (isKeyToken) {
|
|
4274
|
+
const next = this.peek(1);
|
|
4275
|
+
if (next.type === "COLON" || next.type === "EQUALS") {
|
|
4276
|
+
const key = this.advance().value;
|
|
4277
|
+
this.advance();
|
|
4278
|
+
content[key] = this.parseValue();
|
|
4279
|
+
} else if (next.type === "STRING" || next.type === "LBRACE" || next.type === "IDENTIFIER") {
|
|
4280
|
+
const node = this.parseNode();
|
|
4281
|
+
const type = node.type;
|
|
4282
|
+
const name = node.name || `unnamed_${type}_${Object.keys(content).length}`;
|
|
4283
|
+
content[name] = node;
|
|
4284
|
+
} else {
|
|
4285
|
+
const key = this.advance().value;
|
|
4286
|
+
content[key] = true;
|
|
4287
|
+
}
|
|
4288
|
+
} else if (this.check("SPREAD")) {
|
|
4289
|
+
this.advance();
|
|
4290
|
+
const val = this.parseValue();
|
|
4291
|
+
const spreadKey = `__spread_${Object.keys(content).length}`;
|
|
4292
|
+
content[spreadKey] = { type: "spread", argument: val };
|
|
4293
|
+
} else if (this.check("AT")) {
|
|
4294
|
+
const directive = this.parseDirective();
|
|
4295
|
+
if (directive) {
|
|
4296
|
+
const dirKey = ("name" in directive ? directive.name : void 0) || directive.type;
|
|
4297
|
+
content[`@${dirKey}`] = directive;
|
|
4298
|
+
}
|
|
4299
|
+
} else if (this.check("LBRACE")) {
|
|
4300
|
+
let depth = 1;
|
|
4301
|
+
this.advance();
|
|
4302
|
+
while (depth > 0 && !this.check("EOF")) {
|
|
4303
|
+
if (this.check("LBRACE")) depth++;
|
|
4304
|
+
if (this.check("RBRACE")) depth--;
|
|
4305
|
+
this.advance();
|
|
4306
|
+
}
|
|
4307
|
+
} else if (this.check("LPAREN")) {
|
|
4308
|
+
this.skipParens();
|
|
4309
|
+
} else {
|
|
4310
|
+
this.advance();
|
|
4311
|
+
}
|
|
4312
|
+
if (this.check("COMMA")) this.advance();
|
|
4313
|
+
this.skipNewlines();
|
|
4314
|
+
}
|
|
4315
|
+
this.expect("RBRACE", "Expected }");
|
|
4316
|
+
return content;
|
|
4317
|
+
}
|
|
4318
|
+
/**
|
|
4319
|
+
* Parse bindings block: { bind(expr) -> target, ... }
|
|
4320
|
+
*/
|
|
4321
|
+
parseBindingsBlock() {
|
|
4322
|
+
const bindings = [];
|
|
4323
|
+
if (!this.check("LBRACE")) {
|
|
4324
|
+
return bindings;
|
|
4325
|
+
}
|
|
4326
|
+
this.advance();
|
|
4327
|
+
this.skipNewlines();
|
|
4328
|
+
while (!this.check("RBRACE") && !this.check("EOF")) {
|
|
4329
|
+
this.skipNewlines();
|
|
4330
|
+
if (this.check("RBRACE") || this.check("EOF")) break;
|
|
4331
|
+
if (this.check("IDENTIFIER") && this.current().value === "bind") {
|
|
4332
|
+
this.advance();
|
|
4333
|
+
if (this.check("LPAREN")) {
|
|
4334
|
+
this.advance();
|
|
4335
|
+
let source = "";
|
|
4336
|
+
let parenDepth = 1;
|
|
4337
|
+
while (parenDepth > 0 && !this.check("EOF")) {
|
|
3115
4338
|
if (this.check("LPAREN")) parenDepth++;
|
|
3116
4339
|
if (this.check("RPAREN")) {
|
|
3117
4340
|
parenDepth--;
|
|
@@ -3216,7 +4439,8 @@ var HoloScriptPlusParser = class {
|
|
|
3216
4439
|
"camera",
|
|
3217
4440
|
"timeline",
|
|
3218
4441
|
"page",
|
|
3219
|
-
"include"
|
|
4442
|
+
"include",
|
|
4443
|
+
"react"
|
|
3220
4444
|
];
|
|
3221
4445
|
while (!this.check("RBRACE") && !this.check("EOF")) {
|
|
3222
4446
|
const currentDirectives = [];
|
|
@@ -3735,7 +4959,9 @@ var HoloScriptPlusParser = class {
|
|
|
3735
4959
|
if (startToken.type === "STATE_MACHINE") {
|
|
3736
4960
|
this.advance();
|
|
3737
4961
|
}
|
|
3738
|
-
const name = this.
|
|
4962
|
+
const name = this.parseStateMachineIdentifier("Expected state machine name");
|
|
4963
|
+
const inputs = [];
|
|
4964
|
+
const listeners = [];
|
|
3739
4965
|
const states = [];
|
|
3740
4966
|
const transitions = [];
|
|
3741
4967
|
let initialState = "";
|
|
@@ -3748,7 +4974,13 @@ var HoloScriptPlusParser = class {
|
|
|
3748
4974
|
if (current.type === "INITIAL" || current.value === "initial") {
|
|
3749
4975
|
this.advance();
|
|
3750
4976
|
this.expect("COLON", "Expected : after initial");
|
|
3751
|
-
initialState = this.
|
|
4977
|
+
initialState = this.parseStateMachineIdentifier("Expected initial state name");
|
|
4978
|
+
} else if (current.value === "input") {
|
|
4979
|
+
inputs.push(this.parseStateMachineInputDeclaration());
|
|
4980
|
+
} else if (current.value === "listen") {
|
|
4981
|
+
listeners.push(this.parseStateMachineListenerDeclaration());
|
|
4982
|
+
} else if (this.isStateMachineTransitionShorthandStart()) {
|
|
4983
|
+
transitions.push(this.parseStateMachineTransitionShorthand());
|
|
3752
4984
|
} else if (current.type === "STATE" || current.value === "state") {
|
|
3753
4985
|
states.push(this.parseStateNode());
|
|
3754
4986
|
} else if (current.type === "TRANSITION" || current.value === "transitions") {
|
|
@@ -3763,6 +4995,8 @@ var HoloScriptPlusParser = class {
|
|
|
3763
4995
|
type: "state-machine",
|
|
3764
4996
|
name,
|
|
3765
4997
|
initialState,
|
|
4998
|
+
inputs,
|
|
4999
|
+
listeners,
|
|
3766
5000
|
states,
|
|
3767
5001
|
transitions,
|
|
3768
5002
|
loc: {
|
|
@@ -3773,9 +5007,10 @@ var HoloScriptPlusParser = class {
|
|
|
3773
5007
|
}
|
|
3774
5008
|
parseStateNode() {
|
|
3775
5009
|
this.advance();
|
|
3776
|
-
const name = this.
|
|
5010
|
+
const name = this.parseStateMachineIdentifier("Expected state name");
|
|
3777
5011
|
let onEntry;
|
|
3778
5012
|
let onExit;
|
|
5013
|
+
const metadata = {};
|
|
3779
5014
|
this.expect("LBRACE", "Expected { after state name");
|
|
3780
5015
|
this.skipNewlines();
|
|
3781
5016
|
while (!this.check("RBRACE") && !this.check("EOF")) {
|
|
@@ -3788,19 +5023,39 @@ var HoloScriptPlusParser = class {
|
|
|
3788
5023
|
} else if (current.type === "ON_EXIT" || current.value === "on_exit") {
|
|
3789
5024
|
this.advance();
|
|
3790
5025
|
onExit = this.parseCodeBlock();
|
|
5026
|
+
} else if (this.isStateMachineStateMetadataKey(current.value) && this.peek(1).type === "COLON") {
|
|
5027
|
+
const key = this.advance().value;
|
|
5028
|
+
this.expect("COLON", `Expected : after ${key}`);
|
|
5029
|
+
metadata[key] = this.parseValue();
|
|
3791
5030
|
} else {
|
|
3792
5031
|
this.advance();
|
|
3793
5032
|
}
|
|
3794
5033
|
this.skipNewlines();
|
|
3795
5034
|
}
|
|
3796
5035
|
this.expect("RBRACE", "Expected }");
|
|
3797
|
-
return { name, onEntry, onExit };
|
|
5036
|
+
return { name, onEntry, onExit, ...metadata };
|
|
5037
|
+
}
|
|
5038
|
+
isStateMachineStateMetadataKey(key) {
|
|
5039
|
+
return key === "clip" || key === "clips" || key === "parameter" || key === "parameters" || key === "thresholds" || key === "blendType" || key === "blend_type" || key === "blend" || key === "blendMode" || key === "blend_mode" || key === "mask" || key === "baseline";
|
|
3798
5040
|
}
|
|
3799
5041
|
parseOnErrorNode() {
|
|
3800
5042
|
const startToken = this.previous();
|
|
5043
|
+
const params = [];
|
|
5044
|
+
if (this.check("LPAREN")) {
|
|
5045
|
+
this.advance();
|
|
5046
|
+
while (!this.check("RPAREN") && !this.check("EOF") && !this.check("LBRACE")) {
|
|
5047
|
+
if (this.check("IDENTIFIER")) {
|
|
5048
|
+
params.push(this.advance().value);
|
|
5049
|
+
} else {
|
|
5050
|
+
this.advance();
|
|
5051
|
+
}
|
|
5052
|
+
}
|
|
5053
|
+
if (this.check("RPAREN")) this.advance();
|
|
5054
|
+
}
|
|
3801
5055
|
const body = this.parseControlFlowBody();
|
|
3802
5056
|
return {
|
|
3803
5057
|
type: "on_error",
|
|
5058
|
+
params,
|
|
3804
5059
|
body,
|
|
3805
5060
|
loc: {
|
|
3806
5061
|
start: { line: startToken.line, column: startToken.column },
|
|
@@ -3835,17 +5090,153 @@ var HoloScriptPlusParser = class {
|
|
|
3835
5090
|
while (!this.check("RBRACE") && !this.check("EOF")) {
|
|
3836
5091
|
this.skipNewlines();
|
|
3837
5092
|
if (this.check("RBRACE") || this.check("EOF")) break;
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
5093
|
+
if (this.isStateMachineTransitionShorthandStart()) {
|
|
5094
|
+
transitions.push(this.parseStateMachineTransitionShorthand());
|
|
5095
|
+
} else {
|
|
5096
|
+
const from = this.parseStateMachineIdentifier("Expected source state");
|
|
5097
|
+
this.expect("ARROW", "Expected ->");
|
|
5098
|
+
const to = this.parseStateMachineIdentifier("Expected target state");
|
|
5099
|
+
this.expect("COLON", "Expected :");
|
|
5100
|
+
const event = this.parseStateMachineIdentifier("Expected event name");
|
|
5101
|
+
transitions.push({ from, to, event });
|
|
5102
|
+
}
|
|
3844
5103
|
this.skipNewlines();
|
|
3845
5104
|
}
|
|
3846
5105
|
this.expect("RBRACE", "Expected }");
|
|
3847
5106
|
return transitions;
|
|
3848
5107
|
}
|
|
5108
|
+
parseStateMachineInputDeclaration() {
|
|
5109
|
+
this.advance();
|
|
5110
|
+
const name = this.parseStateMachineIdentifier("Expected input name");
|
|
5111
|
+
this.expect("COLON", "Expected : after input name");
|
|
5112
|
+
const rawType = this.parseStateMachineIdentifier("Expected input type");
|
|
5113
|
+
const inputType = rawType === "number" ? "float" : rawType === "boolean" ? "bool" : rawType;
|
|
5114
|
+
let defaultValue;
|
|
5115
|
+
if (this.check("EQUALS")) {
|
|
5116
|
+
this.advance();
|
|
5117
|
+
defaultValue = this.parseValue();
|
|
5118
|
+
}
|
|
5119
|
+
return {
|
|
5120
|
+
type: "animation-input",
|
|
5121
|
+
name,
|
|
5122
|
+
inputType,
|
|
5123
|
+
rawType,
|
|
5124
|
+
default: defaultValue
|
|
5125
|
+
};
|
|
5126
|
+
}
|
|
5127
|
+
parseStateMachineListenerDeclaration() {
|
|
5128
|
+
this.advance();
|
|
5129
|
+
const event = this.parseStateMachineDottedIdentifier("Expected listener event");
|
|
5130
|
+
this.expect("ARROW", "Expected -> after listener event");
|
|
5131
|
+
if (this.current().value === "fire") {
|
|
5132
|
+
this.advance();
|
|
5133
|
+
return {
|
|
5134
|
+
type: "animation-listener",
|
|
5135
|
+
event,
|
|
5136
|
+
action: "fire",
|
|
5137
|
+
parameter: this.parseStateMachineDottedIdentifier("Expected trigger input")
|
|
5138
|
+
};
|
|
5139
|
+
}
|
|
5140
|
+
if (this.current().value === "reset") {
|
|
5141
|
+
this.advance();
|
|
5142
|
+
return {
|
|
5143
|
+
type: "animation-listener",
|
|
5144
|
+
event,
|
|
5145
|
+
action: "reset",
|
|
5146
|
+
parameter: this.parseStateMachineDottedIdentifier("Expected trigger input")
|
|
5147
|
+
};
|
|
5148
|
+
}
|
|
5149
|
+
const parameter = this.parseStateMachineDottedIdentifier("Expected animation input");
|
|
5150
|
+
this.expect("EQUALS", "Expected = in listener binding");
|
|
5151
|
+
const parsedValue = this.parseValue();
|
|
5152
|
+
const listener = {
|
|
5153
|
+
type: "animation-listener",
|
|
5154
|
+
event,
|
|
5155
|
+
action: "set",
|
|
5156
|
+
parameter
|
|
5157
|
+
};
|
|
5158
|
+
if (parsedValue && typeof parsedValue === "object" && "__ref" in parsedValue) {
|
|
5159
|
+
const ref = parsedValue.__ref;
|
|
5160
|
+
if (typeof ref === "string" && (ref === "event" || ref.startsWith("event."))) {
|
|
5161
|
+
listener.source = ref;
|
|
5162
|
+
} else if (typeof ref === "string") {
|
|
5163
|
+
listener.value = ref;
|
|
5164
|
+
} else {
|
|
5165
|
+
listener.value = String(ref ?? "");
|
|
5166
|
+
}
|
|
5167
|
+
} else if (typeof parsedValue === "number" || typeof parsedValue === "boolean" || typeof parsedValue === "string") {
|
|
5168
|
+
listener.value = parsedValue;
|
|
5169
|
+
} else {
|
|
5170
|
+
listener.value = String(parsedValue ?? "");
|
|
5171
|
+
}
|
|
5172
|
+
return listener;
|
|
5173
|
+
}
|
|
5174
|
+
isStateMachineTransitionShorthandStart() {
|
|
5175
|
+
return this.isStateMachineIdentifierToken(0) && this.peek(1).type === "ARROW";
|
|
5176
|
+
}
|
|
5177
|
+
parseStateMachineTransitionShorthand() {
|
|
5178
|
+
const fromRaw = this.parseStateMachineIdentifier("Expected source state");
|
|
5179
|
+
const from = fromRaw.toLowerCase() === "any" ? "any" : fromRaw;
|
|
5180
|
+
this.expect("ARROW", "Expected ->");
|
|
5181
|
+
const to = this.parseStateMachineIdentifier("Expected target state");
|
|
5182
|
+
const transition = { from, to };
|
|
5183
|
+
while (!this.check("NEWLINE") && !this.check("RBRACE") && !this.check("COMMA") && !this.check("EOF")) {
|
|
5184
|
+
if (!this.isStateMachineIdentifierToken(0)) break;
|
|
5185
|
+
const clause = this.current().value.toLowerCase();
|
|
5186
|
+
this.advance();
|
|
5187
|
+
if (clause === "when") {
|
|
5188
|
+
transition.when = this.parseExpression();
|
|
5189
|
+
} else if (clause === "on") {
|
|
5190
|
+
transition.event = this.parseStateMachineIdentifier("Expected trigger input");
|
|
5191
|
+
} else if (clause === "over" || clause === "duration") {
|
|
5192
|
+
transition.duration = this.parseValue();
|
|
5193
|
+
} else if (clause === "easing") {
|
|
5194
|
+
transition.easing = this.parseStateMachineIdentifier("Expected easing name");
|
|
5195
|
+
} else if (clause === "exittime" || clause === "exit_time") {
|
|
5196
|
+
transition.exitTime = this.parseValue();
|
|
5197
|
+
transition.hasExitTime = true;
|
|
5198
|
+
} else if (clause === "pausewhenexiting" || clause === "pause_when_exiting") {
|
|
5199
|
+
transition.pauseWhenExiting = this.parseOptionalStateMachineBoolean();
|
|
5200
|
+
} else if (clause === "priority") {
|
|
5201
|
+
transition.priority = this.parseValue();
|
|
5202
|
+
} else if (clause === "cantransitiontoself" || clause === "can_transition_to_self") {
|
|
5203
|
+
transition.canTransitionToSelf = this.parseOptionalStateMachineBoolean();
|
|
5204
|
+
} else {
|
|
5205
|
+
break;
|
|
5206
|
+
}
|
|
5207
|
+
}
|
|
5208
|
+
return transition;
|
|
5209
|
+
}
|
|
5210
|
+
parseOptionalStateMachineBoolean() {
|
|
5211
|
+
if (this.check("COLON")) this.advance();
|
|
5212
|
+
if (this.check("BOOLEAN")) return this.advance().value === "true";
|
|
5213
|
+
if (this.check("IDENTIFIER")) {
|
|
5214
|
+
const value = this.current().value.toLowerCase();
|
|
5215
|
+
if (value === "true" || value === "false") {
|
|
5216
|
+
this.advance();
|
|
5217
|
+
return value === "true";
|
|
5218
|
+
}
|
|
5219
|
+
}
|
|
5220
|
+
return true;
|
|
5221
|
+
}
|
|
5222
|
+
parseStateMachineIdentifier(message) {
|
|
5223
|
+
if (this.check("IDENTIFIER") || this.check("STRING")) {
|
|
5224
|
+
return this.advance().value;
|
|
5225
|
+
}
|
|
5226
|
+
return this.expect("IDENTIFIER", message).value;
|
|
5227
|
+
}
|
|
5228
|
+
parseStateMachineDottedIdentifier(message) {
|
|
5229
|
+
let value = this.parseStateMachineIdentifier(message);
|
|
5230
|
+
while (this.check("DOT")) {
|
|
5231
|
+
this.advance();
|
|
5232
|
+
value += `.${this.parseStateMachineIdentifier("Expected property name after dot")}`;
|
|
5233
|
+
}
|
|
5234
|
+
return value;
|
|
5235
|
+
}
|
|
5236
|
+
isStateMachineIdentifierToken(offset) {
|
|
5237
|
+
const token = this.peek(offset);
|
|
5238
|
+
return token.type === "IDENTIFIER" || token.type === "STRING";
|
|
5239
|
+
}
|
|
3849
5240
|
parseControlFlowBody() {
|
|
3850
5241
|
const nodes = [];
|
|
3851
5242
|
if (this.check("LBRACE")) {
|
|
@@ -3889,41 +5280,10 @@ var HoloScriptPlusParser = class {
|
|
|
3889
5280
|
return nodes;
|
|
3890
5281
|
}
|
|
3891
5282
|
parseCodeBlock() {
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
if (this.check("LBRACE")) {
|
|
3895
|
-
this.advance();
|
|
3896
|
-
braceDepth = 1;
|
|
3897
|
-
try {
|
|
3898
|
-
while (braceDepth > 0 && !this.check("EOF")) {
|
|
3899
|
-
const token = this.advance();
|
|
3900
|
-
if (token.type === "LBRACE") {
|
|
3901
|
-
braceDepth++;
|
|
3902
|
-
code += "{";
|
|
3903
|
-
} else if (token.type === "RBRACE") {
|
|
3904
|
-
braceDepth--;
|
|
3905
|
-
if (braceDepth > 0) {
|
|
3906
|
-
code += "}";
|
|
3907
|
-
}
|
|
3908
|
-
} else if (token.type === "STRING") {
|
|
3909
|
-
code += `"${token.value}"`;
|
|
3910
|
-
code += " ";
|
|
3911
|
-
} else {
|
|
3912
|
-
code += token.value;
|
|
3913
|
-
if (token.type === "NEWLINE") {
|
|
3914
|
-
code += "\n";
|
|
3915
|
-
} else {
|
|
3916
|
-
code += " ";
|
|
3917
|
-
}
|
|
3918
|
-
}
|
|
3919
|
-
}
|
|
3920
|
-
} catch (e) {
|
|
3921
|
-
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
3922
|
-
if (errorMessage !== "ParseError") console.error(e);
|
|
3923
|
-
this.synchronize();
|
|
3924
|
-
}
|
|
5283
|
+
if (!this.check("LBRACE")) {
|
|
5284
|
+
return "";
|
|
3925
5285
|
}
|
|
3926
|
-
return
|
|
5286
|
+
return this.parseRawBlock();
|
|
3927
5287
|
}
|
|
3928
5288
|
parseInlineExpression() {
|
|
3929
5289
|
let expr = "";
|
|
@@ -4175,6 +5535,9 @@ var HoloScriptPlusParser = class {
|
|
|
4175
5535
|
}
|
|
4176
5536
|
return this.parseParenExpression();
|
|
4177
5537
|
}
|
|
5538
|
+
if (token.type === "ARROW" && token.value === "->") {
|
|
5539
|
+
return this.parseTransitionShorthand();
|
|
5540
|
+
}
|
|
4178
5541
|
if (token.type === "MATCH") {
|
|
4179
5542
|
return this.parseMatchExpression();
|
|
4180
5543
|
}
|
|
@@ -4230,6 +5593,36 @@ var HoloScriptPlusParser = class {
|
|
|
4230
5593
|
err.message = "ParseError";
|
|
4231
5594
|
throw err;
|
|
4232
5595
|
}
|
|
5596
|
+
/**
|
|
5597
|
+
* Parse a state-machine transition shorthand value:
|
|
5598
|
+
* -> "target"
|
|
5599
|
+
* -> "target" action(callback_name)
|
|
5600
|
+
* -> "target" guard(state.credits >= 10) action(begin)
|
|
5601
|
+
* Used as the value of on_<event> keys inside @state_machine states config.
|
|
5602
|
+
* Modifiers (action / guard) may appear in any order, each at most once
|
|
5603
|
+
* meaningfully (last one wins, matching general object semantics).
|
|
5604
|
+
*/
|
|
5605
|
+
parseTransitionShorthand() {
|
|
5606
|
+
this.advance();
|
|
5607
|
+
let target = "";
|
|
5608
|
+
if (this.check("STRING") || this.check("IDENTIFIER")) {
|
|
5609
|
+
target = this.advance().value;
|
|
5610
|
+
} else {
|
|
5611
|
+
this.error(
|
|
5612
|
+
`Expected target state after -> in transition. Got ${this.current().type} "${this.current().value}"`,
|
|
5613
|
+
"HSP300"
|
|
5614
|
+
);
|
|
5615
|
+
}
|
|
5616
|
+
const transition = { type: "transition", target };
|
|
5617
|
+
while (this.check("IDENTIFIER") && (this.current().value === "action" || this.current().value === "guard") && this.peek(1).type === "LPAREN") {
|
|
5618
|
+
const kind = this.advance().value;
|
|
5619
|
+
this.advance();
|
|
5620
|
+
const arg = this.parseExpression();
|
|
5621
|
+
this.expect("RPAREN", `Expected ) after ${kind} argument in transition`);
|
|
5622
|
+
transition[kind] = arg;
|
|
5623
|
+
}
|
|
5624
|
+
return transition;
|
|
5625
|
+
}
|
|
4233
5626
|
parseParenExpression() {
|
|
4234
5627
|
this.expect("LPAREN", "Expected (");
|
|
4235
5628
|
const items = [];
|
|
@@ -4614,6 +6007,14 @@ var HoloScriptPlusParser = class {
|
|
|
4614
6007
|
})
|
|
4615
6008
|
);
|
|
4616
6009
|
}
|
|
6010
|
+
errorAt(token, message, code = "HSP001") {
|
|
6011
|
+
this.errors.push(
|
|
6012
|
+
createRichError(code, message, token.line, token.column, {
|
|
6013
|
+
source: this.source,
|
|
6014
|
+
severity: "error"
|
|
6015
|
+
})
|
|
6016
|
+
);
|
|
6017
|
+
}
|
|
4617
6018
|
errorWithSuggestion(message, suggestion, code = "HSP001") {
|
|
4618
6019
|
const token = this.current();
|
|
4619
6020
|
this.errors.push(
|
|
@@ -4658,7 +6059,7 @@ var HoloScriptPlusParser = class {
|
|
|
4658
6059
|
code: "HSP001"
|
|
4659
6060
|
};
|
|
4660
6061
|
}
|
|
4661
|
-
if (current.type === "IDENTIFIER" &&
|
|
6062
|
+
if (current.type === "IDENTIFIER" && chunkEI3J6LTW_cjs.VR_TRAITS.includes(current.value)) {
|
|
4662
6063
|
if (prev?.type !== "AT") {
|
|
4663
6064
|
return {
|
|
4664
6065
|
message: `'${current.value}' is a trait and requires '@' prefix`,
|
|
@@ -4884,5 +6285,5 @@ exports.getSourceContext = getSourceContext;
|
|
|
4884
6285
|
exports.globalParseCache = globalParseCache;
|
|
4885
6286
|
exports.parse = parse;
|
|
4886
6287
|
exports.parseIncrementalChunks = parseIncrementalChunks;
|
|
4887
|
-
//# sourceMappingURL=chunk-
|
|
4888
|
-
//# sourceMappingURL=chunk-
|
|
6288
|
+
//# sourceMappingURL=chunk-CANAL6CT.cjs.map
|
|
6289
|
+
//# sourceMappingURL=chunk-CANAL6CT.cjs.map
|