@holoscript/core 7.0.0 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (350) hide show
  1. package/README.md +4 -4
  2. package/bin/holoscript.cjs +3 -0
  3. package/dist/GLTFPipeline-N6B6PJ6G.cjs +38 -0
  4. package/dist/GLTFPipeline-P3WMNYCN.js +17 -0
  5. package/dist/HoloScriptPlusParser-7FBIFUFC.js +693 -0
  6. package/dist/HoloScriptPlusParser-A2W7OCN2.cjs +698 -0
  7. package/dist/HoloScriptPlusParser-F2Z56FJR.js +10 -0
  8. package/dist/HoloScriptPlusParser-WKHRIH6T.cjs +27 -0
  9. package/dist/HoloScriptRuntime-CBYJX3LZ.js +10 -0
  10. package/dist/HoloScriptRuntime-VJ374RER.cjs +19 -0
  11. package/dist/USDZExporter-3FWJ25JI.cjs +1037 -0
  12. package/dist/USDZExporter-D2HQLQYK.js +1035 -0
  13. package/dist/agents/index.cjs +19 -0
  14. package/dist/agents/index.d.ts +100 -0
  15. package/dist/agents/index.js +17 -0
  16. package/dist/chunk-2BSMSUCE.js +1941 -0
  17. package/dist/chunk-2IWC4FP7.cjs +1189 -0
  18. package/dist/chunk-2M2DPHKB.js +762 -0
  19. package/dist/chunk-2X7NGX3M.js +2426 -0
  20. package/dist/chunk-2YSNA2F2.cjs +1274 -0
  21. package/dist/chunk-3FOKASKO.cjs +348 -0
  22. package/dist/chunk-3WZEJHUQ.cjs +116 -0
  23. package/dist/chunk-4C57PR42.js +468 -0
  24. package/dist/chunk-4GU5GCIY.js +1384 -0
  25. package/dist/chunk-4N4SXXWF.js +769 -0
  26. package/dist/chunk-4PDEPEQW.cjs +41 -0
  27. package/dist/chunk-4R6SBXDB.js +45 -0
  28. package/dist/chunk-4SDKXQ4C.js +811 -0
  29. package/dist/chunk-4V2E7U7Q.cjs +2015 -0
  30. package/dist/chunk-5FSKKMR7.cjs +2092 -0
  31. package/dist/chunk-5GLCTO44.js +161 -0
  32. package/dist/chunk-5H2G27PK.cjs +627 -0
  33. package/dist/chunk-5JEU52DW.js +382 -0
  34. package/dist/chunk-5NWINHR5.cjs +689 -0
  35. package/dist/chunk-5S7RKFGR.cjs +446 -0
  36. package/dist/chunk-5WUNN6ZN.cjs +428 -0
  37. package/dist/chunk-6CTRH7HT.cjs +1985 -0
  38. package/dist/chunk-6EX3I5P4.cjs +130 -0
  39. package/dist/chunk-6Q7RC2MK.cjs +1418 -0
  40. package/dist/chunk-7H33U5SM.cjs +413 -0
  41. package/dist/chunk-7M3PNU2M.cjs +672 -0
  42. package/dist/chunk-7T25IEZ2.js +449 -0
  43. package/dist/chunk-7V4JI5TB.cjs +6947 -0
  44. package/dist/chunk-A6KINLZJ.js +236 -0
  45. package/dist/chunk-ADADVMXY.js +404 -0
  46. package/dist/chunk-AIA52I7T.cjs +543 -0
  47. package/dist/chunk-ALC6K7GL.cjs +4402 -0
  48. package/dist/chunk-ANXZFVY2.js +113 -0
  49. package/dist/chunk-AOVGZ25K.cjs +56583 -0
  50. package/dist/chunk-AVJHHUC5.cjs +718 -0
  51. package/dist/chunk-BGY3SDG3.js +4396 -0
  52. package/dist/chunk-BOVPWH4H.js +3857 -0
  53. package/dist/chunk-BRQJKJGT.cjs +20 -0
  54. package/dist/chunk-C37BHB7N.cjs +636 -0
  55. package/dist/chunk-CBJY23VL.js +126 -0
  56. package/dist/chunk-CCATWPXM.js +778 -0
  57. package/dist/chunk-CIWWXYHZ.cjs +50 -0
  58. package/dist/chunk-CMT5NMMS.js +669 -0
  59. package/dist/chunk-CR4FMIWL.cjs +1049 -0
  60. package/dist/chunk-CR7XRXRN.cjs +639 -0
  61. package/dist/chunk-CSD27UNQ.js +2176 -0
  62. package/dist/chunk-D3STJ56J.js +714 -0
  63. package/dist/chunk-DAJXW4KX.js +725 -0
  64. package/dist/chunk-DHO2YRIM.js +756 -0
  65. package/dist/chunk-DTGBOSEM.cjs +319 -0
  66. package/dist/chunk-E6XXE66V.js +2252 -0
  67. package/dist/chunk-E7JP3BS3.cjs +61 -0
  68. package/dist/chunk-EKBKLK7P.js +1169 -0
  69. package/dist/chunk-EKYL4PE3.cjs +404 -0
  70. package/dist/chunk-EXKSFGSX.cjs +274 -0
  71. package/dist/chunk-EXUP2BUM.cjs +1173 -0
  72. package/dist/chunk-FDSGHPAK.js +130 -0
  73. package/dist/chunk-FEWUHQNM.cjs +144 -0
  74. package/dist/chunk-FFAOS5HQ.js +70 -0
  75. package/dist/chunk-FGGJQRLZ.js +270 -0
  76. package/dist/chunk-FHP6LXJS.js +415 -0
  77. package/dist/chunk-FJPADH77.cjs +666 -0
  78. package/dist/chunk-FL33V6U7.js +421 -0
  79. package/dist/chunk-FYSPZT4V.cjs +169 -0
  80. package/dist/chunk-GIOYPNTH.js +5575 -0
  81. package/dist/chunk-GJNCFRJU.cjs +125 -0
  82. package/dist/chunk-GMP623FG.cjs +1508 -0
  83. package/dist/chunk-GQHQOPXZ.cjs +5580 -0
  84. package/dist/chunk-GTU2Z2WW.cjs +262 -0
  85. package/dist/chunk-GYZE55MO.js +2007 -0
  86. package/dist/chunk-GZG4KA4E.js +529 -0
  87. package/dist/chunk-H652NHX5.js +600 -0
  88. package/dist/chunk-HCCQLAA4.cjs +74 -0
  89. package/dist/chunk-HKEXJUWS.cjs +4007 -0
  90. package/dist/chunk-HNDK4IQU.cjs +5737 -0
  91. package/dist/chunk-HR2OSYVQ.js +56165 -0
  92. package/dist/chunk-HYNTS5CP.js +422 -0
  93. package/dist/chunk-I6XZ5DZF.cjs +488 -0
  94. package/dist/chunk-ILRBGFVD.cjs +72 -0
  95. package/dist/chunk-IUDGEUDO.cjs +1409 -0
  96. package/dist/chunk-IUTY5WQ2.cjs +424 -0
  97. package/dist/chunk-IVY74O6C.js +247 -0
  98. package/dist/chunk-IWC5DM2M.cjs +611 -0
  99. package/dist/chunk-J32ZJZJH.js +554 -0
  100. package/dist/chunk-J52VSAQ7.js +6884 -0
  101. package/dist/chunk-J6M4FPK5.js +421 -0
  102. package/dist/chunk-J7XZV333.js +844 -0
  103. package/dist/chunk-JBNDTXXV.cjs +2433 -0
  104. package/dist/chunk-JC5YBPSF.cjs +984 -0
  105. package/dist/chunk-JD7CIZ33.js +1949 -0
  106. package/dist/chunk-JIBL5LRK.js +4287 -0
  107. package/dist/chunk-JIYN45TV.cjs +2525 -0
  108. package/dist/chunk-K574J76X.cjs +457 -0
  109. package/dist/chunk-KHDZJE5D.cjs +2196 -0
  110. package/dist/chunk-KKFZ3B6J.cjs +557 -0
  111. package/dist/chunk-KKP7JKN4.cjs +6002 -0
  112. package/dist/chunk-KPJL34Y7.cjs +186 -0
  113. package/dist/chunk-KQCN6AKJ.cjs +3042 -0
  114. package/dist/chunk-L5LKKENW.cjs +424 -0
  115. package/dist/chunk-LHAXPADA.js +882 -0
  116. package/dist/chunk-LM2VU56C.cjs +37 -0
  117. package/dist/chunk-M56JSP4A.js +400 -0
  118. package/dist/chunk-MBOOR7X4.js +18 -0
  119. package/dist/chunk-MQWAT42R.cjs +4310 -0
  120. package/dist/chunk-MXFUTKCO.js +56 -0
  121. package/dist/chunk-MYY4PMWX.cjs +264 -0
  122. package/dist/chunk-N75IH2HY.js +258 -0
  123. package/dist/chunk-NCWCUZNS.cjs +72 -0
  124. package/dist/chunk-NG77ATEW.cjs +778 -0
  125. package/dist/chunk-NW5G5FBQ.js +215 -0
  126. package/dist/chunk-OBIYPYYS.cjs +1993 -0
  127. package/dist/chunk-OH2FAIVU.js +608 -0
  128. package/dist/chunk-OIQYIIO3.cjs +473 -0
  129. package/dist/chunk-OL46QLBJ.js +61 -0
  130. package/dist/chunk-OMXII44L.js +5386 -0
  131. package/dist/chunk-OSYNRVOV.cjs +243 -0
  132. package/dist/chunk-PGANYCAG.cjs +220 -0
  133. package/dist/chunk-PHENW4MQ.js +65 -0
  134. package/dist/chunk-PY37LNDP.js +686 -0
  135. package/dist/chunk-Q56TT7IL.js +483 -0
  136. package/dist/chunk-QD32ADK6.js +1046 -0
  137. package/dist/chunk-QPOQ7VPI.js +1491 -0
  138. package/dist/chunk-QPSKHBJP.js +5963 -0
  139. package/dist/chunk-QXH7QDSZ.js +1989 -0
  140. package/dist/chunk-R24NNAEG.js +1399 -0
  141. package/dist/chunk-R75BSDH7.cjs +50 -0
  142. package/dist/chunk-RARB3MBR.js +207 -0
  143. package/dist/chunk-ROHLEP2W.cjs +847 -0
  144. package/dist/chunk-S3MDHNKB.cjs +490 -0
  145. package/dist/chunk-S6YWHCKV.cjs +410 -0
  146. package/dist/chunk-SIEXCILW.js +229 -0
  147. package/dist/chunk-SLU6UPJI.cjs +410 -0
  148. package/dist/chunk-SMIWS6DE.cjs +212 -0
  149. package/dist/chunk-T5J7ZKP3.cjs +4885 -0
  150. package/dist/chunk-TDCNJHWO.js +341 -0
  151. package/dist/chunk-TG7O4WBC.js +406 -0
  152. package/dist/chunk-THCK6ECW.js +2085 -0
  153. package/dist/chunk-TJHVSBP2.js +439 -0
  154. package/dist/chunk-TVHSPJ4N.cjs +606 -0
  155. package/dist/chunk-TWUXUCEW.cjs +781 -0
  156. package/dist/chunk-U44IKGG7.cjs +5390 -0
  157. package/dist/chunk-UFZZ7TSN.cjs +886 -0
  158. package/dist/chunk-UJXISJBN.js +487 -0
  159. package/dist/chunk-UOIGFQXC.cjs +9750 -0
  160. package/dist/chunk-URG2SJLK.js +2521 -0
  161. package/dist/chunk-UWJHCOH2.js +623 -0
  162. package/dist/chunk-V6MKC2FZ.js +979 -0
  163. package/dist/chunk-VJ3L7CHT.cjs +169 -0
  164. package/dist/chunk-VMLKSV26.js +1216 -0
  165. package/dist/chunk-VVKVQZI6.js +55 -0
  166. package/dist/chunk-W6RW64BB.cjs +1219 -0
  167. package/dist/chunk-WKX5AMOY.js +309 -0
  168. package/dist/chunk-WNNE3PO3.js +34 -0
  169. package/dist/chunk-WRKUDAZJ.js +3038 -0
  170. package/dist/chunk-WRLUBRKS.cjs +1943 -0
  171. package/dist/chunk-WRNEH5MO.js +3169 -0
  172. package/dist/chunk-WRWEX5ZF.js +658 -0
  173. package/dist/chunk-X3GJPRVK.cjs +3246 -0
  174. package/dist/chunk-X3UVCWNL.cjs +2257 -0
  175. package/dist/chunk-XB274MW5.cjs +814 -0
  176. package/dist/chunk-XHIV6326.cjs +793 -0
  177. package/dist/chunk-XIVIE43A.cjs +729 -0
  178. package/dist/chunk-XJAN7CZG.cjs +432 -0
  179. package/dist/chunk-XKTPFXGA.js +164 -0
  180. package/dist/chunk-XL6INWKT.js +121 -0
  181. package/dist/chunk-XSFNHP2E.js +632 -0
  182. package/dist/chunk-XT6JY5W5.js +9684 -0
  183. package/dist/chunk-XUILI4KB.cjs +430 -0
  184. package/dist/chunk-YF2I3MV3.js +46 -0
  185. package/dist/chunk-YIMN575O.js +4847 -0
  186. package/dist/chunk-YIVFJNYV.js +176 -0
  187. package/dist/chunk-YKGPCZEE.cjs +237 -0
  188. package/dist/chunk-YN2YWTXW.js +5731 -0
  189. package/dist/chunk-YN6V7R3L.cjs +327 -0
  190. package/dist/chunk-YQELFNJV.js +39 -0
  191. package/dist/chunk-YVD3CSO3.js +1183 -0
  192. package/dist/chunk-YVOAF4ML.js +623 -0
  193. package/dist/chunk-YWOBW2PV.cjs +759 -0
  194. package/dist/chunk-YYXH45E2.js +426 -0
  195. package/dist/chunk-ZDSYWBIE.cjs +69 -0
  196. package/dist/chunk-ZU7NIRT6.js +325 -0
  197. package/dist/chunk-ZZ7RO2UQ.js +1243 -0
  198. package/dist/cli/holoscript-runner.cjs +2255 -0
  199. package/dist/cli/holoscript-runner.js +2230 -0
  200. package/dist/codebase/index.cjs +336 -0
  201. package/dist/codebase/index.js +331 -0
  202. package/dist/compiler/agent-inference.cjs +31 -0
  203. package/dist/compiler/agent-inference.js +8 -0
  204. package/dist/compiler/android-xr.cjs +24 -0
  205. package/dist/compiler/android-xr.js +14 -0
  206. package/dist/compiler/android.cjs +24 -0
  207. package/dist/compiler/android.js +14 -0
  208. package/dist/compiler/ar.cjs +23 -0
  209. package/dist/compiler/ar.js +11 -0
  210. package/dist/compiler/babylon.cjs +21 -0
  211. package/dist/compiler/babylon.js +15 -0
  212. package/dist/compiler/business-quest.cjs +43 -0
  213. package/dist/compiler/business-quest.js +4 -0
  214. package/dist/compiler/coco.cjs +27 -0
  215. package/dist/compiler/coco.js +4 -0
  216. package/dist/compiler/context.cjs +25 -0
  217. package/dist/compiler/context.d.ts +28 -0
  218. package/dist/compiler/context.js +8 -0
  219. package/dist/compiler/domain-block-utils.cjs +609 -0
  220. package/dist/compiler/domain-block-utils.js +11 -0
  221. package/dist/compiler/dtdl.cjs +27 -0
  222. package/dist/compiler/dtdl.js +11 -0
  223. package/dist/compiler/gltf-pipeline.cjs +39 -0
  224. package/dist/compiler/gltf-pipeline.js +4 -0
  225. package/dist/compiler/godot.cjs +18 -0
  226. package/dist/compiler/godot.js +12 -0
  227. package/dist/compiler/incremental.cjs +34 -0
  228. package/dist/compiler/incremental.js +9 -0
  229. package/dist/compiler/index.cjs +5408 -0
  230. package/dist/compiler/index.d.ts +334 -21
  231. package/dist/compiler/index.js +5069 -0
  232. package/dist/compiler/ios.cjs +23 -0
  233. package/dist/compiler/ios.js +13 -0
  234. package/dist/compiler/llm-provider-capabilities.cjs +25 -0
  235. package/dist/compiler/llm-provider-capabilities.d.ts +43 -0
  236. package/dist/compiler/llm-provider-capabilities.js +8 -0
  237. package/dist/compiler/multi-layer.cjs +24 -0
  238. package/dist/compiler/multi-layer.js +15 -0
  239. package/dist/compiler/nodetoy.cjs +23 -0
  240. package/dist/compiler/nodetoy.d.ts +69 -0
  241. package/dist/compiler/nodetoy.js +4 -0
  242. package/dist/compiler/openxr.cjs +19 -0
  243. package/dist/compiler/openxr.js +13 -0
  244. package/dist/compiler/playcanvas.cjs +19 -0
  245. package/dist/compiler/playcanvas.js +13 -0
  246. package/dist/compiler/r3f.cjs +39 -0
  247. package/dist/compiler/r3f.d.ts +22 -0
  248. package/dist/compiler/r3f.js +17 -0
  249. package/dist/compiler/remotion.cjs +23 -0
  250. package/dist/compiler/remotion.js +4 -0
  251. package/dist/compiler/reproducibility.cjs +39 -0
  252. package/dist/compiler/reproducibility.js +4 -0
  253. package/dist/compiler/sdf.cjs +24 -0
  254. package/dist/compiler/sdf.js +12 -0
  255. package/dist/compiler/semantic-scene.cjs +31 -0
  256. package/dist/compiler/semantic-scene.js +4 -0
  257. package/dist/compiler/state.cjs +21 -0
  258. package/dist/compiler/state.js +11 -0
  259. package/dist/compiler/trait-composition.cjs +30 -0
  260. package/dist/compiler/trait-composition.js +9 -0
  261. package/dist/compiler/unity.cjs +19 -0
  262. package/dist/compiler/unity.js +13 -0
  263. package/dist/compiler/unreal.cjs +23 -0
  264. package/dist/compiler/unreal.js +13 -0
  265. package/dist/compiler/urdf.cjs +52 -0
  266. package/dist/compiler/urdf.js +12 -0
  267. package/dist/compiler/usd-physics.cjs +26 -0
  268. package/dist/compiler/usd-physics.js +9 -0
  269. package/dist/compiler/visionos.cjs +19 -0
  270. package/dist/compiler/visionos.js +13 -0
  271. package/dist/compiler/vrchat.cjs +22 -0
  272. package/dist/compiler/vrchat.js +12 -0
  273. package/dist/compiler/vrr.cjs +24 -0
  274. package/dist/compiler/vrr.js +12 -0
  275. package/dist/compiler/wasm.cjs +36 -0
  276. package/dist/compiler/wasm.js +12 -0
  277. package/dist/compiler/webgpu.cjs +18 -0
  278. package/dist/compiler/webgpu.js +12 -0
  279. package/dist/coordinators/index.cjs +1266 -0
  280. package/dist/coordinators/index.d.ts +72 -1
  281. package/dist/coordinators/index.js +1259 -0
  282. package/dist/debugger.cjs +24 -0
  283. package/dist/debugger.js +11 -0
  284. package/dist/dist-ACXG6IH5.cjs +3113 -0
  285. package/dist/dist-VD4L6V7Q.js +3076 -0
  286. package/dist/entries/interop.cjs +64 -0
  287. package/dist/entries/interop.js +7 -0
  288. package/dist/entries/scripting.cjs +55 -0
  289. package/dist/entries/scripting.js +10 -0
  290. package/dist/hololand/index.cjs +146 -0
  291. package/dist/hololand/index.d.ts +70 -0
  292. package/dist/hololand/index.js +5 -0
  293. package/dist/index.cjs +44660 -0
  294. package/dist/index.d.ts +978 -21
  295. package/dist/index.js +41422 -0
  296. package/dist/math/tropical-spmv.cjs +45 -0
  297. package/dist/math/tropical-spmv.js +4 -0
  298. package/dist/math/vec3.cjs +57 -0
  299. package/dist/math/vec3.js +4 -0
  300. package/dist/ml-dsa-FSKBTE3W.cjs +1265 -0
  301. package/dist/ml-dsa-Z7JDKW4L.js +1265 -0
  302. package/dist/paper-0c-spike/index.cjs +150 -0
  303. package/dist/paper-0c-spike/index.js +141 -0
  304. package/dist/parser.cjs +61 -0
  305. package/dist/parser.d.ts +11 -0
  306. package/dist/parser.js +12 -0
  307. package/dist/playwright-3AT3AKTV.cjs +98673 -0
  308. package/dist/playwright-VZPDVUEQ.js +98660 -0
  309. package/dist/reconstruction/index.cjs +153 -0
  310. package/dist/reconstruction/index.d.ts +29 -2
  311. package/dist/reconstruction/index.js +8 -0
  312. package/dist/runtime.cjs +316 -0
  313. package/dist/runtime.d.ts +61 -0
  314. package/dist/runtime.js +31 -0
  315. package/dist/self-improvement/index.cjs +563 -0
  316. package/dist/self-improvement/index.js +545 -0
  317. package/dist/src-4ROC227P.cjs +2094 -0
  318. package/dist/src-HCCCSYP7.js +2073 -0
  319. package/dist/storage/index.cjs +38 -0
  320. package/dist/storage/index.js +5 -0
  321. package/dist/testing.cjs +25 -0
  322. package/dist/testing.d.ts +70 -0
  323. package/dist/testing.js +4 -0
  324. package/dist/traitDocs/traitDocs.cjs +33 -0
  325. package/dist/traitDocs/traitDocs.js +7 -0
  326. package/dist/traits/botanical-lotus.cjs +177 -0
  327. package/dist/traits/botanical-lotus.d.ts +502 -0
  328. package/dist/traits/botanical-lotus.js +7 -0
  329. package/dist/traits/engines/index.cjs +520 -0
  330. package/dist/traits/engines/index.js +380 -0
  331. package/dist/traits/index.cjs +24548 -0
  332. package/dist/traits/index.d.ts +171 -35
  333. package/dist/traits/index.js +21638 -0
  334. package/dist/traits/simulation-solver-factory.cjs +13 -0
  335. package/dist/traits/simulation-solver-factory.d.ts +23 -0
  336. package/dist/traits/simulation-solver-factory.js +4 -0
  337. package/dist/traits/webcam-gaze.cjs +35 -0
  338. package/dist/traits/webcam-gaze.d.ts +17 -0
  339. package/dist/traits/webcam-gaze.js +4 -0
  340. package/dist/type-checker.cjs +19 -0
  341. package/dist/type-checker.js +6 -0
  342. package/dist/world/index.cjs +947 -0
  343. package/dist/world/index.d.ts +147 -0
  344. package/dist/world/index.js +939 -0
  345. package/dist/world-model/index.cjs +1446 -0
  346. package/dist/world-model/index.d.ts +119 -0
  347. package/dist/world-model/index.js +1414 -0
  348. package/dist/wot/index.cjs +29 -0
  349. package/dist/wot/index.js +4 -0
  350. package/package.json +93 -49
@@ -0,0 +1,2525 @@
1
+ 'use strict';
2
+
3
+ var chunkILRBGFVD_cjs = require('./chunk-ILRBGFVD.cjs');
4
+
5
+ // src/HoloScriptPersistenceParser.ts
6
+ var HoloScriptPersistenceParser = class {
7
+ constructor(context) {
8
+ this.ctx = context;
9
+ }
10
+ /**
11
+ * Parse memory primitive block
12
+ * memory <Name> { semantic: SemanticMemory { ... }, episodic: EpisodicMemory { ... }, procedural: ProceduralMemory { ... } }
13
+ */
14
+ parseMemory() {
15
+ const startToken = this.ctx.check("keyword", "memory");
16
+ if (!startToken) {
17
+ return null;
18
+ }
19
+ this.ctx.advance();
20
+ const name = this.ctx.expectIdentifier() || "UnnamedMemory";
21
+ const node = {
22
+ type: "memory",
23
+ name,
24
+ position: [0, 0, 0]
25
+ };
26
+ if (this.ctx.check("punctuation", "{")) {
27
+ this.ctx.advance();
28
+ while (!this.ctx.check("punctuation", "}") && this.ctx.position < this.ctx.tokens.length) {
29
+ this.ctx.skipNewlines();
30
+ if (this.ctx.check("punctuation", "}")) break;
31
+ const keyToken = this.ctx.currentToken();
32
+ if (!keyToken || keyToken.type !== "identifier" && keyToken.type !== "keyword") {
33
+ this.ctx.advance();
34
+ continue;
35
+ }
36
+ const key = keyToken.value;
37
+ this.ctx.advance();
38
+ if (this.ctx.check("punctuation", ":")) {
39
+ this.ctx.advance();
40
+ }
41
+ const typeToken = this.ctx.currentToken();
42
+ if (typeToken && (typeToken.type === "identifier" || typeToken.type === "keyword")) {
43
+ this.ctx.advance();
44
+ if (this.ctx.check("punctuation", "{")) {
45
+ const properties = this.ctx.parseObject();
46
+ if (key === "semantic" && typeToken.value === "SemanticMemory") {
47
+ node.semantic = {
48
+ type: "semantic-memory",
49
+ properties,
50
+ position: [0, 0, 0]
51
+ };
52
+ } else if (key === "episodic" && typeToken.value === "EpisodicMemory") {
53
+ node.episodic = {
54
+ type: "episodic-memory",
55
+ properties,
56
+ position: [0, 0, 0]
57
+ };
58
+ } else if (key === "procedural" && typeToken.value === "ProceduralMemory") {
59
+ node.procedural = {
60
+ type: "procedural-memory",
61
+ properties,
62
+ position: [0, 0, 0]
63
+ };
64
+ }
65
+ }
66
+ }
67
+ if (this.ctx.check("punctuation", ",")) {
68
+ this.ctx.advance();
69
+ }
70
+ }
71
+ this.ctx.expect("punctuation", "}");
72
+ }
73
+ return node;
74
+ }
75
+ };
76
+
77
+ // src/HoloScriptCodeParser.ts
78
+ var ObjectPool = class {
79
+ constructor(createFn, resetFn, maxSize = 100) {
80
+ this.pool = [];
81
+ this.createFn = createFn;
82
+ this.resetFn = resetFn;
83
+ this.maxSize = maxSize;
84
+ }
85
+ /** Get an object from pool or create new one */
86
+ acquire() {
87
+ if (this.pool.length > 0) {
88
+ return this.pool.pop();
89
+ }
90
+ return this.createFn();
91
+ }
92
+ /** Return object to pool for reuse */
93
+ release(obj) {
94
+ if (this.pool.length < this.maxSize) {
95
+ this.resetFn(obj);
96
+ this.pool.push(obj);
97
+ }
98
+ }
99
+ /** Clear the pool */
100
+ clear() {
101
+ this.pool.length = 0;
102
+ }
103
+ /** Get pool statistics */
104
+ get stats() {
105
+ return { pooled: this.pool.length, maxSize: this.maxSize };
106
+ }
107
+ };
108
+ var tokenPool = new ObjectPool(
109
+ () => ({ type: "", value: "", line: 0, column: 0 }),
110
+ (t) => {
111
+ t.type = "";
112
+ t.value = "";
113
+ t.line = 0;
114
+ t.column = 0;
115
+ }
116
+ );
117
+ var arrayPool = new ObjectPool(
118
+ () => [],
119
+ (arr) => {
120
+ arr.length = 0;
121
+ },
122
+ 50
123
+ );
124
+ var ParserPools = {
125
+ token: tokenPool,
126
+ array: arrayPool,
127
+ clearAll: () => {
128
+ tokenPool.clear();
129
+ arrayPool.clear();
130
+ },
131
+ getStats: () => ({
132
+ token: tokenPool.stats,
133
+ array: arrayPool.stats
134
+ })
135
+ };
136
+ var CODE_SECURITY_CONFIG = {
137
+ maxCodeLength: 5e4,
138
+ maxBlocks: 100,
139
+ suspiciousKeywords: [
140
+ "process",
141
+ "require",
142
+ "eval",
143
+ "constructor",
144
+ "prototype",
145
+ "__proto__",
146
+ "fs",
147
+ "child_process",
148
+ "exec",
149
+ "spawn"
150
+ ]
151
+ };
152
+ function stripCommentsAndStrings(code) {
153
+ let result = "";
154
+ let i = 0;
155
+ while (i < code.length) {
156
+ if (code[i] === "/" && code[i + 1] === "/") {
157
+ while (i < code.length && code[i] !== "\n") i++;
158
+ continue;
159
+ }
160
+ if (code[i] === "/" && code[i + 1] === "*") {
161
+ i += 2;
162
+ while (i < code.length - 1 && !(code[i] === "*" && code[i + 1] === "/")) i++;
163
+ i += 2;
164
+ continue;
165
+ }
166
+ if (code[i] === '"') {
167
+ i++;
168
+ while (i < code.length && code[i] !== '"') {
169
+ if (code[i] === "\\" && i + 1 < code.length) i++;
170
+ i++;
171
+ }
172
+ i++;
173
+ continue;
174
+ }
175
+ if (code[i] === "'") {
176
+ i++;
177
+ while (i < code.length && code[i] !== "'") {
178
+ if (code[i] === "\\" && i + 1 < code.length) i++;
179
+ i++;
180
+ }
181
+ i++;
182
+ continue;
183
+ }
184
+ result += code[i];
185
+ i++;
186
+ }
187
+ return result;
188
+ }
189
+ var ERROR_CODES = {
190
+ HS001: "Expected keyword - a required keyword is missing",
191
+ HS002: "Expected identifier - a name is required here",
192
+ HS003: "Expected operator - an operator like = or : is required",
193
+ HS004: "Unexpected token - this token is not valid in this context",
194
+ HS005: "Unclosed block - missing closing brace }",
195
+ HS006: "Unclosed string - missing closing quote",
196
+ HS007: "Invalid number - numeric literal is malformed",
197
+ HS008: "Unknown keyword - this keyword is not recognized",
198
+ HS009: "Too many items - limit exceeded for performance",
199
+ HS010: "Security violation - blocked for security reasons"
200
+ };
201
+ var HoloScriptCodeParser = class {
202
+ constructor() {
203
+ this.errors = [];
204
+ this.warnings = [];
205
+ this.tokens = [];
206
+ this.position = 0;
207
+ /** Source code lines for error context */
208
+ this.sourceLines = [];
209
+ this.persistenceParser = new HoloScriptPersistenceParser(this);
210
+ this.keywordSet = /* @__PURE__ */ new Set([
211
+ "orb",
212
+ "function",
213
+ "connect",
214
+ "to",
215
+ "as",
216
+ "gate",
217
+ "stream",
218
+ "from",
219
+ "through",
220
+ "return",
221
+ "if",
222
+ "else",
223
+ "nexus",
224
+ "building",
225
+ "pillar",
226
+ "foundation",
227
+ "for",
228
+ "while",
229
+ "forEach",
230
+ "in",
231
+ "of",
232
+ "break",
233
+ "continue",
234
+ "import",
235
+ "export",
236
+ "module",
237
+ "use",
238
+ "type",
239
+ "interface",
240
+ "extends",
241
+ "implements",
242
+ "is",
243
+ "async",
244
+ "await",
245
+ "spawn",
246
+ "parallel",
247
+ "class",
248
+ "new",
249
+ "this",
250
+ "super",
251
+ "static",
252
+ "private",
253
+ "public",
254
+ "try",
255
+ "catch",
256
+ "finally",
257
+ "throw",
258
+ "const",
259
+ "let",
260
+ "var",
261
+ "animate",
262
+ "modify",
263
+ "pulse",
264
+ "move",
265
+ "show",
266
+ "hide",
267
+ "scale",
268
+ "focus",
269
+ "environment",
270
+ "composition",
271
+ "template",
272
+ "settings",
273
+ "chat",
274
+ "migrate",
275
+ // Shape keywords for 3D objects
276
+ "cube",
277
+ "sphere",
278
+ "plane",
279
+ "cylinder",
280
+ "cone",
281
+ "torus",
282
+ "pyramid",
283
+ "box",
284
+ "mesh",
285
+ "model",
286
+ "object",
287
+ "light",
288
+ "camera",
289
+ // System and component keywords (Phase 0: Hololand Bootstrap)
290
+ "system",
291
+ "component",
292
+ "action",
293
+ "props",
294
+ // Additional scene keywords
295
+ "npc",
296
+ "player",
297
+ "entity",
298
+ "trigger",
299
+ "zone",
300
+ "portal",
301
+ "spatial_group",
302
+ "interactive",
303
+ "traits",
304
+ "on_interact",
305
+ "on_collision",
306
+ "on_enter",
307
+ "on_exit",
308
+ "using",
309
+ "memory",
310
+ "semantic",
311
+ "episodic",
312
+ "procedural"
313
+ ]);
314
+ }
315
+ /**
316
+ * Create a rich error with context and suggestions
317
+ */
318
+ createError(code, message, token, suggestion) {
319
+ const line = token?.line || 0;
320
+ const column = token?.column || 0;
321
+ let context = "";
322
+ if (this.sourceLines.length > 0 && line > 0) {
323
+ const lines = [];
324
+ if (line > 1) lines.push(`${line - 1} | ${this.sourceLines[line - 2] || ""}`);
325
+ lines.push(`${line} | ${this.sourceLines[line - 1] || ""}`);
326
+ lines.push(` ${" ".repeat(column)}^`);
327
+ if (line < this.sourceLines.length)
328
+ lines.push(`${line + 1} | ${this.sourceLines[line] || ""}`);
329
+ context = lines.join("\n");
330
+ }
331
+ return {
332
+ line,
333
+ column,
334
+ message,
335
+ code,
336
+ context,
337
+ suggestion,
338
+ severity: "error"
339
+ };
340
+ }
341
+ /**
342
+ * Find similar keywords for "did you mean" suggestions
343
+ */
344
+ findSimilarKeyword(word) {
345
+ if (!word) return void 0;
346
+ const lower = word.toLowerCase();
347
+ let bestMatch;
348
+ let bestScore = 0;
349
+ for (const keyword of this.keywordSet) {
350
+ const score = this.similarity(lower, keyword);
351
+ if (score > bestScore && score > 0.6) {
352
+ bestScore = score;
353
+ bestMatch = keyword;
354
+ }
355
+ }
356
+ return bestMatch;
357
+ }
358
+ /**
359
+ * Simple Levenshtein-based similarity (0-1)
360
+ */
361
+ similarity(a, b) {
362
+ if (a === b) return 1;
363
+ if (a.length === 0 || b.length === 0) return 0;
364
+ const len = Math.max(a.length, b.length);
365
+ let matches = 0;
366
+ for (let i = 0; i < Math.min(a.length, b.length); i++) {
367
+ if (a[i] === b[i]) matches++;
368
+ }
369
+ if (a.startsWith(b) || b.startsWith(a)) {
370
+ matches = Math.max(matches, Math.min(a.length, b.length));
371
+ }
372
+ return matches / len;
373
+ }
374
+ /**
375
+ * Add error and continue parsing (error recovery)
376
+ */
377
+ addError(error) {
378
+ if (!this.errors.some((e) => e.line === error.line && e.message === error.message)) {
379
+ this.errors.push(error);
380
+ }
381
+ }
382
+ /**
383
+ * Recover from error by skipping to next statement boundary
384
+ */
385
+ synchronize() {
386
+ while (this.position < this.tokens.length) {
387
+ const token = this.currentToken();
388
+ if (!token) break;
389
+ if (token.type === "newline") {
390
+ this.advance();
391
+ break;
392
+ }
393
+ if (token.type === "keyword" && [
394
+ "orb",
395
+ "function",
396
+ "gate",
397
+ "for",
398
+ "while",
399
+ "if",
400
+ "return",
401
+ "object",
402
+ "template",
403
+ "composition",
404
+ "spatial_group",
405
+ "logic"
406
+ ].includes(token.value)) {
407
+ break;
408
+ }
409
+ if (token.type === "punctuation" && ["}", ";"].includes(token.value)) {
410
+ this.advance();
411
+ break;
412
+ }
413
+ this.advance();
414
+ }
415
+ }
416
+ /**
417
+ * Parse HoloScript code string into AST
418
+ */
419
+ parse(code) {
420
+ this.errors = [];
421
+ this.warnings = [];
422
+ this.tokens = [];
423
+ this.position = 0;
424
+ this.sourceLines = code.split("\n");
425
+ if (code.length > CODE_SECURITY_CONFIG.maxCodeLength) {
426
+ return {
427
+ success: false,
428
+ ast: [],
429
+ errors: [
430
+ {
431
+ line: 0,
432
+ column: 0,
433
+ message: `Code exceeds max length (${CODE_SECURITY_CONFIG.maxCodeLength})`,
434
+ code: "HS009",
435
+ severity: "error"
436
+ }
437
+ ],
438
+ warnings: []
439
+ };
440
+ }
441
+ const strippedCode = stripCommentsAndStrings(code).toLowerCase();
442
+ for (const keyword of CODE_SECURITY_CONFIG.suspiciousKeywords) {
443
+ const regex = new RegExp(`\\b${keyword}\\b`, "i");
444
+ if (regex.test(strippedCode)) {
445
+ chunkILRBGFVD_cjs.logger.warn("Suspicious keyword detected", { keyword });
446
+ return {
447
+ success: false,
448
+ ast: [],
449
+ errors: [
450
+ {
451
+ line: 0,
452
+ column: 0,
453
+ message: `Suspicious keyword detected: ${keyword}`,
454
+ code: "HS010",
455
+ severity: "error"
456
+ }
457
+ ],
458
+ warnings: []
459
+ };
460
+ }
461
+ }
462
+ try {
463
+ this.tokens = this.tokenize(code);
464
+ const ast = this.parseProgram();
465
+ return {
466
+ success: this.errors.length === 0,
467
+ ast,
468
+ errors: this.errors,
469
+ warnings: this.warnings
470
+ };
471
+ } catch (error) {
472
+ this.addError({
473
+ line: 0,
474
+ column: 0,
475
+ message: String(error),
476
+ code: "HS004",
477
+ severity: "error"
478
+ });
479
+ return {
480
+ success: false,
481
+ ast: [],
482
+ errors: this.errors,
483
+ warnings: this.warnings
484
+ };
485
+ }
486
+ }
487
+ /**
488
+ * Tokenize code into tokens
489
+ */
490
+ tokenize(code) {
491
+ const tokens = [];
492
+ let line = 1;
493
+ let column = 1;
494
+ let i = 0;
495
+ while (i < code.length) {
496
+ const char = code[i];
497
+ if (char === " " || char === " " || char === "\r") {
498
+ i++;
499
+ column++;
500
+ continue;
501
+ }
502
+ if (char === "\n") {
503
+ tokens.push({ type: "newline", value: "\n", line, column });
504
+ line++;
505
+ column = 1;
506
+ i++;
507
+ continue;
508
+ }
509
+ if (char === "/" && code[i + 1] === "/") {
510
+ while (i < code.length && code[i] !== "\n") {
511
+ i++;
512
+ }
513
+ continue;
514
+ }
515
+ if (char === '"' || char === "'") {
516
+ const quote = char;
517
+ let str = "";
518
+ const startCol = column;
519
+ i++;
520
+ column++;
521
+ while (i < code.length && code[i] !== quote) {
522
+ if (code[i] === "\\" && i + 1 < code.length) {
523
+ str += code[i + 1];
524
+ i += 2;
525
+ column += 2;
526
+ } else {
527
+ str += code[i];
528
+ i++;
529
+ column++;
530
+ }
531
+ }
532
+ i++;
533
+ column++;
534
+ tokens.push({ type: "string", value: str, line, column: startCol });
535
+ continue;
536
+ }
537
+ if (/[0-9]/.test(char) || char === "-" && /[0-9]/.test(code[i + 1])) {
538
+ let num = "";
539
+ const startCol = column;
540
+ while (i < code.length && /[0-9.\-]/.test(code[i])) {
541
+ num += code[i];
542
+ i++;
543
+ column++;
544
+ }
545
+ tokens.push({ type: "number", value: num, line, column: startCol });
546
+ continue;
547
+ }
548
+ if (/[a-zA-Z_]/.test(char)) {
549
+ let ident = "";
550
+ const startCol = column;
551
+ while (i < code.length && /[a-zA-Z0-9_]/.test(code[i])) {
552
+ ident += code[i];
553
+ i++;
554
+ column++;
555
+ }
556
+ const isKeyword = this.keywordSet.has(ident.toLowerCase());
557
+ tokens.push({
558
+ type: isKeyword ? "keyword" : "identifier",
559
+ value: ident,
560
+ line,
561
+ column: startCol
562
+ });
563
+ continue;
564
+ }
565
+ const multiCharOps = [
566
+ "===",
567
+ "!==",
568
+ "==",
569
+ "!=",
570
+ ">=",
571
+ "<=",
572
+ "&&",
573
+ "||",
574
+ "??",
575
+ "?.",
576
+ "++",
577
+ "--",
578
+ "+=",
579
+ "-=",
580
+ "*=",
581
+ "/=",
582
+ "%=",
583
+ "=>",
584
+ "->"
585
+ ];
586
+ let foundMultiOp = false;
587
+ for (const op of multiCharOps) {
588
+ if (code.substring(i, i + op.length) === op) {
589
+ tokens.push({ type: "operator", value: op, line, column });
590
+ i += op.length;
591
+ column += op.length;
592
+ foundMultiOp = true;
593
+ break;
594
+ }
595
+ }
596
+ if (foundMultiOp) continue;
597
+ const punctuation = [
598
+ "{",
599
+ "}",
600
+ "(",
601
+ ")",
602
+ "[",
603
+ "]",
604
+ ":",
605
+ ",",
606
+ ".",
607
+ ";",
608
+ "=",
609
+ "<",
610
+ ">",
611
+ "+",
612
+ "-",
613
+ "*",
614
+ "/",
615
+ "%",
616
+ "!",
617
+ "&",
618
+ "|",
619
+ "?",
620
+ "#",
621
+ "@"
622
+ ];
623
+ if (punctuation.includes(char)) {
624
+ tokens.push({ type: "punctuation", value: char, line, column });
625
+ i++;
626
+ column++;
627
+ continue;
628
+ }
629
+ i++;
630
+ column++;
631
+ }
632
+ return tokens;
633
+ }
634
+ /**
635
+ * Parse program (list of declarations)
636
+ */
637
+ parseProgram() {
638
+ const nodes = [];
639
+ let blockCount = 0;
640
+ const maxErrors = 50;
641
+ while (this.position < this.tokens.length) {
642
+ if (this.errors.length >= maxErrors) {
643
+ this.addError({
644
+ line: 0,
645
+ column: 0,
646
+ message: `Too many errors (${maxErrors}+), stopping parse`,
647
+ code: "HS009",
648
+ severity: "error"
649
+ });
650
+ break;
651
+ }
652
+ while (this.currentToken()?.type === "newline") {
653
+ this.advance();
654
+ }
655
+ if (this.position >= this.tokens.length) break;
656
+ blockCount++;
657
+ if (blockCount > CODE_SECURITY_CONFIG.maxBlocks) {
658
+ this.addError({
659
+ line: 0,
660
+ column: 0,
661
+ message: "Too many blocks in program",
662
+ code: "HS009",
663
+ severity: "error"
664
+ });
665
+ break;
666
+ }
667
+ const errorCountBefore = this.errors.length;
668
+ const node = this.parseDeclaration();
669
+ if (node) {
670
+ nodes.push(node);
671
+ } else if (this.errors.length > errorCountBefore) {
672
+ this.synchronize();
673
+ }
674
+ }
675
+ return nodes;
676
+ }
677
+ /**
678
+ * Parse a single declaration
679
+ */
680
+ parseDeclaration() {
681
+ const token = this.currentToken();
682
+ if (!token) return null;
683
+ if (token.type === "keyword") {
684
+ switch (token.value.toLowerCase()) {
685
+ case "orb":
686
+ case "object":
687
+ return this.parseOrb();
688
+ case "function":
689
+ return this.parseFunction();
690
+ case "connect":
691
+ return this.parseConnection();
692
+ case "gate":
693
+ case "if":
694
+ return this.parseGate();
695
+ case "return":
696
+ return this.parseReturn();
697
+ case "stream":
698
+ return this.parseStream();
699
+ case "nexus":
700
+ return this.parseNexus();
701
+ case "building":
702
+ case "class":
703
+ return this.parseBuilding();
704
+ // Phase 2: Loop constructs
705
+ case "for":
706
+ return this.parseForLoop();
707
+ case "while":
708
+ return this.parseWhileLoop();
709
+ case "foreach":
710
+ return this.parseForEachLoop();
711
+ // Phase 2: Module system
712
+ case "import":
713
+ return this.parseImport();
714
+ case "export":
715
+ return this.parseExport();
716
+ // Phase 2: Variable declarations
717
+ // UI Extensions
718
+ case "ui2d":
719
+ case "card":
720
+ case "metric":
721
+ case "button":
722
+ case "row":
723
+ case "col":
724
+ case "text":
725
+ return this.parseUIElement();
726
+ case "const":
727
+ case "let":
728
+ case "var":
729
+ return this.parseVariableDeclaration();
730
+ // DSL-first commands (Phase 54)
731
+ case "animate":
732
+ return this.parseAnimate();
733
+ case "modify":
734
+ return this.parseModify();
735
+ case "scale":
736
+ return this.parseScale();
737
+ case "focus":
738
+ return this.parseFocus();
739
+ case "environment":
740
+ return this.parseEnvironment();
741
+ case "composition":
742
+ return this.parseComposition();
743
+ case "template":
744
+ return this.parseTemplate();
745
+ case "system":
746
+ return this.parseSystem();
747
+ case "component":
748
+ return this.parseComponent();
749
+ case "migrate":
750
+ return this.parseMigration();
751
+ case "settings":
752
+ return this.parseSettings();
753
+ case "chat":
754
+ return this.parseChat();
755
+ // Primitive 3D shapes (Phase 55)
756
+ case "cube":
757
+ case "sphere":
758
+ case "plane":
759
+ case "cylinder":
760
+ case "cone":
761
+ case "torus":
762
+ case "pyramid":
763
+ case "box":
764
+ case "mesh":
765
+ case "model":
766
+ case "light":
767
+ case "camera":
768
+ return this.parsePrimitive();
769
+ case "zone":
770
+ return this.parseZone();
771
+ case "memory":
772
+ return this.parseMemory();
773
+ default:
774
+ return this.parseExpressionStatement();
775
+ }
776
+ }
777
+ this.advance();
778
+ return null;
779
+ }
780
+ /**
781
+ * Parse for loop: for (init; condition; update) { body }
782
+ */
783
+ parseForLoop() {
784
+ this.expect("keyword", "for");
785
+ if (!this.check("punctuation", "(")) {
786
+ this.errors.push({ line: 0, column: 0, message: "Expected ( after for" });
787
+ return null;
788
+ }
789
+ this.advance();
790
+ let init = "", condition = "", update = "";
791
+ let depth = 0;
792
+ while (this.position < this.tokens.length) {
793
+ const t = this.currentToken();
794
+ if (!t) break;
795
+ if (t.value === ";" && depth === 0) {
796
+ this.advance();
797
+ break;
798
+ }
799
+ if (t.value === "(") depth++;
800
+ if (t.value === ")") depth--;
801
+ init += t.value + " ";
802
+ this.advance();
803
+ }
804
+ depth = 0;
805
+ while (this.position < this.tokens.length) {
806
+ const t = this.currentToken();
807
+ if (!t) break;
808
+ if (t.value === ";" && depth === 0) {
809
+ this.advance();
810
+ break;
811
+ }
812
+ if (t.value === "(") depth++;
813
+ if (t.value === ")") depth--;
814
+ condition += t.value + " ";
815
+ this.advance();
816
+ }
817
+ depth = 0;
818
+ while (this.position < this.tokens.length) {
819
+ const t = this.currentToken();
820
+ if (!t) break;
821
+ if (t.value === ")" && depth === 0) {
822
+ this.advance();
823
+ break;
824
+ }
825
+ if (t.value === "(") depth++;
826
+ if (t.value === ")") depth--;
827
+ update += t.value + " ";
828
+ this.advance();
829
+ }
830
+ const body = [];
831
+ if (this.check("punctuation", "{")) {
832
+ this.advance();
833
+ let braceDepth = 1;
834
+ while (braceDepth > 0 && this.position < this.tokens.length) {
835
+ if (this.check("punctuation", "{")) braceDepth++;
836
+ if (this.check("punctuation", "}")) braceDepth--;
837
+ this.advance();
838
+ }
839
+ }
840
+ return {
841
+ type: "for-loop",
842
+ init: init.trim(),
843
+ condition: this.parseConditionExpression(condition.trim()),
844
+ update: update.trim(),
845
+ body,
846
+ position: [0, 0, 0]
847
+ };
848
+ }
849
+ /**
850
+ * Parse while loop: while (condition) { body }
851
+ */
852
+ parseWhileLoop() {
853
+ this.expect("keyword", "while");
854
+ let condition = "";
855
+ if (this.check("punctuation", "(")) {
856
+ this.advance();
857
+ let depth = 1;
858
+ while (depth > 0 && this.position < this.tokens.length) {
859
+ const t = this.currentToken();
860
+ if (!t) break;
861
+ if (t.value === "(") depth++;
862
+ if (t.value === ")") {
863
+ depth--;
864
+ if (depth === 0) {
865
+ this.advance();
866
+ break;
867
+ }
868
+ }
869
+ condition += t.value + " ";
870
+ this.advance();
871
+ }
872
+ }
873
+ if (this.check("punctuation", "{")) {
874
+ this.advance();
875
+ let braceDepth = 1;
876
+ while (braceDepth > 0 && this.position < this.tokens.length) {
877
+ if (this.check("punctuation", "{")) braceDepth++;
878
+ if (this.check("punctuation", "}")) braceDepth--;
879
+ this.advance();
880
+ }
881
+ }
882
+ return {
883
+ type: "while-loop",
884
+ condition: this.parseConditionExpression(condition.trim()),
885
+ body: [],
886
+ position: [0, 0, 0]
887
+ };
888
+ }
889
+ /**
890
+ * Parse forEach loop: forEach item in collection { body }
891
+ */
892
+ parseForEachLoop() {
893
+ this.expect("keyword", "forEach");
894
+ const variable = this.expectIdentifier();
895
+ this.expect("keyword", "in");
896
+ const collection = this.expectIdentifier();
897
+ if (this.check("punctuation", "{")) {
898
+ this.advance();
899
+ let braceDepth = 1;
900
+ while (braceDepth > 0 && this.position < this.tokens.length) {
901
+ if (this.check("punctuation", "{")) braceDepth++;
902
+ if (this.check("punctuation", "}")) braceDepth--;
903
+ this.advance();
904
+ }
905
+ }
906
+ return {
907
+ type: "foreach-loop",
908
+ variable: variable || "item",
909
+ collection: collection || "items",
910
+ body: [],
911
+ position: [0, 0, 0]
912
+ };
913
+ }
914
+ /**
915
+ * Parse import: import { x, y } from "module"
916
+ */
917
+ parseImport() {
918
+ this.expect("keyword", "import");
919
+ const imports = [];
920
+ let modulePath = "";
921
+ let defaultImport;
922
+ const current = this.currentToken();
923
+ if (current?.type === "string") {
924
+ modulePath = current.value;
925
+ this.advance();
926
+ return {
927
+ type: "import",
928
+ imports: [],
929
+ modulePath,
930
+ position: [0, 0, 0]
931
+ };
932
+ }
933
+ if (this.check("punctuation", "{")) {
934
+ this.advance();
935
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
936
+ const name = this.expectIdentifier();
937
+ if (name) imports.push(name);
938
+ if (this.check("punctuation", ",")) this.advance();
939
+ }
940
+ this.expect("punctuation", "}");
941
+ } else {
942
+ defaultImport = this.expectIdentifier() || void 0;
943
+ }
944
+ if (this.check("keyword", "from")) {
945
+ this.advance();
946
+ const pathToken = this.currentToken();
947
+ if (pathToken?.type === "string") {
948
+ modulePath = pathToken.value;
949
+ this.advance();
950
+ }
951
+ }
952
+ return {
953
+ type: "import",
954
+ imports,
955
+ defaultImport,
956
+ modulePath,
957
+ position: [0, 0, 0]
958
+ };
959
+ }
960
+ /**
961
+ * Parse export: export { x, y } or export function/orb
962
+ */
963
+ parseExport() {
964
+ this.expect("keyword", "export");
965
+ const next = this.currentToken();
966
+ if (next?.type === "keyword") {
967
+ const declaration = this.parseDeclaration();
968
+ return {
969
+ type: "export",
970
+ declaration: declaration || void 0,
971
+ position: [0, 0, 0]
972
+ };
973
+ }
974
+ const exports$1 = [];
975
+ if (this.check("punctuation", "{")) {
976
+ this.advance();
977
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
978
+ const name = this.expectIdentifier();
979
+ if (name) exports$1.push(name);
980
+ if (this.check("punctuation", ",")) this.advance();
981
+ }
982
+ this.expect("punctuation", "}");
983
+ }
984
+ return {
985
+ type: "export",
986
+ exports: exports$1,
987
+ position: [0, 0, 0]
988
+ };
989
+ }
990
+ /**
991
+ * Parse variable declaration: const/let/var name = value
992
+ */
993
+ parseVariableDeclaration() {
994
+ const kindToken = this.currentToken()?.value.toLowerCase();
995
+ const kind = kindToken === "let" ? "let" : kindToken === "var" ? "var" : "const";
996
+ this.advance();
997
+ const name = this.expectIdentifier();
998
+ if (!name) return null;
999
+ let dataType;
1000
+ if (this.check("punctuation", ":")) {
1001
+ this.advance();
1002
+ dataType = this.expectIdentifier() || void 0;
1003
+ }
1004
+ const result = {
1005
+ type: "variable-declaration",
1006
+ kind,
1007
+ name,
1008
+ dataType,
1009
+ value: void 0,
1010
+ position: [0, 0, 0]
1011
+ };
1012
+ if (this.check("punctuation", "=")) {
1013
+ this.advance();
1014
+ const valueToken = this.currentToken();
1015
+ if (valueToken?.type === "string") {
1016
+ result.value = valueToken.value;
1017
+ this.advance();
1018
+ } else if (valueToken?.type === "number") {
1019
+ result.value = parseFloat(valueToken.value);
1020
+ this.advance();
1021
+ } else if (this.check("punctuation", "[")) {
1022
+ result.value = this.parseArray();
1023
+ } else if (this.check("punctuation", "{")) {
1024
+ result.value = this.parseObject();
1025
+ } else if (valueToken?.type === "identifier") {
1026
+ if (valueToken.value === "true") {
1027
+ result.value = true;
1028
+ this.advance();
1029
+ } else if (valueToken.value === "false") {
1030
+ result.value = false;
1031
+ this.advance();
1032
+ } else {
1033
+ let expression = "";
1034
+ while (this.position < this.tokens.length) {
1035
+ const t = this.currentToken();
1036
+ if (!t || t.type === "newline" || t.type === "punctuation" && t.value === ";") break;
1037
+ expression += t.value + " ";
1038
+ this.advance();
1039
+ }
1040
+ result.value = expression.trim();
1041
+ result.isExpression = true;
1042
+ }
1043
+ }
1044
+ }
1045
+ return result;
1046
+ }
1047
+ /**
1048
+ * Parse orb declaration
1049
+ */
1050
+ parseOrb() {
1051
+ const startToken = this.currentToken();
1052
+ if (this.check("keyword", "orb") || this.check("keyword", "object")) {
1053
+ this.advance();
1054
+ } else {
1055
+ this.expect("keyword", "orb");
1056
+ }
1057
+ let name = "";
1058
+ if (this.check("punctuation", "#")) {
1059
+ this.advance();
1060
+ name = this.expectName() || `orb_${Date.now()}`;
1061
+ } else {
1062
+ name = this.expectName() || `orb_${Date.now()}`;
1063
+ }
1064
+ let template;
1065
+ if (this.check("keyword", "using")) {
1066
+ this.advance();
1067
+ template = this.expectName() || void 0;
1068
+ }
1069
+ const properties = {};
1070
+ const directives = [];
1071
+ let position;
1072
+ let hologram;
1073
+ if (this.check("punctuation", "{")) {
1074
+ this.advance();
1075
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1076
+ this.skipNewlines();
1077
+ if (this.check("punctuation", "}")) break;
1078
+ if (this.check("punctuation", ",") || this.check("punctuation", ";")) {
1079
+ this.advance();
1080
+ continue;
1081
+ }
1082
+ const token = this.currentToken();
1083
+ if (token?.type === "punctuation" && token.value === "@") {
1084
+ const directive = this.parseDirective();
1085
+ if (directive) directives.push(directive);
1086
+ } else {
1087
+ const prop = this.parseProperty();
1088
+ if (prop) {
1089
+ if (prop.key === "position" || prop.key === "at") {
1090
+ position = this.parsePosition(prop.value);
1091
+ } else if (prop.key === "color" || prop.key === "glow" || prop.key === "size") {
1092
+ hologram = hologram || {
1093
+ shape: "orb",
1094
+ color: "#00ffff",
1095
+ size: 0.5,
1096
+ glow: true,
1097
+ interactive: true
1098
+ };
1099
+ if (prop.key === "color") hologram.color = String(prop.value);
1100
+ if (prop.key === "glow") hologram.glow = Boolean(prop.value);
1101
+ if (prop.key === "size") hologram.size = Number(prop.value);
1102
+ } else {
1103
+ properties[prop.key] = prop.value;
1104
+ }
1105
+ } else {
1106
+ this.advance();
1107
+ }
1108
+ }
1109
+ this.skipNewlines();
1110
+ }
1111
+ this.expect("punctuation", "}");
1112
+ }
1113
+ return {
1114
+ type: "orb",
1115
+ name,
1116
+ position: position || [0, 0, 0],
1117
+ hologram: hologram || {
1118
+ shape: "orb",
1119
+ color: "#00ffff",
1120
+ size: 0.5,
1121
+ glow: true,
1122
+ interactive: true
1123
+ },
1124
+ properties,
1125
+ directives,
1126
+ template,
1127
+ methods: [],
1128
+ children: [],
1129
+ line: startToken?.line || 0
1130
+ };
1131
+ }
1132
+ /**
1133
+ * Parse HoloScript+ directive: @name(...) or @name { ... }
1134
+ */
1135
+ parseDirective() {
1136
+ this.expect("punctuation", "@");
1137
+ const name = this.expectIdentifier();
1138
+ if (!name) return null;
1139
+ if (name === "state") {
1140
+ const body = this.parseObject();
1141
+ return { type: "state", body };
1142
+ }
1143
+ if (name === "bindings") {
1144
+ const bindings = this.parseBindingsBlock();
1145
+ return { type: "bindings", bindings };
1146
+ }
1147
+ if (name.startsWith("on_")) {
1148
+ let body = "";
1149
+ if (this.check("punctuation", "{")) {
1150
+ this.advance();
1151
+ let braceDepth = 1;
1152
+ while (braceDepth > 0 && this.position < this.tokens.length) {
1153
+ const t = this.advance();
1154
+ if (t.value === "{") braceDepth++;
1155
+ if (t.value === "}") braceDepth--;
1156
+ if (braceDepth > 0) {
1157
+ const val = t.type === "string" ? JSON.stringify(t.value) : t.value;
1158
+ body += val + " ";
1159
+ } else if (braceDepth < 0) break;
1160
+ }
1161
+ } else {
1162
+ const t = this.advance();
1163
+ if (t) body = t.value;
1164
+ }
1165
+ return { type: "lifecycle", hook: name, body };
1166
+ }
1167
+ let config = {};
1168
+ if (this.check("punctuation", "(")) {
1169
+ this.advance();
1170
+ while (!this.check("punctuation", ")") && this.position < this.tokens.length) {
1171
+ const prop = this.parseProperty();
1172
+ if (prop) {
1173
+ config[prop.key] = prop.value;
1174
+ }
1175
+ if (this.check("punctuation", ",")) {
1176
+ this.advance();
1177
+ }
1178
+ }
1179
+ this.expect("punctuation", ")");
1180
+ } else if (this.check("punctuation", "{")) {
1181
+ config = this.parseObject();
1182
+ }
1183
+ return { type: "trait", name, config };
1184
+ }
1185
+ /**
1186
+ * Parse @bindings { bind(expr) -> target.prop, ... }
1187
+ */
1188
+ parseBindingsBlock() {
1189
+ const bindings = [];
1190
+ if (!this.check("punctuation", "{")) {
1191
+ return bindings;
1192
+ }
1193
+ this.advance();
1194
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1195
+ this.skipNewlines();
1196
+ if (this.check("identifier") && this.currentToken()?.value === "bind") {
1197
+ this.advance();
1198
+ let expression = "";
1199
+ if (this.check("punctuation", "(")) {
1200
+ this.advance();
1201
+ let parenDepth = 1;
1202
+ while (parenDepth > 0 && this.position < this.tokens.length) {
1203
+ const t = this.advance();
1204
+ if (t.value === "(") parenDepth++;
1205
+ if (t.value === ")") parenDepth--;
1206
+ if (parenDepth > 0) {
1207
+ expression += t.value + " ";
1208
+ }
1209
+ }
1210
+ expression = expression.trim();
1211
+ }
1212
+ if (this.check("punctuation", "-")) {
1213
+ this.advance();
1214
+ if (this.check("punctuation", ">")) {
1215
+ this.advance();
1216
+ }
1217
+ }
1218
+ const target = this.expectIdentifier() || "";
1219
+ let property = "";
1220
+ if (this.check("punctuation", ".")) {
1221
+ this.advance();
1222
+ property = this.expectIdentifier() || "";
1223
+ }
1224
+ if (expression && target && property) {
1225
+ bindings.push({ expression, target, property });
1226
+ }
1227
+ } else {
1228
+ this.advance();
1229
+ }
1230
+ this.skipNewlines();
1231
+ }
1232
+ this.expect("punctuation", "}");
1233
+ return bindings;
1234
+ }
1235
+ // ============================================================================
1236
+ // Phase 7: AI Persistence Memory Syntax
1237
+ // ============================================================================
1238
+ /**
1239
+ * Parse memory primitive block
1240
+ * memory <Name> { semantic: SemanticMemory { ... }, episodic: EpisodicMemory { ... }, procedural: ProceduralMemory { ... } }
1241
+ *
1242
+ * Defers to the modular HoloScriptPersistenceParser
1243
+ */
1244
+ parseMemory() {
1245
+ return this.persistenceParser.parseMemory();
1246
+ }
1247
+ /**
1248
+ * Parse function declaration
1249
+ */
1250
+ parseFunction() {
1251
+ this.expect("keyword", "function");
1252
+ const name = this.expectIdentifier();
1253
+ if (!name) return null;
1254
+ const parameters = [];
1255
+ let returnType;
1256
+ if (this.check("punctuation", "(")) {
1257
+ this.advance();
1258
+ while (!this.check("punctuation", ")") && this.position < this.tokens.length) {
1259
+ const paramName = this.expectIdentifier();
1260
+ if (!paramName) break;
1261
+ let paramType = "any";
1262
+ if (this.check("punctuation", ":")) {
1263
+ this.advance();
1264
+ paramType = this.expectIdentifier() || "any";
1265
+ }
1266
+ parameters.push({
1267
+ type: "parameter",
1268
+ name: paramName,
1269
+ dataType: paramType
1270
+ });
1271
+ if (this.check("punctuation", ",")) {
1272
+ this.advance();
1273
+ }
1274
+ }
1275
+ this.expect("punctuation", ")");
1276
+ }
1277
+ if (this.check("punctuation", ":")) {
1278
+ this.advance();
1279
+ returnType = this.expectIdentifier() || void 0;
1280
+ }
1281
+ const body = [];
1282
+ if (this.check("punctuation", "{")) {
1283
+ this.advance();
1284
+ let depth = 1;
1285
+ while (depth > 0 && this.position < this.tokens.length) {
1286
+ if (this.check("punctuation", "{")) depth++;
1287
+ if (this.check("punctuation", "}")) depth--;
1288
+ this.advance();
1289
+ }
1290
+ }
1291
+ return {
1292
+ type: "method",
1293
+ name,
1294
+ parameters,
1295
+ body,
1296
+ returnType,
1297
+ position: [0, 0, 0],
1298
+ hologram: { shape: "cube", color: "#ff6b35", size: 1.5, glow: true, interactive: true }
1299
+ };
1300
+ }
1301
+ /**
1302
+ * Parse connection
1303
+ */
1304
+ parseConnection() {
1305
+ this.expect("keyword", "connect");
1306
+ const from = this.expectIdentifier();
1307
+ if (!from) return null;
1308
+ this.expect("keyword", "to");
1309
+ const to = this.expectIdentifier();
1310
+ if (!to) return null;
1311
+ let dataType = "any";
1312
+ if (this.check("keyword", "as")) {
1313
+ this.advance();
1314
+ const typeStr = this.currentToken();
1315
+ if (typeStr?.type === "string" || typeStr?.type === "identifier") {
1316
+ dataType = typeStr.value;
1317
+ this.advance();
1318
+ }
1319
+ }
1320
+ return {
1321
+ type: "connection",
1322
+ from,
1323
+ to,
1324
+ dataType,
1325
+ bidirectional: false
1326
+ };
1327
+ }
1328
+ /**
1329
+ * Parse scale block: scale <magnitude> { body }
1330
+ */
1331
+ parseScale() {
1332
+ this.expect("keyword", "scale");
1333
+ const magnitude = this.expectIdentifier() || "standard";
1334
+ const multipliers = {
1335
+ galactic: 1e6,
1336
+ macro: 1e3,
1337
+ standard: 1,
1338
+ micro: 1e-3,
1339
+ atomic: 1e-6
1340
+ };
1341
+ const body = [];
1342
+ if (this.check("punctuation", "{")) {
1343
+ this.advance();
1344
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1345
+ this.skipNewlines();
1346
+ const node = this.parseDeclaration();
1347
+ if (node) body.push(node);
1348
+ this.skipNewlines();
1349
+ }
1350
+ this.expect("punctuation", "}");
1351
+ }
1352
+ return {
1353
+ type: "scale",
1354
+ magnitude,
1355
+ multiplier: multipliers[magnitude] || 1,
1356
+ body,
1357
+ position: [0, 0, 0]
1358
+ };
1359
+ }
1360
+ /**
1361
+ * Parse focus block: focus <target> { body }
1362
+ */
1363
+ parseFocus() {
1364
+ this.expect("keyword", "focus");
1365
+ const target = this.expectIdentifier() || "origin";
1366
+ const body = [];
1367
+ if (this.check("punctuation", "{")) {
1368
+ this.advance();
1369
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1370
+ this.skipNewlines();
1371
+ const node = this.parseDeclaration();
1372
+ if (node) body.push(node);
1373
+ this.skipNewlines();
1374
+ }
1375
+ this.expect("punctuation", "}");
1376
+ }
1377
+ return {
1378
+ type: "focus",
1379
+ target,
1380
+ body,
1381
+ position: [0, 0, 0]
1382
+ };
1383
+ }
1384
+ /**
1385
+ * Parse environment declaration
1386
+ * Supports: environment { ... } or environment #id { ... }
1387
+ */
1388
+ parseEnvironment() {
1389
+ this.expect("keyword", "environment");
1390
+ const settings = {};
1391
+ let envId;
1392
+ if (this.check("punctuation", "#")) {
1393
+ this.advance();
1394
+ envId = this.expectIdentifier() || void 0;
1395
+ }
1396
+ if (this.check("punctuation", "{")) {
1397
+ this.advance();
1398
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1399
+ this.skipNewlines();
1400
+ if (this.check("punctuation", "}")) break;
1401
+ if (this.check("punctuation", "@")) {
1402
+ const directive = this.parseDirective();
1403
+ if (directive) {
1404
+ const dir = directive;
1405
+ settings[`@${directive.type}`] = dir.args || dir.config || [];
1406
+ }
1407
+ continue;
1408
+ }
1409
+ const prop = this.parseProperty();
1410
+ if (prop) {
1411
+ settings[prop.key] = prop.value;
1412
+ }
1413
+ this.skipNewlines();
1414
+ }
1415
+ this.expect("punctuation", "}");
1416
+ } else {
1417
+ while (this.position < this.tokens.length && this.currentToken()?.type !== "newline" && !this.check("punctuation", "}")) {
1418
+ const key = this.expectIdentifier();
1419
+ if (!key) break;
1420
+ settings[key] = this.parseLiteral();
1421
+ }
1422
+ }
1423
+ if (envId) {
1424
+ settings["id"] = envId;
1425
+ }
1426
+ return {
1427
+ type: "environment",
1428
+ settings
1429
+ };
1430
+ }
1431
+ /**
1432
+ * Parse primitive 3D shape declaration
1433
+ * Supports: cylinder #id { ... }, sphere "name" { ... }, etc.
1434
+ */
1435
+ parsePrimitive() {
1436
+ const startToken = this.currentToken();
1437
+ const primitiveType = startToken?.value || "object";
1438
+ this.advance();
1439
+ let name = "";
1440
+ let elementId;
1441
+ if (this.check("punctuation", "#")) {
1442
+ this.advance();
1443
+ elementId = this.expectIdentifier() || void 0;
1444
+ name = elementId || `${primitiveType}_${Date.now()}`;
1445
+ } else {
1446
+ name = this.expectName() || `${primitiveType}_${Date.now()}`;
1447
+ }
1448
+ let template;
1449
+ if (this.check("keyword", "using")) {
1450
+ this.advance();
1451
+ template = this.expectName() || void 0;
1452
+ }
1453
+ const properties = {};
1454
+ const directives = [];
1455
+ let position;
1456
+ if (this.check("punctuation", "{")) {
1457
+ this.advance();
1458
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1459
+ this.skipNewlines();
1460
+ if (this.check("punctuation", "}")) break;
1461
+ if (this.check("punctuation", ",") || this.check("punctuation", ";")) {
1462
+ this.advance();
1463
+ continue;
1464
+ }
1465
+ const token = this.currentToken();
1466
+ if (token?.type === "punctuation" && token.value === "@") {
1467
+ const directive = this.parseDirective();
1468
+ if (directive) directives.push(directive);
1469
+ } else {
1470
+ const prop = this.parseProperty();
1471
+ if (prop) {
1472
+ if (prop.key === "position" || prop.key === "at") {
1473
+ position = this.parsePosition(prop.value);
1474
+ } else {
1475
+ properties[prop.key] = prop.value;
1476
+ }
1477
+ } else {
1478
+ this.advance();
1479
+ }
1480
+ }
1481
+ this.skipNewlines();
1482
+ }
1483
+ this.expect("punctuation", "}");
1484
+ }
1485
+ properties["_primitiveType"] = primitiveType;
1486
+ if (elementId) {
1487
+ properties["id"] = elementId;
1488
+ }
1489
+ return {
1490
+ type: "orb",
1491
+ name,
1492
+ position: position || [0, 0, 0],
1493
+ hologram: {
1494
+ shape: primitiveType,
1495
+ color: "#00d4ff",
1496
+ size: 1,
1497
+ glow: false,
1498
+ interactive: true
1499
+ },
1500
+ properties,
1501
+ directives,
1502
+ template,
1503
+ methods: [],
1504
+ children: [],
1505
+ line: startToken?.line || 0
1506
+ };
1507
+ }
1508
+ /**
1509
+ * Parse zone declaration: zone "Name" { ... } or zone #id { ... }
1510
+ */
1511
+ parseZone() {
1512
+ this.expect("keyword", "zone");
1513
+ let name = "";
1514
+ let zoneId;
1515
+ if (this.check("punctuation", "#")) {
1516
+ this.advance();
1517
+ zoneId = this.expectIdentifier() || void 0;
1518
+ name = zoneId || `zone_${Date.now()}`;
1519
+ } else {
1520
+ name = this.expectName() || `zone_${Date.now()}`;
1521
+ }
1522
+ const properties = {};
1523
+ let position;
1524
+ if (this.check("punctuation", "{")) {
1525
+ this.advance();
1526
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1527
+ this.skipNewlines();
1528
+ if (this.check("punctuation", "}")) break;
1529
+ const prop = this.parseProperty();
1530
+ if (prop) {
1531
+ if (prop.key === "position") {
1532
+ position = this.parsePosition(prop.value);
1533
+ properties["position"] = prop.value;
1534
+ } else {
1535
+ properties[prop.key] = prop.value;
1536
+ }
1537
+ } else {
1538
+ const token = this.currentToken();
1539
+ this.addError(
1540
+ this.createError(
1541
+ "HS004",
1542
+ `Unexpected token in zone: ${token?.type || "unknown"}`,
1543
+ token
1544
+ )
1545
+ );
1546
+ this.advance();
1547
+ }
1548
+ this.skipNewlines();
1549
+ }
1550
+ this.expect("punctuation", "}");
1551
+ }
1552
+ return {
1553
+ type: "zone",
1554
+ name,
1555
+ id: zoneId,
1556
+ position,
1557
+ events: {},
1558
+ // Events are stored in properties for now
1559
+ properties
1560
+ };
1561
+ }
1562
+ /**
1563
+ * Parse composition block
1564
+ */
1565
+ parseComposition() {
1566
+ this.expect("keyword", "composition");
1567
+ const name = this.expectName() || "unnamed";
1568
+ const children = [];
1569
+ if (this.check("punctuation", "{")) {
1570
+ this.advance();
1571
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1572
+ this.skipNewlines();
1573
+ const node = this.parseDeclaration();
1574
+ if (node) children.push(node);
1575
+ this.skipNewlines();
1576
+ }
1577
+ this.expect("punctuation", "}");
1578
+ }
1579
+ return {
1580
+ type: "composition",
1581
+ name,
1582
+ children
1583
+ };
1584
+ }
1585
+ /**
1586
+ * Parse template declaration
1587
+ */
1588
+ parseTemplate() {
1589
+ this.expect("keyword", "template");
1590
+ const name = this.expectName() || "template";
1591
+ let version;
1592
+ const params = [];
1593
+ if (this.check("punctuation", "(")) {
1594
+ this.advance();
1595
+ while (!this.check("punctuation", ")") && this.position < this.tokens.length) {
1596
+ const p = this.expectIdentifier();
1597
+ if (p) params.push(p);
1598
+ if (this.check("punctuation", ",")) this.advance();
1599
+ }
1600
+ this.expect("punctuation", ")");
1601
+ }
1602
+ const children = [];
1603
+ const migrations = [];
1604
+ const directives = [];
1605
+ const properties = {};
1606
+ if (this.check("punctuation", "{")) {
1607
+ this.advance();
1608
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1609
+ this.skipNewlines();
1610
+ const token = this.currentToken();
1611
+ if (token?.type === "punctuation" && token.value === "@") {
1612
+ const startPos2 = this.position;
1613
+ this.advance();
1614
+ const dirName = this.expectIdentifier();
1615
+ if (dirName === "version") {
1616
+ this.expect("punctuation", "(");
1617
+ const vStr = this.currentToken();
1618
+ if (vStr?.type === "number") {
1619
+ version = parseInt(vStr.value, 10);
1620
+ this.advance();
1621
+ }
1622
+ this.expect("punctuation", ")");
1623
+ directives.push({ type: "version", version });
1624
+ this.skipNewlines();
1625
+ continue;
1626
+ } else {
1627
+ this.position = startPos2;
1628
+ const dir = this.parseDirective();
1629
+ if (dir) directives.push(dir);
1630
+ this.skipNewlines();
1631
+ continue;
1632
+ }
1633
+ }
1634
+ const startPos = this.position;
1635
+ const errorCount = this.errors.length;
1636
+ const node = this.parseDeclaration();
1637
+ if (node && node.type !== "expression") {
1638
+ if (node.type === "migration") {
1639
+ migrations.push(node);
1640
+ } else {
1641
+ children.push(node);
1642
+ }
1643
+ this.skipNewlines();
1644
+ continue;
1645
+ }
1646
+ this.position = startPos;
1647
+ this.errors.length = errorCount;
1648
+ const prop = this.parseProperty();
1649
+ if (prop) {
1650
+ properties[prop.key] = prop.value;
1651
+ this.skipNewlines();
1652
+ continue;
1653
+ }
1654
+ this.advance();
1655
+ }
1656
+ this.expect("punctuation", "}");
1657
+ }
1658
+ return {
1659
+ type: "template",
1660
+ name,
1661
+ parameters: params,
1662
+ children,
1663
+ properties,
1664
+ directives,
1665
+ version,
1666
+ migrations
1667
+ };
1668
+ }
1669
+ /**
1670
+ * Parse system declaration: system Name { state {}, on_start {}, action name() {}, ui {} }
1671
+ *
1672
+ * Systems are named trait+logic containers that auto-initialize within a composition.
1673
+ * They encapsulate state, lifecycle hooks, actions, and optional UI.
1674
+ *
1675
+ * Syntax:
1676
+ * system TutorialSystem {
1677
+ * state { currentStep: 0, completed: false }
1678
+ * on_start { ... }
1679
+ * on_update { ... }
1680
+ * action next() { ... }
1681
+ * action skip() { ... }
1682
+ * ui { ... }
1683
+ * }
1684
+ */
1685
+ parseSystem() {
1686
+ this.expect("keyword", "system");
1687
+ const name = this.expectName() || "unnamed_system";
1688
+ const state = {};
1689
+ const actions = [];
1690
+ const hooks = [];
1691
+ const directives = [];
1692
+ const properties = {};
1693
+ const children = [];
1694
+ const uiNodes = [];
1695
+ if (this.check("punctuation", "{")) {
1696
+ this.advance();
1697
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1698
+ this.skipNewlines();
1699
+ if (this.check("punctuation", "}")) break;
1700
+ const token = this.currentToken();
1701
+ if (token?.type === "punctuation" && token.value === "@") {
1702
+ const directive = this.parseDirective();
1703
+ if (directive) directives.push(directive);
1704
+ this.skipNewlines();
1705
+ continue;
1706
+ }
1707
+ if (token?.type === "keyword" || token?.type === "identifier") {
1708
+ const val = token.value.toLowerCase();
1709
+ if (val === "state") {
1710
+ this.advance();
1711
+ if (this.check("punctuation", "{")) {
1712
+ const stateObj = this.parseObject();
1713
+ Object.assign(state, stateObj);
1714
+ }
1715
+ this.skipNewlines();
1716
+ continue;
1717
+ }
1718
+ if (val === "action") {
1719
+ this.advance();
1720
+ const actionName = this.expectIdentifier();
1721
+ if (actionName) {
1722
+ const params = [];
1723
+ if (this.check("punctuation", "(")) {
1724
+ this.advance();
1725
+ while (!this.check("punctuation", ")") && this.position < this.tokens.length) {
1726
+ const p = this.expectIdentifier();
1727
+ if (p) params.push(p);
1728
+ if (this.check("punctuation", ",")) this.advance();
1729
+ }
1730
+ this.expect("punctuation", ")");
1731
+ }
1732
+ const body = this.parseBlockBody();
1733
+ actions.push({ name: actionName, params, body });
1734
+ }
1735
+ this.skipNewlines();
1736
+ continue;
1737
+ }
1738
+ if (val.startsWith("on_")) {
1739
+ this.advance();
1740
+ const body = this.parseBlockBody();
1741
+ hooks.push({ name: val, body });
1742
+ this.skipNewlines();
1743
+ continue;
1744
+ }
1745
+ if (val === "ui") {
1746
+ this.advance();
1747
+ if (this.check("punctuation", "{")) {
1748
+ this.advance();
1749
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1750
+ this.skipNewlines();
1751
+ const node2 = this.parseDeclaration();
1752
+ if (node2) uiNodes.push(node2);
1753
+ this.skipNewlines();
1754
+ }
1755
+ this.expect("punctuation", "}");
1756
+ }
1757
+ this.skipNewlines();
1758
+ continue;
1759
+ }
1760
+ const startPos = this.position;
1761
+ const errorCount = this.errors.length;
1762
+ const node = this.parseDeclaration();
1763
+ if (node && node.type !== "expression") {
1764
+ children.push(node);
1765
+ this.skipNewlines();
1766
+ continue;
1767
+ }
1768
+ this.position = startPos;
1769
+ this.errors.length = errorCount;
1770
+ const prop = this.parseProperty();
1771
+ if (prop) {
1772
+ properties[prop.key] = prop.value;
1773
+ this.skipNewlines();
1774
+ continue;
1775
+ }
1776
+ }
1777
+ this.advance();
1778
+ }
1779
+ this.expect("punctuation", "}");
1780
+ }
1781
+ return {
1782
+ type: "system",
1783
+ id: name,
1784
+ properties,
1785
+ state: Object.keys(state).length > 0 ? state : void 0,
1786
+ actions: actions.length > 0 ? actions : void 0,
1787
+ hooks: hooks.length > 0 ? hooks : void 0,
1788
+ ui: uiNodes.length > 0 ? uiNodes : void 0,
1789
+ children: children.length > 0 ? children : void 0,
1790
+ directives: directives.length > 0 ? directives : void 0
1791
+ };
1792
+ }
1793
+ /**
1794
+ * Parse component declaration: component Name { props {}, state {}, ui {}, action name() {} }
1795
+ *
1796
+ * Components are UI-focused declarations with props, state, and render/ui blocks.
1797
+ *
1798
+ * Syntax:
1799
+ * component MobileControls {
1800
+ * props { visible: true, joystickSize: 120 }
1801
+ * state { isMoving: false }
1802
+ * ui { ... }
1803
+ * }
1804
+ */
1805
+ parseComponent() {
1806
+ this.expect("keyword", "component");
1807
+ const name = this.expectName() || "unnamed_component";
1808
+ const props = {};
1809
+ const state = {};
1810
+ const actions = [];
1811
+ const hooks = [];
1812
+ const directives = [];
1813
+ const properties = {};
1814
+ const children = [];
1815
+ const uiNodes = [];
1816
+ if (this.check("punctuation", "{")) {
1817
+ this.advance();
1818
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1819
+ this.skipNewlines();
1820
+ if (this.check("punctuation", "}")) break;
1821
+ const token = this.currentToken();
1822
+ if (token?.type === "punctuation" && token.value === "@") {
1823
+ const directive = this.parseDirective();
1824
+ if (directive) directives.push(directive);
1825
+ this.skipNewlines();
1826
+ continue;
1827
+ }
1828
+ if (token?.type === "keyword" || token?.type === "identifier") {
1829
+ const val = token.value.toLowerCase();
1830
+ if (val === "props") {
1831
+ this.advance();
1832
+ if (this.check("punctuation", "{")) {
1833
+ const propsObj = this.parseObject();
1834
+ Object.assign(props, propsObj);
1835
+ }
1836
+ this.skipNewlines();
1837
+ continue;
1838
+ }
1839
+ if (val === "state") {
1840
+ this.advance();
1841
+ if (this.check("punctuation", "{")) {
1842
+ const stateObj = this.parseObject();
1843
+ Object.assign(state, stateObj);
1844
+ }
1845
+ this.skipNewlines();
1846
+ continue;
1847
+ }
1848
+ if (val === "action") {
1849
+ this.advance();
1850
+ const actionName = this.expectIdentifier();
1851
+ if (actionName) {
1852
+ const params = [];
1853
+ if (this.check("punctuation", "(")) {
1854
+ this.advance();
1855
+ while (!this.check("punctuation", ")") && this.position < this.tokens.length) {
1856
+ const p = this.expectIdentifier();
1857
+ if (p) params.push(p);
1858
+ if (this.check("punctuation", ",")) this.advance();
1859
+ }
1860
+ this.expect("punctuation", ")");
1861
+ }
1862
+ const body = this.parseBlockBody();
1863
+ actions.push({ name: actionName, params, body });
1864
+ }
1865
+ this.skipNewlines();
1866
+ continue;
1867
+ }
1868
+ if (val.startsWith("on_")) {
1869
+ this.advance();
1870
+ const body = this.parseBlockBody();
1871
+ hooks.push({ name: val, body });
1872
+ this.skipNewlines();
1873
+ continue;
1874
+ }
1875
+ if (val === "ui") {
1876
+ this.advance();
1877
+ if (this.check("punctuation", "{")) {
1878
+ this.advance();
1879
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
1880
+ this.skipNewlines();
1881
+ const node2 = this.parseDeclaration();
1882
+ if (node2) uiNodes.push(node2);
1883
+ this.skipNewlines();
1884
+ }
1885
+ this.expect("punctuation", "}");
1886
+ }
1887
+ this.skipNewlines();
1888
+ continue;
1889
+ }
1890
+ const startPos = this.position;
1891
+ const errorCount = this.errors.length;
1892
+ const node = this.parseDeclaration();
1893
+ if (node && node.type !== "expression") {
1894
+ children.push(node);
1895
+ this.skipNewlines();
1896
+ continue;
1897
+ }
1898
+ this.position = startPos;
1899
+ this.errors.length = errorCount;
1900
+ const prop = this.parseProperty();
1901
+ if (prop) {
1902
+ properties[prop.key] = prop.value;
1903
+ this.skipNewlines();
1904
+ continue;
1905
+ }
1906
+ }
1907
+ this.advance();
1908
+ }
1909
+ this.expect("punctuation", "}");
1910
+ }
1911
+ return {
1912
+ type: "component",
1913
+ name,
1914
+ props: Object.keys(props).length > 0 ? props : void 0,
1915
+ state: Object.keys(state).length > 0 ? state : void 0,
1916
+ actions: actions.length > 0 ? actions : void 0,
1917
+ hooks: hooks.length > 0 ? hooks : void 0,
1918
+ ui: uiNodes.length > 0 ? uiNodes : void 0,
1919
+ children: children.length > 0 ? children : void 0,
1920
+ directives: directives.length > 0 ? directives : void 0,
1921
+ properties: Object.keys(properties).length > 0 ? properties : void 0
1922
+ };
1923
+ }
1924
+ /**
1925
+ * Parse a block body { ... } — captures everything between braces as a string.
1926
+ * Used for action bodies and lifecycle hooks where we capture the raw body.
1927
+ */
1928
+ parseBlockBody() {
1929
+ let body = "";
1930
+ if (this.check("punctuation", "{")) {
1931
+ this.advance();
1932
+ let braceDepth = 1;
1933
+ while (braceDepth > 0 && this.position < this.tokens.length) {
1934
+ const t = this.advance();
1935
+ if (t.value === "{") braceDepth++;
1936
+ if (t.value === "}") braceDepth--;
1937
+ if (braceDepth > 0) {
1938
+ const val = t.type === "string" ? JSON.stringify(t.value) : t.value;
1939
+ body += val + " ";
1940
+ }
1941
+ }
1942
+ }
1943
+ return body.trim();
1944
+ }
1945
+ /**
1946
+ * Parse migration block: migrate from(n) { body }
1947
+ */
1948
+ parseMigration() {
1949
+ this.expect("keyword", "migrate");
1950
+ this.expect("keyword", "from");
1951
+ this.expect("punctuation", "(");
1952
+ let fromVersion = 0;
1953
+ const vStr = this.currentToken();
1954
+ if (vStr?.type === "number") {
1955
+ fromVersion = parseInt(vStr.value, 10);
1956
+ this.advance();
1957
+ }
1958
+ this.expect("punctuation", ")");
1959
+ let body = "";
1960
+ if (this.check("punctuation", "{")) {
1961
+ this.advance();
1962
+ let braceDepth = 1;
1963
+ this.position;
1964
+ while (braceDepth > 0 && this.position < this.tokens.length) {
1965
+ const t = this.advance();
1966
+ if (t.value === "{") braceDepth++;
1967
+ if (t.value === "}") braceDepth--;
1968
+ if (braceDepth > 0) {
1969
+ const val = t.type === "string" ? JSON.stringify(t.value) : t.value;
1970
+ body += val + " ";
1971
+ }
1972
+ }
1973
+ }
1974
+ return {
1975
+ type: "migration",
1976
+ fromVersion,
1977
+ body: body.trim(),
1978
+ position: [0, 0, 0]
1979
+ };
1980
+ }
1981
+ /**
1982
+ * Parse gate (conditional)
1983
+ */
1984
+ parseGate() {
1985
+ const isIf = this.check("keyword", "if");
1986
+ if (isIf) {
1987
+ this.advance();
1988
+ } else {
1989
+ this.expect("keyword", "gate");
1990
+ this.expectIdentifier();
1991
+ }
1992
+ let condition = "";
1993
+ if (this.check("punctuation", "(")) {
1994
+ this.advance();
1995
+ while (!this.check("punctuation", ")") && this.position < this.tokens.length) {
1996
+ const token = this.currentToken();
1997
+ if (token) condition += token.value + " ";
1998
+ this.advance();
1999
+ }
2000
+ this.expect("punctuation", ")");
2001
+ }
2002
+ const truePath = [];
2003
+ if (this.check("punctuation", "{")) {
2004
+ this.advance();
2005
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
2006
+ const node = this.parseDeclaration();
2007
+ if (node) truePath.push(node);
2008
+ else this.advance();
2009
+ }
2010
+ this.expect("punctuation", "}");
2011
+ }
2012
+ const falsePath = [];
2013
+ if (this.check("keyword", "else")) {
2014
+ this.advance();
2015
+ if (this.check("punctuation", "{")) {
2016
+ this.advance();
2017
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
2018
+ const node = this.parseDeclaration();
2019
+ if (node) falsePath.push(node);
2020
+ else this.advance();
2021
+ }
2022
+ this.expect("punctuation", "}");
2023
+ } else {
2024
+ const node = this.parseDeclaration();
2025
+ if (node) falsePath.push(node);
2026
+ }
2027
+ }
2028
+ return {
2029
+ type: "gate",
2030
+ condition: this.parseConditionExpression(condition.trim()),
2031
+ truePath,
2032
+ falsePath,
2033
+ position: [0, 0, 0],
2034
+ hologram: { shape: "pyramid", color: "#4ecdc4", size: 1, glow: true, interactive: true }
2035
+ };
2036
+ }
2037
+ /**
2038
+ * Parse return statement
2039
+ */
2040
+ parseReturn() {
2041
+ this.expect("keyword", "return");
2042
+ let expression = "";
2043
+ let parenDepth = 0;
2044
+ let braceDepth = 0;
2045
+ let bracketDepth = 0;
2046
+ while (this.position < this.tokens.length) {
2047
+ const t = this.currentToken();
2048
+ if (!t) break;
2049
+ if (t.type === "newline" && parenDepth === 0 && braceDepth === 0 && bracketDepth === 0) break;
2050
+ if (t.type === "punctuation" && t.value === ";" && parenDepth === 0 && braceDepth === 0 && bracketDepth === 0)
2051
+ break;
2052
+ if (t.type === "punctuation") {
2053
+ if (t.value === "(") parenDepth++;
2054
+ else if (t.value === ")") parenDepth--;
2055
+ else if (t.value === "{") braceDepth++;
2056
+ else if (t.value === "}") braceDepth--;
2057
+ else if (t.value === "[") bracketDepth++;
2058
+ else if (t.value === "]") bracketDepth--;
2059
+ }
2060
+ expression += t.value + " ";
2061
+ this.advance();
2062
+ }
2063
+ return {
2064
+ type: "return",
2065
+ value: expression.trim(),
2066
+ // Use 'value' to match runtime's executeReturn
2067
+ position: [0, 0, 0]
2068
+ };
2069
+ }
2070
+ /**
2071
+ * Parse generic expression statement (e.g. function call or assignment)
2072
+ */
2073
+ parseExpressionStatement() {
2074
+ let expression = "";
2075
+ let parenDepth = 0;
2076
+ let braceDepth = 0;
2077
+ let bracketDepth = 0;
2078
+ while (this.position < this.tokens.length) {
2079
+ const t = this.currentToken();
2080
+ if (!t) break;
2081
+ if (t.type === "newline" && parenDepth === 0 && braceDepth === 0 && bracketDepth === 0) break;
2082
+ if (t.type === "punctuation" && t.value === ";" && parenDepth === 0 && braceDepth === 0 && bracketDepth === 0)
2083
+ break;
2084
+ if (t.type === "punctuation") {
2085
+ if (t.value === "(") parenDepth++;
2086
+ else if (t.value === ")") parenDepth--;
2087
+ else if (t.value === "{") braceDepth++;
2088
+ else if (t.value === "}") braceDepth--;
2089
+ else if (t.value === "[") bracketDepth++;
2090
+ else if (t.value === "]") bracketDepth--;
2091
+ }
2092
+ expression += t.value + " ";
2093
+ this.advance();
2094
+ }
2095
+ if (expression.trim().length === 0) {
2096
+ this.advance();
2097
+ return null;
2098
+ }
2099
+ return {
2100
+ type: "expression-statement",
2101
+ expression: expression.trim(),
2102
+ position: [0, 0, 0]
2103
+ };
2104
+ }
2105
+ /**
2106
+ * Parse stream
2107
+ */
2108
+ parseStream() {
2109
+ this.expect("keyword", "stream");
2110
+ const name = this.expectIdentifier();
2111
+ if (!name) return null;
2112
+ let source = "unknown";
2113
+ if (this.check("keyword", "from")) {
2114
+ this.advance();
2115
+ source = this.expectIdentifier() || "unknown";
2116
+ }
2117
+ if (this.check("punctuation", "{")) {
2118
+ this.advance();
2119
+ let depth = 1;
2120
+ while (depth > 0 && this.position < this.tokens.length) {
2121
+ if (this.check("punctuation", "{")) depth++;
2122
+ if (this.check("punctuation", "}")) depth--;
2123
+ this.advance();
2124
+ }
2125
+ }
2126
+ return {
2127
+ type: "stream",
2128
+ name,
2129
+ source,
2130
+ transformations: [],
2131
+ position: [0, 0, 0],
2132
+ hologram: { shape: "cylinder", color: "#45b7d1", size: 2, glow: true, interactive: true }
2133
+ };
2134
+ }
2135
+ /**
2136
+ * Parse nexus (multi-agent hub)
2137
+ */
2138
+ parseNexus() {
2139
+ this.expect("keyword", "nexus");
2140
+ const name = this.expectIdentifier();
2141
+ if (!name) return null;
2142
+ if (this.check("punctuation", "{")) {
2143
+ this.advance();
2144
+ let depth = 1;
2145
+ while (depth > 0 && this.position < this.tokens.length) {
2146
+ if (this.check("punctuation", "{")) depth++;
2147
+ if (this.check("punctuation", "}")) depth--;
2148
+ this.advance();
2149
+ }
2150
+ }
2151
+ return {
2152
+ type: "nexus",
2153
+ position: [0, 0, 0],
2154
+ hologram: { shape: "sphere", color: "#9b59b6", size: 3, glow: true, interactive: true }
2155
+ };
2156
+ }
2157
+ /**
2158
+ * Parse building (class-like)
2159
+ */
2160
+ parseBuilding() {
2161
+ this.expect("keyword", "building");
2162
+ const name = this.expectName();
2163
+ if (!name) return null;
2164
+ if (this.check("punctuation", "{")) {
2165
+ this.advance();
2166
+ let depth = 1;
2167
+ while (depth > 0 && this.position < this.tokens.length) {
2168
+ if (this.check("punctuation", "{")) depth++;
2169
+ if (this.check("punctuation", "}")) depth--;
2170
+ this.advance();
2171
+ }
2172
+ }
2173
+ return {
2174
+ type: "building",
2175
+ position: [0, 0, 0],
2176
+ hologram: { shape: "cube", color: "#e74c3c", size: 4, glow: true, interactive: true }
2177
+ };
2178
+ }
2179
+ /**
2180
+ * Parse a literal value (string, number, boolean, array, or object)
2181
+ */
2182
+ parseLiteral() {
2183
+ const token = this.currentToken();
2184
+ if (!token) return null;
2185
+ if (token.type === "string") {
2186
+ this.advance();
2187
+ return token.value;
2188
+ }
2189
+ if (token.type === "number") {
2190
+ this.advance();
2191
+ return parseFloat(token.value);
2192
+ }
2193
+ if (token.type === "identifier") {
2194
+ const val = token.value.toLowerCase();
2195
+ this.advance();
2196
+ if (val === "true") return true;
2197
+ if (val === "false") return false;
2198
+ if (val === "null") return null;
2199
+ return token.value;
2200
+ }
2201
+ if (this.check("punctuation", "[")) {
2202
+ return this.parseArray();
2203
+ }
2204
+ if (this.check("punctuation", "{")) {
2205
+ return this.parseObject();
2206
+ }
2207
+ this.advance();
2208
+ return token.value;
2209
+ }
2210
+ /**
2211
+ * Parse a property (key: value)
2212
+ */
2213
+ parseProperty() {
2214
+ const key = this.expectIdentifier();
2215
+ if (!key) return null;
2216
+ if (!this.check("punctuation", ":")) {
2217
+ return { key, value: true };
2218
+ }
2219
+ this.advance();
2220
+ const value = this.parseLiteral();
2221
+ return { key, value };
2222
+ }
2223
+ /**
2224
+ * Parse array [...]
2225
+ */
2226
+ parseArray() {
2227
+ const arr = [];
2228
+ this.expect("punctuation", "[");
2229
+ while (!this.check("punctuation", "]") && this.position < this.tokens.length) {
2230
+ const token = this.currentToken();
2231
+ if (token?.type === "string" || token?.type === "number" || token?.type === "identifier") {
2232
+ if (token.type === "number") {
2233
+ arr.push(parseFloat(token.value));
2234
+ } else {
2235
+ arr.push(token.value);
2236
+ }
2237
+ this.advance();
2238
+ } else if (this.check("punctuation", ",")) {
2239
+ this.advance();
2240
+ } else {
2241
+ this.addError(
2242
+ this.createError("HS004", `Unexpected token in array: ${token?.type || "unknown"}`, token)
2243
+ );
2244
+ this.advance();
2245
+ }
2246
+ }
2247
+ this.expect("punctuation", "]");
2248
+ return arr;
2249
+ }
2250
+ /**
2251
+ * Parse object {...}
2252
+ */
2253
+ parseObject() {
2254
+ const obj = {};
2255
+ this.expect("punctuation", "{");
2256
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
2257
+ this.skipNewlines();
2258
+ if (this.check("punctuation", "}")) break;
2259
+ const prop = this.parseProperty();
2260
+ if (prop) {
2261
+ obj[prop.key] = prop.value;
2262
+ } else {
2263
+ const token = this.currentToken();
2264
+ this.addError(
2265
+ this.createError(
2266
+ "HS004",
2267
+ `Unexpected token in object: ${token?.type || "unknown"}`,
2268
+ token
2269
+ )
2270
+ );
2271
+ this.advance();
2272
+ }
2273
+ this.skipNewlines();
2274
+ if (this.check("punctuation", ",")) {
2275
+ this.advance();
2276
+ }
2277
+ }
2278
+ this.expect("punctuation", "}");
2279
+ return obj;
2280
+ }
2281
+ /**
2282
+ * Parse position from value
2283
+ */
2284
+ parsePosition(value) {
2285
+ if (Array.isArray(value)) {
2286
+ return [
2287
+ Number(value[0]) || 0,
2288
+ Number(value[1]) || 0,
2289
+ Number(value[2]) || 0
2290
+ ];
2291
+ }
2292
+ if (typeof value === "object" && value !== null) {
2293
+ const v = value;
2294
+ const x = Number(v[0] !== void 0 ? v[0] : v[0]) || 0;
2295
+ const y = Number(v[1] !== void 0 ? v[1] : v[1]) || 0;
2296
+ const z = Number(v[2] !== void 0 ? v[2] : v[2]) || 0;
2297
+ return [x, y, z];
2298
+ }
2299
+ return [0, 0, 0];
2300
+ }
2301
+ // Helper methods
2302
+ currentToken() {
2303
+ return this.tokens[this.position];
2304
+ }
2305
+ advance() {
2306
+ return this.tokens[this.position++];
2307
+ }
2308
+ check(type, value) {
2309
+ const token = this.currentToken();
2310
+ if (!token) return false;
2311
+ if (token.type !== type) return false;
2312
+ if (value !== void 0 && token.value.toLowerCase() !== value.toLowerCase()) return false;
2313
+ return true;
2314
+ }
2315
+ expect(type, value) {
2316
+ if (this.check(type, value)) {
2317
+ this.advance();
2318
+ return true;
2319
+ }
2320
+ const token = this.currentToken();
2321
+ let suggestion;
2322
+ if (type === "keyword" && value && token?.type === "identifier") {
2323
+ const similar = this.findSimilarKeyword(token.value);
2324
+ if (similar) {
2325
+ suggestion = `Did you mean '${similar}'?`;
2326
+ }
2327
+ }
2328
+ this.addError(
2329
+ this.createError(
2330
+ type === "keyword" ? "HS001" : type === "identifier" ? "HS002" : "HS003",
2331
+ `Expected ${type}${value ? ` '${value}'` : ""}, got ${token?.type || "EOF"} '${token?.value || ""}'`,
2332
+ token,
2333
+ suggestion
2334
+ )
2335
+ );
2336
+ return false;
2337
+ }
2338
+ expectIdentifier() {
2339
+ const token = this.currentToken();
2340
+ if (token && (token.type === "identifier" || token.type === "keyword")) {
2341
+ this.advance();
2342
+ return token.value;
2343
+ }
2344
+ this.addError(
2345
+ this.createError(
2346
+ "HS002",
2347
+ `Expected identifier, got ${token?.type || "EOF"}`,
2348
+ token,
2349
+ token?.type === "number" ? "Identifiers cannot start with a number" : void 0
2350
+ )
2351
+ );
2352
+ return null;
2353
+ }
2354
+ /**
2355
+ * Expect an identifier OR a string literal for named declarations
2356
+ * Allows both: composition MyScene { } and composition "MyScene" { }
2357
+ */
2358
+ expectName() {
2359
+ const token = this.currentToken();
2360
+ if (token?.type === "identifier" || token?.type === "keyword") {
2361
+ this.advance();
2362
+ return token.value;
2363
+ }
2364
+ if (token?.type === "string") {
2365
+ this.advance();
2366
+ const val = token.value;
2367
+ if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
2368
+ return val.slice(1, -1);
2369
+ }
2370
+ return val;
2371
+ }
2372
+ this.addError(
2373
+ this.createError(
2374
+ "HS002",
2375
+ `Expected name (identifier or string), got ${token?.type || "EOF"}`,
2376
+ token
2377
+ )
2378
+ );
2379
+ return null;
2380
+ }
2381
+ /**
2382
+ * Parse animate command: animate target property: "..." from: 0 to: 1 duration: 1000
2383
+ */
2384
+ parseAnimate() {
2385
+ this.expect("keyword", "animate");
2386
+ const target = this.expectIdentifier();
2387
+ if (!target) return null;
2388
+ const properties = {};
2389
+ while (this.position < this.tokens.length) {
2390
+ this.skipNewlines();
2391
+ const t = this.currentToken();
2392
+ if (!t || t.type === "newline" || t.type === "keyword" && this.keywordSet.has(t.value.toLowerCase()))
2393
+ break;
2394
+ const prop = this.parseProperty();
2395
+ if (prop) {
2396
+ properties[prop.key] = prop.value;
2397
+ } else {
2398
+ break;
2399
+ }
2400
+ }
2401
+ return {
2402
+ type: "expression-statement",
2403
+ expression: `animate("${target}", ${JSON.stringify(properties)})`,
2404
+ position: [0, 0, 0]
2405
+ };
2406
+ }
2407
+ /**
2408
+ * Parse modify command: modify target { prop: value }
2409
+ */
2410
+ parseModify() {
2411
+ this.expect("keyword", "modify");
2412
+ const target = this.expectIdentifier();
2413
+ if (!target) return null;
2414
+ const properties = {};
2415
+ if (this.check("punctuation", "{")) {
2416
+ this.advance();
2417
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
2418
+ this.skipNewlines();
2419
+ if (this.check("punctuation", "}")) break;
2420
+ const prop = this.parseProperty();
2421
+ if (prop) {
2422
+ properties[prop.key] = prop.value;
2423
+ }
2424
+ this.skipNewlines();
2425
+ }
2426
+ this.expect("punctuation", "}");
2427
+ }
2428
+ return {
2429
+ type: "expression-statement",
2430
+ expression: `modify("${target}", ${JSON.stringify(properties)})`,
2431
+ position: [0, 0, 0]
2432
+ };
2433
+ }
2434
+ /**
2435
+ * Parse UI Element: ui2d dashboard#id { ... }
2436
+ */
2437
+ parseUIElement() {
2438
+ const typeToken = this.currentToken();
2439
+ if (!typeToken) return null;
2440
+ const elementType = typeToken.value;
2441
+ this.advance();
2442
+ let elementId = `${elementType}_${Date.now()}`;
2443
+ const token = this.currentToken();
2444
+ if (token?.type === "punctuation" && token.value === "#") {
2445
+ this.advance();
2446
+ const idToken = this.currentToken();
2447
+ if (idToken) {
2448
+ elementId = idToken.value;
2449
+ this.advance();
2450
+ }
2451
+ } else if (token?.type === "identifier" && token.value.startsWith("#")) {
2452
+ elementId = token.value.slice(1) || elementId;
2453
+ this.advance();
2454
+ }
2455
+ const properties = {};
2456
+ if (this.check("punctuation", "{")) {
2457
+ this.advance();
2458
+ while (!this.check("punctuation", "}") && this.position < this.tokens.length) {
2459
+ this.skipNewlines();
2460
+ if (this.check("punctuation", "}")) break;
2461
+ const prop = this.parseProperty();
2462
+ if (prop) {
2463
+ properties[prop.key] = prop.value;
2464
+ }
2465
+ this.skipNewlines();
2466
+ }
2467
+ this.expect("punctuation", "}");
2468
+ }
2469
+ return {
2470
+ type: "ui2d",
2471
+ name: elementType,
2472
+ properties: { id: elementId, ...properties },
2473
+ position: [0, 0, 0]
2474
+ };
2475
+ }
2476
+ /**
2477
+ * Parse settings command: settings
2478
+ */
2479
+ parseSettings() {
2480
+ this.expect("keyword", "settings");
2481
+ return {
2482
+ type: "expression-statement",
2483
+ expression: "showSettings()",
2484
+ position: [0, 0, 0]
2485
+ };
2486
+ }
2487
+ parseChat() {
2488
+ this.expect("keyword", "chat");
2489
+ return {
2490
+ type: "expression-statement",
2491
+ expression: "openChat()",
2492
+ position: [0, 0, 0]
2493
+ };
2494
+ }
2495
+ /**
2496
+ * Parse a condition string into a structured TypeGuardExpression if applicable,
2497
+ * otherwise returns the string as-is.
2498
+ */
2499
+ parseConditionExpression(condition) {
2500
+ const isPattern = /^([a-zA-Z_][a-zA-Z0-9_]*)\s+is\s+["']([^"']+)["']$/;
2501
+ const match = condition.match(isPattern);
2502
+ if (match) {
2503
+ return {
2504
+ type: "type-guard",
2505
+ subject: match[1],
2506
+ guardType: match[2],
2507
+ line: 0,
2508
+ // Simplified for now
2509
+ column: 0
2510
+ };
2511
+ }
2512
+ return condition;
2513
+ }
2514
+ skipNewlines() {
2515
+ while (this.currentToken()?.type === "newline") {
2516
+ this.advance();
2517
+ }
2518
+ }
2519
+ };
2520
+
2521
+ exports.ERROR_CODES = ERROR_CODES;
2522
+ exports.HoloScriptCodeParser = HoloScriptCodeParser;
2523
+ exports.ParserPools = ParserPools;
2524
+ //# sourceMappingURL=chunk-JIYN45TV.cjs.map
2525
+ //# sourceMappingURL=chunk-JIYN45TV.cjs.map